Launchpad is a Clojure dev process launcher.
It starts from these observations:
And these preferences:
Launchpad is a babashka-compatible library, through a number of steps it builds
up a Clojure command line invocation, including JVM options, extra dependencies,
and forms to evaluate, including starting nREPL with selected middleware,
watching deps.edn
files for changes, starting ClojureScript build watchers,
and hooking up your editor (if supported, otherwise a manual connect to nREPL is
needed).
It takes information from deps.edn
(checked in) and deps.local.edn
(not
checked in) and arguments passed in on the command line to determine which
modules to include, which middleware to add to nREPL, which shadow-cljs builds
to start, etc.
Launchpad integrates with lambdaisland.classpath
to provide hot-reloading of
deps.edn
and deps.local.edn
, so you can add dependencies to your project,
switch a dependency to a newer version, or from a Maven-provided jar to a local
checkout, all without restarting your process and REPL. You can even activate
additional aliases without restarting. How cool is that?
See template
for an example setup, you need a few different pieces.
bb.edn
{:deps {com.lambdaisland/launchpad { ... }}}
bin/launchpad
This is the default convention for launchpad-based projects, it provides a recognizable, predictable entry point that people will be looking for in your project, so use it. This is a simple babashka script invoking launchpad, but there's lots of room to customize this. Want to check the Java version, launch docker-compose, ensure environment variables are set up? You do that here.
#!/usr/bin/env bb
(require '[lambdaisland.launchpad :as launchpad])
(launchpad/main {})
;; (launchpad/main {:steps (into [(partial launchpad/ensure-java-version 17)]
;; launchpad/default-steps)})
deps.edn
You need a top-level deps.edn
, where you reference your sub-projects with
aliases and :local/root
.
{:deps
{... good place for dev tooling like portal, scope-capture ...}
;; Monorepo setup with two subprojects, if you have a multi-repo setup then use
;; paths like `"../proj1"`
:aliases
{:proj1
{:deps {com.example/proj1 {:local/root "proj1"}}}
:proj2
{:deps {com.example/proj2 {:local/root "proj2"}}}}}
proj1
and proj2
are then folders with their own deps.edn
, src
, etc.
.gitignore
Make sure to .gitignore
the deps.local.edn
file, this is where you can do
individual configuration.
echo deps.local.edn >> .gitignore
deps.local.edn
This follows the structure like deps.edn
, and gets passed to tools.deps as an
extra source, but there are a few special keys here that you can use to
configure launchpad.
{;; regular deps.edn stuff will work in here
:deps {}
:aliases {}
;; but some extra keys are supported to influence launchpad itself
:launchpad/aliases [:proj1] ; additional aliases, will be added to whatever
; aliases you specify on the command line
:launchpad/main-opts ["--emacs"] ; additional CLI flags, so you can encode your
; own preferences
:launchpad/shadow-build-ids [] ; which shadow builds to start, although it may
; be preferable to configure this as part of
; specific aliases in your main deps.edn
;; which shadow builds to automatically connect to if `--emacs` flag is provided
:launchpad/shadow-connect-ids []
}
You don't have to stop there, you could add a dev/user.clj
(add "dev" to your
:paths
in that case), add other useful scripts or repl sessions, maybe you
even want to put cross-project integration tests in this repo, but the above is
the main stuff you need.
When invoking bin/launchpad
you pass it any aliases you want to start, plus a
number of optional flags. These currently allow injecting the CIDER and/or
refactor-nrepl middleware, which will suffice to use launchpad with Emacs/CIDER,
VS Code/Calva, and probably others.
Please do file issues on Github for your favorite editor environment, we want to eventually support every Clojure editor out there with a non-negligible user base.
Emacs is currently best supported, since we are able to query Emacs to find which versions of cider-nrepl and refactor-nrepl we should inject, and are also able to instruct Emacs to connect to the REPL, so the whole process is smooth and automated. This level of integration will not be possible with every editor, but we can look into what options we have.
➜ bin/launchpad --help
bin/launchpad <options> [proj1|proj2]+
-h, --help
-v, --verbose Print debug information
--cider-nrepl Include the CIDER nREPL middleware
--refactor-nrepl Include the refactor-nrepl middleware
--cider-connect Automatically connect CIDER
--emacs Shorthand for --cider-nrepl --refactor-nrepl --cider-connect
For example
➜ bin/launchpad backend frontend --emacs
[INFO] clojure -J-XX:-OmitStackTraceInFastThrow -J-Dlambdaisland.launchpad.aliases=backend,frontend -A:backend:frontend -Sdeps '{:deps {cider/cider-nrepl #:mvn{:version "0.28.5"}, refactor-nrepl/refactor-nrepl #:mvn{:version "3.5.2"}, com.lambdaisland/classpath #:mvn{:version "0.4.44"}, com.lambdaisland/launchpad #:local{:root "/home/arne/github/lambdaisland/launchpad"}}}' -M -e '(do (require (quote lambdaisland.classpath.watch-deps) (quote lambdaisland.launchpad.deps)) (lambdaisland.classpath.watch-deps/start! {:aliases [:backend :frontend], :include-local-roots? true, :basis-fn lambdaisland.launchpad.deps/basis, :watch-paths [(lambdaisland.classpath.watch-deps/canonical-path "deps.local.edn")], :launchpad/extra-deps (quote {cider/cider-nrepl #:mvn{:version "0.28.5"}, refactor-nrepl/refactor-nrepl #:mvn{:version "3.5.2"}, com.lambdaisland/classpath #:mvn{:version "0.4.44"}})}) (require (quote nrepl.cmdline)) (nrepl.cmdline/-main "--port" "41545" "--middleware" "[cider.nrepl/cider-middleware refactor-nrepl.middleware/wrap-refactor]"))'
nREPL server started on port 41545 on host localhost - nrepl://localhost:41545
At this point in Emacs you'll see this pop up:
[nREPL] Establishing direct connection to localhost:41545 ...
[nREPL] Direct connection to localhost:41545 established
For other editors connect to the given port manually.
launchpad is part of a growing collection of quality Clojure libraries created and maintained by the fine folks at Gaiwan.
Pay it forward by becoming a backer on our Open Collective, so that we may continue to enjoy a thriving Clojure ecosystem.
You can find an overview of our projects at lambdaisland/open-source.
Launchpad is not currently open to external contributions.
Copyright © 2022 Arne Brasseur and Contributors
Licensed under the term of the Mozilla Public License 2.0, see LICENSE.
Can you improve this documentation? These fine people already did:
Arne Brasseur & Mitesh ShahEdit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close