From 84079e10cfde4e0187decdef98fd052bfa5976ef Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 18 Sep 2024 12:07:15 -0400 Subject: [PATCH] No more `Path` in `libnixcmd` Co-authored-by: Vinayak Goyal --- src/libcmd/common-eval-args.cc | 9 +++++---- src/libcmd/include/nix/cmd/command.hh | 4 ++-- .../include/nix/cmd/common-eval-args.hh | 2 +- .../include/nix/cmd/installable-value.hh | 2 +- src/libcmd/include/nix/cmd/repl.hh | 11 ++++++++++- src/libcmd/installables.cc | 18 ++++++++++-------- src/libcmd/repl.cc | 19 ++++++++++--------- src/libutil/args.cc | 4 ++-- src/libutil/include/nix/util/args.hh | 2 +- src/libutil/include/nix/util/args/root.hh | 4 ++-- src/nix/app.cc | 6 +++--- src/nix/formatter.cc | 4 ++-- src/nix/repl.cc | 2 +- src/nix/run.cc | 4 ++-- 14 files changed, 52 insertions(+), 39 deletions(-) diff --git a/src/libcmd/common-eval-args.cc b/src/libcmd/common-eval-args.cc index 00b09f4ea..30e76b245 100644 --- a/src/libcmd/common-eval-args.cc +++ b/src/libcmd/common-eval-args.cc @@ -165,7 +165,7 @@ Bindings * MixEvalArgs::getAutoArgs(EvalState & state) state.parseExprFromString( arg.expr, compatibilitySettings.nixShellShebangArgumentsRelativeToScript - ? state.rootPath(absPath(getCommandBaseDir())) + ? state.rootPath(absPath(getCommandBaseDir()).string()) : state.rootPath("."))); }, [&](const AutoArgString & arg) { v->mkString(arg.s, state.mem); }, @@ -177,7 +177,7 @@ Bindings * MixEvalArgs::getAutoArgs(EvalState & state) return res.finish(); } -SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * baseDir) +SourcePath lookupFileArg(EvalState & state, std::string_view s, const std::filesystem::path * baseDir) { if (EvalSettings::isPseudoUrl(s)) { auto accessor = fetchers::downloadTarball(*state.store, state.fetchSettings, EvalSettings::resolvePseudoUrl(s)); @@ -197,12 +197,13 @@ SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * bas } else if (s.size() > 2 && s.at(0) == '<' && s.at(s.size() - 1) == '>') { - Path p(s.substr(1, s.size() - 2)); + // Should perhaps be a `CanonPath`? + std::string p(s.substr(1, s.size() - 2)); return state.findFile(p); } else - return state.rootPath(baseDir ? absPath(s, *baseDir) : absPath(s)); + return state.rootPath(absPath(std::filesystem::path{s}, baseDir).string()); } } // namespace nix diff --git a/src/libcmd/include/nix/cmd/command.hh b/src/libcmd/include/nix/cmd/command.hh index 2f97b30da..d1b528e24 100644 --- a/src/libcmd/include/nix/cmd/command.hh +++ b/src/libcmd/include/nix/cmd/command.hh @@ -134,7 +134,7 @@ struct MixFlakeOptions : virtual Args, EvalCommand struct SourceExprCommand : virtual Args, MixFlakeOptions { - std::optional file; + std::optional file; std::optional expr; SourceExprCommand(); @@ -310,7 +310,7 @@ static RegisterCommand registerCommand2(std::vector && name) struct MixProfile : virtual StoreCommand { - std::optional profile; + std::optional profile; MixProfile(); diff --git a/src/libcmd/include/nix/cmd/common-eval-args.hh b/src/libcmd/include/nix/cmd/common-eval-args.hh index 62518ba0e..67cb07148 100644 --- a/src/libcmd/include/nix/cmd/common-eval-args.hh +++ b/src/libcmd/include/nix/cmd/common-eval-args.hh @@ -84,6 +84,6 @@ private: /** * @param baseDir Optional [base directory](https://nix.dev/manual/nix/development/glossary#gloss-base-directory) */ -SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * baseDir = nullptr); +SourcePath lookupFileArg(EvalState & state, std::string_view s, const std::filesystem::path * baseDir = nullptr); } // namespace nix diff --git a/src/libcmd/include/nix/cmd/installable-value.hh b/src/libcmd/include/nix/cmd/installable-value.hh index 3521a4154..27a1fb981 100644 --- a/src/libcmd/include/nix/cmd/installable-value.hh +++ b/src/libcmd/include/nix/cmd/installable-value.hh @@ -17,7 +17,7 @@ class AttrCursor; struct App { std::vector context; - Path program; + std::filesystem::path program; // FIXME: add args, sandbox settings, metadata, ... }; diff --git a/src/libcmd/include/nix/cmd/repl.hh b/src/libcmd/include/nix/cmd/repl.hh index a2c905f86..b72a9b7d1 100644 --- a/src/libcmd/include/nix/cmd/repl.hh +++ b/src/libcmd/include/nix/cmd/repl.hh @@ -19,7 +19,16 @@ struct AbstractNixRepl typedef std::vector> AnnotatedValues; - using RunNix = void(Path program, const Strings & args, const std::optional & input); + /** + * Run a nix executable + * + * @todo this is a layer violation + * + * @param programName Name of the command, e.g. `nix` or `nix-env`. + * @param args aguments to the command. + */ + using RunNix = + void(const std::string & programName, const Strings & args, const std::optional & input); /** * @param runNix Function to run the nix CLI to support various diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 36777fb9c..2fa2280ea 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -132,7 +132,7 @@ MixFlakeOptions::MixFlakeOptions() lockFlags.writeLockFile = false; lockFlags.inputOverrides.insert_or_assign( flake::parseInputAttrPath(inputAttrPath), - parseFlakeRef(fetchSettings, flakeRef, absPath(getCommandBaseDir()), true)); + parseFlakeRef(fetchSettings, flakeRef, absPath(getCommandBaseDir()).string(), true)); }}, .completer = {[&](AddCompletions & completions, size_t n, std::string_view prefix) { if (n == 0) { @@ -173,7 +173,7 @@ MixFlakeOptions::MixFlakeOptions() auto flake = flake::lockFlake( flakeSettings, *evalState, - parseFlakeRef(fetchSettings, flakeRef, absPath(getCommandBaseDir())), + parseFlakeRef(fetchSettings, flakeRef, absPath(getCommandBaseDir()).string()), {.writeLockFile = false}); for (auto & [inputName, input] : flake.lockFile.root->inputs) { auto input2 = flake.lockFile.findInput({inputName}); // resolve 'follows' nodes @@ -263,7 +263,7 @@ void SourceExprCommand::completeInstallable(AddCompletions & completions, std::s evalSettings.pureEval = false; auto state = getEvalState(); - auto e = state->parseExprFromFile(resolveExprPath(lookupFileArg(*state, *file))); + auto e = state->parseExprFromFile(resolveExprPath(lookupFileArg(*state, file->string()))); Value root; state->eval(e, root); @@ -465,10 +465,10 @@ Installables SourceExprCommand::parseInstallables(ref store, std::vector< state->eval(e, *vFile); } else if (file) { auto dir = absPath(getCommandBaseDir()); - state->evalFile(lookupFileArg(*state, *file, &dir), *vFile); + state->evalFile(lookupFileArg(*state, file->string(), &dir), *vFile); } else { - Path dir = absPath(getCommandBaseDir()); - auto e = state->parseExprFromString(*expr, state->rootPath(dir)); + auto dir = absPath(getCommandBaseDir()); + auto e = state->parseExprFromString(*expr, state->rootPath(dir.string())); state->eval(e, *vFile); } @@ -801,7 +801,8 @@ std::vector RawInstallablesCommand::getFlakeRefsForCompletion() std::vector res; res.reserve(rawInstallables.size()); for (const auto & i : rawInstallables) - res.push_back(parseFlakeRefWithFragment(fetchSettings, expandTilde(i), absPath(getCommandBaseDir())).first); + res.push_back( + parseFlakeRefWithFragment(fetchSettings, expandTilde(i), absPath(getCommandBaseDir()).string()).first); return res; } @@ -820,7 +821,8 @@ void RawInstallablesCommand::run(ref store) std::vector InstallableCommand::getFlakeRefsForCompletion() { - return {parseFlakeRefWithFragment(fetchSettings, expandTilde(_installable), absPath(getCommandBaseDir())).first}; + return {parseFlakeRefWithFragment(fetchSettings, expandTilde(_installable), absPath(getCommandBaseDir()).string()) + .first}; } void InstallablesCommand::run(ref store, std::vector && rawInstallables) diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 162f048af..38a0da0f8 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -58,8 +58,7 @@ struct NixRepl : AbstractNixRepl, detail::ReplCompleterMixin, gc { size_t debugTraceIndex; - // Arguments passed to :load, saved so they can be reloaded with :reload - Strings loadedFiles; + std::list loadedFiles; // Arguments passed to :load-flake, saved so they can be reloaded with :reload Strings loadedFlakes; std::function getValues; @@ -73,7 +72,7 @@ struct NixRepl : AbstractNixRepl, detail::ReplCompleterMixin, gc RunNix * runNixPtr; - void runNix(Path program, const Strings & args, const std::optional & input = {}); + void runNix(const std::string & program, const Strings & args, const std::optional & input = {}); std::unique_ptr interacter; @@ -92,7 +91,7 @@ struct NixRepl : AbstractNixRepl, detail::ReplCompleterMixin, gc StorePath getDerivationPath(Value & v); ProcessLineResult processLine(std::string line); - void loadFile(const Path & path); + void loadFile(const std::filesystem::path & path); void loadFlake(const std::string & flakeRef); void loadFiles(); void loadFlakes(); @@ -539,7 +538,9 @@ ProcessLineResult NixRepl::processLine(std::string line) Value v; evalString(arg, v); StorePath drvPath = getDerivationPath(v); - Path drvPathRaw = state->store->printStorePath(drvPath); + // N.B. This need not be a local / native file path. For + // example, we might be using an SSH store to a different OS. + std::string drvPathRaw = state->store->printStorePath(drvPath); if (command == ":b" || command == ":bl") { state->store->buildPaths({ @@ -712,12 +713,12 @@ ProcessLineResult NixRepl::processLine(std::string line) return ProcessLineResult::PromptAgain; } -void NixRepl::loadFile(const Path & path) +void NixRepl::loadFile(const std::filesystem::path & path) { loadedFiles.remove(path); loadedFiles.push_back(path); Value v, v2; - state->evalFile(lookupFileArg(*state, path), v); + state->evalFile(lookupFileArg(*state, path.string()), v); state->autoCallFunction(*autoArgs, v, v2); addAttrsToScope(v2); } @@ -790,7 +791,7 @@ void NixRepl::reloadFilesAndFlakes() void NixRepl::loadFiles() { - Strings old = loadedFiles; + decltype(loadedFiles) old = loadedFiles; loadedFiles.clear(); for (auto & i : old) { @@ -888,7 +889,7 @@ void NixRepl::evalString(std::string s, Value & v) state->forceValue(v, v.determinePos(noPos)); } -void NixRepl::runNix(Path program, const Strings & args, const std::optional & input) +void NixRepl::runNix(const std::string & program, const Strings & args, const std::optional & input) { if (runNixPtr) (*runNixPtr)(program, args, input); diff --git a/src/libutil/args.cc b/src/libutil/args.cc index 05b5a25c7..c6d450a0b 100644 --- a/src/libutil/args.cc +++ b/src/libutil/args.cc @@ -371,13 +371,13 @@ void RootArgs::parseCmdline(const Strings & _cmdline, bool allowShebang) d.completer(*completions, d.n, d.prefix); } -Path Args::getCommandBaseDir() const +std::filesystem::path Args::getCommandBaseDir() const { assert(parent); return parent->getCommandBaseDir(); } -Path RootArgs::getCommandBaseDir() const +std::filesystem::path RootArgs::getCommandBaseDir() const { return commandBaseDir; } diff --git a/src/libutil/include/nix/util/args.hh b/src/libutil/include/nix/util/args.hh index 99f6e23e8..d79341124 100644 --- a/src/libutil/include/nix/util/args.hh +++ b/src/libutil/include/nix/util/args.hh @@ -59,7 +59,7 @@ public: * * This only returns the correct value after parseCmdline() has run. */ - virtual Path getCommandBaseDir() const; + virtual std::filesystem::path getCommandBaseDir() const; protected: diff --git a/src/libutil/include/nix/util/args/root.hh b/src/libutil/include/nix/util/args/root.hh index 86b677be4..15919a7ac 100644 --- a/src/libutil/include/nix/util/args/root.hh +++ b/src/libutil/include/nix/util/args/root.hh @@ -38,7 +38,7 @@ protected: * * @see getCommandBaseDir() */ - Path commandBaseDir = "."; + std::filesystem::path commandBaseDir = "."; public: /** Parse the command line, throwing a UsageError if something goes @@ -48,7 +48,7 @@ public: std::shared_ptr completions; - Path getCommandBaseDir() const override; + std::filesystem::path getCommandBaseDir() const override; protected: diff --git a/src/nix/app.cc b/src/nix/app.cc index f1937bc23..634db04f3 100644 --- a/src/nix/app.cc +++ b/src/nix/app.cc @@ -140,9 +140,9 @@ App UnresolvedApp::resolve(ref evalStore, ref store) auto res = unresolved; auto builtContext = build(evalStore, store); - res.program = resolveString(*store, unresolved.program, builtContext); - if (!store->isInStore(res.program)) - throw Error("app program '%s' is not in the Nix store", res.program); + res.program = resolveString(*store, unresolved.program.string(), builtContext); + if (!store->isInStore(res.program.string())) + throw Error("app program '%s' is not in the Nix store", res.program.string()); return res; } diff --git a/src/nix/formatter.cc b/src/nix/formatter.cc index f5eb966d6..2c0b5c62b 100644 --- a/src/nix/formatter.cc +++ b/src/nix/formatter.cc @@ -84,7 +84,7 @@ struct CmdFormatterRun : MixFormatter, MixJSON assert(maybeFlakeDir.has_value()); auto flakeDir = maybeFlakeDir.value(); - Strings programArgs{app.program}; + Strings programArgs{app.program.string()}; // Propagate arguments from the CLI for (auto & i : args) { @@ -103,7 +103,7 @@ struct CmdFormatterRun : MixFormatter, MixJSON execProgramInStore( store, UseLookupPath::DontUse, - app.program, + app.program.string(), programArgs, std::nullopt, // Use default system env); diff --git a/src/nix/repl.cc b/src/nix/repl.cc index 5dd53e932..19f02e759 100644 --- a/src/nix/repl.cc +++ b/src/nix/repl.cc @@ -11,7 +11,7 @@ namespace nix { -void runNix(Path program, const Strings & args, const std::optional & input = {}) +void runNix(const std::string & program, const Strings & args, const std::optional & input = {}) { auto subprocessEnv = getEnv(); subprocessEnv["NIX_CONFIG"] = globalConfig.toKeyValue(); diff --git a/src/nix/run.cc b/src/nix/run.cc index 368a5ed57..324b736a6 100644 --- a/src/nix/run.cc +++ b/src/nix/run.cc @@ -160,7 +160,7 @@ struct CmdRun : InstallableValueCommand, MixEnvironment lockFlags.applyNixConfig = true; auto app = installable->toApp(*state).resolve(getEvalStore(), store); - Strings allArgs{app.program}; + Strings allArgs{app.program.string()}; for (auto & i : args) allArgs.push_back(i); @@ -170,7 +170,7 @@ struct CmdRun : InstallableValueCommand, MixEnvironment setEnviron(); - execProgramInStore(store, UseLookupPath::DontUse, app.program, allArgs); + execProgramInStore(store, UseLookupPath::DontUse, app.program.string(), allArgs); } };