{:deps/prep-lib {:alias :build
:fn compile
:ensure "target/classes"}}
09 July 2021
Fogus
Several years ago, Clojure introduced deps.edn (a data definition for dependencies), tools.deps (a library for computing classpaths), and the Clojure CLI to run programs. The Clojure community has widely adopted these and we are excited today to provide a clear path for users looking to use these same tools to build their projects:
tools.build - a library for building artifacts
CLI updates to make working with source repos as libs easier
CLI updates for installing, introspecting, and using custom tools
Builds are processes and are best represented as programs. The tools.build library provides building blocks to write build programs - this is a modular and compositional approach to artifact building, making the best use of Clojure itself as the language.
We take advantage of Clojure’s dynamic nature to use source repositories directly as libraries, avoiding the overhead of building, deploying, and consuming artifacts. While most Clojure libraries can be consumed directly as source, sometimes they require a preparation step (like compiling Java in mixed source projects). We’ve added support for this as well.
Finally, we’ve enhanced making, installing, and running custom tools that run independently of the project classpath. Tools embrace all of the ideas above and require only a git repository for others to install and run.
The new tools.build library is a set of helper functions for writing build programs. To add a build for your deps.edn project, you will:
Write a Clojure program that uses tools.build to build your project
Provide function entry points in your program for whatever targets make sense (things like clean
, compile
or jar
)
Add an alias to your deps.edn that invokes your build program and includes tools.build as a dependency
Invoke the build as a tool using -T
. -T
is similar to -X
but omits the project classpath and includes the root of the project as one of the :paths
.
For more details and full examples, see the following:
Due to Clojure’s dynamic nature, we can directly use source repositories as libraries without the overhead of making, distributing, and consuming artifacts. This release provides some updates for git libraries:
Git repository urls are now optional and inferred if the library name follows a naming convention
Git tag and short git sha prefix are now sufficient to identify a git lib version. The prefix is included to verify that the tag has not moved (both must point to the same commit).
Occasionally, source dependencies will require preparation (e.g. compilation, resource text replacement, code gen, etc.) to use them on the classpath. A common case is needing to compile Java source in a mixed source library. A source-based lib declares how it should be prepped in its deps.edn:
{:deps/prep-lib {:alias :build
:fn compile
:ensure "target/classes"}}
The Clojure CLI library checks that the :ensure
directory exists and if it’s not found, program execution will not proceed. To tell the CLI to prepare this (and any other libraries), you can run the command:
clj -X:deps prep
This command will find the unprepped libs, and run the compile
function using the :build
alias, presumably filling the target/classes
directory with necessary classes to put on the classpath ("target/classes"
should be in the project :paths
). More information on supporting unprepped dependencies is available in the Clojure CLI reference.
We have also enhanced the Clojure CLI to explore, install, invoke, and introspect tools based on a set of conventions for tool creators. Installing a new tool such as tools.deps.graph can be done as follows:
clj -Ttools install io.github.clojure/tools.deps.graph '{:git/tag "v1.0.63"}' :as graph
The use of a Git library name io.github.clojure/tools.deps.graph
and the git tag v1.0.63
allows the CLI to find and install the tool as graph
, which is the name that used for invocation, a la clj -Tgraph <function> <args>
. In this one case, a :sha
is not required (but it will be resolved and recorded to check for a match in the future).
The command above uses -Ttools
which is invoking the tools
tool, which is automatically installed by the Clojure CLI.
The CLI also provides a way to explore the available versions of tools with the clj -X:deps find-versions
command to list the tags available for a tool (also works for Maven versions).
Finally, there are new help/doc
and help/dir
functions available in the :deps
alias for introspecting what functions are available and how to use them. For example, you can run:
clj -X:deps help/doc :ns help
To look at the documentation for the clojure.tools.cli.help
namespace.
More information on the new tools support in the CLI is available in the reference docs.
A prerelease version of the CLI is now available: 1.10.3.905.
On Mac or Linux, you can install the prerelease using brew. On Linux or Windows you can use the installer per the instructions in Getting Started to install the specific version above.
All items below are additive updates, there should be no changes required for existing deps.edn projects or CLI usage.
tools.build - a new library for builds
deps.edn:
If a git library name follows the repo convention names, the :git/url
can now be inferred (:git/url
can also be specified explicitly and takes precedence)
:git/tag
and short :git/sha
can now be specified instead of the full sha. Both must point to the same commit.
:sha
has been renamed to :git/sha
but the original is still supported for backwards compatibility
A new :deps/prep-lib
top-level key is used to say how a lib is prepared with the following keys: :alias
, :fn
, and :ensures
. See prep docs for more.
A new :tools/usage
top-level key is used to provide the :ns-default
and :ns-aliases
context for a tool
New -T
switch is like -X
(invokes a function) but omits the project :paths
and :deps
and adds :paths ["."]
to provide a clean tool classpath. -T:aliases
is same as -X, -Ttoolname
- resolves and uses tool context.
New API help functions available via the built-in :deps
alias: help/doc
and help/dir
New API function basis
that can be used to provide a custom basis to use, in combination with other tools that take a basis
New API program prep
that is used to prep source libs
New library API: create-basis
(also available in tools.build - use that one if writing a build program)
tools.tools - a tool library for managing tools
You may also want to check out Alex Miller’s talk about this release at clojureD.
Issues and bugs can be reported on https://ask.clojure.org or in Clojurians Slack in #tools-deps.