aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/manual/src/command-ref/nix-store/query.md14
-rw-r--r--doc/manual/src/release-notes/rl-next.md4
-rw-r--r--src/nix-store/nix-store.cc18
-rw-r--r--tests/check-refs.nix2
-rw-r--r--tests/dependencies.nix13
-rw-r--r--tests/dependencies.sh17
-rw-r--r--tests/dyn-drv/eval-outputOf.sh4
-rw-r--r--tests/export-graph.nix4
-rw-r--r--tests/remote-store.sh2
9 files changed, 68 insertions, 10 deletions
diff --git a/doc/manual/src/command-ref/nix-store/query.md b/doc/manual/src/command-ref/nix-store/query.md
index cd45a4932..a158c76aa 100644
--- a/doc/manual/src/command-ref/nix-store/query.md
+++ b/doc/manual/src/command-ref/nix-store/query.md
@@ -5,8 +5,8 @@
# Synopsis
`nix-store` {`--query` | `-q`}
- {`--outputs` | `--requisites` | `-R` | `--references` |
- `--referrers` | `--referrers-closure` | `--deriver` | `-d` |
+ {`--outputs` | `--requisites` | `-R` | `--references` | `--referrers` |
+ `--referrers-closure` | `--deriver` | `-d` | `--valid-derivers` |
`--graph` | `--tree` | `--binding` *name* | `-b` *name* | `--hash` |
`--size` | `--roots`}
[`--use-output`] [`-u`] [`--force-realise`] [`-f`]
@@ -82,13 +82,21 @@ symlink.
in the Nix store that are dependent on *paths*.
- `--deriver`; `-d`\
- Prints the [deriver] of the store paths *paths*. If
+ Prints the [deriver] that was used to build the store paths *paths*. If
the path has no deriver (e.g., if it is a source file), or if the
deriver is not known (e.g., in the case of a binary-only
deployment), the string `unknown-deriver` is printed.
+ The returned deriver is not guaranteed to exist in the local store, for
+ example when *paths* were substituted from a binary cache.
+ Use `--valid-derivers` instead to obtain valid paths only.
[deriver]: ../../glossary.md#gloss-deriver
+ - `--valid-derivers`\
+ Prints a set of derivation files (`.drv`) which are supposed produce
+ said paths when realized. Might print nothing, for example for source paths
+ or paths subsituted from a binary cache.
+
- `--graph`\
Prints the references graph of the store paths *paths* in the format
of the `dot` tool of AT\&T's [Graphviz
diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md
index 5a870f1ab..02ad0a661 100644
--- a/doc/manual/src/release-notes/rl-next.md
+++ b/doc/manual/src/release-notes/rl-next.md
@@ -24,3 +24,7 @@
It is part of the [`dynamic-derivations`](@docroot@/contributing/experimental-features.md#xp-feature-dynamic-derivations) experimental feature.
- Flake follow paths at depths greater than 2 are now handled correctly, preventing "follows a non-existent input" errors.
+
+- [`nix-store --query`](@docroot@/command-ref/nix-store/query.md) gained a new type of query: `--valid-derivers`. It returns all `.drv` files in the local store that *can be* used to build the output passed in argument.
+This is in contrast to `--deriver`, which returns the single `.drv` file that *was actually* used to build the output passed in argument. In case the output was substituted from a binary cache,
+this `.drv` file may only exist on said binary cache and not locally.
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index 94956df66..96c3f7d7e 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -283,7 +283,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
{
enum QueryType
{ qOutputs, qRequisites, qReferences, qReferrers
- , qReferrersClosure, qDeriver, qBinding, qHash, qSize
+ , qReferrersClosure, qDeriver, qValidDerivers, qBinding, qHash, qSize
, qTree, qGraph, qGraphML, qResolve, qRoots };
std::optional<QueryType> query;
bool useOutput = false;
@@ -299,6 +299,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
else if (i == "--referrers" || i == "--referers") query = qReferrers;
else if (i == "--referrers-closure" || i == "--referers-closure") query = qReferrersClosure;
else if (i == "--deriver" || i == "-d") query = qDeriver;
+ else if (i == "--valid-derivers") query = qValidDerivers;
else if (i == "--binding" || i == "-b") {
if (opArgs.size() == 0)
throw UsageError("expected binding name");
@@ -372,6 +373,21 @@ static void opQuery(Strings opFlags, Strings opArgs)
}
break;
+ case qValidDerivers: {
+ StorePathSet result;
+ for (auto & i : opArgs) {
+ auto derivers = store->queryValidDerivers(store->followLinksToStorePath(i));
+ for (const auto &i: derivers) {
+ result.insert(i);
+ }
+ }
+ auto sorted = store->topoSortPaths(result);
+ for (StorePaths::reverse_iterator i = sorted.rbegin();
+ i != sorted.rend(); ++i)
+ cout << fmt("%s\n", store->printStorePath(*i));
+ break;
+ }
+
case qBinding:
for (auto & i : opArgs) {
auto path = useDeriver(store->followLinksToStorePath(i));
diff --git a/tests/check-refs.nix b/tests/check-refs.nix
index 99d69a226..89690e456 100644
--- a/tests/check-refs.nix
+++ b/tests/check-refs.nix
@@ -2,7 +2,7 @@ with import ./config.nix;
rec {
- dep = import ./dependencies.nix;
+ dep = import ./dependencies.nix {};
makeTest = nr: args: mkDerivation ({
name = "check-refs-" + toString nr;
diff --git a/tests/dependencies.nix b/tests/dependencies.nix
index 45aca1793..be1a7ae9a 100644
--- a/tests/dependencies.nix
+++ b/tests/dependencies.nix
@@ -1,3 +1,4 @@
+{ hashInvalidator ? "" }:
with import ./config.nix;
let {
@@ -21,6 +22,17 @@ let {
'';
};
+ fod_input = mkDerivation {
+ name = "fod-input";
+ buildCommand = ''
+ echo ${hashInvalidator}
+ echo FOD > $out
+ '';
+ outputHashMode = "flat";
+ outputHashAlgo = "sha256";
+ outputHash = "1dq9p0hnm1y75q2x40fws5887bq1r840hzdxak0a9djbwvx0b16d";
+ };
+
body = mkDerivation {
name = "dependencies-top";
builder = ./dependencies.builder0.sh + "/FOOBAR/../.";
@@ -29,6 +41,7 @@ let {
input1_drv = input1;
input2_drv = input2;
input0_drv = input0;
+ fod_input_drv = fod_input;
meta.description = "Random test package";
};
diff --git a/tests/dependencies.sh b/tests/dependencies.sh
index d5cd30396..b93dacac0 100644
--- a/tests/dependencies.sh
+++ b/tests/dependencies.sh
@@ -53,3 +53,20 @@ nix-store -q --referrers-closure "$input2OutPath" | grep "$outPath"
# Check that the derivers are set properly.
test $(nix-store -q --deriver "$outPath") = "$drvPath"
nix-store -q --deriver "$input2OutPath" | grepQuiet -- "-input-2.drv"
+
+# --valid-derivers returns the currently single valid .drv file
+test "$(nix-store -q --valid-derivers "$outPath")" = "$drvPath"
+
+# instantiate a different drv with the same output
+drvPath2=$(nix-instantiate dependencies.nix --argstr hashInvalidator yay)
+
+# now --valid-derivers returns both
+test "$(nix-store -q --valid-derivers "$outPath" | sort)" = "$(sort <<< "$drvPath"$'\n'"$drvPath2")"
+
+# check that nix-store --valid-derivers only returns existing drv
+nix-store --delete "$drvPath"
+test "$(nix-store -q --valid-derivers "$outPath")" = "$drvPath2"
+
+# check that --valid-derivers returns nothing when there are no valid derivers
+nix-store --delete "$drvPath2"
+test -z "$(nix-store -q --valid-derivers "$outPath")"
diff --git a/tests/dyn-drv/eval-outputOf.sh b/tests/dyn-drv/eval-outputOf.sh
index 99d917c06..9467feb8d 100644
--- a/tests/dyn-drv/eval-outputOf.sh
+++ b/tests/dyn-drv/eval-outputOf.sh
@@ -13,14 +13,14 @@ nix --experimental-features 'nix-command' eval --impure --expr \
# the future so it does work, but there are some design questions to
# resolve first. Adding a test so we don't liberalise it by accident.
expectStderr 1 nix --experimental-features 'nix-command dynamic-derivations' eval --impure --expr \
- 'builtins.outputOf (import ../dependencies.nix) "out"' \
+ 'builtins.outputOf (import ../dependencies.nix {}) "out"' \
| grepQuiet "value is a set while a string was expected"
# Test that "DrvDeep" string contexts are not supported at this time
#
# Like the above, this is a restriction we could relax later.
expectStderr 1 nix --experimental-features 'nix-command dynamic-derivations' eval --impure --expr \
- 'builtins.outputOf (import ../dependencies.nix).drvPath "out"' \
+ 'builtins.outputOf (import ../dependencies.nix {}).drvPath "out"' \
| grepQuiet "has a context which refers to a complete source and binary closure. This is not supported at this time"
# Test using `builtins.outputOf` with static derivations
diff --git a/tests/export-graph.nix b/tests/export-graph.nix
index fdac9583d..64fe36bd1 100644
--- a/tests/export-graph.nix
+++ b/tests/export-graph.nix
@@ -17,13 +17,13 @@ rec {
foo."bar.runtimeGraph" = mkDerivation {
name = "dependencies";
builder = builtins.toFile "build-graph-builder" "${printRefs}";
- exportReferencesGraph = ["refs" (import ./dependencies.nix)];
+ exportReferencesGraph = ["refs" (import ./dependencies.nix {})];
};
foo."bar.buildGraph" = mkDerivation {
name = "dependencies";
builder = builtins.toFile "build-graph-builder" "${printRefs}";
- exportReferencesGraph = ["refs" (import ./dependencies.nix).drvPath];
+ exportReferencesGraph = ["refs" (import ./dependencies.nix {}).drvPath];
};
}
diff --git a/tests/remote-store.sh b/tests/remote-store.sh
index ea32a20d3..50e6f24b9 100644
--- a/tests/remote-store.sh
+++ b/tests/remote-store.sh
@@ -24,7 +24,7 @@ fi
import (
mkDerivation {
name = "foo";
- bla = import ./dependencies.nix;
+ bla = import ./dependencies.nix {};
buildCommand = "
echo \\\"hi\\\" > $out
";