Skip to content

Commit 3826d51

Browse files
authored
Merge pull request #13565 from NixOS/prefetch-inputs
Add `nix flake prefetch-inputs` command
2 parents 615b10c + 5fe6c53 commit 3826d51

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed

src/nix/flake-prefetch-inputs.cc

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#include "flake-command.hh"
2+
#include "nix/fetchers/fetch-to-store.hh"
3+
#include "nix/util/thread-pool.hh"
4+
#include "nix/store/filetransfer.hh"
5+
#include "nix/util/exit.hh"
6+
7+
#include <nlohmann/json.hpp>
8+
9+
using namespace nix;
10+
using namespace nix::flake;
11+
12+
struct CmdFlakePrefetchInputs : FlakeCommand
13+
{
14+
std::string description() override
15+
{
16+
return "fetch the inputs of a flake";
17+
}
18+
19+
std::string doc() override
20+
{
21+
return
22+
#include "flake-prefetch-inputs.md"
23+
;
24+
}
25+
26+
void run(nix::ref<nix::Store> store) override
27+
{
28+
auto flake = lockFlake();
29+
30+
ThreadPool pool{fileTransferSettings.httpConnections};
31+
32+
struct State
33+
{
34+
std::set<const Node *> done;
35+
};
36+
37+
Sync<State> state_;
38+
39+
std::atomic<size_t> nrFailed{0};
40+
41+
std::function<void(const Node & node)> visit;
42+
visit = [&](const Node & node) {
43+
if (!state_.lock()->done.insert(&node).second)
44+
return;
45+
46+
if (auto lockedNode = dynamic_cast<const LockedNode *>(&node)) {
47+
try {
48+
Activity act(*logger, lvlInfo, actUnknown, fmt("fetching '%s'", lockedNode->lockedRef));
49+
auto accessor = lockedNode->lockedRef.input.getAccessor(store).first;
50+
fetchToStore(
51+
fetchSettings, *store, accessor, FetchMode::Copy, lockedNode->lockedRef.input.getName());
52+
} catch (Error & e) {
53+
printError("%s", e.what());
54+
nrFailed++;
55+
}
56+
}
57+
58+
for (auto & [inputName, input] : node.inputs) {
59+
if (auto inputNode = std::get_if<0>(&input))
60+
pool.enqueue(std::bind(visit, **inputNode));
61+
}
62+
};
63+
64+
pool.enqueue(std::bind(visit, *flake.lockFile.root));
65+
66+
pool.process();
67+
68+
throw Exit(nrFailed ? 1 : 0);
69+
}
70+
};
71+
72+
static auto rCmdFlakePrefetchInputs = registerCommand2<CmdFlakePrefetchInputs>({"flake", "prefetch-inputs"});

src/nix/flake-prefetch-inputs.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
R""(
2+
3+
# Examples
4+
5+
* Fetch the inputs of the `hydra` flake:
6+
7+
```console
8+
# nix flake prefetch-inputs github:NixOS/hydra
9+
```
10+
11+
# Description
12+
13+
Fetch the inputs of a flake. This ensures that they are already available for any subsequent evaluation of the flake.
14+
15+
This operation is recursive: it will fetch not just the direct inputs of the top-level flake, but also transitive inputs.
16+
17+
)""

src/nix/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ nix_sources = [ config_priv_h ] + files(
7878
'env.cc',
7979
'eval.cc',
8080
'flake.cc',
81+
'flake-prefetch-inputs.cc',
8182
'formatter.cc',
8283
'hash.cc',
8384
'log.cc',

0 commit comments

Comments
 (0)