Add 'nix flake archive' command
This copies a flake and all its inputs recursively to a store (e.g. a binary cache). This is intended to enable long-term reproducibility for flakes. However this will also require #3253. Example: $ nix flake archive --json --to file:///tmp/my-cache nixops {"path":"/nix/store/272igzkgl1gdzmabsjvb2kb2zqbphb3p-source","inputs":{"nixops-aws":{"path":"/nix/store/ybcykw13gr7iq1pzg18iyibbcv8k9q1v-source","inputs":{}},"nixops-hetzner":{"path":"/nix/store/6yn0205x3nz55w8ms3335p2841javz2d-source","inputs":{}},"nixpkgs":{"path":"/nix/store/li3lkr2ajrzphqqz3jj2avndnyd3i5lc-source","inputs":{}}}} $ ll /tmp/my-cache total 16 -rw-r--r-- 1 eelco users 403 Jan 30 01:01 272igzkgl1gdzmabsjvb2kb2zqbphb3p.narinfo -rw-r--r-- 1 eelco users 403 Jan 30 01:01 6yn0205x3nz55w8ms3335p2841javz2d.narinfo -rw-r--r-- 1 eelco users 408 Jan 30 01:01 li3lkr2ajrzphqqz3jj2avndnyd3i5lc.narinfo drwxr-xr-x 2 eelco users 6 Jan 30 01:01 nar -rw-r--r-- 1 eelco users 21 Jan 30 01:01 nix-cache-info -rw-r--r-- 1 eelco users 404 Jan 30 01:01 ybcykw13gr7iq1pzg18iyibbcv8k9q1v.narinfo Fixes #3336.
This commit is contained in:
parent
b9f93e7386
commit
3c54e9ba01
1 changed files with 76 additions and 1 deletions
|
@ -11,6 +11,7 @@
|
|||
#include "attr-path.hh"
|
||||
#include "fetchers/fetchers.hh"
|
||||
#include "fetchers/registry.hh"
|
||||
#include "json.hh"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <queue>
|
||||
|
@ -213,7 +214,7 @@ struct CmdFlakeInfo : FlakeCommand, MixJSON
|
|||
}
|
||||
};
|
||||
|
||||
struct CmdFlakeCheck : FlakeCommand, MixJSON
|
||||
struct CmdFlakeCheck : FlakeCommand
|
||||
{
|
||||
bool build = true;
|
||||
|
||||
|
@ -604,6 +605,79 @@ struct CmdFlakeClone : FlakeCommand
|
|||
}
|
||||
};
|
||||
|
||||
struct CmdFlakeArchive : FlakeCommand, MixJSON, MixDryRun
|
||||
{
|
||||
std::string dstUri;
|
||||
|
||||
CmdFlakeArchive()
|
||||
{
|
||||
mkFlag()
|
||||
.longName("to")
|
||||
.labels({"store-uri"})
|
||||
.description("URI of the destination Nix store")
|
||||
.dest(&dstUri);
|
||||
}
|
||||
|
||||
std::string description() override
|
||||
{
|
||||
return "copy a flake and all its inputs to a store";
|
||||
}
|
||||
|
||||
Examples examples() override
|
||||
{
|
||||
return {
|
||||
Example{
|
||||
"To copy the dwarffs flake and its dependencies to a binary cache:",
|
||||
"nix flake archive --to file:///tmp/my-cache dwarffs"
|
||||
},
|
||||
Example{
|
||||
"To fetch the dwarffs flake and its dependencies to the local Nix store:",
|
||||
"nix flake archive dwarffs"
|
||||
},
|
||||
Example{
|
||||
"To print the store paths of the flake sources of NixOps without fetching them:",
|
||||
"nix flake archive --json --dry-run nixops"
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
void run(nix::ref<nix::Store> store) override
|
||||
{
|
||||
auto flake = lockFlake();
|
||||
|
||||
auto jsonRoot = json ? std::optional<JSONObject>(std::cout) : std::optional<JSONObject>();
|
||||
|
||||
StorePathSet sources;
|
||||
|
||||
sources.insert(flake.flake.sourceInfo->storePath.clone());
|
||||
if (jsonRoot)
|
||||
jsonRoot->attr("path", store->printStorePath(flake.flake.sourceInfo->storePath));
|
||||
|
||||
std::function<void(const LockedInputs & inputs, std::optional<JSONObject> & jsonObj)> traverse;
|
||||
traverse = [&](const LockedInputs & inputs, std::optional<JSONObject> & jsonObj)
|
||||
{
|
||||
auto jsonObj2 = jsonObj ? jsonObj->object("inputs") : std::optional<JSONObject>();
|
||||
for (auto & input : inputs.inputs) {
|
||||
auto jsonObj3 = jsonObj2 ? jsonObj2->object(input.first) : std::optional<JSONObject>();
|
||||
if (!dryRun)
|
||||
input.second.ref.input->fetchTree(store);
|
||||
auto storePath = input.second.computeStorePath(*store);
|
||||
if (jsonObj3)
|
||||
jsonObj3->attr("path", store->printStorePath(storePath));
|
||||
sources.insert(std::move(storePath));
|
||||
traverse(input.second, jsonObj3);
|
||||
}
|
||||
};
|
||||
|
||||
traverse(flake.lockFile, jsonRoot);
|
||||
|
||||
if (!dryRun && !dstUri.empty()) {
|
||||
ref<Store> dstStore = dstUri.empty() ? openStore() : openStore(dstUri);
|
||||
copyPaths(store, dstStore, sources);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct CmdFlake : virtual MultiCommand, virtual Command
|
||||
{
|
||||
CmdFlake()
|
||||
|
@ -617,6 +691,7 @@ struct CmdFlake : virtual MultiCommand, virtual Command
|
|||
{"pin", []() { return make_ref<CmdFlakePin>(); }},
|
||||
{"init", []() { return make_ref<CmdFlakeInit>(); }},
|
||||
{"clone", []() { return make_ref<CmdFlakeClone>(); }},
|
||||
{"archive", []() { return make_ref<CmdFlakeArchive>(); }},
|
||||
})
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue