nixos/nixos-option: Convert --all into -r

This commit is contained in:
Chuck 2019-12-17 12:08:07 -08:00 committed by Maximilian Bosch
parent 9dd23e8743
commit ed51fd0033
3 changed files with 47 additions and 36 deletions

View File

@ -14,12 +14,16 @@
<refsynopsisdiv> <refsynopsisdiv>
<cmdsynopsis> <cmdsynopsis>
<command>nixos-option</command> <command>nixos-option</command>
<arg> <arg>
<option>-I</option> <replaceable>path</replaceable> <group choice='req'>
<arg choice='plain'><option>-r</option></arg>
<arg choice='plain'><option>--recursive</option></arg>
</group>
</arg> </arg>
<arg> <arg>
<option>--all</option> <option>-I</option> <replaceable>path</replaceable>
</arg> </arg>
<arg> <arg>
@ -45,6 +49,15 @@
This command accepts the following options: This command accepts the following options:
</para> </para>
<variablelist> <variablelist>
<varlistentry>
<term><option>-r</option></term>
<term><option>--recursive</option></term>
<listitem>
<para>
Print all the values at or below the specified path recursively.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<option>-I</option> <replaceable>path</replaceable> <option>-I</option> <replaceable>path</replaceable>
@ -56,16 +69,6 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>--all</option>
</term>
<listitem>
<para>
Print the values of all options.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsection> </refsection>
<refsection> <refsection>

View File

@ -52,7 +52,7 @@
<listitem> <listitem>
<para> <para>
<command>nixos-option</command> has been rewritten in C++, speeding it up, improving correctness, <command>nixos-option</command> has been rewritten in C++, speeding it up, improving correctness,
and adding a <option>--all</option> option which prints all options and their values. and adding a <option>-r</option> option which prints all options and their values recursively.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>

View File

@ -290,9 +290,14 @@ FindAlongOptionPathRet findAlongOptionPath(Context & ctx, const std::string & pa
return {v, processedPath}; return {v, processedPath};
} }
// Calls f on all the option names // Calls f on all the option names at or below the option described by `path`.
void mapOptions(const std::function<void(const std::string & path)> & f, Context & ctx, Value root) // Note that "the option described by `path`" is not trivial -- if path describes a value inside an aggregate
// option (such as users.users.root), the *option* described by that path is one path component shorter
// (eg: users.users), which results in f being called on sibling-paths (eg: users.users.nixbld1). If f
// doesn't want these, it must do its own filtering.
void mapOptions(const std::function<void(const std::string & path)> & f, Context & ctx, const std::string & path)
{ {
auto root = findAlongOptionPath(ctx, path);
recurse( recurse(
[f, &ctx](const std::string & path, std::variant<Value, std::exception_ptr> v) { [f, &ctx](const std::string & path, std::variant<Value, std::exception_ptr> v) {
bool isOpt = std::holds_alternative<std::exception_ptr>(v) || isOption(ctx, std::get<Value>(v)); bool isOpt = std::holds_alternative<std::exception_ptr>(v) || isOption(ctx, std::get<Value>(v));
@ -301,7 +306,7 @@ void mapOptions(const std::function<void(const std::string & path)> & f, Context
} }
return !isOpt; return !isOpt;
}, },
ctx, root, ""); ctx, root.option, root.path);
} }
// Calls f on all the config values inside one option. // Calls f on all the config values inside one option.
@ -475,17 +480,26 @@ void printConfigValue(Context & ctx, Out & out, const std::string & path, std::v
out << ";\n"; out << ";\n";
} }
void printAll(Context & ctx, Out & out) // Replace with std::starts_with when C++20 is available
bool starts_with(const std::string & s, const std::string & prefix)
{
return s.size() >= prefix.size() &&
std::equal(s.begin(), std::next(s.begin(), prefix.size()), prefix.begin(), prefix.end());
}
void printRecursive(Context & ctx, Out & out, const std::string & path)
{ {
mapOptions( mapOptions(
[&ctx, &out](const std::string & optionPath) { [&ctx, &out, &path](const std::string & optionPath) {
mapConfigValuesInOption( mapConfigValuesInOption(
[&ctx, &out](const std::string & configPath, std::variant<Value, std::exception_ptr> v) { [&ctx, &out, &path](const std::string & configPath, std::variant<Value, std::exception_ptr> v) {
printConfigValue(ctx, out, configPath, v); if (starts_with(configPath, path)) {
printConfigValue(ctx, out, configPath, v);
}
}, },
optionPath, ctx); optionPath, ctx);
}, },
ctx, ctx.optionsRoot); ctx, path);
} }
void printAttr(Context & ctx, Out & out, const std::string & path, Value & root) void printAttr(Context & ctx, Out & out, const std::string & path, Value & root)
@ -569,7 +583,7 @@ void printOne(Context & ctx, Out & out, const std::string & path)
int main(int argc, char ** argv) int main(int argc, char ** argv)
{ {
bool all = false; bool recursive = false;
std::string path = "."; std::string path = ".";
std::string optionsExpr = "(import <nixpkgs/nixos> {}).options"; std::string optionsExpr = "(import <nixpkgs/nixos> {}).options";
std::string configExpr = "(import <nixpkgs/nixos> {}).config"; std::string configExpr = "(import <nixpkgs/nixos> {}).config";
@ -585,8 +599,8 @@ int main(int argc, char ** argv)
nix::showManPage("nixos-option"); nix::showManPage("nixos-option");
} else if (*arg == "--version") { } else if (*arg == "--version") {
nix::printVersion("nixos-option"); nix::printVersion("nixos-option");
} else if (*arg == "--all") { } else if (*arg == "-r" || *arg == "--recursive") {
all = true; recursive = true;
} else if (*arg == "--path") { } else if (*arg == "--path") {
path = nix::getArg(*arg, arg, end); path = nix::getArg(*arg, arg, end);
} else if (*arg == "--options_expr") { } else if (*arg == "--options_expr") {
@ -615,18 +629,12 @@ int main(int argc, char ** argv)
Context ctx{*state, *myArgs.getAutoArgs(*state), optionsRoot, configRoot}; Context ctx{*state, *myArgs.getAutoArgs(*state), optionsRoot, configRoot};
Out out(std::cout); Out out(std::cout);
if (all) { auto print = recursive ? printRecursive : printOne;
if (!args.empty()) { if (args.empty()) {
throw UsageError("--all cannot be used with arguments"); print(ctx, out, "");
} }
printAll(ctx, out); for (const auto & arg : args) {
} else { print(ctx, out, arg);
if (args.empty()) {
printOne(ctx, out, "");
}
for (const auto & arg : args) {
printOne(ctx, out, arg);
}
} }
ctx.state.printStats(); ctx.state.printStats();