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

Args::Flag: Add required attribute

This commit is contained in:
Eelco Dolstra 2025-09-10 17:40:54 +02:00
parent 8aa4669328
commit eec4dece33
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 &) {
}
}
for (auto pos = cmdline.begin(); pos != cmdline.end();) {
auto arg = *pos;
@ -354,6 +355,9 @@ void RootArgs::parseCmdline(const Strings & _cmdline, bool allowShebang)
processArgs(pendingArgs, true);
if (!completions)
checkArgs();
initialFlagsProcessed();
/* 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 process = [&](const std::string & name, const Flag & flag) -> bool {
auto process = [&](const std::string & name, Flag & flag) -> bool {
++pos;
if (auto & f = flag.experimentalFeature)
@ -413,6 +417,7 @@ bool Args::processFlag(Strings::iterator & pos, Strings::iterator end)
}
if (!anyCompleted)
flag.handler.fun(std::move(args));
flag.timesUsed++;
return true;
};
@ -504,6 +509,14 @@ bool Args::processArgs(const Strings & args, bool finish)
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()
{
auto flags = nlohmann::json::object();
@ -643,6 +656,13 @@ bool MultiCommand::processArgs(const Strings & args, bool finish)
return Args::processArgs(args, finish);
}
void MultiCommand::checkArgs()
{
Args::checkArgs();
if (command)
command->second->checkArgs();
}
nlohmann::json MultiCommand::toJSON()
{
auto cmds = nlohmann::json::object();

View file

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

View file

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