1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-09 03:56:01 +01:00

Merge pull request #14087 from NixOS/required-args

Args::Flag: Add `required` attribute
This commit is contained in:
Eelco Dolstra 2025-10-08 19:33:22 +00:00 committed by GitHub
commit 925f10d5ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 32 additions and 6 deletions

View file

@ -318,6 +318,7 @@ void RootArgs::parseCmdline(const Strings & _cmdline, bool allowShebang)
} catch (SystemError &) { } catch (SystemError &) {
} }
} }
for (auto pos = cmdline.begin(); pos != cmdline.end();) { for (auto pos = cmdline.begin(); pos != cmdline.end();) {
auto arg = *pos; auto arg = *pos;
@ -354,6 +355,9 @@ void RootArgs::parseCmdline(const Strings & _cmdline, bool allowShebang)
processArgs(pendingArgs, true); processArgs(pendingArgs, true);
if (!completions)
checkArgs();
initialFlagsProcessed(); initialFlagsProcessed();
/* Now that we are done parsing, make sure that any experimental /* Now that we are done parsing, make sure that any experimental
@ -384,7 +388,7 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
auto & rootArgs = getRoot(); auto & rootArgs = getRoot();
auto process = [&](const std::string & name, const Flag & flag) -> bool { auto process = [&](const std::string & name, Flag & flag) -> bool {
++pos; ++pos;
if (auto & f = flag.experimentalFeature) if (auto & f = flag.experimentalFeature)
@ -413,6 +417,7 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
} }
if (!anyCompleted) if (!anyCompleted)
flag.handler.fun(std::move(args)); flag.handler.fun(std::move(args));
flag.timesUsed++;
return true; return true;
}; };
@ -504,6 +509,14 @@ bool Args::processArgs(const Strings & args, bool finish)
return res; return res;
} }
void Args::checkArgs()
{
for (auto & [name, flag] : longFlags) {
if (flag->required && flag->timesUsed == 0)
throw UsageError("required argument '--%s' is missing", name);
}
}
nlohmann::json Args::toJSON() nlohmann::json Args::toJSON()
{ {
auto flags = nlohmann::json::object(); auto flags = nlohmann::json::object();
@ -643,6 +656,13 @@ bool MultiCommand::processArgs(const Strings & args, bool finish)
return Args::processArgs(args, finish); return Args::processArgs(args, finish);
} }
void MultiCommand::checkArgs()
{
Args::checkArgs();
if (command)
command->second->checkArgs();
}
nlohmann::json MultiCommand::toJSON() nlohmann::json MultiCommand::toJSON()
{ {
auto cmds = nlohmann::json::object(); auto cmds = nlohmann::json::object();

View file

@ -202,8 +202,12 @@ public:
Strings labels; Strings labels;
Handler handler; Handler handler;
CompleterClosure completer; CompleterClosure completer;
bool required = false;
std::optional<ExperimentalFeature> experimentalFeature; std::optional<ExperimentalFeature> experimentalFeature;
// FIXME: this should be private, but that breaks designated initializers.
size_t timesUsed = 0;
}; };
protected: protected:
@ -283,6 +287,8 @@ protected:
StringSet hiddenCategories; StringSet hiddenCategories;
virtual void checkArgs();
/** /**
* Called after all command line flags before the first non-flag * Called after all command line flags before the first non-flag
* argument (if any) have been processed. * argument (if any) have been processed.
@ -428,6 +434,8 @@ public:
protected: protected:
std::string commandName = ""; std::string commandName = "";
bool aliasUsed = false; bool aliasUsed = false;
void checkArgs() override;
}; };
Strings argvToStrings(int argc, char ** argv); Strings argvToStrings(int argc, char ** argv);

View file

@ -144,7 +144,7 @@ static auto rCmdSign = registerCommand2<CmdSign>({"store", "sign"});
struct CmdKeyGenerateSecret : Command struct CmdKeyGenerateSecret : Command
{ {
std::optional<std::string> keyName; std::string keyName;
CmdKeyGenerateSecret() CmdKeyGenerateSecret()
{ {
@ -153,6 +153,7 @@ struct CmdKeyGenerateSecret : Command
.description = "Identifier of the key (e.g. `cache.example.org-1`).", .description = "Identifier of the key (e.g. `cache.example.org-1`).",
.labels = {"name"}, .labels = {"name"},
.handler = {&keyName}, .handler = {&keyName},
.required = true,
}); });
} }
@ -170,11 +171,8 @@ struct CmdKeyGenerateSecret : Command
void run() override void run() override
{ {
if (!keyName)
throw UsageError("required argument '--key-name' is missing");
logger->stop(); logger->stop();
writeFull(getStandardOutput(), SecretKey::generate(*keyName).to_string()); writeFull(getStandardOutput(), SecretKey::generate(keyName).to_string());
} }
}; };