polylith

msolli 2024-11-28T09:01:07.644809Z

Good morning! Just getting started with Polylith, and I have question about its usage with Cursive, specifically tools namespaces in projects that aren't recognised by Cursive (see screenshot). In my workspace I have a project with a :build alias in its deps.edn. It references a build.clj file (`:ns-default build`) in the project dir. The project is a "module" in IntelliJ Project Structure, and the build alias has been checked in the "Tool Aliases" section of the Clojure Deps tool window. How can I teach Cursive to see this file as part of the project?

imre 2024-11-28T10:03:09.704049Z

Here's what I did:

imre 2024-11-28T10:03:12.845909Z

1. I have a build base and build project housing it. Most of my build code is in the base and I have some parts in components 2. I have the base (and component dependencies) included in my dev alias so they are available in the dev repl 3. my :build alias hase the build project in its extra-deps, and has the main namespace from the build base as :ns-default

imre 2024-11-28T10:07:42.201869Z

this worked fine so far

msolli 2024-11-28T10:09:41.576639Z

Sounds reasonable, I'll give that a try. Thanks!

imre 2024-11-28T10:19:53.208229Z

Would you mind pinging back here once you do please? This bit is something I often wonder if I've overengineered.

imre 2024-11-28T10:20:11.171409Z

And I'd be interested in your experience with it.

msolli 2024-11-28T10:22:14.834749Z

Sure! I'm tinkering now. Will report back tomorrow. I have several artifacts that must be built in a similar way, so it makes sense to parameterize the build, and more generally just treat it as any other code.

msolli 2024-11-28T10:24:09.918809Z

Re: overengineering: I'm just getting started with Polylith, and there is (I feel) a fair bit of plumbing that must be set up just so. But doing that forces more structure into the whole workspace, which will pay off.

imre 2024-11-28T10:25:21.548199Z

> just treat it as any other code This is exactly why I put it into the poly workspace proper. Since I already have the workspace with multiple deployables (projects, executables, programs, however you call it) in it, it just didn't make sense to have build (another program) outside of that structure.

👍 1
msolli 2024-11-28T10:39:36.611599Z

A related question: Do you import all components, bases and projects as separate modules in IntelliJ?

imre 2024-11-28T10:40:43.097249Z

Not explicitly, but I think that's how Cursive does it by default. There are some important settings you'll want to double-check, see https://cursive-ide.com/userguide/polylith.html

msolli 2024-11-28T10:42:59.415039Z

Yeah, I've set those. I'm just puzzled about the workflow after creating new bases (for example) with poly create . Should I then "Import module" and select the new base dir? Or re-import the whole workspace (root deps.edn)?

imre 2024-11-28T10:43:36.674339Z

unless you run into issues I wouldn't bother

imre 2024-11-28T10:58:12.876949Z

> When Cursive syncs a polylith project, the main app and the individual components are all synced as IntelliJ modules

imre 2024-11-28T10:59:57.715759Z

I think by "sync", Colin here refers to the "Refresh Clojure Deps Projects" action

msolli 2024-11-28T11:02:27.584329Z

Ah, I see. Just tried it, and that is indeed what happens. 👌

seancorfield 2024-11-28T16:35:57.901189Z

I can't speak to Cursive -- I use Calva -- but at work we have build.clj at the top-level and don't treat it like part of Polylith. However, that also means that we have to manually manage its dependencies "separately" too and I've been thinking about making more of it into a base and having a proper project for the build, so it's interesting to read this thread and see how others have done it. Do you still have a top-level build.clj file at all, or is it subsumed into <top-ns>.build and you just work with that instead?

imre 2024-11-28T18:03:01.874459Z

I don't have a top-level build.clj, just use a namespace from the base so it's similar to <top-ns>.build at the moment. :ns-default in the build alias makes it convenient to use it.

seancorfield 2024-11-28T18:55:46.502349Z

Gotcha. That's what I assumed for the changes I'm currently making at work 🙂

👍🏼 1
msolli 2024-11-29T07:50:25.137579Z

I've successfully moved my build programs into the structure that you outlined, @imre. It works beautifully, thank you! I now have one mycompany.build namespace (in a build base, point 1 above) with both general functions for building jars, and more specialized functions for building the various jars (defining the lib names, target dirs, versions and so on). This namespoace can be exercised from the dev REPL (point 2 above). In the top-level deps.edn there's a :build alias with {:local/root "projects/build"} and :ns-default mycompany.build . The jar-building functions in mycompany.build are called from the command-line with clj -T:build <build-some-jar-fn>.

msolli 2024-11-29T07:54:50.701299Z

I don't know if it's necessary to have a build project, though. As per the Polylith docs, projects are for assembling code into artifacts - here we're just using the code in the base.

msolli 2024-11-29T08:00:20.524919Z

The build project seems like an unnecessary indirection. The only thing it does is specifying the Clojure version and depending on the build base. I'm now experimenting with using the base directly from :build alias, and it seems that works fine. Is there some advantage to having a project for this that I'm missing, given my very limited experience with Polylith?

imre 2024-11-29T09:20:08.724719Z

I suppose it doesn't make too much difference if all your build code is in the base. I have some utility components used both by build and production code and so the project references all of them (base plus components needed). I could reference all those in the build alias too, but having them in the project makes poly check aware of them and signals if I forgot to include a component dep.

msolli 2024-11-29T10:24:15.602629Z

Gotcha, makes sense!

seancorfield 2024-11-29T16:16:26.394219Z

If you have projects, poly test will runs tests for each project, to exercise any code that changes -- useful if you end up with tests for your build (base), or you build depends on components that changed.

👍 1
imre 2024-11-29T16:16:58.982629Z

Also true!