polylith

https://polylith.gitbook.io/ and https://github.com/polyfy/polylith
seancorfield 2021-04-17T00:10:29.127900Z

After a bit of back and forth at work, we’ve decided to abandon :override-deps and just live with repeated dependency declarations. That opens up the ability for any new Polylith code we write to depend on “legacy” subprojects while we tease them apart into components.

tengstrand 2021-04-17T07:47:53.129600Z

A small adjustment of what I just wrote could be to always pick the latest version of the libraries, and then have warnings for the projects (`dev` included) that use earlier versions (if not overridden). The warning could be skipped if a brick uses an older version, as long as all projects use at least one other brick that uses the latest version. The libs command would end up with a lot of different versions of the libraries, so that could look a bit messy, so I think a sync command could still be useful.

tengstrand 2021-04-17T12:26:18.129900Z

I tested to use only :extra-deps in both Calva and Cursive for the ./deps.edn file and it turned out to work! In Calva everything works as expected as soon as you start the REPL. In Cursive, you don’t get the coloring of the src directories, but except from that, it also works!

seancorfield 2021-04-17T18:36:56.139200Z

Cool. Yes, automatically checking consistency of lib versions sounds like a great thing — with an option to turn off the warnings 🙂 And then a sync command for folks who are not in my camp — and even there, I’d want the default behavior to be “tell me what changes you would make” and you have to provide an explicit option to actually make those changes, so you could choose to have it sync just one project at a time if you want.

tengstrand 2021-04-18T01:57:02.144Z

Yes, now when we have the new :projects attribute in workspace.edn we could easily add a sync attribute that could either be left out or set to on or off, be set to auto which would automatically keep all libraries in sync when you run certain commands, and maybe an attribute warn that could be set to true/false. I will think more about this later, but yes, it’s not hard to support.

seancorfield 2021-04-18T01:59:51.144200Z

Did you have any more thoughts about the git root issue we discussed a while back? (last week)

tengstrand 2021-04-18T02:01:19.144400Z

Yes, I think the solution where the tool searches for the git root, starting from the directory where the command is executed, would solve the problem, which would also support your use case.

seancorfield 2021-04-18T02:01:57.144600Z

Awesome! Thank you.

tengstrand 2021-04-18T02:02:05.144800Z

You are welcome!

tengstrand 2021-04-17T05:52:04.128Z

Okay. I guess this can be cleaned up when the sync command is added to the poly tool.

seancorfield 2021-04-17T05:58:18.128200Z

When you get around to writing that for the CLI/`deps.edn` version, I have opinions 🙂

seancorfield 2021-04-17T05:59:39.128400Z

I think the definitive source should be the brick's dependencies and the options should be to update :dev to match and/or update each individual project to match -- but it should also be possible for :dev and/or any individual project to override the brick's version.

seancorfield 2021-04-17T06:00:26.128600Z

So a tool that said "brick X's dep version if A but :dev has B and project Y has C" would be a good place to start.

seancorfield 2021-04-17T06:00:56.128800Z

(I'm not much of a fan of tools that update my files for me, so err on the side of opt-in, rather than opt-out)

tengstrand 2021-04-17T06:36:56.129Z

I think we need a single place that specifies the default version of all the libraries which naturally could be the ./dep.edn file. Using the latest version of all libraries is a good default for the dev project, because that’s the place we work with all our code. As I see it, it’s also good if the whole codebase uses the latest version of the libraries (at least as default). Otherwise we could end up using different versions of a library in different projects. Let’s say component a uses version 1.0 of a library, but component b uses 1.1. Then if only a is used in a project, then that project will pick version 1.0 whereas projects that include b will use 1.1. A solution is to print warnings if a component doesn’t use the latest version of a library, so that it can be manually updated or fixed by executing the sync command.

tengstrand 2021-04-17T06:55:02.129200Z

The current version of the poly tool in the issue-66 branch already supports including bricks by using extra-deps in the devproject. The reason I don’t use it right now is that Cursive (that I use) doesn’t recognise the source code from the bricks. If it could, then that would solve our problem even more elegantly letting all projects include bricks using extra-deps . The latest version for all libraries that are included in dev via its bricks, could then be the “master” for the library versions.

pavlosmelissinos 2021-04-17T18:33:40.138900Z

Can the interface of a component be in a nested namespace? If :top-namespace is "se.example" , se.example.user.interface would be a valid namespace for the interface of component user . What happens though if you want to have namespaces for your components that correspond to a (reverse) domain, e.g. se.example.com.domainA.interface, se.example.com.domainB.interface and se.example.de.domainC.interface or disambiguate between similar tasks by introducing a namespace level e.g. se.example.case1.parser and se.example.case2.parser. Is that even possible? FYI, I'm also using the issue-66 branch edit: renamed namespaces to use the same prefix

seancorfield 2021-04-17T19:01:36.142200Z

@pavlos First off, I think you need the :top-namespace to be consistent across the whole workspace, but I think you could get close to what you want with sub namespaces in interfaces: se.example.user.interface.domainA, se.example.user.interface.domainB, se.example.user.interface.domainC? The README of the poly tool talks about this:

This can be handy if we want to group the functions and not put everyone into one place. A common usage is to place clojure specs in its own spec sub namespace, which we have an example of in the RealWorld example app, where the article component also has an interface.spec sub interface.
and gives an example of <top-namespace>.util.interface.color etc.

👍 1
seancorfield 2021-04-17T19:04:46.143300Z

(I have also felt a bit limited by the single segment brick names but I suspect I’ll end up using kebab-case a lot more for naming bricks over time and I won’t feel that way)

👍 1
pavlosmelissinos 2021-04-17T20:27:59.143800Z

@seancorfield Sub-namespaces would not work I believe because I'd like to have a separate component for each of the domains! kebab-case was my backup plan in case the original didn't work. It's reassuring that you think it's a good workaround 🙂 (namespaces have no notion of hierarchy anyway, so it's not a huge deal)