• Stars
    star
    225
  • Rank 177,187 (Top 4 %)
  • Language
    Clojure
  • License
    Eclipse Public Li...
  • Created almost 5 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A faithful port of the clojure CLI bash script to Clojure

deps.clj

CircleCI Build status Clojars Project

About

A faithful port of the Clojure CLI bash script to Clojure. Used as native CLI, deps resolver in babashka, and getting started REPL in Calva.

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

  • Run as executable compiled with GraalVM Or run directly from source with babashka or the JVM
  • Similar startup to bash (with native or babashka)
  • Easy installation on all three major platforms including Windows
  • Works in cmd.exe on Windows

Quickstart

Linux and macOS:

$ curl -sL https://raw.githubusercontent.com/borkdude/deps.clj/master/install > install_clojure
$ chmod +x ./install_clojure
$ ./install_clojure # you may need sudo, depending on your system
$ deps
Clojure 1.10.1
user=>

Windows:

C:\Temp> PowerShell -Command "irm https://raw.githubusercontent.com/borkdude/deps.clj/master/install.ps1" > install_clojure.ps1
C:\Temp> PowerShell -f install_clojure.ps1
C:\> deps.exe
Clojure 1.10.1
user=>

To install deps / deps.exe as clojure / clojure.exe on your system, add the --as-clj flag:

$ ./install_clojure --as-clj

If your Windows system does not run PowerShell, you can simply download a Windows binary from Github releases and place it on your path.

As of 1.11.1.1165, the scripts passes the values of the CLJ_JVM_OPTS or JAVA_OPTIONS to java when downloading dependencies or executing all other commands respectively (useful for setting up network connectivity behind firewalls).

Why

Originally this project was created as a proof of concept to see if the clojure bash script could be ported to Clojure and be used as a babashka script.

Nowadays it is used as the code behind the babashka.deps namespace and the clojure subcommand in babashka, to resolve and download dependencies for babashka itself, or when running a Clojure process with babashka.

This project 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 with cmd.exe unlike the current Powershell based approach.

Projects using deps.clj

Babashka

Available under the clojure subcommand. It is also available as a programmatic API under babashka.deps.

Calva

Used to provide a getting started REPL.

Status

Deps.clj tries to follow the official Clojure CLI as faithfully as possible and as such, this project can be considered a stable drop-in replacement. Experimental extra options may still be changed or removed in the future.

Installation

There are three ways of running:

  • As a compiled binary called deps which is tailored to your OS.
  • From source, as a script file called deps.clj using the bb or clojure runtime.
  • As a JVM library or uberjar (see Github releases).

Binary

The binary version of deps.clj, called deps (without the .clj extension), only requires a working installation of java.

Manual download

Binaries for linux, macOS and Windows can be obtained on the Github releases page.

Linux and macOS

$ curl -sL https://raw.githubusercontent.com/borkdude/deps.clj/master/install > install_clojure
$ chmod +x ./install_clojure
$ ./install_clojure # you may need sudo, depending on your system
$ deps
Clojure 1.10.1
user=>

Windows

On Windows you might want to install deps.clj using scoop.

To install deps.clj as a replacement for the clj command, install clj-deps:

scoop bucket add scoop-clojure https://github.com/littleli/scoop-clojure
scoop install clj-deps

Alternatively you can install deps.exe using by executing the following line:

C:\Temp> PowerShell -Command "irm https://raw.githubusercontent.com/borkdude/deps.clj/master/install.ps1" > install_clojure.ps1
C:\Temp> PowerShell -f install_clojure.ps1
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.

clj-msi

If you're interested in installing deps.clj as clj.exe and clojure.exe via an MSI installer, take a look at clj-msi!

Script

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=>

On Windows you can use the deps.bat script:

C:\Temp> curl -sL https://raw.githubusercontent.com/borkdude/deps.clj/master/deps.bat -o c:\Temp\deps.bat
C:\Temp> deps
C:\Temp>
Clojure 1.10.1
user=>

Environment variables

DEPS_CLJ_TOOLS_DIR

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 invoking java using the value of the CLJ_JVM_OPTS environment variable as options. You can override the location of these jars with the DEPS_CLJ_TOOLS_DIR environment variable. If the download fails for some reason, you can try to download the zip yourself at the location suggested by the failure message.

If you have an already installed version of clojure using e.g. brew, you can set DEPS_CLJ_TOOLS_DIR to that directory:

DEPS_CLJ_TOOLS_VERSION

This project assumes a specific version of the tools jar. However, it can be desirable to up- or downgrade the targetted tools jar in case of bug fixes or bugs in newer versions. Be aware that the code of this project is written with a specific version of the tools jar in mind, so use this at your own risk. Given that there isn't a lot of churn in the bash code that this project replaces, the risk should be relatively low.

Extra features

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.

-Scommand

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}}

-Sdeps-file

The -Sdeps-file option may be used to load a different project file than deps.edn.

Proxy environment variables

deps.clj supports setting a proxy server via the "standard" environment variables (the lowercase versions are tried first):

  • http_proxy or HTTP_PROXY for http traffic
  • https_proxy or HTTPs_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.

API

Since version 1.11.1.1273-3, deps.clj exposes an API so it can be embedded in applications, rather than just using it from the command line directly.

See API.md docs.

E.g to parse CLI options:

(require '[borkdude.deps :as deps])
(deps/parse-cli-opts ["-M:foo:bar" "-m" "foo.bar"])
;;=> {:mode :main, :main-aliases ":foo:bar", :args ("-m" "foo.bar")}

Re-binding the *aux-process-fn*, used for calculating the classpath, pom etc and *clojure-process-fn*, used for creating the actual Clojure process, gives you more control during the "shelling out" parts of deps.clj.

$ clj -Sdeps '{:deps {babashka/process {:mvn/version "0.5.19"}}}'
(require '[babashka.process :as p] '[borkdude.deps :as deps])

(defn my-aux-process [{:keys [cmd out]}]
  (binding [*out* *err*]
    (apply println "Calling aux process with cmd:" cmd))
  (p/shell {:cmd cmd :out out :extra-env {"GITLIBS" "/tmp/gitlibs"}}))

(defn my-clojure-process [{:keys [cmd out]}]
  (binding [*out* *err*]
    (apply println "Calling Clojure with command:" cmd))
  (p/shell {:cmd cmd :out *out* :extra-env {"FOO" "BAR"}}))

(binding [deps/*aux-process-fn* my-aux-process
          deps/*clojure-process-fn* my-clojure-process]
  (with-out-str (deps/-main "-Sforce" "-M" "-e" (pr-str '(System/getenv "FOO")))))

;;=>
Calling aux process with cmd: /usr/bin/java -XX:-OmitStackTraceInFastThrow -classpath ...
Calling Clojure with command: /usr/bin/java -XX:-OmitStackTraceInFastThrow -Dclojure.basis=... clojure.main -e (System/getenv "FOO")
"\"BAR\"\n"

Note that you should handle the exit codes yourself when implementing your own -process-fn. If you don't do that, then *exit-fn* will be called, which defaults to exiting the process if the :exit code was non-zero. To prevent this, you can re-bind *exit-fn* to throwing an exception instead:

Without re-binding *exit-fn*:

user=> (require '[borkdude.deps :as deps])
nil
user=> (deps/-main "-M" "-e" "(/ 1 0)")
Execution error (ArithmeticException) at user/eval1 (REPL:1).
Divide by zero

Full report at:
/var/folders/j9/xmjlcym958b1fr0npsp9msvh0000gn/T/clojure-8365878068735118865.edn
user=> (binding [deps/*exit-fn* (fn [{:keys [exit message]}] (println "Exit code:" exit))] (deps/-main "-M" "-e" "(/ 1 0)"))
Execution error (ArithmeticException) at user/eval1 (REPL:1).
Divide by zero

Full report at:
/var/folders/j9/xmjlcym958b1fr0npsp9msvh0000gn/T/clojure-2500586512812528128.edn
Exit code: 1
{:out nil, :exit 1}
user=> ;; we're still in the REPL

Developing deps.clj

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:

$ bb jvm-test

To run with babashka after making changes to src/borkdude/deps.clj, you should run:

$ bb gen-script

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:

$ bb compile

If everything worked out, there will be a deps binary in the root of the project.

To run executable tests:

$ bb exe-test

License

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.

More Repositories

1

jet

CLI to transform between JSON, EDN, YAML and Transit using Clojure
Clojure
584
star
2

carve

Remove unused Clojure vars
Clojure
275
star
3

grasp

Grep Clojure code using clojure.spec regexes
Clojure
233
star
4

speculative

Unofficial community-driven specs for clojure.core
Clojure
187
star
5

edamame

Configurable EDN/Clojure parser with location metadata
Clojure
155
star
6

clojure-rust-graalvm

An example of Clojure program calling a Rust library, all combined into one executable using GraalVM.
Rust
120
star
7

re-find

Find functions by matching specs
Clojure
118
star
8

quickblog

Light-weight static blog engine for Clojure and babashka
Clojure
117
star
9

quickdoc

Quick and minimal API doc generation for Clojure
Clojure
116
star
10

bebo

Run Clojure scripts on deno
Clojure
98
star
11

flycheck-clj-kondo

Emacs integration for clj-kondo via flycheck
Emacs Lisp
84
star
12

rewrite-edn

Utility lib on top of rewrite-clj with common operations to update EDN while preserving whitespace and comments.
Clojure
76
star
13

clj2el

Transpile Clojure to Emacs Lisp!
Clojure
63
star
14

glam

A cross-platform package manager.
Clojure
62
star
15

api-diff

Print API diffs between library versions
Clojure
59
star
16

deflet

Make let-expressions REPL-friendly!
Clojure
57
star
17

cljtree-graalvm

Tree version in Clojure built with GraalVM
Clojure
53
star
18

respeced

Testing library for clojure.spec fdefs
Clojure
52
star
19

dynaload

The dynaload logic from clojure.spec.alpha as a library
Clojure
52
star
20

jayfu

Jayfu is a tutorial on how to create a Clojure CLI with GraalVM native-image and SCI.
Clojure
52
star
21

lein2deps

Lein project.clj to deps.edn converter
Clojure
50
star
22

blog

HTML
49
star
23

plsci

PostgreSQL procedural language handler for Clojure via SCI
Rust
48
star
24

advent-of-cljc

Cross platform Clojure Advent of Code solutions
Clojure
44
star
25

boot-bundle

boot-bundle: managed dependencies for boot, the clojure build tool
Clojure
43
star
26

deps-infer

Infer mvn deps from sources
Clojure
39
star
27

puget-cli

A CLI version of puget
Shell
37
star
28

specter-cli

A native Specter CLI, compiled with GraalVM native-image and executed by SCI.
Clojure
33
star
29

draggable-button-in-reagent

Very simple example of a draggable button in Reagent
Clojure
31
star
30

spartan.spec

A spartan version of clojure.spec compatible with babashka
Clojure
30
star
31

lein-new-liberagent

leiningen template for apps that use reagent and liberator
Clojure
29
star
32

re-find.web

Web version of re-find
Clojure
25
star
33

nbb-action-example

An example of writing a Github action with nbb
Clojure
24
star
34

lein2boot

The goal of this exercise is to convert a leiningen project to boot and have exactly the same workflow.
Clojure
24
star
35

gh-release-artifact

Upload artifacts to Github releases idempotently
Clojure
24
star
36

balcony

Should I water my balcony?
Clojure
23
star
37

generate-podcast

A babashka script to create a podcast from a local directory with mp3 files
Clojure
22
star
38

tools

Tools
Clojure
19
star
39

fly_io_clojure

A fly.io example for Clojure
Clojure
17
star
40

refl

Clean up generated reflection configs for GraalVM native-image compiled Clojure programs
Clojure
17
star
41

analyze-reify

Analyze occurrences of reify in Clojure code. Implemented using tree-sitter-clojure and Rust.
Rust
17
star
42

advent-of-babashka

Advent of Code using babashka and nbb
Clojure
16
star
43

aoc2017

Advent of Code 2017
Clojure
15
star
44

lein-new-wrom

Webjars + Ring + Om leiningen template
Clojure
15
star
45

clj-reflector-graal-java11-fix

A fix for an issue with clojure.lang.Reflector in GraalVM native-image JDK11.
Clojure
15
star
46

cljs-showcase

Clojure
13
star
47

clj.el

Clojure-like macros and functions in elisp
Emacs Lisp
13
star
48

balcony-hs

Should I water my balcony?
Haskell
13
star
49

babashka-docker-action-example

Dockerfile
12
star
50

who-follows-me

Check who follows you, but you're not following back and vice versa. https://twitter.michielborkent.nl
Clojure
12
star
51

trickle-playground

A Truffle Clojure Interpreter (playground)
Java
12
star
52

finitize

Limit and realize possibly infinite seqs
Clojure
12
star
53

nrepl-server

Proof of concept nREPL server
Clojure
10
star
54

full-stack-clojure-han-okt-2015

Talk about developing full stack Clojure applications at HAN University of Applied Sciences
Clojure
10
star
55

clojurecursus

Introductiecursus Functioneel Programmeren met Clojure
CSS
10
star
56

missing.test.assertions

A library that detects missing test assertions in clojure.test tests
Clojure
9
star
57

deps.add-lib

Clojure 1.12's add-lib feature for leiningen and/or other environments without a specific version of the clojure CLI
Clojure
8
star
58

figwheel-keep-om-turning

Code for blog post at http://blog.michielborkent.nl/2014/09/25/figwheel-keep-Om-turning/
Clojure
8
star
59

cljtree-planck

A ClojureScript version of `tree` in Planck
Shell
6
star
60

bun-squint-loader

JavaScript
6
star
61

simple-cljs-examples

Curated list of ClojureScript sample applications suited for those starting with ClojureScript
6
star
62

graal.locking

A workaround for CLJ-1472 as a library
Clojure
6
star
63

tictactoe

tictactoe (clojure)
Clojure
5
star
64

bb-cherry-example

A web app showing real time JS compilation with babashka and cherry
Clojure
5
star
65

immutable-webapp

Immutable Webapp!
HTML
5
star
66

spartan.test

A spartan test framework compatible with babashka.
Clojure
5
star
67

speculative-kaocha-plugin

speculative kaocha plugin
Clojure
5
star
68

aoc2015_day7

Solution of Advent of Code Day 7 using clojure.spec
Clojure
4
star
69

oredev2014

Slides and code for ร˜redev 2014
Clojure
4
star
70

tictactoe-cljs

Tictactoe in Clojurescript and Om
Clojure
4
star
71

cherry-action-example

Github action implemented with cherry
Clojure
4
star
72

homebrew-brew

Homebrew formulas
Shell
4
star
73

datalevin-native

Clojure
4
star
74

sci-wallpaper-downloader

A port of @yogthos's wallpaper downloader to the Small Clojure Interpreter on NodeJS
Clojure
4
star
75

domcode-cljs-react

Slides and code for presentation at the DomCode meetup
Clojure
4
star
76

clj-jdbc

A hypothetical Clojure command tool focusing around SQL interaction via JDBC
Clojure
4
star
77

sci-birch

tree CLI using sci, ported from lambdaisland's birch
Clojure
3
star
78

clj-native-sound-demo

A demo of using the Java sound API with GraalVM native-image
Clojure
3
star
79

bb-php-guestbook

A guestbook using babashka and PHP
Clojure
2
star
80

michielborkent.nl

Home page sources
Clojure
2
star
81

clj-kondo-configurator

CLI tool to merge clj-kondo configurations.
Clojure
2
star
82

boot.bundle.edn

My boot.bundle.edn file
Clojure
2
star
83

my-aob

Clojure
2
star
84

FP-AMS-ClojureScript-talk

Slides and code for talk at FP AMS about Clojurescript
Clojure
2
star
85

react-amsterdam

Talk for React-Amsterdam, February 12th 2015
Clojure
2
star
86

pprint

Clojure
2
star
87

sytac-core-async

Slides and code for presentation at Sytac Devjam
Clojure
2
star
88

SnakeYAML

Temporary fork of SnakeYAML
Java
1
star
89

leiningen.org

Leiningen's web site
Clojure
1
star
90

try_git

1
star
91

clj-1472-repro

A repro of CLJ-1472
Clojure
1
star
92

cljs-macro

Example of usage of a macro in ClojureScript.
Clojure
1
star
93

itunes2dropbox

Share the current playing song or selected songs from iTunes to your Dropbox public folder.
AppleScript
1
star
94

squint-bun-cloudflare

JavaScript
1
star
95

aoc2016

Advent of Clojure 2016
Clojure
1
star
96

fp-hu-may-2016

Talk about Functional Programming at Hogeschool Utrecht, May 2016
Clojure
1
star
97

Clojure-FinalAssignment

Quiz
Clojure
1
star
98

ns-parser

Helper library for parsing ns forms in combination with edamame and rewrite-clj
Clojure
1
star
99

clj-kondo.web

playground for clj-kondo
Clojure
1
star
100

test-repo

Repo to test Github features
Clojure
1
star