This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-02-28
Channels
- # announcements (1)
- # beginners (43)
- # calva (7)
- # clojure (48)
- # clojure-europe (19)
- # clojure-nl (1)
- # clojure-norway (24)
- # clojure-uk (4)
- # clojuredesign-podcast (4)
- # clojurescript (11)
- # conjure (15)
- # core-async (1)
- # cursive (1)
- # datomic (33)
- # events (1)
- # fulcro (2)
- # humbleui (21)
- # hyperfiddle (34)
- # introduce-yourself (1)
- # joyride (24)
- # lambdaisland (8)
- # lsp (3)
- # malli (30)
- # meander (2)
- # observability (5)
- # off-topic (2)
- # pathom (3)
- # polylith (26)
- # portal (5)
- # re-frame (28)
- # shadow-cljs (7)
- # spacemacs (2)
- # xtdb (6)
Any good examples how to build a library jar for publishing to a maven repository. I managed to whip up a project that could do it, but generating the pom.xml file was tricky, I ended up just copying all the transitive lib dependencies (from bases, components), into the deps.edn file of the project, or it wouldn't appear in pom.xml. The library can be produced from a component, base, or project, it doesn't matter to me.
just found this, definitely helpful https://clojurians.slack.com/archives/C013B7MQHJQ/p1633641521349900?thread_ts=1633579209.348500&cid=C013B7MQHJQ
You can look at how the poly tool deploys itself in its https://github.com/polyfy/polylith/blob/master/build.clj.
https://github.com/polyfy/polylith/blob/master/.circleci/config.yml has usage examples for different scenarios. It has more explanation https://cljdoc.org/d/polylith/clj-poly/0.2.19/doc/ci/polylith-ci-setup.
So a base
doesn’t have to follow any particular namespace structure (I could have my-ns.my-random-package.*
? In contrast with a component
that requires an interface named top-ns.my-component.interface*
?
I’m shipping an API (library), and was planning to have an example “usage” of that API. It sounds like I want a base
api
for the API itself, and also a base
example
that is example code for using the api? Should a base depend on another base? Or in my situation should I put example logic code in a project, where I understand src
is discouraged?
Pretty sure bases
have to have the <top-ns>.<base>.
prefix but otherwise are unrestricted. Easy enough to test with poly check
...
I've toyed with the idea of merging HoneySQL and next.jdbc
into a single Polylith monorepo but there are problems with shipping libraries from Polylith:
• shared nses will run into version conflicts if users end up depending, even transitively, on multiple libraries -- since you'll end up with the same (`component`) nses on both paths
• you can't put the library API in projects
if anything else in your code depends on it
• you shouldn't have bases
depending on each other
Polylith is designed for applications.
I don't know if there will ever be a solution. There's been some talk of adding machinery to rewrite nses to support libraries (so a shared component
would get rewritten to have a different <top-ns>.<component>.
prefix, presumably, based on the library project
) but that's fragile, IMO, and means you'd end up with nses in your library that didn't match your actual source code which messes with documentation generation (e.g., http://cljdoc.org) and potentially other tooling too.
So instead of shipping one library jar, it sounds like I could potentially ship multiple… base.jar, component.jar and component-fake.jar
. It just means the users would have to set up their dev so when running locally, they use one jar instead of the other. That sounds like it might jive with polylith model and might be acceptable as this is all internal facing code.
If component.jar
and component-fake.jar
contain the same nses, that can still cause those same conflicts if a user ends up with versions of both on their classpath due to some transitive dependency on your libraries...
When you build a jar with polylith it is effectively an uberjar(components are collapsed into it), and as a library you have all the issues that uberjar as libraries produce, and exclusions at the jar level don't fix those
if have two components CA and CB that implement the same interface, then both of their jars at a minimum will overlap in both defining the "same" interface namespace, where if you depend on different versions of CA and CB the interface namespace might have the same name between them but be different
that is before you even start looking at transitive dependencies between components and how those are packaged
CA/CB needing to be the same version number doesn’t seem too bad to me, although it would be nice if deps.edn allowed for a constant to be defined. The transitive dependencies. Not sure on that. I would want to build a jar that is devoid of any “overloaded” component interfaces, and a jar for each “overloaded” implementation. Being a newbie to polylist, I don’t know how difficult that would be to figure out.
Although, in general polylith isn’t looking like a “fit” for my purposes, which is disappointing. Sean’s https://corfield.org/blog/2021/02/23/deps-edn-monorepo/ might be more amenable.
> I would want to build a jar that is devoid of any “overloaded” component interfaces, and a jar for each “overloaded” implementation. Right, but as soon as someone else's library decided to depend on yours, they're going to have deps for each of those pieces at a specific version, and you're off into transitive dependency conflict land at that point. There really is no current safe way to build/deploy libraries from Polylith (short of some tool to rewrite namespaces -- sometimes called "shading" -- MrAnderson is an example).
More than a decade ago steve yegge proposed some feature to add to clojure, and I don't even remember what it was, and when he didn't get a hearty "hell yeah!" about it he soured on clojure pretty quickly and decided the clojure community was a bunch for crypto-MLers (like a crypto-catholic, but for the ml family of languages). I forget if he ever actually used that term, but it is what was associated with his critique in my mind. And I think polylith is in some ways doomed to disappoint because it plays to ML sensibilities (components are structures and interfaces are signatures) without being able to deliver on what people want from that (functors, parameterized module sort of things). Shading is a way to hack together generative functors on top of clojures existing namespace system.