Fork me on GitHub
#leiningen
<
2022-05-12
>
Ferdinand Beyer08:05:25

Hello! I seem to be missing some understanding how Leiningen processes profiles. In my case, lein pom includes some unexpected dev/test dependencies. project.clj defines the following profiles:

:profiles {
   :dev           [:project/dev]
   :test          [:project/dev :project/test]

   :project/dev  {:jvm-opts ["-Dconf=dev-config.edn" ]
                  :dependencies [[pjstadig/humane-test-output "0.10.0"]
                                 [cprop "0.1.17"]
                                 [mount "0.1.16"]]
                  :plugins      [[com.jakemccrary/lein-test-refresh "0.24.1"]
                                 [lein-cljfmt "0.6.4"]]
                  :source-paths ["env/dev/clj"]
                  :injections [(require 'pjstadig.humane-test-output)
                               (pjstadig.humane-test-output/activate!)]}
   :project/test {:jvm-opts ["-Dconf=test-config.edn" ]
                  :resource-paths ["env/test/resources"]
                  :dependencies [[org.testcontainers/testcontainers "1.15.3"]
                                 [org.testcontainers/kafka "1.15.3"]]}}
We are creating a library from that, and the generated pom claims that dependencies from :project/dev and :project/test are required for the library. I expected them to be “stripped out”, as they don’t have the ^:leaky metadata (as described in PROFILES.md)?

mikerod13:05:35

@ferdinand Indeed those profiles should not be included when the pom is created. How are you calling the pom cmd and what’s the generated pom look like? Also do you have any non-profile :dependencies in the project?

Ferdinand Beyer14:05:15

I noticed this from an application project that uses the library that is based on the project.clj excerpt above. So I first noticed it from lein release I then verified that calling lein pom creates the pom.xml with all dependencies in the “default” scope. Meanwhile I improved it by getting rid of the :project/dev and :project/test profiles and moving the dependencies to :dev and :test directly, so that the deps get the “test” scope in pom.xml. Ideally though, I’d like for them to not show up at all. There are indeed additional non-profile :dependencies

mikerod16:05:28

The pom task definitely strips out non leaky profiles. So I'm still unsure what you seeing

Ferdinand Beyer07:05:28

Here is a minimal example.

$ lein version
Leiningen 2.9.8 on Java 17.0.2 OpenJDK 64-Bit Server VM
project.clj:
(defproject demo "0.1.0-SNAPSHOT"
  :dependencies []
  :profiles {:dev [:dev-only]
             :dev-only {:dependencies [[org.clojure/tools.namespace "1.2.0"]]}})
So you can see that :dev includes :dev-only and the intention would be to have dependencies here that the demo library does not need during runtime, only during development.
$ lein pom
Wrote /private/tmp/lein-pom/pom.xml
The resulting pom.xml contains (stripped the irrelevant parts):
<?xml version="1.0" encoding="UTF-8"?>
<project ...>
  ...
  <dependencyManagement>
    <dependencies/>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.clojure</groupId>
      <artifactId>tools.namespace</artifactId>
      <version>1.2.0</version>
    </dependency>
  </dependencies>
</project>

<!-- This file was autogenerated by Leiningen. ... -->
As you can see, it contains tools.namespace as a dependency, making users of the demo lib depend on it as well. This dependency is not stripped. Removing the :dev-only profile and adding the dependency to :dev gives me:
<dependencies>
    <dependency>
      <groupId>org.clojure</groupId>
      <artifactId>tools.namespace</artifactId>
      <version>1.2.0</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
So now tools.namespace is required for the test scope, which is actually also not what I want but at least this does not add a transitive dependency. Given Leiningen’s maturity, I’m pretty sure this is not a bug but I am misunderstanding how Leiningen treats profiles 🙂

mikerod13:05:52

This definitely seems wrong to me. Probably worth posting a GitHub issue with this example