Skip to content
This repository was archived by the owner on Nov 30, 2023. It is now read-only.

Commit 2a7e959

Browse files
authored
Clojure Dev Container Definition (#1062)
1 parent 5bdd85d commit 2a7e959

File tree

7 files changed

+293
-0
lines changed

7 files changed

+293
-0
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# [Choice] Java version (use -bullseye variants on local arm64/Apple Silicon): 11, 17, 11-bullseye, 17-bullseye, 11-buster, 17-buster
2+
ARG VARIANT=17
3+
FROM mcr.microsoft.com/vscode/devcontainers/java:${VARIANT}
4+
5+
# [Optional] Clojure version
6+
ARG CLOJURE_VERSION=1.10.3
7+
8+
# [Optional] Clojure tools version
9+
ARG CLOJURE_CLI_VERSION=1.10.3.1075
10+
11+
# [Optional] Leiningen version
12+
ARG LEININGEN_VERSION="stable"
13+
14+
# [Optional] POLYLITH version
15+
ARG POLYLITH_VERSION="0.2.13-alpha"
16+
17+
# [Optional] Boot version
18+
ENV BOOT_VERSION=2.8.3
19+
20+
# [Optional] Clojure version used by Boot
21+
ENV BOOT_CLOJURE_VERSION=${CLOJURE_VERSION}
22+
23+
# [Option] Install Clojure CLI tool
24+
ARG INSTALL_CLOJURE_CLI="true"
25+
26+
# [Option] Install Boot
27+
ARG INSTALL_BOOT="true"
28+
29+
# [Option] Install Leiningen
30+
ARG INSTALL_LEININGEN="true"
31+
32+
# [Option] Install Polylith
33+
ARG INSTALL_POLYLITH="true"
34+
35+
RUN if [ "${INSTALL_CLOJURE_CLI}" = "true" ]; then \
36+
apt-get update \
37+
&& apt-get -y install rlwrap \
38+
&& curl -OL "https://download.clojure.org/install/linux-install-${CLOJURE_CLI_VERSION}.sh" \
39+
&& chmod +x linux-install-${CLOJURE_CLI_VERSION}.sh \
40+
&& /linux-install-${CLOJURE_CLI_VERSION}.sh \
41+
&& rm /linux-install-${CLOJURE_CLI_VERSION}.sh \
42+
&& su vscode -c "clj --version"; fi
43+
44+
RUN if [ "${INSTALL_BOOT}" = "true" ]; then \
45+
curl -OL "https://github.com/boot-clj/boot-bin/releases/download/latest/boot.sh" \
46+
&& chmod +x boot.sh \
47+
&& mv boot.sh /usr/local/sbin/boot \
48+
&& su vscode -c "boot -u"; fi
49+
50+
RUN if [ "${INSTALL_LEININGEN}" = "true" ]; then \
51+
curl -OL "https://raw.githubusercontent.com/technomancy/leiningen/${LEININGEN_VERSION}/bin/lein" \
52+
&& chmod +x lein \
53+
&& mv lein /usr/local/sbin; fi
54+
55+
# Cache Clojure and dependencies
56+
RUN if [ "${INSTALL_LEININGEN}" = "true" ]; then \
57+
su vscode -c " cd ~ \
58+
&& echo '(defproject dummy \"\" :dependencies [[org.clojure/clojure \"'${CLOJURE_VERSION}'\"]])' > project.clj \
59+
&& lein deps \
60+
&& rm project.clj"; fi
61+
62+
RUN if [ "${INSTALL_POLYLITH}" = "true" ]; then \
63+
curl -OL "https://github.com/polyfy/polylith/releases/download/v${POLYLITH_VERSION}/poly-${POLYLITH_VERSION}.jar" \
64+
&& mkdir -p /usr/local/polylith \
65+
&& mv poly-$POLYLITH_VERSION.jar /usr/local/polylith \
66+
&& echo '#!/bin/sh\nARGS=""\nwhile [ "$1" != "" ] ; do\n ARGS="$ARGS $1"\n shift\ndone\nexec "java" $JVM_OPTS "-jar" "/usr/local/polylith/poly-'$POLYLITH_VERSION'.jar" $ARGS\n' > /usr/local/sbin/poly \
67+
&& chmod +x /usr/local/sbin/poly \
68+
&& /usr/local/sbin/poly version; fi
69+
70+
# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
71+
ARG NODE_VERSION="lts/*"
72+
RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
73+
74+
# [Optional] Uncomment this section to install additional OS packages.
75+
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
76+
# && apt-get -y install --no-install-recommends <your-package-list-here>
77+
78+
# [Optional] Uncomment this line to install global node packages.
79+
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1
80+
81+
# Clean up package lists
82+
RUN apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"name": "Clojure (Community)",
3+
"build": {
4+
"dockerfile": "Dockerfile",
5+
"args": {
6+
// Update the VARIANT arg to pick a Java version.
7+
// Append -bullseye or -buster to pin to an OS version.
8+
// Use the -bullseye variants on local arm64/Apple Silicon.
9+
"VARIANT": "17",
10+
// Options
11+
"CLOJURE_VERSION": "1.10.3",
12+
"INSTALL_CLOJURE_CLI": "true",
13+
"INSTALL_BOOT": "true",
14+
"INSTALL_LEININGEN": "true",
15+
"INSTALL_POLYLITH": "true",
16+
"NODE_VERSION": "lts/*"
17+
}
18+
},
19+
20+
// Set *default* container specific settings.json values on container create.
21+
"settings": {
22+
"java.home": "/docker-java-home"
23+
},
24+
25+
// Add the IDs of extensions you want installed when the container is created.
26+
"extensions": [
27+
"vscjava.vscode-java-pack",
28+
"borkdude.clj-kondo",
29+
"betterthantomorrow.calva"
30+
],
31+
32+
// Use 'forwardPorts' to make a list of ports inside the container available locally.
33+
// "forwardPorts": [],
34+
35+
// Use 'postCreateCommand' to run commands after the container is created.
36+
// "postCreateCommand": "java -version",
37+
38+
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
39+
"remoteUser": "vscode"
40+
}

containers/clojure/.npmignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
README.md
2+
test-project
3+
history
4+
definition-manifest.json
5+
.vscode
6+
.npmignore
7+
.calva
8+
.clj-kondo
9+
.cljs_node_repl
10+
.nrepl-port

containers/clojure/README.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# Clojure (Community)
2+
3+
## Summary
4+
5+
*Develop Clojure applications. Includes the Calva and clj-kondo extensions.*
6+
7+
| Metadata | Value |
8+
|-----------------------------|-----------------------|
9+
| *Contributors* | [Christopher Miles](https://github.com/cmiles74), [Matthew Ferry](https://github.com/matthewferry) |
10+
| *Categories* | Community, Languages |
11+
| *Definition Type* | Dockerfile |
12+
| *Works in Codespaces* | Yes |
13+
| *Container host OS support* | Linux, MacOS, Windows |
14+
| *Container OS* | Debian |
15+
| *Languages, platforms* | Clojure |
16+
17+
## Using this definition
18+
19+
While this definition should work unmodified, you can select the version of Java the container uses by updating the `VARIANT` arg in the included `devcontainer.json` (and rebuilding if you've already created the container).
20+
21+
```json
22+
// Or you can use 17-bullseye or 17-buster if you want to pin to an OS version
23+
"args": { "VARIANT": "17" }
24+
```
25+
26+
### Installing a Specific Clojure Version
27+
28+
You can set the default Clojure version used by Boot as well as the version of Clojure that is pre-loaded with Leiningen by adding the `"CLOJURE_VERSION"` to the build arguments in `.devcontainer/devcontainer.json`.
29+
30+
```json
31+
"args": {
32+
"CLOJURE_VERSION": "1.10.3"
33+
}
34+
```
35+
36+
### Installing Clojure CLI Tools
37+
38+
The Clojure command line tools will be installed by default but you can change this behavior by setting the `"INSTALL_CLOJURE_CLI"` build argument to false in
39+
`.devcontainer/devcontainer.json`. The version of the tools may be set with the `"CLOJURE_CLI_VERSION"` argument.
40+
41+
```json
42+
"args": {
43+
"INSTALL_CLOJURE_CLI": "false"
44+
}
45+
```
46+
47+
### Installing Boot
48+
49+
The Boot command line tools will be installed by default but you can change this behavior by setting the `"INSTALL_BOOT"` build argument to false in `.devcontainer/devcontainer.json`. The version of Boot may be set with the `"BOOT_VERSION"` argument.
50+
51+
```json
52+
"args": {
53+
"INSTALL_BOOT": "false"
54+
}
55+
```
56+
57+
Boot will use the same Clojure verson as specified with the `"CLOJURE_VERSION"` argument. You may set a specific version just for Boot by customizing the `"BOOT_CLOJURE_VERSION"` environment variable.
58+
59+
```json
60+
"args": {
61+
"BOOT_CLOJURE_VERSION": "1.10.3"
62+
}
63+
```
64+
65+
### Installing Leiningen
66+
67+
Leiningen will be installed by default but you can change this behavior by setting the `"INSTALL_LEININGEN"` build argument to false in `.devcontainer/devcontainer.json`. The version of Leiningen may be set with the `"LEININGEN_VERSION"` argument, the default value is "stable".
68+
69+
```json
70+
"args": {
71+
"INSTALL_LEININGEN": "false"
72+
}
73+
```
74+
75+
### Installing Polylith
76+
77+
Polylith will be installed by default but you can change this behavior by setting the `"INSTALL_POLYLITH"` build argument to false in `.devcontainer/devcontainer.json`. The version of Polylith may be set with the `"POLYLITH_VERSION"` argument.
78+
79+
```json
80+
"args": {
81+
"POLYLITH_LEININGEN": "false"
82+
}
83+
```
84+
85+
### Installing Node.js
86+
87+
Clojurescript is a compiler for Clojure that targets Javascript. By default the newest long term support release of NodeJS will be installed but you can change this behavior by setting the `"NODE_VERSION"` argument. Setting this argument to "none" will prevent the installation of NodeJS.
88+
89+
```json
90+
"args": {
91+
"NODE_VERSION": "10" // Set to "none" to skip Node.js installation
92+
}
93+
```
94+
95+
This container also includes `nvm` so that you can easily install and switch between multiple Node.js versions.
96+
97+
### Adding the definition to your folder
98+
99+
1. If this is your first time using a development container, please see getting started information on [setting up](https://aka.ms/vscode-remote/containers/getting-started) Remote-Containers or [creating a codespace](https://aka.ms/ghcs-open-codespace) using GitHub Codespaces.
100+
101+
2. To use the pre-built image:
102+
1. Start VS Code and open your project folder or connect to a codespace.
103+
2. Press <kbd>F1</kbd> select and **Add Development Container Configuration Files...** command for **Remote-Containers** or **Codespaces**.
104+
4. Select this definition. You may also need to select **Show All Definitions...** for it to appear.
105+
106+
3. To build a custom version of the image instead:
107+
1. Clone this repository locally.
108+
2. Start VS Code and open your project folder or connect to a codespace.
109+
3. Use your local operating system's file explorer to drag-and-drop the locally cloned copy of the `.devcontainer` folder for this definition into the VS Code file explorer for your opened project or codespace.
110+
4. Update `.devcontainer/devcontainer.json` to reference `"dockerfile": "base.Dockerfile"`.
111+
112+
4. After following step 2 or 3, the contents of the `.devcontainer` folder in your project can be adapted to meet your needs.
113+
114+
5. Finally, press <kbd>F1</kbd> and run **Remote-Containers: Reopen Folder in Container** or **Codespaces: Rebuild Container** to start using the definition.
115+
116+
## Testing the definition
117+
118+
This definition includes some test code that will help you verify it is working as expected on your system. Follow these steps:
119+
120+
1. If this is your first time using a development container, please follow the [getting started steps](https://aka.ms/vscode-remote/containers/getting-started) to set up your machine.
121+
2. Clone this repository.
122+
3. Start VS Code, press <kbd>F1</kbd>, and select **Remote-Containers: Open Folder in Container...**
123+
4. Select the `containers/clojure` folder.
124+
125+
5. To test Clojure:
126+
1. Open the "test-project" folder and click on the `project.clj` file to open the project file.
127+
2. Open the command palette and choose "Calva: Start a Project REPL and Connect (aka Jack-In)".
128+
3. When prompted for a project type, choose "Leiningen".
129+
4. A new Clojure REPL panel will appear, type `(require 'sample)` and press "alt+enter".
130+
5. Type `(sample/main)` and press "alt+enter".
131+
6. Should return "Hello world".
132+
133+
6. To test ClojureScript with Node:
134+
1. Open the "test-project" folder and click on the `project.clj` file to open the project file.
135+
2. Open the command palette and choose "Calva: Start a Project REPL and Connect (aka Jack-In)".
136+
3. When prompted for a project type, choose "Leiningen + ClojureScript built-in for node"
137+
4. A new ClojureScript REPL panel will appear, type `(require 'sample.main)` and press "alt+enter".
138+
5. Should return "Hello world".
139+
140+
7. From here, you can add breakpoints or edit the contents of the `test-project` folder to do further testing.
141+
142+
## License
143+
144+
Licensed under the MIT License. See [LICENSE](https://github.com/microsoft/vscode-dev-containers/blob/main/LICENSE).
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
(defproject sample-project "0.1"
2+
:source-paths ["src/clj" "src/cljs"]
3+
:dependencies [[org.clojure/clojure "1.10.3"]
4+
[org.clojure/clojurescript "1.10.758"]])
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
(ns sample
2+
(:gen-class))
3+
4+
(defn main
5+
[& args]
6+
(println "Hello world"))
7+
8+
(defn -main
9+
[& args]
10+
(apply main args))
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
(ns sample.main)
2+
3+
(println "Hello world")

0 commit comments

Comments
 (0)