clojure-maven-plugin
conveniently integrates Clojure tooling and processing steps into your Maven builds.
Intentionally Spartan, it is specifically designed to wrangle those critters commonly found in Clojure- and Java-slinging development shops, likely the ones you are using now:
- Apache Maven, the primary driver of your build.
clojure
CLI tooling and itsdeps.edn
ecosystem.- Leiningen
project.clj
workflows.
This plugin doesn't offer any new packaging type such as clojure
.
First, ensure your Maven build uses the Clojars repository for dependency and plugin resolution with this snippet:
<repository>
<id>clojars.org</id>
<url>https://repo.clojars.org/</url>
</repository>
in each of the <repositories>
and <pluginRepositories>
sections in the appropriate Maven
configuration, such as your pom.xml
.
Execute the CLI clojure
command in a sub-process using the Maven project classpath.
<plugin>
<groupId>vivid</groupId>
<artifactId>clojure-maven-plugin</artifactId>
<version>0.3.0</version>
<executions>
<execution>
<id>leiningen-release-build</id> <!-- Each execution requires a unique ID -->
<phase>compile</phase> <!-- Tie goal execution to the desired Maven phase -->
<goals>
<goal>clojure</goal> <!-- The vivid:clojure-maven-plugin Clojure goal -->
</goals>
<configuration>
<!-- Optional path to the clojure executable -->
<executable>clojure</executable>
<!-- Optional arguments to Clojure. CDATA might be necessary to handle dashes. -->
<args>release</args>
<!-- Maven classpath scope provided to `clojure`.
Defaults to COMPILE. Other values are TEST and NONE. -->
<classpathScope>TEST</classpathScope>
<!-- Defaults to Maven's default of just src/main/clojure -->
<sourcePaths>
<sourcePath>src/main/clojure</sourcePath>
</sourcePaths>
<!-- Defaults to Maven's default of just src/test/clojure -->
<testPaths>
<testPath>src/test/clojure</testPath>
</testPaths>
</configuration>
</execution>
</executions>
</plugin>
Skip tests by setting the skip
parameter to true.
Also honors the maven.test.skip
parameter and -Dclojure-maven-plugin.clojure.test.skip=true
.
Writes a deps.edn
file that replicates each of the clojure
goal execution configurations in the POM.
They can then be directly run by the clojure
CLI tools.
The Maven goal runs during the generate-resources
phase by default.
<plugin>
<groupId>vivid</groupId>
<artifactId>clojure-maven-plugin</artifactId>
<version>0.3.0</version>
<executions>
<execution>
<id>hello-wumpus</id> <!-- Each 'clojure' goal execution ID servers as the deps.edn alias -->
<goals><goal>clojure</goal></goals>
...
</execution>
...
<execution>
<goals>
<goal>deps.edn</goal> <!-- The vivid:clojure-maven-plugin deps.edn goal -->
</goals>
<configuration>
<!-- Optional. Specify where to write the file. If a directory, deps.edn will
be written to that directory. Paths in deps.edn are written relative to
Maven's $project.basedir -->
<pathname>../projects/deps.edn</pathname>
</configuration>
</execution>
</executions>
</plugin>
To run the deps.edn
goal from the CLI:
$ mvn vivid:clojure-maven-plugin:deps.edn
...
[INFO] --- clojure-maven-plugin:0.3.0:deps.edn (default-cli) @ multiple-use-project ---
[INFO] Wrote deps.edn
Continuing with the running example, the deps.edn
file now has an :alias
for :hello-wumpus
that replicates the same classpath and options as its originating clojure
Maven goal:
{:aliases {:hello-wumpus {:extra-paths ["src/main/clojure"
"target/classes"]
:main-opts ["-m hello-wumpus.core"]
:extra-deps {org.clojure/clojure {:mvn/version "1.10.1"}}}
... }}
and can be run with:
$ clojure -A:hello-wumpus
Hello from planet Irata!
Useful for bringing a build into other tooling for further work or experimentation. Now, wasn't that .. anticlimactic? And, boring? And time-saving? And effective? And reliable? Just like Maven..
Execute Leiningen directly within Maven's running process.
Faster and less resource-intensive than running lein
in a sub-process.
<plugin>
<groupId>vivid</groupId>
<artifactId>clojure-maven-plugin</artifactId>
<version>0.3.0</version>
<executions>
<execution>
<id>leiningen-release-build</id> <!-- Each execution requires a unique ID -->
<phase>compile</phase> <!-- Bind goal execution to the desired Maven phase -->
<goals>
<goal>leiningen</goal> <!-- The vivid:clojure-maven-plugin Leiningen goal -->
</goals>
<configuration>
<!-- Immediately prior to running Leiningen, vivid:clojure-maven-plugin will
automatically download the specified version of Leiningen and its
dependencies as necessary using Maven's dependency resolution system. -->
<version>2.9.3</version>
<!-- Leiningen tasks, aliases. Any valid 'lein' CLI arguments can be used here. -->
<args>release</args>
</configuration>
</execution>
</executions>
</plugin>
Current working directory:
For the duration of an invocation of Leiningen, both user.dir
and Leiningen's own leiningen.core.main/*cwd*
var are
set to the Maven module's basedir
, giving Leiningen and its various tasks the information they need to correctly
determine the current working directory.
Afterwards user.dir
is restored to its prior value.
Portions of a Leiningen run might express ill behavior with file paths in the context of a Maven multi-module build;
tasks must account for user.dir
.
Run the tests and build the deliverables:
bin/test.sh
Motivation: Among the methods of integration Clojure tooling into Maven, none provided the integrative experience of IntelliJ (Maven classpath) and CI (JUnit reporting).
This project is licensed under the Apache License Version 2.0, modulo portions derived from these donors:
-
Inge Solvoll
lein-maven-plugin
. MIT License. -
James Reeves
eftest
. Eclipse Public License 1.0. -
CMP logo illustration by ei8htz.
© Copyright Vivid Inc.