Skip to content

Clojure CLI deps.edn

Jordi Burguet-Castell edited this page Dec 13, 2023 · 2 revisions

Whilst both Leiningen and Boot provide a somewhat "batteries" included approach to Clojure development and, in particular, building and deploying a library JAR file, the Clojure CLI is decidedly narrow in focus and uses the deps.edn file to specify "how to run programs". Accordingly, there are a large number of community tools available for the CLI and you have to mix'n'match them in order to assemble a pipeline of tools that you are happy with, as a developer.

Minimum Requirements

In order to publish a library to Clojars, you need a JAR file and a pom.xml file. Leiningen and Boot both have tasks to create JAR files and both will automatically create pom.xml files as needed for the deployment to Clojars. With the CLI, you need to handle both of these tasks separately and somewhat manually.

The CLI can create a minimal pom.xml file for your project using the clojure -Spom command. It will "guess" the group and artifact IDs, based on your project's directory name, and it will use a default version, but it will ensure the dependencies section in the pom.xml file matches your deps.edn file. You will generally need to edit pom.xml manually to set the group, artifact, and version appropriately.

To build a JAR file, the standard way is to use tools.build. If you have a build.clj file like the example at tools.build, you should be able to produce a JAR file with this command:

clj -T:build jar

The final step is to deploy your JAR file to Clojars, for which you can either use Maven (as described on the Deploying page) or a tool like deps-deploy:

env CLOJARS_USERNAME=username CLOJARS_PASSWORD=clojars-token clj -X:deploy

(assuming you have the :deploy alias appropriately defined in your deps.edn)

Expanding pom.xml

If you are planning to also setup your library's documentation on cljdoc.org then you will need additional sections in your pom.xml file. See the cljdoc.org FAQ for details.

If you created your project using clj-new, the built-in lib template will have generated a pom.xml that contains all of the information you need for deployment to Clojars and for building documentation on cljdoc.org. clj-new tries to ensure that the group and artifact values comply with Clojars' Verified Group Names policy and also the SCM information required by cljdoc.org is correct for projects based on either github.com or gitlab.com. See the Generated pom.xml file section of clj-new's README for more details.

If you are using depstar, you can ask it to update the version string in the pom.xml file automatically when building a JAR and it will try to keep the SCM information in sync with the version by also adjusting the tag field. See the pom.xml section of depstar's README. If you used clj-new to create your project, it will already include the :jar alias to run depstar.

Batteries Included

As noted in the previous section, if you created your new library project with clj-new, it will produce a suitable pom.xml file, it will have a :jar alias in deps.edn for building a JAR file, and it will also have a :deploy alias for deploying to Clojars.

The simplest workflow is:

# create a new library project:
clojure -X:new :template lib :name my-username/my-cool-lib
cd my-cool-lib
# edit and test your new masterpiece
...
# build a JAR for a specific version:
clojure -X:jar :version '"1.0.0"'
# deploy to Clojars
clojure -X:deploy

That last line assumes you have CLOJARS_USERNAME and CLOJARS_PASSWORD set appropriately as environment variables. If not, you can provide them on the command line as shown in the first section above.

The generated pom.xml starts off with:

  <groupId>net.clojars.my-username</groupId>
  <artifactId>my-cool-lib</artifactId>
  <version>0.1.0-SNAPSHOT</version>

and

  <scm>
    <url>https://github.com/my-username/my-cool-lib</url>
    <connection>scm:git:git://github.com/my-username/my-cool-lib.git</connection>
    <developerConnection>scm:git:ssh://[email protected]/my-username/my-cool-lib.git</developerConnection>
    <tag>v0.1.0-SNAPSHOT</tag>
  </scm>

When the JAR is built, both <version> and <tag> will be updated to reflect the new version. You can see how the qualified name used in the clojure -X:new command is reflected in the group, artifact, and SCM information.

The deps.edn file will include these aliases (along with others for testing and installing locally):

  :jar {:replace-deps {com.github.seancorfield/depstar {:mvn/version "2.0.211"}}
        :exec-fn hf.depstar/jar
        :exec-args {:jar "my-cool-lib.jar" :sync-pom true}}
  :deploy {:replace-deps {slipset/deps-deploy {:mvn/version "0.1.5"}}
           :exec-fn deps-deploy.deps-deploy/deploy
           :exec-args {:installer :remote :artifact "my-cool-lib.jar"}}

The :sync-pom true exec argument in the :jar alias ensures that when you build a JAR file, the dependencies will automatically be updated to reflect the latest information in your deps.edn file.