From 32dccd5605b665525100e8a43d6b0ce19dc50e90 Mon Sep 17 00:00:00 2001 From: Krzysztof Nazarewski Date: Fri, 24 Mar 2023 09:09:00 +0100 Subject: [PATCH] flakes CLI: add container commands --- src/devenv-devShell.nix | 53 +++++----------------- src/devenv-devShell.sh | 86 ++++++++++++++++++++++++++++++++++++ templates/flake-parts/.envrc | 11 +++++ 3 files changed, 109 insertions(+), 41 deletions(-) create mode 100755 src/devenv-devShell.sh create mode 100644 templates/flake-parts/.envrc diff --git a/src/devenv-devShell.nix b/src/devenv-devShell.nix index 2efb7bfb8..397350874 100644 --- a/src/devenv-devShell.nix +++ b/src/devenv-devShell.nix @@ -1,46 +1,17 @@ { config, pkgs }: let lib = pkgs.lib; - version = lib.fileContents ./modules/latest-version; -in -pkgs.writeScriptBin "devenv" '' - #!/usr/bin/env bash - - # we want subshells to fail the program - set -e - NIX_FLAGS="--show-trace --extra-experimental-features nix-command --extra-experimental-features flakes" + app = pkgs.writeShellApplication { + name = "devenv-flake-cli"; + runtimeInputs = with pkgs; [ docopts ]; + text = builtins.readFile ./devenv-devShell.sh; + }; - command=$1 - if [[ ! -z $command ]]; then - shift - fi - - case $command in - up) - procfilescript=${config.procfileScript} - if [ "$(cat $procfilescript|tail -n +2)" = "" ]; then - echo "No 'processes' option defined: https://devenv.sh/processes/" - exit 1 - else - $procfilescript - fi - ;; - version) - echo "devenv: ${version}" - ;; - *) - echo "https://devenv.sh (version ${version}): Fast, Declarative, Reproducible, and Composable Developer Environments" - echo - echo "This is a flake integration wrapper that comes with a subset of functionality from the flakeless devenv CLI." - echo - echo "Usage: devenv command" - echo - echo "Commands:" - echo - echo "up Starts processes in foreground. See http://devenv.sh/processes" - echo "version Display devenv version" - echo - exit 1 - esac -'' + envs = lib.concatStringsSep " " (lib.mapAttrsToList lib.toShellVar { + PROCFILESCRIPT = config.procfileScript; + VERSION = lib.fileContents ./modules/latest-version; + CUSTOM_NIX = "${pkgs.nix}/bin/nix"; + }); +in +pkgs.writeScriptBin "devenv" ''${envs} "${app}/bin/devenv-flake-cli" "$@"'' diff --git a/src/devenv-devShell.sh b/src/devenv-devShell.sh new file mode 100755 index 000000000..578490a9a --- /dev/null +++ b/src/devenv-devShell.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash +set -eEuo pipefail + +if [ "${DEBUG:-}" == 1 ]; then + set -x +fi +PROCFILESCRIPT="${PROCFILESCRIPT:-"placeholder"}" +VERSION="${VERSION:-"placeholder"}" +CUSTOM_NIX="${CUSTOM_NIX:-"nix"}" + +NIX_FLAGS=(--show-trace --extra-experimental-features 'nix-command flakes') + +function nix { + "$CUSTOM_NIX" "${NIX_FLAGS[@]}" "${@}" +} + +function container { + declare -A args + # shellcheck disable=SC2016 + eval "$(docopts -A args -h ' +Usage: container [options] [--] [...] + +Options: + -s , --shell `devenv.shells.` to use. [default: default] + -c , --container `devenv.shells.*.containers.` name to use. [default: shell] + -r , --registry Registry to copy the container to. [default: containers-storage:localhost/] + --copy Copy the container to the registry. + --copy-args= Arguments passed to `skopeo copy`. + --docker-run Execute `docker run`. + --run Execute `docker run` or `podman run`. +' : "$@")" + + local shell_name="${args['--shell']}" container_name="${args['--container']}" shell_prefix="" + if [ "${shell_name}" != "default" ]; then + shell_prefix="${shell_name}-" + fi + + if [[ "${args['--copy']}" != false ]]; then + # shellcheck disable=SC2086 + nix run "${DEVENV_ROOT}#${shell_prefix}container-${container_name}-copy-to" "${args['--registry']}" ${args['--copy-args']} + fi + + if [[ "${args['--run']}" != false || "${args['--docker-run']}" != false ]] ; then + # shellcheck disable=SC1090 + source "$(command -v docopts.sh)" + # shellcheck disable=SC2207 + run_args=( $(docopt_get_values args '') ) + nix run "${DEVENV_ROOT}#${shell_prefix}container-${container_name}" -- "${run_args[@]}" + fi +} + +command="${1:-}" +if [[ -n "$command" ]]; then + shift +fi + +case "$command" in +up) + if [ "$(tail -n +2 <<<"$PROCFILESCRIPT")" = "" ]; then + echo "No 'processes' option defined: https://devenv.sh/processes/" + exit 1 + else + "$PROCFILESCRIPT" + fi + ;; +container) + container "$@" + ;; +version) + echo "devenv: ${VERSION}" + ;; +*) + echo "https://devenv.sh (version ${VERSION}): Fast, Declarative, Reproducible, and Composable Developer Environments" + echo + echo "This is a flake integration wrapper that comes with a subset of functionality from the flakeless devenv CLI." + echo + echo "Usage: devenv command" + echo + echo "Commands:" + echo + echo "up Starts processes in foreground. See http://devenv.sh/processes" + echo "version Display devenv version" + echo + exit 1 + ;; +esac diff --git a/templates/flake-parts/.envrc b/templates/flake-parts/.envrc new file mode 100644 index 000000000..ce4386fd0 --- /dev/null +++ b/templates/flake-parts/.envrc @@ -0,0 +1,11 @@ +if ! has nix_direnv_version || ! nix_direnv_version 2.2.1; then + source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.2.1/direnvrc" "sha256-zelF0vLbEl5uaqrfIzbgNzJWGmLzCmYAkInj/LNxvKs=" +fi + +nix_direnv_watch_file devenv.nix +nix_direnv_watch_file devenv.lock +nix_direnv_watch_file devenv.yaml +if ! use flake . --impure +then + echo "devenv could not be build. The devenv environment was not loaded. Make the necessary changes to devenv.nix and hit enter to try again." >&2 +fi