Merge pull request #7750 from obsidiansystems/no-args-prepare

Make command infra less stateful and more regular
This commit is contained in:
John Ericson 2023-03-15 17:23:40 -04:00 committed by GitHub
commit eb56cb7cc7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 137 additions and 136 deletions

View file

@ -165,7 +165,7 @@ BuiltPathsCommand::BuiltPathsCommand(bool recursive)
}); });
} }
void BuiltPathsCommand::run(ref<Store> store) void BuiltPathsCommand::run(ref<Store> store, Installables && installables)
{ {
BuiltPaths paths; BuiltPaths paths;
if (all) { if (all) {
@ -211,7 +211,7 @@ void StorePathsCommand::run(ref<Store> store, BuiltPaths && paths)
run(store, std::move(sorted)); run(store, std::move(sorted));
} }
void StorePathCommand::run(ref<Store> store, std::vector<StorePath> && storePaths) void StorePathCommand::run(ref<Store> store, StorePaths && storePaths)
{ {
if (storePaths.size() != 1) if (storePaths.size() != 1)
throw UsageError("this command requires exactly one store path"); throw UsageError("this command requires exactly one store path");
@ -246,7 +246,7 @@ void MixProfile::updateProfile(const BuiltPaths & buildables)
{ {
if (!profile) return; if (!profile) return;
std::vector<StorePath> result; StorePaths result;
for (auto & buildable : buildables) { for (auto & buildable : buildables) {
std::visit(overloaded { std::visit(overloaded {

View file

@ -29,6 +29,9 @@ struct NixMultiCommand : virtual MultiCommand, virtual Command
nlohmann::json toJSON() override; nlohmann::json toJSON() override;
}; };
// For the overloaded run methods
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
/* A command that requires a Nix store. */ /* A command that requires a Nix store. */
struct StoreCommand : virtual Command struct StoreCommand : virtual Command
{ {
@ -97,10 +100,10 @@ struct SourceExprCommand : virtual Args, MixFlakeOptions
SourceExprCommand(); SourceExprCommand();
std::vector<std::shared_ptr<Installable>> parseInstallables( Installables parseInstallables(
ref<Store> store, std::vector<std::string> ss); ref<Store> store, std::vector<std::string> ss);
std::shared_ptr<Installable> parseInstallable( ref<Installable> parseInstallable(
ref<Store> store, const std::string & installable); ref<Store> store, const std::string & installable);
virtual Strings getDefaultFlakeAttrPaths(); virtual Strings getDefaultFlakeAttrPaths();
@ -115,36 +118,43 @@ struct MixReadOnlyOption : virtual Args
MixReadOnlyOption(); MixReadOnlyOption();
}; };
/* A command that operates on a list of "installables", which can be /* Like InstallablesCommand but the installables are not loaded */
store paths, attribute paths, Nix expressions, etc. */ struct RawInstallablesCommand : virtual Args, SourceExprCommand
struct InstallablesCommand : virtual Args, SourceExprCommand
{ {
std::vector<std::shared_ptr<Installable>> installables; RawInstallablesCommand();
InstallablesCommand(); virtual void run(ref<Store> store, std::vector<std::string> && rawInstallables) = 0;
void prepare() override; void run(ref<Store> store) override;
Installables load();
virtual bool useDefaultInstallables() { return true; } // FIXME make const after CmdRepl's override is fixed up
virtual void applyDefaultInstallables(std::vector<std::string> & rawInstallables);
bool readFromStdIn = false; bool readFromStdIn = false;
std::vector<std::string> getFlakesForCompletion() override; std::vector<std::string> getFlakesForCompletion() override;
protected: private:
std::vector<std::string> _installables; std::vector<std::string> rawInstallables;
};
/* A command that operates on a list of "installables", which can be
store paths, attribute paths, Nix expressions, etc. */
struct InstallablesCommand : RawInstallablesCommand
{
virtual void run(ref<Store> store, Installables && installables) = 0;
void run(ref<Store> store, std::vector<std::string> && rawInstallables) override;
}; };
/* A command that operates on exactly one "installable" */ /* A command that operates on exactly one "installable" */
struct InstallableCommand : virtual Args, SourceExprCommand struct InstallableCommand : virtual Args, SourceExprCommand
{ {
std::shared_ptr<Installable> installable;
InstallableCommand(); InstallableCommand();
void prepare() override; virtual void run(ref<Store> store, ref<Installable> installable) = 0;
void run(ref<Store> store) override;
std::vector<std::string> getFlakesForCompletion() override std::vector<std::string> getFlakesForCompletion() override
{ {
@ -179,22 +189,18 @@ public:
BuiltPathsCommand(bool recursive = false); BuiltPathsCommand(bool recursive = false);
using StoreCommand::run;
virtual void run(ref<Store> store, BuiltPaths && paths) = 0; virtual void run(ref<Store> store, BuiltPaths && paths) = 0;
void run(ref<Store> store) override; void run(ref<Store> store, Installables && installables) override;
bool useDefaultInstallables() override { return !all; } void applyDefaultInstallables(std::vector<std::string> & rawInstallables) override;
}; };
struct StorePathsCommand : public BuiltPathsCommand struct StorePathsCommand : public BuiltPathsCommand
{ {
StorePathsCommand(bool recursive = false); StorePathsCommand(bool recursive = false);
using BuiltPathsCommand::run; virtual void run(ref<Store> store, StorePaths && storePaths) = 0;
virtual void run(ref<Store> store, std::vector<StorePath> && storePaths) = 0;
void run(ref<Store> store, BuiltPaths && paths) override; void run(ref<Store> store, BuiltPaths && paths) override;
}; };
@ -202,11 +208,9 @@ struct StorePathsCommand : public BuiltPathsCommand
/* A command that operates on exactly one store path. */ /* A command that operates on exactly one store path. */
struct StorePathCommand : public StorePathsCommand struct StorePathCommand : public StorePathsCommand
{ {
using StorePathsCommand::run;
virtual void run(ref<Store> store, const StorePath & storePath) = 0; virtual void run(ref<Store> store, const StorePath & storePath) = 0;
void run(ref<Store> store, std::vector<StorePath> && storePaths) override; void run(ref<Store> store, StorePaths && storePaths) override;
}; };
/* A helper class for registering commands globally. */ /* A helper class for registering commands globally. */

View file

@ -422,10 +422,10 @@ ref<eval_cache::EvalCache> openEvalCache(
}); });
} }
std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables( Installables SourceExprCommand::parseInstallables(
ref<Store> store, std::vector<std::string> ss) ref<Store> store, std::vector<std::string> ss)
{ {
std::vector<std::shared_ptr<Installable>> result; Installables result;
if (file || expr) { if (file || expr) {
if (file && expr) if (file && expr)
@ -451,7 +451,7 @@ std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables(
for (auto & s : ss) { for (auto & s : ss) {
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(s); auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(s);
result.push_back( result.push_back(
std::make_shared<InstallableAttrPath>( make_ref<InstallableAttrPath>(
InstallableAttrPath::parse( InstallableAttrPath::parse(
state, *this, vFile, prefix, extendedOutputsSpec))); state, *this, vFile, prefix, extendedOutputsSpec)));
} }
@ -468,7 +468,7 @@ std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables(
if (prefix.find('/') != std::string::npos) { if (prefix.find('/') != std::string::npos) {
try { try {
result.push_back(std::make_shared<InstallableDerivedPath>( result.push_back(make_ref<InstallableDerivedPath>(
InstallableDerivedPath::parse(store, prefix, extendedOutputsSpec))); InstallableDerivedPath::parse(store, prefix, extendedOutputsSpec)));
continue; continue;
} catch (BadStorePath &) { } catch (BadStorePath &) {
@ -480,7 +480,7 @@ std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables(
try { try {
auto [flakeRef, fragment] = parseFlakeRefWithFragment(std::string { prefix }, absPath(".")); auto [flakeRef, fragment] = parseFlakeRefWithFragment(std::string { prefix }, absPath("."));
result.push_back(std::make_shared<InstallableFlake>( result.push_back(make_ref<InstallableFlake>(
this, this,
getEvalState(), getEvalState(),
std::move(flakeRef), std::move(flakeRef),
@ -501,7 +501,7 @@ std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables(
return result; return result;
} }
std::shared_ptr<Installable> SourceExprCommand::parseInstallable( ref<Installable> SourceExprCommand::parseInstallable(
ref<Store> store, const std::string & installable) ref<Store> store, const std::string & installable)
{ {
auto installables = parseInstallables(store, {installable}); auto installables = parseInstallables(store, {installable});
@ -513,7 +513,7 @@ std::vector<BuiltPathWithResult> Installable::build(
ref<Store> evalStore, ref<Store> evalStore,
ref<Store> store, ref<Store> store,
Realise mode, Realise mode,
const std::vector<std::shared_ptr<Installable>> & installables, const Installables & installables,
BuildMode bMode) BuildMode bMode)
{ {
std::vector<BuiltPathWithResult> res; std::vector<BuiltPathWithResult> res;
@ -522,11 +522,11 @@ std::vector<BuiltPathWithResult> Installable::build(
return res; return res;
} }
std::vector<std::pair<std::shared_ptr<Installable>, BuiltPathWithResult>> Installable::build2( std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> Installable::build2(
ref<Store> evalStore, ref<Store> evalStore,
ref<Store> store, ref<Store> store,
Realise mode, Realise mode,
const std::vector<std::shared_ptr<Installable>> & installables, const Installables & installables,
BuildMode bMode) BuildMode bMode)
{ {
if (mode == Realise::Nothing) if (mode == Realise::Nothing)
@ -535,7 +535,7 @@ std::vector<std::pair<std::shared_ptr<Installable>, BuiltPathWithResult>> Instal
struct Aux struct Aux
{ {
ExtraPathInfo info; ExtraPathInfo info;
std::shared_ptr<Installable> installable; ref<Installable> installable;
}; };
std::vector<DerivedPath> pathsToBuild; std::vector<DerivedPath> pathsToBuild;
@ -548,7 +548,7 @@ std::vector<std::pair<std::shared_ptr<Installable>, BuiltPathWithResult>> Instal
} }
} }
std::vector<std::pair<std::shared_ptr<Installable>, BuiltPathWithResult>> res; std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> res;
switch (mode) { switch (mode) {
@ -620,7 +620,7 @@ BuiltPaths Installable::toBuiltPaths(
ref<Store> store, ref<Store> store,
Realise mode, Realise mode,
OperateOn operateOn, OperateOn operateOn,
const std::vector<std::shared_ptr<Installable>> & installables) const Installables & installables)
{ {
if (operateOn == OperateOn::Output) { if (operateOn == OperateOn::Output) {
BuiltPaths res; BuiltPaths res;
@ -642,7 +642,7 @@ StorePathSet Installable::toStorePaths(
ref<Store> evalStore, ref<Store> evalStore,
ref<Store> store, ref<Store> store,
Realise mode, OperateOn operateOn, Realise mode, OperateOn operateOn,
const std::vector<std::shared_ptr<Installable>> & installables) const Installables & installables)
{ {
StorePathSet outPaths; StorePathSet outPaths;
for (auto & path : toBuiltPaths(evalStore, store, mode, operateOn, installables)) { for (auto & path : toBuiltPaths(evalStore, store, mode, operateOn, installables)) {
@ -656,7 +656,7 @@ StorePath Installable::toStorePath(
ref<Store> evalStore, ref<Store> evalStore,
ref<Store> store, ref<Store> store,
Realise mode, OperateOn operateOn, Realise mode, OperateOn operateOn,
std::shared_ptr<Installable> installable) ref<Installable> installable)
{ {
auto paths = toStorePaths(evalStore, store, mode, operateOn, {installable}); auto paths = toStorePaths(evalStore, store, mode, operateOn, {installable});
@ -668,7 +668,7 @@ StorePath Installable::toStorePath(
StorePathSet Installable::toDerivations( StorePathSet Installable::toDerivations(
ref<Store> store, ref<Store> store,
const std::vector<std::shared_ptr<Installable>> & installables, const Installables & installables,
bool useDeriver) bool useDeriver)
{ {
StorePathSet drvPaths; StorePathSet drvPaths;
@ -692,9 +692,8 @@ StorePathSet Installable::toDerivations(
return drvPaths; return drvPaths;
} }
InstallablesCommand::InstallablesCommand() RawInstallablesCommand::RawInstallablesCommand()
{ {
addFlag({ addFlag({
.longName = "stdin", .longName = "stdin",
.description = "Read installables from the standard input.", .description = "Read installables from the standard input.",
@ -703,40 +702,45 @@ InstallablesCommand::InstallablesCommand()
expectArgs({ expectArgs({
.label = "installables", .label = "installables",
.handler = {&_installables}, .handler = {&rawInstallables},
.completer = {[&](size_t, std::string_view prefix) { .completer = {[&](size_t, std::string_view prefix) {
completeInstallable(prefix); completeInstallable(prefix);
}} }}
}); });
} }
void InstallablesCommand::prepare() void RawInstallablesCommand::applyDefaultInstallables(std::vector<std::string> & rawInstallables)
{ {
installables = load(); if (rawInstallables.empty()) {
}
Installables InstallablesCommand::load()
{
if (_installables.empty() && useDefaultInstallables() && !readFromStdIn)
// FIXME: commands like "nix profile install" should not have a // FIXME: commands like "nix profile install" should not have a
// default, probably. // default, probably.
_installables.push_back("."); rawInstallables.push_back(".");
}
}
void RawInstallablesCommand::run(ref<Store> store)
{
if (readFromStdIn && !isatty(STDIN_FILENO)) { if (readFromStdIn && !isatty(STDIN_FILENO)) {
std::string word; std::string word;
while (std::cin >> word) { while (std::cin >> word) {
_installables.emplace_back(std::move(word)); rawInstallables.emplace_back(std::move(word));
} }
} }
return parseInstallables(getStore(), _installables); applyDefaultInstallables(rawInstallables);
run(store, std::move(rawInstallables));
} }
std::vector<std::string> InstallablesCommand::getFlakesForCompletion() std::vector<std::string> RawInstallablesCommand::getFlakesForCompletion()
{ {
if (_installables.empty() && useDefaultInstallables()) applyDefaultInstallables(rawInstallables);
return {"."}; return rawInstallables;
return _installables; }
void InstallablesCommand::run(ref<Store> store, std::vector<std::string> && rawInstallables)
{
auto installables = parseInstallables(store, rawInstallables);
run(store, std::move(installables));
} }
InstallableCommand::InstallableCommand() InstallableCommand::InstallableCommand()
@ -752,9 +756,16 @@ InstallableCommand::InstallableCommand()
}); });
} }
void InstallableCommand::prepare() void InstallableCommand::run(ref<Store> store)
{ {
installable = parseInstallable(getStore(), _installable); auto installable = parseInstallable(store, _installable);
run(store, std::move(installable));
}
void BuiltPathsCommand::applyDefaultInstallables(std::vector<std::string> & rawInstallables)
{
if (rawInstallables.empty() && !all)
rawInstallables.push_back(".");
} }
} }

View file

@ -79,6 +79,9 @@ struct BuiltPathWithResult
typedef std::vector<DerivedPathWithInfo> DerivedPathsWithInfo; typedef std::vector<DerivedPathWithInfo> DerivedPathsWithInfo;
struct Installable;
typedef std::vector<ref<Installable>> Installables;
struct Installable struct Installable
{ {
virtual ~Installable() { } virtual ~Installable() { }
@ -122,14 +125,14 @@ struct Installable
ref<Store> evalStore, ref<Store> evalStore,
ref<Store> store, ref<Store> store,
Realise mode, Realise mode,
const std::vector<std::shared_ptr<Installable>> & installables, const Installables & installables,
BuildMode bMode = bmNormal); BuildMode bMode = bmNormal);
static std::vector<std::pair<std::shared_ptr<Installable>, BuiltPathWithResult>> build2( static std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> build2(
ref<Store> evalStore, ref<Store> evalStore,
ref<Store> store, ref<Store> store,
Realise mode, Realise mode,
const std::vector<std::shared_ptr<Installable>> & installables, const Installables & installables,
BuildMode bMode = bmNormal); BuildMode bMode = bmNormal);
static std::set<StorePath> toStorePaths( static std::set<StorePath> toStorePaths(
@ -137,18 +140,18 @@ struct Installable
ref<Store> store, ref<Store> store,
Realise mode, Realise mode,
OperateOn operateOn, OperateOn operateOn,
const std::vector<std::shared_ptr<Installable>> & installables); const Installables & installables);
static StorePath toStorePath( static StorePath toStorePath(
ref<Store> evalStore, ref<Store> evalStore,
ref<Store> store, ref<Store> store,
Realise mode, Realise mode,
OperateOn operateOn, OperateOn operateOn,
std::shared_ptr<Installable> installable); ref<Installable> installable);
static std::set<StorePath> toDerivations( static std::set<StorePath> toDerivations(
ref<Store> store, ref<Store> store,
const std::vector<std::shared_ptr<Installable>> & installables, const Installables & installables,
bool useDeriver = false); bool useDeriver = false);
static BuiltPaths toBuiltPaths( static BuiltPaths toBuiltPaths(
@ -156,9 +159,7 @@ struct Installable
ref<Store> store, ref<Store> store,
Realise mode, Realise mode,
OperateOn operateOn, OperateOn operateOn,
const std::vector<std::shared_ptr<Installable>> & installables); const Installables & installables);
}; };
typedef std::vector<std::shared_ptr<Installable>> Installables;
} }

View file

@ -198,7 +198,6 @@ struct Command : virtual public Args
virtual ~Command() { } virtual ~Command() { }
virtual void prepare() { };
virtual void run() = 0; virtual void run() = 0;
typedef int Category; typedef int Category;

View file

@ -119,11 +119,11 @@ App UnresolvedApp::resolve(ref<Store> evalStore, ref<Store> store)
{ {
auto res = unresolved; auto res = unresolved;
std::vector<std::shared_ptr<Installable>> installableContext; Installables installableContext;
for (auto & ctxElt : unresolved.context) for (auto & ctxElt : unresolved.context)
installableContext.push_back( installableContext.push_back(
std::make_shared<InstallableDerivedPath>(store, DerivedPath { ctxElt })); make_ref<InstallableDerivedPath>(store, DerivedPath { ctxElt }));
auto builtContext = Installable::build(evalStore, store, Realise::Outputs, installableContext); auto builtContext = Installable::build(evalStore, store, Realise::Outputs, installableContext);
res.program = resolveString(*store, unresolved.program, builtContext); res.program = resolveString(*store, unresolved.program, builtContext);

View file

@ -89,7 +89,7 @@ struct CmdBuild : InstallablesCommand, MixDryRun, MixJSON, MixProfile
; ;
} }
void run(ref<Store> store) override void run(ref<Store> store, Installables && installables) override
{ {
if (dryRun) { if (dryRun) {
std::vector<DerivedPath> pathsToBuild; std::vector<DerivedPath> pathsToBuild;

View file

@ -70,7 +70,7 @@ struct CmdBundle : InstallableCommand
return res; return res;
} }
void run(ref<Store> store) override void run(ref<Store> store, ref<Installable> installable) override
{ {
auto evalState = getEvalState(); auto evalState = getEvalState();

View file

@ -10,8 +10,6 @@ struct CmdCopy : virtual CopyCommand, virtual BuiltPathsCommand
SubstituteFlag substitute = NoSubstitute; SubstituteFlag substitute = NoSubstitute;
using BuiltPathsCommand::run;
CmdCopy() CmdCopy()
: BuiltPathsCommand(true) : BuiltPathsCommand(true)
{ {

View file

@ -374,7 +374,7 @@ struct Common : InstallableCommand, MixProfile
return res; return res;
} }
StorePath getShellOutPath(ref<Store> store) StorePath getShellOutPath(ref<Store> store, ref<Installable> installable)
{ {
auto path = installable->getStorePath(); auto path = installable->getStorePath();
if (path && hasSuffix(path->to_string(), "-env")) if (path && hasSuffix(path->to_string(), "-env"))
@ -392,9 +392,10 @@ struct Common : InstallableCommand, MixProfile
} }
} }
std::pair<BuildEnvironment, std::string> getBuildEnvironment(ref<Store> store) std::pair<BuildEnvironment, std::string>
getBuildEnvironment(ref<Store> store, ref<Installable> installable)
{ {
auto shellOutPath = getShellOutPath(store); auto shellOutPath = getShellOutPath(store, installable);
auto strPath = store->printStorePath(shellOutPath); auto strPath = store->printStorePath(shellOutPath);
@ -480,9 +481,9 @@ struct CmdDevelop : Common, MixEnvironment
; ;
} }
void run(ref<Store> store) override void run(ref<Store> store, ref<Installable> installable) override
{ {
auto [buildEnvironment, gcroot] = getBuildEnvironment(store); auto [buildEnvironment, gcroot] = getBuildEnvironment(store, installable);
auto [rcFileFd, rcFilePath] = createTempFile("nix-shell"); auto [rcFileFd, rcFilePath] = createTempFile("nix-shell");
@ -537,7 +538,7 @@ struct CmdDevelop : Common, MixEnvironment
nixpkgsLockFlags.inputOverrides = {}; nixpkgsLockFlags.inputOverrides = {};
nixpkgsLockFlags.inputUpdates = {}; nixpkgsLockFlags.inputUpdates = {};
auto bashInstallable = std::make_shared<InstallableFlake>( auto bashInstallable = make_ref<InstallableFlake>(
this, this,
state, state,
installable->nixpkgsFlakeRef(), installable->nixpkgsFlakeRef(),
@ -573,7 +574,7 @@ struct CmdDevelop : Common, MixEnvironment
// Need to chdir since phases assume in flake directory // Need to chdir since phases assume in flake directory
if (phase) { if (phase) {
// chdir if installable is a flake of type git+file or path // chdir if installable is a flake of type git+file or path
auto installableFlake = std::dynamic_pointer_cast<InstallableFlake>(installable); auto installableFlake = installable.dynamic_pointer_cast<InstallableFlake>();
if (installableFlake) { if (installableFlake) {
auto sourcePath = installableFlake->getLockedFlake()->flake.resolvedRef.input.getSourcePath(); auto sourcePath = installableFlake->getLockedFlake()->flake.resolvedRef.input.getSourcePath();
if (sourcePath) { if (sourcePath) {
@ -604,9 +605,9 @@ struct CmdPrintDevEnv : Common, MixJSON
Category category() override { return catUtility; } Category category() override { return catUtility; }
void run(ref<Store> store) override void run(ref<Store> store, ref<Installable> installable) override
{ {
auto buildEnvironment = getBuildEnvironment(store).first; auto buildEnvironment = getBuildEnvironment(store, installable).first;
stopProgressBar(); stopProgressBar();

View file

@ -25,7 +25,7 @@ struct CmdEdit : InstallableCommand
Category category() override { return catSecondary; } Category category() override { return catSecondary; }
void run(ref<Store> store) override void run(ref<Store> store, ref<Installable> installable) override
{ {
auto state = getEvalState(); auto state = getEvalState();

View file

@ -54,7 +54,7 @@ struct CmdEval : MixJSON, InstallableCommand, MixReadOnlyOption
Category category() override { return catSecondary; } Category category() override { return catSecondary; }
void run(ref<Store> store) override void run(ref<Store> store, ref<Installable> installable) override
{ {
if (raw && json) if (raw && json)
throw UsageError("--raw and --json are mutually exclusive"); throw UsageError("--raw and --json are mutually exclusive");

View file

@ -1329,7 +1329,6 @@ struct CmdFlake : NixMultiCommand
if (!command) if (!command)
throw UsageError("'nix flake' requires a sub-command."); throw UsageError("'nix flake' requires a sub-command.");
settings.requireExperimentalFeature(Xp::Flakes); settings.requireExperimentalFeature(Xp::Flakes);
command->second->prepare();
command->second->run(); command->second->run();
} }
}; };

View file

@ -151,7 +151,6 @@ struct CmdHash : NixMultiCommand
{ {
if (!command) if (!command)
throw UsageError("'nix hash' requires a sub-command."); throw UsageError("'nix hash' requires a sub-command.");
command->second->prepare();
command->second->run(); command->second->run();
} }
}; };

View file

@ -23,7 +23,7 @@ struct CmdLog : InstallableCommand
Category category() override { return catSecondary; } Category category() override { return catSecondary; }
void run(ref<Store> store) override void run(ref<Store> store, ref<Installable> installable) override
{ {
settings.readOnlyMode = true; settings.readOnlyMode = true;

View file

@ -394,7 +394,6 @@ void mainWrapped(int argc, char * * argv)
if (args.command->second->forceImpureByDefault() && !evalSettings.pureEval.overridden) { if (args.command->second->forceImpureByDefault() && !evalSettings.pureEval.overridden) {
evalSettings.pureEval = false; evalSettings.pureEval = false;
} }
args.command->second->prepare();
args.command->second->run(); args.command->second->run();
} }

View file

@ -28,7 +28,6 @@ struct CmdMakeContentAddressed : virtual CopyCommand, virtual StorePathsCommand,
; ;
} }
using StorePathsCommand::run;
void run(ref<Store> srcStore, StorePaths && storePaths) override void run(ref<Store> srcStore, StorePaths && storePaths) override
{ {
auto dstStore = dstUri.empty() ? openStore() : openStore(dstUri); auto dstStore = dstUri.empty() ? openStore() : openStore(dstUri);

View file

@ -25,7 +25,6 @@ struct CmdNar : NixMultiCommand
{ {
if (!command) if (!command)
throw UsageError("'nix nar' requires a sub-command."); throw UsageError("'nix nar' requires a sub-command.");
command->second->prepare();
command->second->run(); command->second->run();
} }
}; };

View file

@ -256,11 +256,11 @@ struct ProfileManifest
static std::map<Installable *, std::pair<BuiltPaths, ExtraPathInfo>> static std::map<Installable *, std::pair<BuiltPaths, ExtraPathInfo>>
builtPathsPerInstallable( builtPathsPerInstallable(
const std::vector<std::pair<std::shared_ptr<Installable>, BuiltPathWithResult>> & builtPaths) const std::vector<std::pair<ref<Installable>, BuiltPathWithResult>> & builtPaths)
{ {
std::map<Installable *, std::pair<BuiltPaths, ExtraPathInfo>> res; std::map<Installable *, std::pair<BuiltPaths, ExtraPathInfo>> res;
for (auto & [installable, builtPath] : builtPaths) { for (auto & [installable, builtPath] : builtPaths) {
auto & r = res[installable.get()]; auto & r = res[&*installable];
/* Note that there could be conflicting info /* Note that there could be conflicting info
(e.g. meta.priority fields) if the installable returned (e.g. meta.priority fields) if the installable returned
multiple derivations. So pick one arbitrarily. FIXME: multiple derivations. So pick one arbitrarily. FIXME:
@ -296,7 +296,7 @@ struct CmdProfileInstall : InstallablesCommand, MixDefaultProfile
; ;
} }
void run(ref<Store> store) override void run(ref<Store> store, Installables && installables) override
{ {
ProfileManifest manifest(*getEvalState(), *profile); ProfileManifest manifest(*getEvalState(), *profile);
@ -307,7 +307,7 @@ struct CmdProfileInstall : InstallablesCommand, MixDefaultProfile
for (auto & installable : installables) { for (auto & installable : installables) {
ProfileElement element; ProfileElement element;
auto & [res, info] = builtPaths[installable.get()]; auto & [res, info] = builtPaths[&*installable];
if (info.originalRef && info.resolvedRef && info.attrPath && info.extendedOutputsSpec) { if (info.originalRef && info.resolvedRef && info.attrPath && info.extendedOutputsSpec) {
element.source = ProfileElementSource { element.source = ProfileElementSource {
@ -513,7 +513,7 @@ struct CmdProfileUpgrade : virtual SourceExprCommand, MixDefaultProfile, MixProf
auto matchers = getMatchers(store); auto matchers = getMatchers(store);
std::vector<std::shared_ptr<Installable>> installables; Installables installables;
std::vector<size_t> indices; std::vector<size_t> indices;
auto upgradedCount = 0; auto upgradedCount = 0;
@ -529,7 +529,7 @@ struct CmdProfileUpgrade : virtual SourceExprCommand, MixDefaultProfile, MixProf
Activity act(*logger, lvlChatty, actUnknown, Activity act(*logger, lvlChatty, actUnknown,
fmt("checking '%s' for updates", element.source->attrPath)); fmt("checking '%s' for updates", element.source->attrPath));
auto installable = std::make_shared<InstallableFlake>( auto installable = make_ref<InstallableFlake>(
this, this,
getEvalState(), getEvalState(),
FlakeRef(element.source->originalRef), FlakeRef(element.source->originalRef),
@ -582,7 +582,7 @@ struct CmdProfileUpgrade : virtual SourceExprCommand, MixDefaultProfile, MixProf
for (size_t i = 0; i < installables.size(); ++i) { for (size_t i = 0; i < installables.size(); ++i) {
auto & installable = installables.at(i); auto & installable = installables.at(i);
auto & element = manifest.elements[indices.at(i)]; auto & element = manifest.elements[indices.at(i)];
element.updateStorePaths(getEvalStore(), store, builtPaths[installable.get()].first); element.updateStorePaths(getEvalStore(), store, builtPaths[&*installable].first);
} }
updateProfile(manifest.build(store)); updateProfile(manifest.build(store));
@ -798,7 +798,6 @@ struct CmdProfile : NixMultiCommand
{ {
if (!command) if (!command)
throw UsageError("'nix profile' requires a sub-command."); throw UsageError("'nix profile' requires a sub-command.");
command->second->prepare();
command->second->run(); command->second->run();
} }
}; };

View file

@ -21,7 +21,6 @@ struct CmdRealisation : virtual NixMultiCommand
{ {
if (!command) if (!command)
throw UsageError("'nix realisation' requires a sub-command."); throw UsageError("'nix realisation' requires a sub-command.");
command->second->prepare();
command->second->run(); command->second->run();
} }
}; };

View file

@ -227,7 +227,6 @@ struct CmdRegistry : virtual NixMultiCommand
settings.requireExperimentalFeature(Xp::Flakes); settings.requireExperimentalFeature(Xp::Flakes);
if (!command) if (!command)
throw UsageError("'nix registry' requires a sub-command."); throw UsageError("'nix registry' requires a sub-command.");
command->second->prepare();
command->second->run(); command->second->run();
} }
}; };

View file

@ -5,26 +5,12 @@
namespace nix { namespace nix {
struct CmdRepl : InstallablesCommand struct CmdRepl : RawInstallablesCommand
{ {
CmdRepl() { CmdRepl() {
evalSettings.pureEval = false; evalSettings.pureEval = false;
} }
void prepare() override
{
if (!settings.isExperimentalFeatureEnabled(Xp::ReplFlake) && !(file) && this->_installables.size() >= 1) {
warn("future versions of Nix will require using `--file` to load a file");
if (this->_installables.size() > 1)
warn("more than one input file is not currently supported");
auto filePath = this->_installables[0].data();
file = std::optional(filePath);
_installables.front() = _installables.back();
_installables.pop_back();
}
installables = InstallablesCommand::load();
}
std::vector<std::string> files; std::vector<std::string> files;
Strings getDefaultFlakeAttrPaths() override Strings getDefaultFlakeAttrPaths() override
@ -32,11 +18,6 @@ struct CmdRepl : InstallablesCommand
return {""}; return {""};
} }
bool useDefaultInstallables() override
{
return file.has_value() or expr.has_value();
}
bool forceImpureByDefault() override bool forceImpureByDefault() override
{ {
return true; return true;
@ -54,11 +35,27 @@ struct CmdRepl : InstallablesCommand
; ;
} }
void run(ref<Store> store) override void applyDefaultInstallables(std::vector<std::string> & rawInstallables) override
{
if (!settings.isExperimentalFeatureEnabled(Xp::ReplFlake) && !(file) && rawInstallables.size() >= 1) {
warn("future versions of Nix will require using `--file` to load a file");
if (rawInstallables.size() > 1)
warn("more than one input file is not currently supported");
auto filePath = rawInstallables[0].data();
file = std::optional(filePath);
rawInstallables.front() = rawInstallables.back();
rawInstallables.pop_back();
}
if (rawInstallables.empty() && (file.has_value() || expr.has_value())) {
rawInstallables.push_back(".");
}
}
void run(ref<Store> store, std::vector<std::string> && rawInstallables) override
{ {
auto state = getEvalState(); auto state = getEvalState();
auto getValues = [&]()->AbstractNixRepl::AnnotatedValues{ auto getValues = [&]()->AbstractNixRepl::AnnotatedValues{
auto installables = load(); auto installables = parseInstallables(store, rawInstallables);
AbstractNixRepl::AnnotatedValues values; AbstractNixRepl::AnnotatedValues values;
for (auto & installable: installables){ for (auto & installable: installables){
auto what = installable->what(); auto what = installable->what();

View file

@ -97,7 +97,7 @@ struct CmdShell : InstallablesCommand, MixEnvironment
; ;
} }
void run(ref<Store> store) override void run(ref<Store> store, Installables && installables) override
{ {
auto outPaths = Installable::toStorePaths(getEvalStore(), store, Realise::Outputs, OperateOn::Output, installables); auto outPaths = Installable::toStorePaths(getEvalStore(), store, Realise::Outputs, OperateOn::Output, installables);
@ -183,7 +183,7 @@ struct CmdRun : InstallableCommand
return res; return res;
} }
void run(ref<Store> store) override void run(ref<Store> store, ref<Installable> installable) override
{ {
auto state = getEvalState(); auto state = getEvalState();

View file

@ -61,7 +61,7 @@ struct CmdSearch : InstallableCommand, MixJSON
}; };
} }
void run(ref<Store> store) override void run(ref<Store> store, ref<Installable> installable) override
{ {
settings.readOnlyMode = true; settings.readOnlyMode = true;
evalSettings.enableImportFromDerivation.setDefault(false); evalSettings.enableImportFromDerivation.setDefault(false);

View file

@ -39,7 +39,7 @@ struct CmdShowDerivation : InstallablesCommand
Category category() override { return catUtility; } Category category() override { return catUtility; }
void run(ref<Store> store) override void run(ref<Store> store, Installables && installables) override
{ {
auto drvPaths = Installable::toDerivations(store, installables, true); auto drvPaths = Installable::toDerivations(store, installables, true);

View file

@ -219,7 +219,6 @@ struct CmdKey : NixMultiCommand
{ {
if (!command) if (!command)
throw UsageError("'nix key' requires a sub-command."); throw UsageError("'nix key' requires a sub-command.");
command->second->prepare();
command->second->run(); command->second->run();
} }
}; };

View file

@ -26,7 +26,7 @@ struct CmdCopyLog : virtual CopyCommand, virtual InstallablesCommand
Category category() override { return catUtility; } Category category() override { return catUtility; }
void run(ref<Store> srcStore) override void run(ref<Store> srcStore, Installables && installables) override
{ {
auto & srcLogStore = require<LogStore>(*srcStore); auto & srcLogStore = require<LogStore>(*srcStore);

View file

@ -32,7 +32,7 @@ struct CmdStoreDelete : StorePathsCommand
; ;
} }
void run(ref<Store> store, std::vector<StorePath> && storePaths) override void run(ref<Store> store, StorePaths && storePaths) override
{ {
auto & gcStore = require<GcStore>(*store); auto & gcStore = require<GcStore>(*store);

View file

@ -17,7 +17,7 @@ struct CmdStoreRepair : StorePathsCommand
; ;
} }
void run(ref<Store> store, std::vector<StorePath> && storePaths) override void run(ref<Store> store, StorePaths && storePaths) override
{ {
for (auto & path : storePaths) for (auto & path : storePaths)
store->repairPath(path); store->repairPath(path);

View file

@ -18,7 +18,6 @@ struct CmdStore : virtual NixMultiCommand
{ {
if (!command) if (!command)
throw UsageError("'nix store' requires a sub-command."); throw UsageError("'nix store' requires a sub-command.");
command->second->prepare();
command->second->run(); command->second->run();
} }
}; };