diff --git a/src/libstore/build.hh b/src/libstore/build.hh index ed83d678ec..52e7c9b9d5 100644 --- a/src/libstore/build.hh +++ b/src/libstore/build.hh @@ -21,9 +21,12 @@ Derivation derivationFromPath(const Path & drvPath); /* Place in `paths' the set of all store paths in the file system closure of `storePath'; that is, all paths than can be directly or - indirectly reached from it. `paths' is not cleared. */ + indirectly reached from it. `paths' is not cleared. If + `flipDirection' is true, the set of paths that can reach + `storePath' is returned; that is, the closures under the `referers' + relation instead of the `references' relation is returned. */ void computeFSClosure(const Path & storePath, - PathSet & paths); + PathSet & paths, bool flipDirection = false); /* Place in `paths' the set of paths that are required to `realise' the given store path, i.e., all paths necessary for valid diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc index dbb9273f79..802e576512 100644 --- a/src/libstore/misc.cc +++ b/src/libstore/misc.cc @@ -12,17 +12,20 @@ Derivation derivationFromPath(const Path & drvPath) void computeFSClosure(const Path & storePath, - PathSet & paths) + PathSet & paths, bool flipDirection) { if (paths.find(storePath) != paths.end()) return; paths.insert(storePath); PathSet references; - queryReferences(storePath, references); + if (flipDirection) + queryReferers(storePath, references); + else + queryReferences(storePath, references); for (PathSet::iterator i = references.begin(); i != references.end(); ++i) - computeFSClosure(*i, paths); + computeFSClosure(*i, paths, flipDirection); } diff --git a/src/nix-store/help.txt b/src/nix-store/help.txt index deef23ff8f..35d5423cd8 100644 --- a/src/nix-store/help.txt +++ b/src/nix-store/help.txt @@ -4,7 +4,8 @@ nix-store [OPTIONS...] [ARGUMENTS...] Operations: - --realise / -r: build a Nix derivation + --realise / -r: ensure path validity; if a derivation, ensure that + validity of the outputs --add / -A: copy a path to the Nix store --query / -q: query information @@ -27,9 +28,16 @@ Query flags: --outputs: query the output paths of a Nix derivation (default) --requisites / -R: print all paths necessary to realise a path --references: print all paths referenced by the given path - --referers: print all paths refering to the given path + --referers: print all paths directly refering to the given path + --referers-closure: print all paths (in)directly refering to the given path --graph: print a dot graph rooted at given ids +Query switches (not applicable to all queries): + + --use-output: perform query on output of derivation, not derivation itself + --force-realise: realise the path before performing the query + --include-outputs: in `-R' on a derivation, include requisites of outputs + Options: --verbose / -v: verbose operation (may be repeated) diff --git a/src/nix-store/main.cc b/src/nix-store/main.cc index addf9c7d0d..dc7a6de8b8 100644 --- a/src/nix-store/main.cc +++ b/src/nix-store/main.cc @@ -96,7 +96,8 @@ static void printPathSet(const PathSet & paths) /* Perform various sorts of queries. */ static void opQuery(Strings opFlags, Strings opArgs) { - enum { qOutputs, qRequisites, qReferences, qReferers, qGraph } query = qOutputs; + enum { qOutputs, qRequisites, qReferences, qReferers, + qReferersClosure, qGraph } query = qOutputs; bool useOutput = false; bool includeOutputs = false; bool forceRealise = false; @@ -107,6 +108,7 @@ static void opQuery(Strings opFlags, Strings opArgs) else if (*i == "--requisites" || *i == "-R") query = qRequisites; else if (*i == "--references") query = qReferences; else if (*i == "--referers") query = qReferers; + else if (*i == "--referers-closure") query = qReferersClosure; else if (*i == "--graph") query = qGraph; else if (*i == "--use-output" || *i == "-u") useOutput = true; else if (*i == "--force-realise" || *i == "-f") forceRealise = true; @@ -128,7 +130,8 @@ static void opQuery(Strings opFlags, Strings opArgs) case qRequisites: case qReferences: - case qReferers: { + case qReferers: + case qReferersClosure: { PathSet paths; for (Strings::iterator i = opArgs.begin(); i != opArgs.end(); i++) @@ -138,6 +141,7 @@ static void opQuery(Strings opFlags, Strings opArgs) storePathRequisites(path, includeOutputs, paths); else if (query == qReferences) queryReferences(path, paths); else if (query == qReferers) queryReferers(path, paths); + else if (query == qReferersClosure) computeFSClosure(path, paths, true); } printPathSet(paths); break; diff --git a/tests/dependencies.sh b/tests/dependencies.sh index fe4aa0c3c9..56cb1e4c38 100644 --- a/tests/dependencies.sh +++ b/tests/dependencies.sh @@ -20,4 +20,7 @@ echo "$deps" | grep -q "$outPath" if echo "$deps" | grep -q "dependencies-input-1"; then exit 1; fi # Input-2 is retained. -echo "$deps" | grep -q "dependencies-input-2" +input2OutPath=$(echo "$deps" | grep "dependencies-input-2") + +# The referers closure of input-2 should include outPath. +$TOP/src/nix-store/nix-store -q --referers-closure "$input2OutPath" | grep "$outPath"