Files
coder/examples/templates/quickstart/install-languages.sh.tftpl
T
Nick Vigilante 369a191972 feat: add Quickstart template with language and IDE selection (#24904)
Add a new Quickstart starter template that lets users pick programming
languages, editors, and an optional Git repo to clone. The template uses
Docker under the hood but presents a developer-focused experience: pick
your tools, start coding.

## What's included

- **Languages parameter** (multi-select): Python, Node.js, Go, Rust,
Java, C/C++
- **IDEs parameter** (multi-select): VS Code (Browser), VS Code Desktop,
Cursor, JetBrains, Zed, Windsurf
- **Git repo parameter**: Optional URL to clone on workspace start
- **JetBrains filtering**: Maps selected languages to relevant IDE codes
(Python → PyCharm, Go → GoLand, etc.)
- **Docker precondition check**: Uses `data "external"` +
`terraform_data` precondition to surface a friendly error when Docker is
unavailable, before the Docker provider fails with a cryptic message
- **4 presets**: Web Development, Backend (Go), Data Science, Full Stack
- **Single install script**: All languages install in one `coder_script`
to avoid apt-get lock conflicts (agent scripts run in parallel via
`errgroup`)

<details><summary>Design decisions</summary>

- **Docker as invisible backend**: Docker is required on the Coder
server but never mentioned in the user-facing parameter UI. The
experience is entirely "pick languages, pick editors, start coding."
- **`coder_script` over startup_script**: Language installs use a
templated script file (`install-languages.sh.tftpl`) driven by the
languages parameter. A single script avoids dpkg lock contention since
`coder_script` resources execute concurrently.
- **`data "external"` for Docker check**: The external provider probes
Docker availability independently of the Docker provider. If Docker is
down, the `terraform_data` precondition fails with a human-readable
message before any `docker_*` resource is evaluated. This depends on the
Docker provider connecting lazily (at resource eval time, not at
provider init), which current behavior confirms.
- **JetBrains filtering by language**: Rather than showing all 9
JetBrains IDEs, the template computes relevant IDE codes from the
language selection (e.g. Python → PY, Go → GO) and passes them as
`default` to the JetBrains module.
- **Arch-aware Go install**: The install script detects `uname -m` to
download the correct Go binary for amd64 or arm64.

</details>

<details><summary>Screenshots and recordings from the UI</summary>
<p>
<img width="1851" height="1471" alt="Screenshot 2026-05-05 at 2 14
20 PM"
src="https://github.com/user-attachments/assets/d4c9cdc5-d311-43a5-9e2e-f90b0019eda7"
/>
<img width="1851" height="1471" alt="Screenshot 2026-05-05 at 2 15
06 PM"
src="https://github.com/user-attachments/assets/cf3023fe-b6db-4503-a6c4-eaa0ec0659f8"
/>


https://github.com/user-attachments/assets/7507fd7d-ddb5-457a-9f7d-cbf89b36eb20


</p>
</details> 

> [!NOTE]
> This PR was authored by Coder Agents.
2026-05-06 13:55:38 +00:00

89 lines
2.6 KiB
Plaintext

#!/bin/bash
set -e
LANGUAGES="${LANGUAGES}"
APT_UPDATED=false
apt_update() {
if [ "$APT_UPDATED" = "false" ]; then
sudo apt-get update -qq
APT_UPDATED=true
fi
}
if echo "$LANGUAGES" | grep -q "python"; then
if command -v python3 >/dev/null 2>&1; then
echo "Python: $(python3 --version)"
else
echo "Installing Python..."
apt_update
sudo apt-get install -y -qq python3 python3-pip python3-venv
echo "Installed Python: $(python3 --version)"
fi
fi
if echo "$LANGUAGES" | grep -q "nodejs"; then
if command -v node >/dev/null 2>&1; then
echo "Node.js: $(node --version)"
else
echo "Installing Node.js 22..."
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y -qq nodejs
echo "Installed Node.js: $(node --version)"
fi
fi
if echo "$LANGUAGES" | grep -q "go"; then
if command -v /usr/local/go/bin/go >/dev/null 2>&1; then
echo "Go: $(/usr/local/go/bin/go version)"
else
echo "Installing Go..."
ARCH=$(uname -m)
case $ARCH in
x86_64) GOARCH="amd64" ;;
aarch64) GOARCH="arm64" ;;
*) echo "Unsupported architecture: $ARCH"; exit 1 ;;
esac
GO_VERSION=$(curl -fsSL "https://go.dev/VERSION?m=text" | head -1)
curl -fsSL "https://go.dev/dl/$${GO_VERSION}.linux-$${GOARCH}.tar.gz" | sudo tar -C /usr/local -xz
echo 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' | sudo tee /etc/profile.d/go.sh >/dev/null
echo "Installed Go: $(/usr/local/go/bin/go version)"
fi
fi
if echo "$LANGUAGES" | grep -q "rust"; then
if command -v rustc >/dev/null 2>&1 || [ -f "$HOME/.cargo/bin/rustc" ]; then
RUSTC=$${HOME}/.cargo/bin/rustc
command -v rustc >/dev/null 2>&1 && RUSTC=rustc
echo "Rust: $($RUSTC --version)"
else
echo "Installing Rust..."
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
echo "Installed Rust: $($HOME/.cargo/bin/rustc --version)"
fi
fi
if echo "$LANGUAGES" | grep -q "java"; then
if command -v java >/dev/null 2>&1; then
echo "Java: $(java --version 2>&1 | head -1)"
else
echo "Installing Java (OpenJDK 21)..."
apt_update
sudo apt-get install -y -qq openjdk-21-jdk
echo "Installed Java: $(java --version 2>&1 | head -1)"
fi
fi
if echo "$LANGUAGES" | grep -q "cpp"; then
if command -v gcc >/dev/null 2>&1; then
echo "C/C++: $(gcc --version | head -1)"
else
echo "Installing C/C++ toolchain..."
apt_update
sudo apt-get install -y -qq gcc g++ make cmake
echo "Installed C/C++: $(gcc --version | head -1)"
fi
fi
echo "Language setup complete."