Fork me on GitHub
#polylith
<
2021-04-09
>
seancorfield05:04:44

Question: in our current monorepo setup at work, we rely on an alias (`:defaults`) in our workspace deps.edn file to “pin” the versions of 3rd party dependencies across all of our subprojects (via :override-deps). This allows for consistency of builds since all our code is tested and built against specific versions of libraries, and we treat library version updates as actionable tickets that require everything to be updated and tested in a single step. Polylith’s approach has nowhere to “hang” this alias in a single place: the development project and each individual project are all independent “top-level” deps.edn and there’s no commonality. In Polylith, we’d either have to carefully coordinate 3rd party library versions across all components or duplicate our :override-deps into all projects. Is this a pain point that anyone has run into and, if so, what was your solution?

3
tengstrand07:04:40

I think we should let the libraries be defined under :dev > :extra-deps and be the master of what library versions to use. Then we could introduce a sync command that updates the library version for all`deps.edn` brick and project files. Most dependencies would be defined in the bricks, but project files may also need to be updated if we change e.g. the version of Clojure itself (or other shared dependencies we might put there). The good thing with the brick deps.edn files is that we almost only change them if we need to add new libraries to them. With a sync command, we just have to update the version in the development project and execute the sync command.

tengstrand07:04:27

We could also add e.g. keep-library-version to workspace.edn where we can specify libraries that should keep the version that is specified for selected projects. This should be quite rare, but I’ve experienced that we have used different version in development and in production for a library (in a Java enterprise project where JBoss couldn’t be upgraded in prod). My philosophy is to guide people to do the right thing, but not stopping them from doing what they want.

seancorfield16:04:09

Well, more to the point, as Polylith stands right now, there is no way to “pin” a library version across multiple bricks via :override-deps — which allows you to pin transitive dependencies as well as explicit dependencies — in a single place. You could add :override-deps to the :dev alias for the brick dev/test but you would have to repeat that information in each of the project deps.edn that use those libs and I’m not clear on whether you’d need to add :override-deps to both the :test alias and whatever aliases are used for “builds”? If you have a dozen projects in a workspace — equivalent to what we have at work — then you potentially have to have those :override-deps in two dozen plus one places, I think? At least one dozen plus one.

seancorfield18:04:03

I don’t know what a solution might look like for this — or even whether it would be considered “in scope” — since we at WSN seem to be in a very small minority of people who actually use :override-deps in the first place 🙂

seancorfield18:04:26

If only the CLI had an option for an extra deps.edn file somewhere, this could be so much simpler…

tengstrand19:04:38

I totally understand why you want to keep the libraries in sync. We achieved the same thing with the sync command in the old Leiningen based version, and I think it will work even better in this tools.deps version. Yes, if they wanted, they could probably improve the monorepo experience quite easily, but it seems like they have other plans. About the tests, my idea is that people should use poly test to run different tests, and in that case the tool will include all the dependencies declared in the bricks (in contrast to tools.deps). If they need to run the tests through tools.deps, they will have to define the test dependencies in each project manually.

seancorfield16:04:09
replied to a thread:Question: in our current monorepo setup at work, we rely on an alias (`:defaults`) in our workspace `deps.edn` file to “pin” the versions of 3rd party dependencies across all of our subprojects (via `:override-deps`). This allows for consistency of builds since all our code is tested and built against specific versions of libraries, and we treat library version updates as actionable tickets that require everything to be updated and tested in a single step. Polylith’s approach has nowhere to “hang” this alias in a single place: the development project and each individual project are all independent “top-level” `deps.edn` and there’s no commonality. In Polylith, we’d either have to carefully coordinate 3rd party library versions across all components or duplicate our `:override-deps` into all projects. Is this a pain point that anyone has run into and, if so, what was your solution?

Well, more to the point, as Polylith stands right now, there is no way to “pin” a library version across multiple bricks via :override-deps — which allows you to pin transitive dependencies as well as explicit dependencies — in a single place. You could add :override-deps to the :dev alias for the brick dev/test but you would have to repeat that information in each of the project deps.edn that use those libs and I’m not clear on whether you’d need to add :override-deps to both the :test alias and whatever aliases are used for “builds”? If you have a dozen projects in a workspace — equivalent to what we have at work — then you potentially have to have those :override-deps in two dozen plus one places, I think? At least one dozen plus one.

tengstrand19:04:38
replied to a thread:Question: in our current monorepo setup at work, we rely on an alias (`:defaults`) in our workspace `deps.edn` file to “pin” the versions of 3rd party dependencies across all of our subprojects (via `:override-deps`). This allows for consistency of builds since all our code is tested and built against specific versions of libraries, and we treat library version updates as actionable tickets that require everything to be updated and tested in a single step. Polylith’s approach has nowhere to “hang” this alias in a single place: the development project and each individual project are all independent “top-level” `deps.edn` and there’s no commonality. In Polylith, we’d either have to carefully coordinate 3rd party library versions across all components or duplicate our `:override-deps` into all projects. Is this a pain point that anyone has run into and, if so, what was your solution?

I totally understand why you want to keep the libraries in sync. We achieved the same thing with the sync command in the old Leiningen based version, and I think it will work even better in this tools.deps version. Yes, if they wanted, they could probably improve the monorepo experience quite easily, but it seems like they have other plans. About the tests, my idea is that people should use poly test to run different tests, and in that case the tool will include all the dependencies declared in the bricks (in contrast to tools.deps). If they need to run the tests through tools.deps, they will have to define the test dependencies in each project manually.

seancorfield20:04:43

That sync command/option sounds interesting. Good to know that you already tackled that problem before.

seancorfield20:04:59

As for running the tests, that didn't answer my question - which was about the project tests, not the brick tests.

seancorfield20:04:41

I'm talking to other monorepo users to see what they're doing about library versions 🙂

seancorfield20:04:52

I don't honestly know how much value we're really getting out of this today so we may abandon it anyway. Maybe. Need to do some research and experiments.

seancorfield20:04:59

Oh, for a bit of fun, I looked into what it would take to start moving our repo over to Polylith: oh boy, that's a lot of renaming namespaces and moving files around!

seancorfield20:04:01

However, I will be building one or two new apps in the repo soon, so I will use the Polylith structure for those and see how it goes.