diff --git a/doc/manual/src/command-ref/nix-store.md b/doc/manual/src/command-ref/nix-store.md index b712a74635ee..e6dcb4c86f36 100644 --- a/doc/manual/src/command-ref/nix-store.md +++ b/doc/manual/src/command-ref/nix-store.md @@ -281,7 +281,7 @@ error: cannot delete path `/nix/store/zq0h41l75vlb4z45kzgjjmsjxvcv1qk7-mesa-6.4' {`--outputs` | `--requisites` | `-R` | `--references` | `--referrers` | `--referrers-closure` | `--deriver` | `-d` | `--graph` | `--tree` | `--binding` *name* | `-b` *name* | `--hash` | - `--size` | `--roots`} + `--size` | `--roots` | `--uncached` | `-U`} [`--use-output`] [`-u`] [`--force-realise`] [`-f`] *paths…* @@ -397,6 +397,10 @@ symlink. Prints the garbage collector roots that point, directly or indirectly, at the store paths *paths*. + - `--uncached`; `-U`\ + Outputs a list of the store paths *paths* which are not available in + any configured caches. + ## Examples Print the closure (runtime dependencies) of the `svn` program in the @@ -435,6 +439,16 @@ $ nix-store -q --tree $(nix-store -qd $(which svn)) ... ``` +Show uncached build & runtime dependencies: + +```console +$ drv=$(nix-store -qd $(which svn)) +$ nix-store -qU $(nix-store -qR --include-outputs $drv) +/nix/store/5mbglq5ldqld8sj57273aljwkfvj22mc-subversion-1.1.4 +/nix/store/9lz9yc6zgmc0vlqmn2ipcpkjlmbi51vv-glibc-2.3.4 +... +``` + Show all paths that depend on the same OpenSSL library as `svn`: ```console diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 3bbefedbe07d..27e93024ad8b 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -15,6 +15,8 @@ #include "graphml.hh" #include "legacy.hh" #include "path-with-outputs.hh" +#include "filetransfer.hh" +#include "thread-pool.hh" #include #include @@ -24,6 +26,8 @@ #include #include +#include + namespace nix_store { @@ -276,7 +280,7 @@ static void opQuery(Strings opFlags, Strings opArgs) enum QueryType { qDefault, qOutputs, qRequisites, qReferences, qReferrers , qReferrersClosure, qDeriver, qBinding, qHash, qSize - , qTree, qGraph, qGraphML, qResolve, qRoots }; + , qTree, qGraph, qGraphML, qResolve, qRoots, qUncached }; QueryType query = qDefault; bool useOutput = false; bool includeOutputs = false; @@ -300,6 +304,7 @@ static void opQuery(Strings opFlags, Strings opArgs) } else if (i == "--hash") query = qHash; else if (i == "--size") query = qSize; + else if (i == "--uncached" || i == "-U") query = qUncached; else if (i == "--tree") query = qTree; else if (i == "--graph") query = qGraph; else if (i == "--graphml") query = qGraphML; @@ -364,6 +369,32 @@ static void opQuery(Strings opFlags, Strings opArgs) } break; + case qUncached: { + if (opArgs.empty()) throw UsageError("no paths passed"); + + ThreadPool pool(fileTransferSettings.httpConnections); + + std::function queryPath; + queryPath = [&](const StorePath & req) { + SubstitutablePathInfos infos; + store->querySubstitutablePathInfos({{req, std::nullopt}}, infos); + + if (infos.empty()) { + cout << store->printStorePath(req) << '\n'; + } + }; + + for (auto & i : opArgs) { + auto path = store->followLinksToStorePath(i); + + pool.enqueue(std::bind(queryPath, path)); + } + + pool.process(); + + break; + } + case qBinding: for (auto & i : opArgs) { auto path = useDeriver(store->followLinksToStorePath(i)); @@ -680,7 +711,6 @@ static void opExport(Strings opFlags, Strings opArgs) sink.flush(); } - static void opImport(Strings opFlags, Strings opArgs) { for (auto & i : opFlags)