Welcome! Please see the About page for a little more info on how this works.

+3 votes
in tools.build by
recategorized by

To work appropriately in the Java ecosystem, optional dependencies for libraries can be included with scope 'provided' within a pom.xml file.

deps.edn explicitly does not support including dependencies with a scope of 'provided', in favour of using aliases.

In order to work well as a library within a wider Java ecosystem, it would be very helpful to be able to write out a library jar file with a pom.xml file with additional dependencies that are not included in deps.edn, but with a scope of 'provided' for Java build tools.

An example is cljdoc, which cannot build documentation when a library is built and all dependencies are not included appropriately.

'write-pom' already has an option to include a template 'source' pom.xml, but the dependencies are overwritten with information from the deps.edn file.

There are workarounds - e.g. see thread https://clojurians.slack.com/archives/C8V0BQ0M6/p1680090647156119 which patch the process to include deps with a 'provided' scope - but they are not ideal.

Options.

  1. do nothing - we monkey patch tools.build as per Slack thread example, or otherwise alter the generated pom.xml to include additional 'provided' scope deps.

  2. merge existing dependencies from the source (template) pom.xml instead of overwriting [but perhaps a breaking change]

  3. provide an additional parameter to 'write-pom' to include arbitrary deps, a sequence of maps that are converted to XML including :scope which would be :provided for these optional dependencies.

  4. work with cljdoc to support aliases so that documentation builds can be customised by library authors so builds such as this do not fail.

1 Answer

+2 votes
by
by
I think I would lean towards #3 on first impression.
by
By following #3, will it be possible to have something like `:pom-plugins` Leiningen equivalent, that will generate `<plugins><plugin>...</plugin></plugins>` block?

Or is there are better way to add a custom maven blocks? Some maven plugins can add new elements and attributes as well.
by
For sections other than :dependencies, :repositories, and the few other things we set, it's best to put that info in the template pom.xml.
by
I'll chime in on cljdoc's current behaviour:

> An example is cljdoc, which cannot build documentation when a library is built and all dependencies are not included appropriately.

This is true.  Sometimes, a library x will not want to force a dependency on a library y and, therefore, not specify it explicitly. Library x's documentation will specify that the user should also depend on library y should they wish to use certain features.

As of this writing, cljdoc loads a library dynamically to discover its public API. If a library's code uses a missing dep, API analysis will fail. Cljdoc's current convention for specifying optional libraries is via provided deps as documented here: https://github.com/cljdoc/cljdoc/blob/master/doc/userguide/for-library-authors.adoc#getting-dependencies-right.

This doesn't mean this is the only way cljdoc will ever support optional deps; it is one (and currently the only) technique we've come up with so far.  

Also, cljdoc does have plans to support static analysis of libraries via clj-kondo analysis data. Deps are not consulted for static analysis, and therefore, optional deps will not be an issue under static analysis.
...