diff --git a/src/nix/flake-archive.md b/src/nix/flake-archive.md index 85bbeeb16..3311ed578 100644 --- a/src/nix/flake-archive.md +++ b/src/nix/flake-archive.md @@ -15,11 +15,10 @@ R""( # nix flake archive dwarffs ``` -* Print the store paths of the flake sources of NixOps without - fetching them: +* Copy and print the store paths of the flake sources of NixOps: ```console - # nix flake archive --json --dry-run nixops + # nix flake archive --json nixops ``` # Description diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 2ff096faa..e11d9223f 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -877,8 +877,7 @@ struct CmdFlakeClone : FlakeCommand } }; -#if 0 -struct CmdFlakeArchive : FlakeCommand, MixJSON, MixDryRun +struct CmdFlakeArchive : FlakeCommand, MixJSON { std::string dstUri; @@ -906,45 +905,44 @@ struct CmdFlakeArchive : FlakeCommand, MixJSON, MixDryRun void run(nix::ref store) override { + auto dstStore = store; + if (!dstUri.empty()) + dstStore = openStore(dstUri); + auto flake = lockFlake(); auto jsonRoot = json ? std::optional(std::cout) : std::nullopt; - StorePathSet sources; - - sources.insert(flake.flake.sourceInfo->storePath); - if (jsonRoot) - jsonRoot->attr("path", store->printStorePath(flake.flake.sourceInfo->storePath)); + { + Activity act(*logger, lvlChatty, actUnknown, fmt("archiving root")); + auto storePath = flake.flake.lockedRef.input.fetchToStore(dstStore).first; + if (jsonRoot) + jsonRoot->attr("path", store->printStorePath(storePath)); + } // FIXME: use graph output, handle cycles. - std::function & jsonObj)> traverse; - traverse = [&](const Node & node, std::optional & jsonObj) + std::function & jsonObj)> traverse; + traverse = [&](const Node & node, const InputPath & parentPath, std::optional & jsonObj) { auto jsonObj2 = jsonObj ? jsonObj->object("inputs") : std::optional(); for (auto & [inputName, input] : node.inputs) { if (auto inputNode = std::get_if<0>(&input)) { + auto inputPath = parentPath; + inputPath.push_back(inputName); + Activity act(*logger, lvlChatty, actUnknown, + fmt("archiving input '%s'", printInputPath(inputPath))); auto jsonObj3 = jsonObj2 ? jsonObj2->object(inputName) : std::optional(); - auto storePath = - dryRun - ? (*inputNode)->lockedRef.input.computeStorePath(*store) - : (*inputNode)->lockedRef.input.fetch(store).first.storePath; + auto storePath = (*inputNode)->lockedRef.input.fetchToStore(dstStore).first; if (jsonObj3) jsonObj3->attr("path", store->printStorePath(storePath)); - sources.insert(std::move(storePath)); - traverse(**inputNode, jsonObj3); + traverse(**inputNode, inputPath, jsonObj3); } } }; - traverse(*flake.lockFile.root, jsonRoot); - - if (!dryRun && !dstUri.empty()) { - ref dstStore = dstUri.empty() ? openStore() : openStore(dstUri); - copyPaths(*store, *dstStore, sources); - } + traverse(*flake.lockFile.root, {}, jsonRoot); } }; -#endif struct CmdFlakeShow : FlakeCommand, MixJSON { @@ -1200,7 +1198,7 @@ struct CmdFlake : NixMultiCommand {"init", []() { return make_ref(); }}, {"new", []() { return make_ref(); }}, {"clone", []() { return make_ref(); }}, - //{"archive", []() { return make_ref(); }}, + {"archive", []() { return make_ref(); }}, {"show", []() { return make_ref(); }}, {"prefetch", []() { return make_ref(); }}, })