Continuing the discussion from Amazing Ideas that blew your mind:
I’ve spent quite a bit of time chatting with @tengstrand over the last few days and exploring Polylith with a lot of feedback in both directions. There’s a lot to take in about Polylith and I think some of the communication done about it so far has caused some folks – me included – to focus on parts of it that are not really core to the ideas behind it.
Joakim has already updated the Polylith website to clarify the core problems Polylith is trying to address and expanded the Polylith FAQ to answer several questions that cropped up on Slack and other places recently.
We’ve talked quite a bit about the naming and structure of Polylith projects and he’s made it clear to me that a larger degree of flexibility is allowed than the documentation currently suggests, and it’s possible that Polylith will soon explicitly allow some variations in naming and structure.
After addressing that, I voiced the opinion that Polylith’s tooling seemed to be a very powerful and a really important part of the whole package: the poly info
command provides a lot of information about the workspace structure and poly test
provides incremental testing because it understands the relationship between the various parts of a Polylith project. Joakim said the team had worked with the architecture for some years before building the tooling. It’s impressive tooling but, clearly, again not core to the ideas behind it.
There were a lot of small nuances about Polylith that I didn’t “get” at first but having talked with Joakim and also experimented with Polylith for a few days, I’m appreciating the concepts more:
- bases and components don’t need to specify their interdependence in their
deps.edn
files, only their external dependencies – it’s in the projects that the actual combination of bases and components comes together (this is key to the Lego-like aspect of Polylith) - projects are deliberately separated from both the bases and the root
deps.edn
file (used for development) – so you can both separate production from development (I got that bit) and so that you can build different deployable artifacts from similar collections of bases and components - the “strict” adherence to “interfaces” in components is what allows for the mix’n’match approach that lets you build those different deployable artifacts
I still feel the emphasis on functional delegation in several places is a bit of “boilerplate” but at least now I understand why that delegation is there and what it enables.
So I’ve decided to add a built-in polylith
template to clj-new
so that you can quickly get a minimal working Polylith project running locally:
$ clojure -Sdeps '{:deps {seancorfield/clj-new
{:git/url "https://github.com/seancorfield/clj-new"
:sha "d38b731d4d52ab57647c4462576197997c729491"}}}' \
-X clj-new/create :template polylith :name myname/myproject
$ cd myproject
$ clojure -M:poly info
... information about the workspace ...
$ clojure -M:poly test :all :dev
... run all the tests ...
$ (cd projects/myproject && clojure -X:uberjar)
... builds an application ...
$ java -jar projects/myproject/myproject.jar Lisa
Hello, Lisa!
$ (cd projects/myproject-lib && clojure -X:jar)
... builds a library ...
$ (cd projects/myproject-lib && clojure -X:deploy)
... deploys that new library to Clojars ...
$ clj -A:dev:test
... starts a REPL for development and testing against the workspace ...
Clojure 1.10.3
user=> (require '[myname.myproject.greeter.interface :as greeter])
nil
user=> (greeter/greeting {:person "ClojureVerse"})
"Hello, ClojureVerse!"
And, just like the poly create workspace
command, this also sets up git
and commits the initial version of the workspace so that Polylith can track changes etc. See the git
section in the Polylith README.
This is a work-in-progress, tracking changes being made to Polylith on its
issue-66
branch, but it will be part of the nextclj-new
release once the Polylith team has completed that work.