From 2b2a5f652bd3df0cb514e21af064c5390b53d0f0 Mon Sep 17 00:00:00 2001 From: "nohz.afk" <149959021+nohzafk@users.noreply.github.com> Date: Fri, 19 Jan 2024 01:20:49 +0800 Subject: [PATCH] feature nix: add option useAttrPath to use packages attribute path (#787) * add option `useAttrPath` to support `nix-env -iA` * add test and fix problem * change to useAttributePath * bump the version * update test --- src/nix/devcontainer-feature.json | 11 +++++++--- src/nix/install.sh | 9 ++++---- src/nix/post-install-steps.sh | 19 ++++++++++++++++ test/nix/packages-use-attr-path.sh | 35 ++++++++++++++++++++++++++++++ test/nix/scenarios.json | 13 ++++++++++- 5 files changed, 79 insertions(+), 8 deletions(-) create mode 100755 test/nix/packages-use-attr-path.sh diff --git a/src/nix/devcontainer-feature.json b/src/nix/devcontainer-feature.json index 96a75016b..0e37efed2 100644 --- a/src/nix/devcontainer-feature.json +++ b/src/nix/devcontainer-feature.json @@ -1,9 +1,9 @@ { "id": "nix", - "version": "1.1.3", + "version": "1.2.0", "name": "Nix Package Manager", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/nix", - "description": "Installs the Nix package manager and optionally a set of packages.", + "description": "Installs the Nix package manager and optionally a set of packages.", "options": { "version": { "type": "string", @@ -21,6 +21,11 @@ "default": "", "description": "Optional comma separated list of Nix packages to install in profile." }, + "useAttributePath": { + "type": "boolean", + "default": false, + "description": "Enable this option to use exact attribute path of the package in the Nixpkgs repository, aligning with the nix-env -iA command." + }, "flakeUri": { "type": "string", "default": "", @@ -39,4 +44,4 @@ "PATH": "/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:${PATH}" }, "entrypoint": "/usr/local/share/nix-entrypoint.sh" -} \ No newline at end of file +} diff --git a/src/nix/install.sh b/src/nix/install.sh index ed048fe8d..5b8fe8f28 100755 --- a/src/nix/install.sh +++ b/src/nix/install.sh @@ -8,6 +8,7 @@ cd "${FEATURE_DIR}" VERSION="${VERSION:-"latest"}" MULTIUSER="${MULTIUSER:-"true"}" PACKAGES="${PACKAGES//,/ }" +USEATTRIBUTEPATH="${USEATTRIBUTEPATH:-"false"}" FLAKEURI="${FLAKEURI:-""}" EXTRANIXCONFIG="${EXTRANIXCONFIG:-""}" USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" @@ -68,7 +69,7 @@ else exit 1 fi echo "(*) Performing single-user install..." - echo -e "\n**NOTE: Nix will only work for user ${USERNAME} on Linux if the host machine user's UID is $(id -u ${USERNAME}). You will need to chown /nix otherwise.**\n" + echo -e "\n**NOTE: Nix will only work for user ${USERNAME} on Linux if the host machine user's UID is $(id -u ${USERNAME}). You will need to chown /nix otherwise.**\n" # Install per https://nixos.org/manual/nix/stable/installation/installing-binary.html#single-user-installation mkdir -p /nix chown ${USERNAME} /nix ${tmpdir} @@ -79,14 +80,14 @@ else ' update_rc_file "$home_dir/.bashrc" "${snippet}" update_rc_file "$home_dir/.zshenv" "${snippet}" - update_rc_file "$home_dir/.profile" "${snippet}" + update_rc_file "$home_dir/.profile" "${snippet}" fi rm -rf "${tmpdir}" "/tmp/tmp-gnupg" fi # Set nix config mkdir -p /etc/nix -create_or_update_file /etc/nix/nix.conf 'sandbox = false' +create_or_update_file /etc/nix/nix.conf 'sandbox = false' if [ ! -z "${FLAKEURI}" ] && [ "${FLAKEURI}" != "none" ]; then create_or_update_file /etc/nix/nix.conf 'experimental-features = nix-command flakes' fi @@ -127,4 +128,4 @@ else " fi -echo "Done!" \ No newline at end of file +echo "Done!" diff --git a/src/nix/post-install-steps.sh b/src/nix/post-install-steps.sh index aa466798b..68f93a391 100755 --- a/src/nix/post-install-steps.sh +++ b/src/nix/post-install-steps.sh @@ -2,10 +2,29 @@ set -e echo "(*) Executing post-installation steps..." +# if not starts with "nixpkgs." add it as prefix to package name +add_nixpkgs_prefix() { + local packages=$1 + local -a addr + IFS=' ' read -ra addr <<<"$packages" + for i in "${!addr[@]}"; do + if [[ ${addr[i]} != nixpkgs.* ]]; then + addr[i]="nixpkgs.${addr[i]}" + fi + done + IFS=' ' echo "${addr[*]}" +} + # Install list of packages in profile if specified. if [ ! -z "${PACKAGES}" ] && [ "${PACKAGES}" != "none" ]; then + if [ "${USEATTRIBUTEPATH}" = "true" ]; then + PACKAGES=$(add_nixpkgs_prefix "$PACKAGES") + echo "Installing packages \"${PACKAGES}\" in profile..." + nix-env -iA ${PACKAGES} + else echo "Installing packages \"${PACKAGES}\" in profile..." nix-env --install ${PACKAGES} + fi fi # Install Nix flake in profile if specified diff --git a/test/nix/packages-use-attr-path.sh b/test/nix/packages-use-attr-path.sh new file mode 100755 index 000000000..7f34a96ea --- /dev/null +++ b/test/nix/packages-use-attr-path.sh @@ -0,0 +1,35 @@ +#!/bin/bash +set -e + +# Optional: Import test library bundled with the devcontainer CLI +source dev-container-features-test-lib + +uid="$(id -u)" +echo "Current user UID is ${uid}." +if [ "${uid}" != "1000" ]; then + echo "Current user UID was adjusted." +fi +set +e +vscode_uid="$(id -u vscode)" +set -e +if [ "${vscode_uid}" != "" ]; then + echo "User vscode UID is ${vscode_uid}." + if [ "${vscode_uid}" != "1000" ]; then + echo "User vscode UID was adjusted." + fi +fi +nix_uid="$(stat /nix -c "%u")" +echo "/nix UID is ${nix_uid}." + +cat /etc/os-release + +# Feature-specific tests +# The 'check' command comes from the dev-container-features-test-lib. +check "nix-env" type nix-env +check "vim_installed" type vim +check "node_installed" type node +check "yarn_installed" type yarn + +# Report result +# If any of the checks above exited with a non-zero exit code, the test will fail. +reportResults &2>1 diff --git a/test/nix/scenarios.json b/test/nix/scenarios.json index c287f58c7..80ead7ff6 100644 --- a/test/nix/scenarios.json +++ b/test/nix/scenarios.json @@ -81,6 +81,17 @@ } } }, + "packages-use-attr-path": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "remoteUser": "vscode", + "features": { + "nix": { + "packages": "nodePackages.nodejs,nixpkgs.vim,nixpkgs.yarn", + "useAttributePath": true + } + } + }, + "flake": { "image": "mcr.microsoft.com/devcontainers/base:ubuntu", "remoteUser": "vscode", @@ -99,4 +110,4 @@ } } } -} \ No newline at end of file +}