I’ve had a number of questions about uploading libraries to maven and clojars with pack. This is a tutorial on how to go about that.
Generate a pom.xml
Generate a pom.xml using clojure -Spom.
You must update this file with coordinates and an appropriate
version. To update your coordinates in the pom.xml, you need to update
the existing groupId, artifactId and version tags to match. This
example is equivalent to {com.acme/anvil {:mvn/version "0.1.0"}} in
deps.edn.
<groupId>com.acme</groupId>
<artifactId>anvil</artifactId>
<version>0.1.0</version>You should add repository information. This will enable tools like
https://cljdoc.org/ to generate documentation for your library. Put
this inside the <project> tags and update the links.
Example from cljdoc’s documentation
<scm>
<connection>scm:git:git://github.com/laforge49/aatree.git</connection>
<developerConnection>scm:git:ssh://git@github.com/laforge49/aatree.git</developerConnection>
<tag>edb7cefa9a01852b101ed742b278aaba8d832b02</tag>
<url>https://github.com/laforge49/aatree</url>
</scm>Install the pack alias
Run this command to add the pack alias to your deps.edn.
$ clojure -Sdeps '{:deps {pack/pack.alpha {:git/url "https://github.com/juxt/pack.alpha.git" :sha "dccf2134bcf03726a9465d2b9997c42e5cd91bff"}}}' -m mach.pack.alpha.inject 'c70740ffc10805f34836da2160fa1899601fac02'You may want to adjust the formatting afterwards.
Build your JAR
Pack provides a mode named “skinny jar”. This was originally designed for companies who deploy by uploading their classpath separately from their project. But it has a flag to not output the classpath at all, just a jar containing your project files. This separation can be used to create a jar that is suitable for upload to clojars.
$ clojure -A:pack #
mach.pack.alpha.skinny #
--no-libs #
--project-path anvil.jar#-
Load the pack alias, which will run the selected pack mode
-
Select the skinny mode of pack
-
Don’t output libs
-
Specify the name of your jar. Here, I selected “anvil.jar”.
Release the JAR
You have 2 options at this point, mvn or deps-deploy. mvn has a
sometimes better story around encryption of credentials, and is well
established. deps-deploy avoids having to install mvn, but is still
very new.
mvn approach
You will need to set up your ~/.m2/settings.xml in order to add
authentication information for your upload destination.
Example settings.xml for Clojars
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
https://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>clojars</id>
<username>wil_e_coyote</username>
<password>r04drunn3R$</password>
</server>
</servers>
</settings>The above example leaves your password in plaintext on your filesystem. I highly recommend utilising maven’s password encryption.
Now you are ready to upload your JAR and pom.xml to upstream using
mvn deploy:deploy-file.
Upload to clojars
$ mvn deploy:deploy-file \
-Dfile=anvil.jar #
-DrepositoryId=clojars \
-Durl=https://clojars.org/repo \
-DpomFile=pom.xml
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building anvil 0.1.6
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-deploy-plugin:2.7:deploy-file (default-cli) @ anvil ---
Uploading: https://clojars.org/repo/com/acme/anvil/0.1.6/anvil-0.1.6.jar
Uploaded: https://clojars.org/repo/com/acme/anvil/0.1.6/anvil-0.1.6.jar (780 B at 0.3 KB/sec)
Uploading: https://clojars.org/repo/com/acme/anvil/0.1.6/anvil-0.1.6.pom
Uploaded: https://clojars.org/repo/com/acme/anvil/0.1.6/anvil-0.1.6.pom (980 B at 0.4 KB/sec)
Downloading: https://clojars.org/repo/com/acme/anvil/maven-metadata.xml
Downloaded: https://clojars.org/repo/com/acme/anvil/maven-metadata.xml (439 B at 0.8 KB/sec)
Uploading: https://clojars.org/repo/com/acme/anvil/maven-metadata.xml
Uploaded: https://clojars.org/repo/com/acme/anvil/maven-metadata.xml (470 B at 0.2 KB/sec)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.475 s
[INFO] Finished at: 2018-11-18T13:18:06+00:00
[INFO] Final Memory: 12M/317M
[INFO] ------------------------------------------------------------------------- Replace this with the name of your jar.
Deps Deploy
slipset has made a wonderful clojure library named deps-deploy.
You can add an alias for it in your deps.edn:
{:aliases
{:pack {…}
:deploy {:extra-deps {deps-deploy {:mvn/version "RELEASE"}}
:main-opts ["-m" "deps-deploy.deps-deploy" "deploy" "anvil.jar"]}}Then you can invoke it:
$ export HISTFILE=/dev/null#
$ CLOJARS_USERNAME=wil_e_coyote CLOJARS_PASSWORD='r04drunn3R$' clojure -A:deploy
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Deploying com.acme/anvil-0.1.4 to clojars as Smeagol
done.- This is to disable history from storing your username & password in plaintext.
Example
There’s an example at https://github.com/SevereOverfl0w/super-duper-octo-barnacle. You can update the groupId in the pom.xml and deploy it as a test to your own groupId.


