If all IDE’s had support for defining the bricks using :local/root
then this would be less of a problem, because then the development
environment would look very similar to the other projects, except that it also needs to define the test
paths (and profiles, if any).
About your question @seancorfield “I haven’t figured out a good way, yet, of setting up test-only resources that can still easily be overridden when running the `poly` tool -- especially since the way you do it for the alias and for the AOT/shell-script version are essentially different. Hard problems.“. One solution would be to add support for profiles for all kind of projects, not just development
. Then all projects could have a default
profile that would be used if no profile was specified, and one or more profiles that can switch in/out different combinations of dependencies and paths (for example an extra test resources
directory). So if we run the test
command without any profiles specified, it would use the default
profile for each project (if exists) or if we run e.g. poly test +myprofile
then it will use the +myprofile
alias in each project (if any) when running the tests.
I can no longer figure out what problem I was trying to solve at the time I wrote the above so I’m not sure whether or not profiles would address the issue. For now, things are working “as expected” so I’m all good. I think this was mostly around — quite literally — a resources
folder that should be part of the :dev
context but didn’t seem to be picked up when running test :dev
, but I solved it by specifying an absolute path in my environment variable. If I ever run into a similar issue (or somehow manage to repro what I had tripped over) I’ll let you know!
Oh, interesting... Sounds like Leiningen 🙂 When I read over the profiles stuff in the docs, it didn't make much sense but I'll go back and take another look.
Ah, I see what you mean: right now this is development
only. I'll have to go back and look at what I was trying to do -- since it wasn't related to projects -- this was about components that are not yet used by a project (only by our existing "legacy" subprojects).
Yeah, reading over that, it might well do what I need... I'll let you know after I try it out tomorrow at work...
I have pushed some changes to the issue-66
branch:
- Create ~/.polylith/config.edn file if not exists when executing the poly command.
- Pass in JVM_OPTS in the poly command script.
- Resolve library versions correctly if used in more than one brick.
- Added :auto-add to the :vcs key, e.g. {:name “git”, :auto-add false}, that will only add files and directories to git when executing the create command if set to true.
- Only retrieve the latest sha if :latest-sha is passed in + make sure that it works offline.
- Updated the help.
Nice! I’ve wanted :auto-add false
for a while 🙂
An interactive poly
shell 🙂
(! 870)-> clj -Sdeps '{:deps {polyfy/polylith
{:git/url "<https://github.com/polyfy/polylith>"
:sha "0a29ee8fc800c1b055552d19c5a1401cc51c42cc"
:deps/root "projects/poly"}}}'
Clojure 1.11.0-alpha1
user=> (require '[polylith.clj.core.poly-cli.core :as p])
nil
user=> (require '[clojure.string :as str])
nil
user=> (loop [words (vec (str/split (do (print "poly> ") (flush) (read-line)) #" "))]
(when-not (= "quit" (first words))
(apply p/-main (conj words ":no-exit"))
(recur (vec (str/split (do (print "poly> ") (flush) (read-line)) #" ")))))
poly> info
stable since: 7701e4c | stable-sean
projects: 2 interfaces: 17
bases: 2 components: 17
project alias status dev
-------------------------------- ---
google-search-job gs --- ---
development * dev --- ---
...
poly> test :dev
Projects to run tests from: development
...
quit
user=>
Nice implementation!
The prompt-and-read expression should be a function of course but this means the startup overhead of running the tool is avoided. Perhaps something like this could be added to the poly-cli
as some sort of interactive
command? (`poly interactive`)
Yes, not a bad idea, and this actually something that is supported by the Leiningen based version https://github.com/tengstrand/lein-polylith#prompt (I’m not saying that people should start using that tool though!).
I’ll probably make a wrapper for use at work, for the time being. I have the paths/deps checking code up and running too, so I’ll probably wrap the check
command in interactive mode to run that report. I’ll share that once I have it cleaned up.
Thanks for sharing the Polylith architecture! I really like some ideas and I’m trying to explore the ones I don’t understand yet. I hope you don’t mind me asking some questions here 🙂
When adding a component it says "Remember to add src, resources and test directories to 'deps.edn"
.Since we are using tools.deps
, why don’t we rely on a deps.edn
file? This would make it also easier to isolate projects?
I am still wrapping my head around the interface approach and I’m wondering if working with protocols isn’t easier. This wouldn’t require swapping classpaths. I need to explore this more I guess
And I’m curious if we could make a Babashka version of the poly
tool to improve startup
LMK if you need help if you need to setup the poly tool using GraalVM 🙂
#graalvm may help as well
Yes, if you want to look into this, that would be great @ericdallo!
That’s it for now 🙂
E.g. I’m used to create components (the Stuart Sierra version of it). These components implement a protocol and switching between dev and production is switching a component in the system configuration
One argument I can think of this that it doesn’t worked well for test dirs
I guess you are working from the master
branch where we have to add the paths for the bricks that we use in each project (this is also what we recommend at the moment). In the https://github.com/polyfy/polylith/tree/issue-66 we instead let each brick (component/base) have its own deps.edn
file that can be included by the projects using the local/root
syntax. We are working hard to get this branch into a state where it can be merged back to master
. Hope this answered your question.
Ah great! I’ll have a look. Thanks!
Polylith takes another approach where each project is just a set of bricks, where each brick is a block of code. Once the bricks are put together they form a single codebase where all building blocks automatically “connect” to each other, and no other configuration is needed. You can get an idea how a Polylith workspace looks like together with Stuart Sierra’s components https://github.com/seancorfield/usermanager-example/tree/polylith.
Yes, that would be great (and I have had the same ide)! Maybe someone in the community could help out with this, and maybe create a PR, because there are a lot of other tasks that need to be done before this can be prioritised.
Thanks, i’ll have a look! I’m sure I’m not grasping everything yet
@jeroenvandijk Even on the issue 66 branch, you still have to manually add paths to the workspace-level deps.edn
file but Joakim has talked about maybe adding a sync
command to add things to the :dev
/`:test` aliases in that file, and I have some code I plan to release shortly that at least does a check to highlight anything that is missing (you need to add :extra-deps
to :dev
to match any :deps
from components that you add — and that’s always going to be partially manually since it is up to the developer to add new deps to components as they are needed).
It seems like an FAQ when folks first start looking at Polylith. The “problem” with a protocol is that you need a common first argument to dispatch on. With Polylith’s purely “functional interface” approach, that’s not needed: they are just regular functions. I also asked about this when I got started but now the functional interface approach seems natural.
Thank you @seancorfield
I’ve tidied up my little interactive poly
“REPL” and added the :dev
/`:test` deps/paths check — happy to donate it to the Polylith project if there’s interest:
(! 875)-> clojure -X:poly
OpenJDK 64-Bit Server VM warning: Option --illegal-access is deprecated and will be removed in a future release.
Welcome to Polylith!
poly> check
The following paths appear to be missing from :dev > :extra-paths
- components/crud-form/src
- components/host-services/resources
The following dependencies appear to be missing from :dev > :extra-deps
- com.google.apis/google-api-services-searchconsole #:mvn{:version v1-rev20201209-1.31.0}
- exoscale/coax #:mvn{:version 1.0.0-alpha12}
The following paths appear to be missing from :test > :extra-paths
- components/environment/test
- components/safe-coercions/test
OK
poly> quit
The check
command runs my dep/path check and then runs poly check
. All other commands are just passed as-is to poly
.Our :poly
alias:
:poly {; for our development/logging operations:
:jvm-opts ["-Dclojure.core.async.go-checking=true"
"-Dclojure.tools.logging.factory=clojure.tools.logging.impl/log4j2-factory"
"-Dlogged-future=synchronous"
"-XX:-OmitStackTraceInFastThrow"
"--illegal-access=warn"]
:extra-paths ["development/src"]
:extra-deps {polyfy/polylith
{:git/url "<https://github.com/polyfy/polylith>"
:sha "0a29ee8fc800c1b055552d19c5a1401cc51c42cc"
:deps/root "projects/poly"}
org.clojure/tools.deps.alpha
;; the add-libs branch
{:git/url "<https://github.com/clojure/tools.deps.alpha>"
:sha "241cd24c35ba770aea4773ea161d45276e5d3a73"}}
:exec-fn ws.poly-wrapper.interactive/repl
:main-opts ["-m" "polylith.clj.core.poly-cli.core"]}
(issue-66 branch head). clojure -M:poly
will run the regular poly
tool “one shot”. clojure -X:poly
will run my interactive wrapper. EOF or quit
will exit.(my deps-checking code currently relies on some parts of t.d.a that aren’t present in the t.d.a version poly
uses, although it could use "0.11.922"
instead of the add-libs
branch version)
Okay, nice work! I think this functionality could be part of the poly
tool as its own command, e.g. prompt
. I’m very curious to see your code, and I will put it up on my todo list to implement. It’s really cool what you can do with tools.deps CLI. It’s so composable!
Here’s the ws.poly-wrapper.interactive
namespace from the development/src
folder — feel free to incorporate whatever you want directly into poly
:
It doesn’t care if :dev
/`:test` contain more paths/deps, only if they contain fewer.
Ok, cool. I saw that you use t.d.a/slurp-deps instead of just slurp and read-string (as I currently do). I had a look at the t.d.a/slurp-deps and it does canonical-all-syms. Need to have a look what useful stuff that function does, and maybe I can use that in the poly tool instead.
I would definitely recommend updating to a more recent t.d.a than you are currently using and leveraging the functionality it provides for reading/merging deps.edn
files.
Good idea.