Clojure provides the clojure
command line tool for:
- Running an interactive REPL (Read-Eval-Print Loop)
- Running Clojure programs
- Evaluating Clojure expressions
The clojure
CLI is written in bash. This is a port of that tool written in
Clojure itself.
Features:
- Available as executable compiled with GraalVM
- Run directly from source with babashka or the JVM
- Similar startup to bash
- Easy installation on all three major platforms including Windows
- Works in
cmd.exe
on Windows
Linux and macOS:
$ bash <(curl -s https://raw.githubusercontent.com/borkdude/deps.clj/master/install)
$ deps
Clojure 1.10.1
user=>
Windows:
C:\> PowerShell -Command "iwr -useb https://raw.githubusercontent.com/borkdude/deps.clj/master/install.ps1 | iex"
C:\> deps.exe
Clojure 1.10.1
user=>
If your Windows system does not run PowerShell, you can simply download a Windows binary from Github releases and place it on your path.
Reasons why I made this:
-
The port was done as proof of concept for babashka. The entire bash script was ported to Clojure successfully and runs just as fast with
bb
. -
This offers an arguably easier way to get going with
deps.edn
based projects in CI. Just download an installer script, execute it with bash or Powershell and you're set. Installer scripts are provided for linux, macOS and Windows. -
Windows users might find the
deps.exe
executable of value if they have trouble getting their system up and running. It works withcmd.exe
unlike the current Powershell based approach. -
This repo might be a place to experiment with features that are not available in the original
clojure
command. Most notably it offers an-Scommand
option which allows other programs to be started than just the JVM version of Clojure, e.g.babashka
orplanck
. -
Arguably bash and Powershell are less attractive languages for Clojure developers than Clojure itself. This repo provides the
clojure
bash script as a port in Clojure. It can be used as a binary, script (deps.clj
), uberjar or library. -
This repo can be seen as a proof of concept of what is possible with GraalVM and Clojure.
Experimental, but in a usable state. Breaking changes might happen to the non-standard functionality. Feedback and PRs are welcome.
There are three ways of running:
- as a compiled binary called
deps
which is tailored to your OS - as a script file called
deps.clj
usingbb
orclojure
- as a JVM library or uberjar (see Github releases).
The binary version of deps.clj, called deps
(without the .clj
extension), only requires a working
installation of java
.
Binaries for linux, macOS and Windows can be obtained on the Github releases page.
Install using the installation script on linux or macOS:
$ bash <(curl -s https://raw.githubusercontent.com/borkdude/deps.clj/master/install) /tmp
$ /tmp/deps
Clojure 1.10.1
user=>
On Windows you might want to install deps.clj
using
scoop.
Alternatively you can install deps.exe
using by executing the following line:
C:\> PowerShell -Command "iwr -useb https://raw.githubusercontent.com/borkdude/deps.clj/master/install.ps1 | iex"
C:\> deps.exe
Clojure 1.10.1
user=>
It's automatically added to your path. In Powershell you can use it right away. In cmd.exe
you'll have to restart the session for it to become available on the path.
When you get a message about a missing MSVCR100.dll
, also install the
Microsoft Visual C++ 2010 Redistributable Package
(x64) which is
also available in the
extras
Scoop bucket.
The script, deps.clj
, requires a working installation of java
and
additionally bb
or clojure
.
It can simply be downloaded from this repo:
$ curl -sL https://raw.githubusercontent.com/borkdude/deps.clj/master/deps.clj -o /tmp/deps.clj
$ chmod +x /tmp/deps.clj
$ bb /tmp/deps.clj
Clojure 1.10.1
user=>
This project will look in $HOME/.deps.clj/<clojure-version>/ClojureTools
for
clojure-tools-<clojure-version>.jar
, exec.jar
and example-deps.edn
. If it
cannot it find those files there, it will try to download them from
this
location. You can override the location of these jars with the
CLOJURE_TOOLS_DIR
environment variable. If the download fails for some reason,
you can try to download the zip yourself and unzip it at the expected location.
The deps.clj
script adds the following features compared to the clojure
tool:
-Sdeps-file Use this file instead of deps.edn
-Scommand A custom command that will be invoked. Substitutions: {{classpath}}, {{main-opts}}.
It also is able to pick up proxy information from environment variables.
One of the use cases for deps.clj
is invoking a different command than java
.
Given this deps.edn
:
{:aliases
{:test
{:extra-paths ["test"]
:extra-deps {borkdude/spartan.test {:mvn/version "0.0.4"}}
:main-opts ["-m" "spartan.test" "-n" "borkdude.deps-test"]}}}
you can invoke bb
like this:
$ deps.clj -A:test -Scommand "bb -cp {{classpath}} {{main-opts}}"
Ran 3 tests containing 3 assertions.
0 failures, 0 errors.
If you use -Scommand
often, an alias can be helpful:
$ alias bbk='rlwrap deps.clj -Scommand "bb -cp {{classpath}} {{main-opts}}"'
$ bbk -A:test
Ran 3 tests containing 3 assertions.
0 failures, 0 errors.
The bbk
alias is similar to the clj
alias in that it adds rlwrap
.
Additional args are passed along to the command:
$ bbk -e '(+ 1 2 3)'
6
Of course you can create another alias without rlwrap
for CI, similar to the
clojure
command:
$ alias babashka='deps.clj -Scommand "bb -cp {{classpath}} {{main-opts}}"'
This approach can also be used with planck or lumo:
$ alias lm='deps.clj -Scommand "lumo -c {{classpath}} {{main-opts}}"'
$ lm -Sdeps '{:deps {medley {:mvn/version "1.2.0"}}}' -K \
-e "(require '[medley.core :refer [index-by]]) (index-by :id [{:id 1} {:id 2}])"
{1 {:id 1}, 2 {:id 2}}
The -Sdeps-file
option may be used to load a different project file than deps.edn
.
deps.clj supports setting a proxy server via the "standard" environment variables (the lowercase versions are tried first):
http_proxy
orHTTP_PROXY
for http traffichttps_proxy
orHTTPs_PROXY
for https traffic
This will set the JVM properties -Dhttp[s].proxyHost
and -Dhttp[s].proxyPort
.
The format of the proxy string supported is http[s]://[username:password@]host:port
. Any username and password info is ignored as not supported by the underlying JVM properties.
For running locally, you can invoke deps.clj with clojure
(totally meta
right?). E.g. for creating a classpath with deps.clj, you can run:
$ clojure -M -m borkdude.deps -Spath
or with lein
:
$ lein run -m borkdude.deps -Spath
To run jvm tests:
$ script/jvm_test
To run with babashka after making changes to src/borkdude/deps.clj
, you should run:
$ script/gen_script.clj
and then:
$ ./deps.clj -Spath
# or
$ bb deps.clj -Spath
To run as an executable, you'll first have to compile it. First,
download a GraalVM
distro. The compile script assumes that you will have set GRAALVM_HOME
to the
location of your GraalVM installation. Currently this project uses java-11-20.1.0
.
$ export GRAALVM_HOME=/Users/borkdude/Downloads/graalvm-ce-java11-20.1.0/Contents/Home
The script also assumes that you have
lein
installed.
Run the compile script with:
$ script/compile
If everything worked out, there will be a deps
binary in the root of the
project.
To run executable tests:
$ script/exe_test
Copyright © 2019-2020 Michiel Borkent
Distributed under the EPL License. See LICENSE.
This project is based on code from clojure/brew-install which is licensed under the same EPL License.