I was always using -A with clojure tools, but some warnings were saying that I should use -M instead, I found this doc, but haven't got to a conclusion when to use each yet.
The Clojure CLI is still evolving so, the -X
option is relatively new, and the meaning of the -M
option has changed in the same timeframe.
You can see the CLI versions and short release notes here: https://clojure.org/releases/tools
Up until the middle of 2020, you used -A
for everything. -M
simply ran the :main-opts
-- it did not respect any classpath options or resolving options.
In version 1.10.1.697 (September 25, 2020), the -X
option was introduced to allow for execution of a specific Clojure function, passing a hash map of data as the single argument. That release also expanded the behavior of the -M
option to respect :extra-paths
and :extra-deps
as well as running :main-opts
-- effectively making -M
equivalent to -A
.
There were quite a few changes to how those options worked and how the CLI overall behaved, until things settled down about a month later with 1.10.1.727 (October 21, 2020). During this time, the -A
option's behavior of running :main-opts
was effectively deprecated: if you use -A
to run :main-opts
now, you'll get a warning that you should use -M
instead.
Several community tools based on the Clojure CLI and deps.edn
have notes in their README that you need to use at least version 1.10.1.727 in order to leverage their features. Version 1.10.3.814 is the current version (as of March 16, 2021). It's worth staying up to date as the CLI adds new features (and it's likely to get another round of changes soon).
The TL;DR of all this is:
-M
to run clojure.main
and any :main-opts
-- this includes -m
to identify a namespace whose -main
function should be executed and also -e
to evaluate an expression. Note that -main
is a variadic function that is invoked with zero or more String
arguments.-X
to run a specific function, taking a single hash map as its argument, passing in key/value pairs via the command-line, in addition to the :exec-args
in deps.edn
. Note that -X
accepts EDN values, which means that strings need to be quoted carefully on the command-line: '"A string"'
-- the double-quotes are for EDN strings and the single-quotes are to ensure the value is passed as-is via the shell. On Windows, via cmd.exe
or Powershell, quoting is more complex than this (it is much easier to use the Clojure CLI on Linux and macOS, so for Windows it is worth considering WSL2).-A
to start a REPL. For now, that means you need to be careful about mixing :main-opts
with aliases that you use when starting a REPL (because -A
still runs :main-opts
but at some point it will stop doing that).Another useful option these days is -P
-- prepare -- which you can add immediately after clojure
(before -X
, -M
, or -A
), which lets the CLI calculate and resolve all of the dependencies from the deps.edn
files and the provided aliases (and download Maven/Clojars JARs and clone git deps), but then stops prior to actual execution of a function (the specific function for -X
, clojure.main
for -M
, or the REPL for -A
).
A final note on versions: although the CLI version number is prefixed with a Clojure version number, they are not directly tied. You can run any version of Clojure (back to 1.0.0) with any version of the CLI. The version number for the CLI is x.y.z.commits
where x.y.z
is the default version of Clojure you will get if you don't override it via an alias or via your project's deps.edn
file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With