From 38a536e59e6e18c509cd2c6492f06b7da39a0e1e Mon Sep 17 00:00:00 2001 From: Nicolas Mattia Date: Thu, 13 Aug 2020 14:28:10 +0200 Subject: [PATCH] Add NIV_OVERRIDE_{...} This updates the sources.nix to replace the `outPath` field of package `foo` with the content of envionment variable `NIV_OVERRIDE_foo`. In the environment variable name, all characters outside of `[a-zA-Z0-9_]` are escaped to `_`. --- default.nix | 1 + nix/sources.nix | 12 ++++++++++- src/Niv/Sources.hs | 4 ++++ tests/eval/default.nix | 45 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 tests/eval/default.nix diff --git a/default.nix b/default.nix index 77584e4..c07e521 100644 --- a/default.nix +++ b/default.nix @@ -197,6 +197,7 @@ rec tests-github = pkgs.callPackage ./tests/github { inherit niv; }; tests-git = pkgs.callPackage ./tests/git { inherit niv; }; + tests-eval = pkgs.callPackage ./tests/eval {}; fmt-check = pkgs.stdenv.mkDerivation diff --git a/nix/sources.nix b/nix/sources.nix index 7bd0f3e..b094841 100644 --- a/nix/sources.nix +++ b/nix/sources.nix @@ -73,6 +73,15 @@ let else abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}"; + # If the environment variable NIV_OVERRIDE_${name} is set, then use + # the path directly as opposed to the fetched source. + replace = name: drv: + let + saneName = stringAsChars (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name; + ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}"; + in + if ersatz == "" then drv else ersatz; + # Ports of functions for older nix versions # a Nix version of mapAttrs if the built-in doesn't exist @@ -119,7 +128,7 @@ let then abort "The values in sources.json should not have an 'outPath' attribute" else - spec // { outPath = fetch config.pkgs name spec; } + spec // { outPath = replace name (fetch config.pkgs name spec); } ) config.sources; # The "config" used by the fetchers @@ -134,5 +143,6 @@ let # The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers inherit pkgs; }; + in mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); } diff --git a/src/Niv/Sources.hs b/src/Niv/Sources.hs index 33c46e4..b977bc9 100644 --- a/src/Niv/Sources.hs +++ b/src/Niv/Sources.hs @@ -160,6 +160,8 @@ data SourcesNixVersion | -- prettify derivation name -- add 'local' type of sources V18 + | -- add NIV_OVERRIDE_{name} + V19 deriving stock (Bounded, Enum, Eq) -- | A user friendly version @@ -183,6 +185,7 @@ sourcesVersionToText = \case V16 -> "16" V17 -> "17" V18 -> "18" + V19 -> "19" latestVersionMD5 :: T.Text latestVersionMD5 = sourcesVersionToMD5 maxBound @@ -213,6 +216,7 @@ sourcesVersionToMD5 = \case V16 -> "2d93c52cab8e960e767a79af05ca572a" V17 -> "149b8907f7b08dc1c28164dfa55c7fad" V18 -> "bc5e6aefcaa6f9e0b2155ca4f44e5a33" + V19 -> "543621698065cfc6a4a7985af76df718" -- | The MD5 sum of ./nix/sources.nix sourcesNixMD5 :: IO T.Text diff --git a/tests/eval/default.nix b/tests/eval/default.nix new file mode 100644 index 0000000..880cc02 --- /dev/null +++ b/tests/eval/default.nix @@ -0,0 +1,45 @@ +{ pkgs ? import {} +}: + +pkgs.runCommand "foobar" { nativeBuildInputs = [ pkgs.jq pkgs.nix pkgs.moreutils ]; } + '' + # for nix to run smoothly in multi-user install + # https://github.com/NixOS/nix/issues/3258 + # https://github.com/cachix/install-nix-action/issues/16 + export NIX_STATE_DIR="$TMPDIR" + export NIX_LOG_DIR="$TMPDIR" + + cp ${ ../../nix/sources.nix} sources.nix + echo '{}' > sources.json + + update_sources() { + cat sources.json | jq -cMe "$1" | sponge sources.json + } + + update_sources '.foo = { type: "tarball", url: "foo", sha256: "whocares" }' + update_sources '."ba-r" = { type: "tarball", url: "foo", sha256: "whocares" }' + update_sources '."ba z" = { type: "tarball", url: "foo", sha256: "whocares" }' + + eval_outPath() { + nix eval --raw '(let sources = import ./sources.nix; in sources.'"$1"'.outPath)' + } + + eq() { + if ! [ "$1" == "$2" ]; then + echo "expected" + echo " '$1' == '$2'" + exit 1 + fi + } + + res="$(NIV_OVERRIDE_foo="hello" eval_outPath "foo")" + eq "$res" "hello" + + res="$(NIV_OVERRIDE_ba_r="hello" eval_outPath "ba-r")" + eq "$res" "hello" + + res="$(NIV_OVERRIDE_ba_z="hello" eval_outPath '"ba z"')" + eq "$res" "hello" + + touch "$out" + ''