Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

flake-parts: add nix run interface along with devenv container subcommand and improvements #503

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion devenv.nix
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
grep -F 'nix-develop started succesfully' <./console
grep -F "$(${lib.getExe pkgs.hello})" <./console
# Test that a container can be built
nix build --impure .#container-processes
nix build --impure .#devenv-default-container-processes-spec
popd
rm -rf "$tmp"

Expand Down
53 changes: 49 additions & 4 deletions flake-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ devenvFlake: { flake-parts-lib, lib, inputs, ... }: {
};
}];
}).type;

shellPrefix = shellName: if shellName == "default" then "" else "${shellName}-";
in

{
Expand Down Expand Up @@ -44,8 +42,55 @@ devenvFlake: { flake-parts-lib, lib, inputs, ... }: {
(shellName: devenv:
lib.concatMapAttrs
(containerName: container:
{ "${shellPrefix shellName}container-${containerName}" = container.derivation; }
)
let prefix = "devenv-${shellName}-container-${containerName}"; in {
"${prefix}-spec" = container.derivation;
})
devenv.containers
)
config.devenv.shells;

config.apps =
lib.concatMapAttrs
(shellName: devenv:
lib.concatMapAttrs
(containerName: config:
let prefix = "devenv-${shellName}-container-${containerName}"; in {
"${prefix}-copy-to" = {
type = "app";
program = pkgs.writeShellApplication {
name = "${prefix}-copy-to";
text = ''
${config.copyScript} ${config.derivation} "$@"
'';
};
};
"${prefix}-docker-run" = {
type = "app";
program = "${config.dockerRun}";
};
"${prefix}-docker-load" = {
type = "app";
program = pkgs.writeShellApplication {
name = "${prefix}-docker-load";
text = ''
${config.copyScript} ${config.derivation} --registry local-docker "$@"
'';
};
};
"${prefix}-podman-run" = {
type = "app";
program = "${config.podmanRun}";
};
"${prefix}-podman-load" = {
type = "app";
program = pkgs.writeShellApplication {
name = "${prefix}-podman-load";
text = ''
${config.copyScript} ${config.derivation} --registry local "$@"
'';
};
};
})
devenv.containers
)
config.devenv.shells;
Expand Down
53 changes: 12 additions & 41 deletions src/devenv-devShell.nix
Original file line number Diff line number Diff line change
@@ -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
exec $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_BIN = "${pkgs.nix}/bin";
});
in
pkgs.writeScriptBin "devenv" ''${envs} "${app}/bin/devenv-flake-cli" "$@"''
98 changes: 98 additions & 0 deletions src/devenv-devShell.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env bash
set -eEuo pipefail

if [ "${DEBUG:-}" == 1 ]; then
set -x
fi
PROCFILESCRIPT="${PROCFILESCRIPT:-"placeholder"}"
VERSION="${VERSION:-"placeholder"}"
CUSTOM_NIX_BIN="${CUSTOM_NIX_BIN:-"$(dirname "$(command -v nix)")"}"

NIX_FLAGS=(--show-trace --extra-experimental-features 'nix-command flakes')

function nix {
"$CUSTOM_NIX_BIN/nix" "${NIX_FLAGS[@]}" "${@}"
}

function container {
# shellcheck disable=SC1090
source "$(command -v docopts).sh"
# shellcheck disable=SC2016
eval "$(docopts -A args -h '
Usage: container [options] <container-name> [--] [<run-args>...]

Options:
-s <shell>, --shell <shell> `devenv.shells.<shell>` to use. [default: default]
-r <name>, --registry <name> Registry to copy the container to.
Available shortcuts: config, local-docker, local [default: config]
-i <name>, --image <name> Image name:tag to replace ${container.name}:${container.version} with.
--copy Copy the container to the registry.
--copy-args <args> Arguments passed to `skopeo copy`.
--docker-run Execute `docker run`.
--podman-run Execute `podman run`.
' : "$@")"

local run_args=()
eval "$(docopt_get_eval_array args '<run-args>' run_args)"

local registry="${args['--registry']}"
local copy_args=()

local flake_root="${DEVENV_ROOT:-"${DIRENV_ROOT}"}"
local app_prefix="${flake_root}#devenv-${args['--shell']}-container-${args['<container-name>']}"

if [[ "${args['--copy']}" != false || "${args['--docker-run']}" != false || "${args['--podman-run']}" != false ]]; then
if [[ ${args['--docker-run']} == true ]]; then
registry=local-docker
elif [[ ${args['--podman-run']} == true ]]; then
registry=local
fi
if [[ -n "${args['--image']}" ]]; then
copy_args+=(--image "${args['--image']}")
fi
# shellcheck disable=SC2086
nix run --impure "${app_prefix}-copy-to" -- --registry "${registry}" "${copy_args[@]}" ${args['--copy-args']}
fi

if [[ "${args['--docker-run']}" != false ]]; then
nix run --impure "${app_prefix}-docker-run" -- "${run_args[@]}"
elif [[ "${args['--podman-run']}" != false ]]; then
nix run --impure "${app_prefix}-podman-run" -- "${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
exec "$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
34 changes: 25 additions & 9 deletions src/devenv.nix
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,23 @@ pkgs.writeScriptBin "devenv" ''
container)
assemble
help=$(${coreutils}/bin/cat << 'EOF'
Usage: container [options] CONTAINER-NAME
Usage: container [options] CONTAINER-NAME [--] [<run-args>...]

Options:
--registry=<reg> Registry to copy the container to.
--copy Copy the container to the registry.
--copy-args=<args> Arguments passed to `skopeo copy`.
--docker-run Execute `docker run`.
-r <name>, --registry <name> Registry to copy the container to.
-i <name>, --image <name> Image name:tag to replace ''${container.name}:''${container.version} with.
--copy Copy the container to the registry.
--copy-args=<args> Arguments passed to `skopeo copy`.
--docker-run Execute `docker run`.
--podman-run Execute `podman run`.
EOF
)

# shellcheck disable=SC1090
source "$(command -v ${docopts}/bin/docopts.sh)"
eval "$(${docopts}/bin/docopts -A subcommand -h "$help" : "$@")"
local run_args=()
eval "$(docopt_get_eval_array args '<run-args>' run_args)"

export DEVENV_CONTAINER=1
container="''${subcommand[CONTAINER-NAME]}"
Expand All @@ -132,20 +138,30 @@ pkgs.writeScriptBin "devenv" ''
echo $spec

# copy container
if [[ ''${subcommand[--copy]} != false || ''${subcommand[--docker-run]} != false ]]; then
if [[ ''${subcommand[--copy]} != false || ''${subcommand[--docker-run]} != false || ''${subcommand[--podman-run]} != false ]]; then
copyScript=$(${nix}/bin/nix $NIX_FLAGS build --print-out-paths --no-link --impure ".#devenv.containers.\"$container\".copyScript")

args=()

if [[ ''${subcommand[--docker-run]} == true ]]; then
registry=docker-daemon:
registry=local-docker
elif [[ ''${subcommand[--podman-run]} == true ]]; then
registry=local
else
registry="''${subcommand[--registry]}"
fi
$copyScript $spec $registry ''${subcommand[--copy-args]}
if [[ -n "''${subcommand[--image]}" ]]; then
args+=(--image "''${subcommand[--image]}")
fi

$copyScript "$spec" --registry "$registry" "''${args[@]}" ''${subcommand[--copy-args]}
fi

# docker run
if [[ ''${subcommand[--docker-run]} != false ]]; then
$(${nix}/bin/nix $NIX_FLAGS build --print-out-paths --no-link --impure ".#devenv.containers.\"$container\".dockerRun")
$(${nix}/bin/nix $NIX_FLAGS build --print-out-paths --no-link --impure ".#devenv.containers.\"$container\".dockerRun") -- "''${run_args[@]}"
elif [[ ''${subcommand[--podman-run]} != false ]]; then
$(${nix}/bin/nix $NIX_FLAGS build --print-out-paths --no-link --impure ".#devenv.containers.\"$container\".podmanRun") -- "''${run_args[@]}"
fi
;;
search)
Expand Down
Loading