diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index d1fba94..1088413 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -22,6 +22,7 @@ jobs: - charmbracelet-gum - chezmoi.io - deno.com + - devenv.sh - feature-installer - jj-vcs.dev - nixos.org @@ -60,6 +61,7 @@ jobs: - charmbracelet-gum - chezmoi.io - deno.com + - devenv.sh - feature-installer - jj-vcs.dev - nixos.org diff --git a/src/devenv.sh/README.md b/src/devenv.sh/README.md new file mode 100644 index 0000000..b8c57bc --- /dev/null +++ b/src/devenv.sh/README.md @@ -0,0 +1,24 @@ + +# devenv.sh (devenv.sh) + +Install "devenv" binary + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainer-community/devcontainer-features/devenv.sh:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| version | Version of "devenv" to install. | string | latest | + + + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainer-community/devcontainer-features/blob/main/src/devenv.sh/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/devenv.sh/devcontainer-feature.json b/src/devenv.sh/devcontainer-feature.json new file mode 100644 index 0000000..01809e6 --- /dev/null +++ b/src/devenv.sh/devcontainer-feature.json @@ -0,0 +1,17 @@ +{ + "name": "devenv.sh", + "id": "devenv.sh", + "version": "1.0.0", + "description": "Install devenv via Nix", + "documentationURL": "https://github.com/devcontainer-community/devcontainer-features/tree/main/src/devenv.sh", + "options": { + "version": { + "type": "string", + "default": "latest", + "proposals": [ + "latest" + ], + "description": "Version of devenv to install (e.g. \"2.0.4\"), or \"latest\"." + } + } +} diff --git a/src/devenv.sh/install.sh b/src/devenv.sh/install.sh new file mode 100755 index 0000000..d8a1016 --- /dev/null +++ b/src/devenv.sh/install.sh @@ -0,0 +1,86 @@ +#!/bin/bash +set -o errexit +set -o pipefail +set -o noclobber +set -o nounset +set -o allexport +readonly binaryName='devenv' +readonly binaryTargetFolder='/usr/local/bin' +readonly nixBin='/nix/var/nix/profiles/default/bin/nix' +readonly nixDaemonBin='/nix/var/nix/profiles/default/bin/nix-daemon' +readonly nixDaemonSocket='/nix/var/nix/daemon-socket/socket' +apt_get_update() { + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + echo "Running apt-get update..." + apt-get update -y + fi +} +apt_get_checkinstall() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + apt_get_update + DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends --no-install-suggests --option 'Debug::pkgProblemResolver=true' --option 'Debug::pkgAcquire::Worker=1' "$@" + fi +} +apt_get_cleanup() { + apt-get clean + rm -rf /var/lib/apt/lists/* +} +echo_banner() { + local text="$1" + echo -e "\e[1m\e[97m\e[41m$text\e[0m" +} +install() { + local remote_user="${_REMOTE_USER:-root}" + if [ -z "${remote_user}" ]; then + echo "ERROR: _REMOTE_USER is not set" + exit 1 + fi + apt_get_checkinstall curl ca-certificates + if [ ! -x "${nixBin}" ]; then + # sandbox = false is required in Docker/devcontainer environments where + # the host kernel may not support Nix's sandboxing (seccomp restrictions) + su "${remote_user}" -c "curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install linux --extra-conf 'sandbox = false' --no-confirm --init none" + fi + # nix-daemon without --daemon runs in the foreground (no fork), so $! is the actual PID + "${nixDaemonBin}" > /dev/null 2>&1 & + local daemon_pid=$! + local attempts=0 + until [ -S "${nixDaemonSocket}" ]; do + if ! kill -0 "${daemon_pid}" 2>/dev/null; then + echo "ERROR: Nix daemon process exited unexpectedly" + exit 1 + fi + sleep 1 + attempts=$((attempts + 1)) + if [ "${attempts}" -ge 30 ]; then + echo "ERROR: Nix daemon did not become ready within 30 seconds" + exit 1 + fi + done + local nix_flake_ref + if [ "${VERSION:-latest}" = 'latest' ] || [ -z "${VERSION:-}" ]; then + nix_flake_ref='github:cachix/devenv' + else + nix_flake_ref="github:cachix/devenv/v${VERSION}" + fi + local remote_home + if [ "${remote_user}" = 'root' ]; then + remote_home='/root' + else + remote_home="$(eval echo "~${remote_user}")" + fi + su "${remote_user}" -c " + . /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh 2>/dev/null || true + '${nixBin}' profile install \ + --extra-experimental-features 'nix-command flakes' \ + --extra-trusted-public-keys 'devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw= cachix.cachix.org-1:eWNHQldwUO7G2VkjpnjDbWwy4KQ/HNxht7H4SSoMckM=' \ + --extra-substituters 'https://devenv.cachix.org https://cachix.cachix.org' \ + '${nix_flake_ref}#devenv' + " + ln -sf "${remote_home}/.nix-profile/bin/${binaryName}" "${binaryTargetFolder}/${binaryName}" + apt_get_cleanup +} +echo_banner "devcontainer.community" +echo "Installing ${binaryName}..." +install "$@" +echo "(*) Done!" diff --git a/test/devenv.sh/test.sh b/test/devenv.sh/test.sh new file mode 100755 index 0000000..d12516e --- /dev/null +++ b/test/devenv.sh/test.sh @@ -0,0 +1,18 @@ +#!/bin/bash + + +set -e + +# Optional: Import test library bundled with the devcontainer CLI +# See https://github.com/devcontainers/cli/blob/HEAD/docs/features/test.md#dev-container-features-test-lib +# Provides the 'check' and 'reportResults' commands. +source dev-container-features-test-lib + +# Feature-specific tests +# The 'check' command comes from the dev-container-features-test-lib. Syntax is... +# check