c2b1cbbf0c447bb55b10d0450aa2c0539c7f225b
DevEnvironmentLauncher.md
... | ... | @@ -1,5 +1,3 @@ |
1 | -## Dev Environment Launcher |
|
2 | - |
|
3 | 1 | In order to start working on a project, certain prerequisites need to be met, and certain processes need to be started. |
4 | 2 | |
5 | 3 | Prerequisites can include |
... | ... | @@ -28,4 +26,4 @@ So a certain level of local customizability is still desirable, developers may w |
28 | 26 | |
29 | 27 | We call the pattern that resolves these tension a "Dev Environment Launcher". A well-known entry-point that handles as much of this process as is reasonably possible. When tools are required, it either installs them, or alternatively validates that they are present, at the correct version, providing clear guidance for which steps the developer should take next to get their environment in order. |
30 | 28 | |
31 | -For an ecosystem exploration see [[Ecosystem/Ecosystem: Dev Environment Launcher]]. For the implementation of this pattern within the Gaiwan System, see [[GaiwanStack/Launchpad]]. |
|
29 | +For an ecosystem exploration see [[DevEnvironmentLauncherEcosystem]]. For the implementation of this pattern within the Gaiwan stack, see [[GaiwanStack/Launchpad]]. |
DevEnvironmentLauncherEcosystem.md
... | ... | @@ -0,0 +1,31 @@ |
1 | +_This is the ecosystem assesment for the [[DevEnvironmentLauncher]] pattern._ |
|
2 | + |
|
3 | +We are aware of few projects that aim to be a general implementation of a [[DevEnvironmentLauncher]], although we've seen many partial attempts within specific projects, often as shell or babashka scripts. There are however several available offerings that offer part of the solution. |
|
4 | + |
|
5 | +You can read about our own take on this, which forms both a [[DevEnvironmentLauncher]] and [[WellKnownEntrypoint]], and provides aspects of a [[LiveEnvironment]], under [[GaiwanStack/Launchpad]]. We use Launchpad on virtually every project now, making sure that `bin/launchpad` handles all necessary steps to get to a working interactive programming environment. |
|
6 | + |
|
7 | +What follows is a summary of the commonly used partial solutions. Clojure CLI (or Leiningen) handles the downloading of language level dependencies, and the constructing of a java invocation, with the necessary classpath, main namespace, and other options and flags as needed. |
|
8 | + |
|
9 | +For dependent services Docker Compose is a popular and attractive solution, and one we reach for often for projects that rely on packaged, off the shelf products, for instance PostgreSQL or Redis. |
|
10 | + |
|
11 | +Editors like Emacs/CIDER implement part of the solution through "Jack-in" functionality, i.e. the ability to launch an (n)REPL server within a project, and connecting to it once it's available, in the process installing any language-level dependencies through Clojure CLI (itself leveraging tools.deps.alpha). |
|
12 | + |
|
13 | +Tension arises here when not everyone on the team uses such an editor, for instance Vim/Conjure users are instructed to create an `:nrepl/cider` alias in `deps.edn` which handles the starting of an nREPL server, manually specifying the necessary dependency versions and middlewares, which will then invariably drift from the versions required by the editor. |
|
14 | + |
|
15 | +Configuration and secret management is an important topic in this regard, and one worthy of a separate more in-depth exploration. Modern projects often require configuration like API keys, things which are developer-specific and should generally not be checked in to the repository. One thing we want to point out here is that for people who start their main interactive development process outside of their editor, like Vim/Conjure users, it is quite natural to use a solution like `dotenv`, to load a local `.env` file and thus set environment variables that are available to the main process. For people who delegate their REPL startup to their editor, this option is not available, and they are left searching for workarounds, often necessitating extra supporting code within the application. |
|
16 | + |
|
17 | +To tie it all together we've seen multiple approaches |
|
18 | + |
|
19 | +- Make / Makefile |
|
20 | +- Just / Justfile |
|
21 | +- shell script |
|
22 | +- babashka script |
|
23 | +- bb tasks |
|
24 | + |
|
25 | +Make we tend to avoid on new projects, while it has proven its merit over decades, it contains plenty of idiosyncracies and sharp edges, and teaching developers about things like `PHONY` is no longer a good use of their time, especially considering that the main feature that make excells at, namely the tracking of build dependencies and outputs to avoid duplicate compilation work, is one that is of little use on most projects we work on. |
|
26 | + |
|
27 | +Just is a modern make-alike, it is only a task runner, so it does not track build dependencies the way make does, and it doesn't require a tab in the first column (thank goodness). One thing we really like about Just is that task definitions can start with a shebang, and thus be written in any language, including Clojure/Babashka. It does have a few minor sharp edges, in the absence of a shebang line, each line in a task runs in a separate shell process, meaning variables do not make it across. |
|
28 | + |
|
29 | +We have used shell and babashka scripts extensively for these kind of "launcher" purposes, these days defaulting to babashka, often under a [[Pattern: Well Known Entrypoint]], like `bin/dev`, `bin/proj`, or `bin/launchpad`. |
|
30 | + |
|
31 | +We see little benefit to using bb tasks over using a babashka script and handling argument parsing in there directly. `bb.edn` being mirrored on `deps.edn` should in our opinion primarily be kept for declarative things like dependencies and paths, and not get muddled with code. |
Ecosystem/Ecosystem: Dev Environment Launcher.md
... | ... | @@ -1,29 +0,0 @@ |
1 | -We are aware of few projects that aim to be a general implementation of a [[Pattern: Dev Environment Launcher]], although we've seen many partial attempts within specific projects, often as shell or babashka scripts. There are however several available offerings that offer part of the solution. |
|
2 | - |
|
3 | -You can read about our own take on this, which forms both a [[Pattern: Dev Environment Launcher]] and [[Pattern: Well Known Entrypoint]], and provides aspects of a [[Pattern: Live Environment]], under [[Gaiwan System: Launchpad]]. We use Launchpad on virtually every project now, making sure that `bin/launchpad` handles all necessary steps to get to a working interactive programming environment. |
|
4 | - |
|
5 | -What follows is a summary of the commonly used partial solutions. Clojure CLI (or Leiningen) handles the downloading of language level dependencies, and the constructing of a java invocation, with the necessary classpath, main namespace, and other options and flags as needed. |
|
6 | - |
|
7 | -For dependent services Docker Compose is a popular and attractive solution, and one we reach for often for projects that rely on packaged, off the shelf products, for instance PostgreSQL or Redis. |
|
8 | - |
|
9 | -Editors like Emacs/CIDER implement part of the solution through "Jack-in" functionality, i.e. the ability to launch an (n)REPL server within a project, and connecting to it once it's available, in the process installing any language-level dependencies through Clojure CLI (itself leveraging tools.deps.alpha). |
|
10 | - |
|
11 | -Tension arises here when not everyone on the team uses such an editor, for instance Vim/Conjure users are instructed to create an `:nrepl/cider` alias in `deps.edn` which handles the starting of an nREPL server, manually specifying the necessary dependency versions and middlewares, which will then invariably drift from the versions required by the editor. |
|
12 | - |
|
13 | -Configuration and secret management is an important topic in this regard, and one worthy of a separate more in-depth exploration. Modern projects often require configuration like API keys, things which are developer-specific and should generally not be checked in to the repository. One thing we want to point out here is that for people who start their main interactive development process outside of their editor, like Vim/Conjure users, it is quite natural to use a solution like `dotenv`, to load a local `.env` file and thus set environment variables that are available to the main process. For people who delegate their REPL startup to their editor, this option is not available, and they are left searching for workarounds, often necessitating extra supporting code within the application. |
|
14 | - |
|
15 | -To tie it all together we've seen multiple approaches |
|
16 | - |
|
17 | -- Make / Makefile |
|
18 | -- Just / Justfile |
|
19 | -- shell script |
|
20 | -- babashka script |
|
21 | -- bb tasks |
|
22 | - |
|
23 | -Make we tend to avoid on new projects, while it has proven its merit over decades, it contains plenty of idiosyncracies and sharp edges, and teaching developers about things like `PHONY` is no longer a good use of their time, especially considering that the main feature that make excells at, namely the tracking of build dependencies and outputs to avoid duplicate compilation work, is one that is of little use on most projects we work on. |
|
24 | - |
|
25 | -Just is a modern make-alike, it is only a task runner, so it does not track build dependencies the way make does, and it doesn't require a tab in the first column (thank goodness). One thing we really like about Just is that task definitions can start with a shebang, and thus be written in any language, including Clojure/Babashka. It does have a few minor sharp edges, in the absence of a shebang line, each line in a task runs in a separate shell process, meaning variables do not make it across. |
|
26 | - |
|
27 | -We have used shell and babashka scripts extensively for these kind of "launcher" purposes, these days defaulting to babashka, often under a [[Pattern: Well Known Entrypoint]], like `bin/dev`, `bin/proj`, or `bin/launchpad`. |
|
28 | - |
|
29 | -We see little benefit to using bb tasks over using a babashka script and handling argument parsing in there directly. `bb.edn` being mirrored on `deps.edn` should in our opinion primarily be kept for declarative things like dependencies and paths, and not get muddled with code. |