diff --git a/src/libcmd/include/nix/cmd/common-eval-args.hh b/src/libcmd/include/nix/cmd/common-eval-args.hh index 6f3367e58..62af64230 100644 --- a/src/libcmd/include/nix/cmd/common-eval-args.hh +++ b/src/libcmd/include/nix/cmd/common-eval-args.hh @@ -5,6 +5,7 @@ #include "nix/util/canon-path.hh" #include "nix/main/common-args.hh" #include "nix/expr/search-path.hh" +#include "nix/expr/eval-settings.hh" #include @@ -15,10 +16,8 @@ class Store; namespace fetchers { struct Settings; } class EvalState; -struct EvalSettings; struct CompatibilitySettings; class Bindings; -struct SourcePath; namespace flake { struct Settings; } diff --git a/src/nix/flake-command.hh b/src/nix/flake-command.hh new file mode 100644 index 000000000..36dfe44c6 --- /dev/null +++ b/src/nix/flake-command.hh @@ -0,0 +1,27 @@ +#pragma once + +#include "nix/cmd/command.hh" +#include "nix/cmd/installable-flake.hh" +#include "nix/flake/flake.hh" + +namespace nix { + +using namespace nix::flake; + +class FlakeCommand : virtual Args, public MixFlakeOptions +{ +protected: + std::string flakeUrl = "."; + +public: + + FlakeCommand(); + + FlakeRef getFlakeRef(); + + LockedFlake lockFlake(); + + std::vector getFlakeRefsForCompletion() override; +}; + +} diff --git a/src/nix/flake-prefetch-inputs.cc b/src/nix/flake-prefetch-inputs.cc new file mode 100644 index 000000000..fe676726c --- /dev/null +++ b/src/nix/flake-prefetch-inputs.cc @@ -0,0 +1,62 @@ +#include "flake-command.hh" +#include "nix/fetchers/fetch-to-store.hh" +#include "nix/util/thread-pool.hh" +#include "nix/store/filetransfer.hh" + +#include + +using namespace nix; +using namespace nix::flake; + +struct CmdFlakePrefetchInputs : FlakeCommand +{ + std::string description() override + { + return "fetch the inputs of a flake"; + } + + std::string doc() override + { + return +#include "flake-prefetch-inputs.md" + ; + } + + void run(nix::ref store) override + { + auto flake = lockFlake(); + + ThreadPool pool{fileTransferSettings.httpConnections}; + + struct State + { + std::set done; + }; + + Sync state_; + + std::function visit; + visit = [&](const Node & node) { + if (!state_.lock()->done.insert(&node).second) + return; + + if (auto lockedNode = dynamic_cast(&node)) { + Activity act(*logger, lvlInfo, actUnknown, fmt("fetching '%s'", lockedNode->lockedRef)); + auto accessor = lockedNode->lockedRef.input.getAccessor(store).first; + if (!evalSettings.lazyTrees) + fetchToStore(*store, accessor, FetchMode::Copy, lockedNode->lockedRef.input.getName()); + } + + for (auto & [inputName, input] : node.inputs) { + if (auto inputNode = std::get_if<0>(&input)) + pool.enqueue(std::bind(visit, **inputNode)); + } + }; + + pool.enqueue(std::bind(visit, *flake.lockFile.root)); + + pool.process(); + } +}; + +static auto rCmdFlakePrefetchInputs = registerCommand2({"flake", "prefetch-inputs"}); diff --git a/src/nix/flake.cc b/src/nix/flake.cc index c2aa442bc..35e96e493 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -1,11 +1,9 @@ -#include "nix/cmd/command.hh" -#include "nix/cmd/installable-flake.hh" +#include "flake-command.hh" #include "nix/main/common-args.hh" #include "nix/main/shared.hh" #include "nix/expr/eval.hh" #include "nix/expr/eval-inline.hh" #include "nix/expr/eval-settings.hh" -#include "nix/flake/flake.hh" #include "nix/expr/get-drvs.hh" #include "nix/util/signals.hh" #include "nix/store/store-open.hh" @@ -19,8 +17,6 @@ #include "nix/util/users.hh" #include "nix/fetchers/fetch-to-store.hh" #include "nix/store/local-fs-store.hh" -#include "nix/util/thread-pool.hh" -#include "nix/store/filetransfer.hh" #include #include @@ -35,43 +31,36 @@ using namespace nix::flake; using json = nlohmann::json; struct CmdFlakeUpdate; -class FlakeCommand : virtual Args, public MixFlakeOptions + +FlakeCommand::FlakeCommand() { -protected: - std::string flakeUrl = "."; + expectArgs({ + .label = "flake-url", + .optional = true, + .handler = {&flakeUrl}, + .completer = {[&](AddCompletions & completions, size_t, std::string_view prefix) { + completeFlakeRef(completions, getStore(), prefix); + }} + }); +} -public: +FlakeRef FlakeCommand::getFlakeRef() +{ + return parseFlakeRef(fetchSettings, flakeUrl, std::filesystem::current_path().string()); //FIXME +} - FlakeCommand() - { - expectArgs({ - .label = "flake-url", - .optional = true, - .handler = {&flakeUrl}, - .completer = {[&](AddCompletions & completions, size_t, std::string_view prefix) { - completeFlakeRef(completions, getStore(), prefix); - }} - }); - } +LockedFlake FlakeCommand::lockFlake() +{ + return flake::lockFlake(flakeSettings, *getEvalState(), getFlakeRef(), lockFlags); +} - FlakeRef getFlakeRef() - { - return parseFlakeRef(fetchSettings, flakeUrl, std::filesystem::current_path().string()); //FIXME - } - - LockedFlake lockFlake() - { - return flake::lockFlake(flakeSettings, *getEvalState(), getFlakeRef(), lockFlags); - } - - std::vector getFlakeRefsForCompletion() override - { - return { - // Like getFlakeRef but with expandTilde calld first - parseFlakeRef(fetchSettings, expandTilde(flakeUrl), std::filesystem::current_path().string()) - }; - } -}; +std::vector FlakeCommand::getFlakeRefsForCompletion() +{ + return { + // Like getFlakeRef but with expandTilde calld first + parseFlakeRef(fetchSettings, expandTilde(flakeUrl), std::filesystem::current_path().string()) + }; +} struct CmdFlakeUpdate : FlakeCommand { @@ -1142,59 +1131,6 @@ struct CmdFlakeArchive : FlakeCommand, MixJSON, MixDryRun } }; -struct CmdFlakePrefetchInputs : FlakeCommand -{ - std::string description() override - { - return "fetch the inputs of a flake"; - } - - std::string doc() override - { - return - #include "flake-prefetch-inputs.md" - ; - } - - void run(nix::ref store) override - { - auto flake = lockFlake(); - - ThreadPool pool{fileTransferSettings.httpConnections}; - - struct State - { - std::set done; - }; - - Sync state_; - - std::function visit; - visit = [&](const Node & node) - { - if (!state_.lock()->done.insert(&node).second) - return; - - if (auto lockedNode = dynamic_cast(&node)) { - Activity act(*logger, lvlInfo, actUnknown, - fmt("fetching '%s'", lockedNode->lockedRef)); - auto accessor = lockedNode->lockedRef.input.getAccessor(store).first; - if (!evalSettings.lazyTrees) - fetchToStore(*store, accessor, FetchMode::Copy, lockedNode->lockedRef.input.getName()); - } - - for (auto & [inputName, input] : node.inputs) { - if (auto inputNode = std::get_if<0>(&input)) - pool.enqueue(std::bind(visit, **inputNode)); - } - }; - - pool.enqueue(std::bind(visit, *flake.lockFile.root)); - - pool.process(); - } -}; - struct CmdFlakeShow : FlakeCommand, MixJSON { bool showLegacy = false; @@ -1586,22 +1522,7 @@ struct CmdFlakePrefetch : FlakeCommand, MixJSON struct CmdFlake : NixMultiCommand { CmdFlake() - : NixMultiCommand( - "flake", - { - {"update", []() { return make_ref(); }}, - {"lock", []() { return make_ref(); }}, - {"metadata", []() { return make_ref(); }}, - {"info", []() { return make_ref(); }}, - {"check", []() { return make_ref(); }}, - {"init", []() { return make_ref(); }}, - {"new", []() { return make_ref(); }}, - {"clone", []() { return make_ref(); }}, - {"archive", []() { return make_ref(); }}, - {"prefetch-inputs", []() { return make_ref(); }}, - {"show", []() { return make_ref(); }}, - {"prefetch", []() { return make_ref(); }}, - }) + : NixMultiCommand("flake", RegisterCommand::getCommandsFor({"flake"})) { } @@ -1619,3 +1540,14 @@ struct CmdFlake : NixMultiCommand }; static auto rCmdFlake = registerCommand("flake"); +static auto rCmdFlakeArchive = registerCommand2({"flake", "archive"}); +static auto rCmdFlakeCheck = registerCommand2({"flake", "check"}); +static auto rCmdFlakeClone = registerCommand2({"flake", "clone"}); +static auto rCmdFlakeInfo = registerCommand2({"flake", "info"}); +static auto rCmdFlakeInit = registerCommand2({"flake", "init"}); +static auto rCmdFlakeLock = registerCommand2({"flake", "lock"}); +static auto rCmdFlakeMetadata = registerCommand2({"flake", "metadata"}); +static auto rCmdFlakeNew = registerCommand2({"flake", "new"}); +static auto rCmdFlakePrefetch = registerCommand2({"flake", "prefetch"}); +static auto rCmdFlakeShow = registerCommand2({"flake", "show"}); +static auto rCmdFlakeUpdate = registerCommand2({"flake", "update"}); diff --git a/src/nix/meson.build b/src/nix/meson.build index 11c30914b..0273b6f51 100644 --- a/src/nix/meson.build +++ b/src/nix/meson.build @@ -78,6 +78,7 @@ nix_sources = [config_priv_h] + files( 'env.cc', 'eval.cc', 'flake.cc', + 'flake-prefetch-inputs.cc', 'formatter.cc', 'hash.cc', 'log.cc',