From fb30259fd188b039cc88d148f34c683c258ebf9b Mon Sep 17 00:00:00 2001 From: Timothy DeHerrera Date: Wed, 11 Jan 2023 13:53:42 -0700 Subject: [PATCH] path-info: implement --filter-substitutable Fixes #3946 Filters out any paths from the output which are already available in the configured substituters. Useful in CI environments, to avoid builds that are already cached. --- src/nix/path-info.cc | 35 +++++++++++++++++++++++++++++++++-- src/nix/path-info.md | 9 +++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/nix/path-info.cc b/src/nix/path-info.cc index 613c5b1918d..10ceacf12b0 100644 --- a/src/nix/path-info.cc +++ b/src/nix/path-info.cc @@ -16,6 +16,7 @@ struct CmdPathInfo : StorePathsCommand, MixJSON bool showClosureSize = false; bool humanReadable = false; bool showSigs = false; + bool showSubStatus = false; CmdPathInfo() { @@ -45,6 +46,14 @@ struct CmdPathInfo : StorePathsCommand, MixJSON .description = "Show signatures.", .handler = {&showSigs, true}, }); + + addFlag({ + .longName = "filter-substitutable", + .description = + "Query path availability in the configured substituters, printing only those that are not available. " + "When used with `--json`, a `substitutable` boolean is added to the output.", + .handler = {&showSubStatus, true}, + }); } std::string description() override @@ -86,14 +95,36 @@ struct CmdPathInfo : StorePathsCommand, MixJSON for (auto & storePath : storePaths) pathLen = std::max(pathLen, store->printStorePath(storePath).size()); + StorePathSet substitutablePaths; + if (showSubStatus) + substitutablePaths = store->querySubstitutablePaths(StorePathSet(storePaths.begin(), storePaths.end())); + if (json) { - std::cout << store->pathInfoToJSON( + auto json = store->pathInfoToJSON( // FIXME: preserve order? StorePathSet(storePaths.begin(), storePaths.end()), - true, showClosureSize, SRI, AllowInvalid).dump(); + true, showClosureSize, SRI, AllowInvalid); + + if (showSubStatus) { + for (auto & v : json) { + std::string const storePathS = v["path"]; + v["substitutable"] = (bool) substitutablePaths.count(store->parseStorePath(storePathS)); + } + } + std::cout << json.dump(); } else { + StorePaths missingPaths; + + if (showSubStatus) { + for (auto & path : storePaths) { + if (!substitutablePaths.count(path)) + missingPaths.emplace_back(std::move(path)); + } + + storePaths = missingPaths; + } for (auto & storePath : storePaths) { auto info = store->queryPathInfo(storePath); diff --git a/src/nix/path-info.md b/src/nix/path-info.md index b30898ac0f0..e569e0557ed 100644 --- a/src/nix/path-info.md +++ b/src/nix/path-info.md @@ -39,6 +39,15 @@ R""( ``` +* Print all dependant paths which do not exist in any configured binary cache: + + ```console + # nix path-info -r --filter-substitutable /nix/store/blzxgyvrk32ki6xga10phr4sby2xf25q-geeqie-1.5.1 + /nix/store/blzxgyvrk32ki6xga10phr4sby2xf25q-geeqie-1.5.1 + /nix/store/w2vgpk3rdl6smqz7ixxywqapgagsarjf-fbida-2.14 + ... + ``` + * Print the 10 most recently added paths (using --json and the jq(1) command):