From d72ee91d07a286b18862235792326297199a0d75 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 1 Mar 2024 14:14:14 +0100 Subject: [PATCH 1/5] Clean up --arg processing --- src/libcmd/common-eval-args.cc | 20 ++++++++++++-------- src/libcmd/common-eval-args.hh | 7 ++++++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/libcmd/common-eval-args.cc b/src/libcmd/common-eval-args.cc index 444ff81c9..ed2c126a4 100644 --- a/src/libcmd/common-eval-args.cc +++ b/src/libcmd/common-eval-args.cc @@ -20,7 +20,7 @@ MixEvalArgs::MixEvalArgs() .description = "Pass the value *expr* as the argument *name* to Nix functions.", .category = category, .labels = {"name", "expr"}, - .handler = {[&](std::string name, std::string expr) { autoArgs[name] = 'E' + expr; }} + .handler = {[&](std::string name, std::string expr) { autoArgs.insert_or_assign(name, AutoArg{AutoArgExpr(expr)}); }} }); addFlag({ @@ -28,7 +28,7 @@ MixEvalArgs::MixEvalArgs() .description = "Pass the string *string* as the argument *name* to Nix functions.", .category = category, .labels = {"name", "string"}, - .handler = {[&](std::string name, std::string s) { autoArgs[name] = 'S' + s; }}, + .handler = {[&](std::string name, std::string s) { autoArgs.insert_or_assign(name, AutoArg{AutoArgString(s)}); }}, }); addFlag({ @@ -154,13 +154,17 @@ MixEvalArgs::MixEvalArgs() Bindings * MixEvalArgs::getAutoArgs(EvalState & state) { auto res = state.buildBindings(autoArgs.size()); - for (auto & i : autoArgs) { + for (auto & [name, arg] : autoArgs) { auto v = state.allocValue(); - if (i.second[0] == 'E') - state.mkThunk_(*v, state.parseExprFromString(i.second.substr(1), state.rootPath("."))); - else - v->mkString(((std::string_view) i.second).substr(1)); - res.insert(state.symbols.create(i.first), v); + std::visit(overloaded { + [&](const AutoArgExpr & arg) { + state.mkThunk_(*v, state.parseExprFromString(arg.expr, state.rootPath("."))); + }, + [&](const AutoArgString & arg) { + v->mkString(arg.s); + } + }, arg); + res.insert(state.symbols.create(name), v); } return res.finish(); } diff --git a/src/libcmd/common-eval-args.hh b/src/libcmd/common-eval-args.hh index 2eb63e15d..2e2f18385 100644 --- a/src/libcmd/common-eval-args.hh +++ b/src/libcmd/common-eval-args.hh @@ -26,7 +26,12 @@ struct MixEvalArgs : virtual Args, virtual MixRepair std::optional evalStoreUrl; private: - std::map autoArgs; + struct AutoArgExpr { std::string expr; }; + struct AutoArgString { std::string s; }; + + using AutoArg = std::variant; + + std::map autoArgs; }; SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * baseDir = nullptr); From 291b10c607e3f9d19acee692ac2488056e53eeee Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 1 Mar 2024 14:35:27 +0100 Subject: [PATCH 2/5] Add --arg-from-file for reading a string from a file --- src/libcmd/common-eval-args.cc | 12 ++++++++++++ src/libcmd/common-eval-args.hh | 3 ++- tests/functional/eval.sh | 8 ++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/libcmd/common-eval-args.cc b/src/libcmd/common-eval-args.cc index ed2c126a4..89df67406 100644 --- a/src/libcmd/common-eval-args.cc +++ b/src/libcmd/common-eval-args.cc @@ -31,6 +31,15 @@ MixEvalArgs::MixEvalArgs() .handler = {[&](std::string name, std::string s) { autoArgs.insert_or_assign(name, AutoArg{AutoArgString(s)}); }}, }); + addFlag({ + .longName = "arg-from-file", + .description = "Pass the contents of file *path* as the argument *name* to Nix functions.", + .category = category, + .labels = {"name", "path"}, + .handler = {[&](std::string name, std::string path) { autoArgs.insert_or_assign(name, AutoArg{AutoArgFile(path)}); }}, + .completer = completePath + }); + addFlag({ .longName = "include", .shortName = 'I', @@ -162,6 +171,9 @@ Bindings * MixEvalArgs::getAutoArgs(EvalState & state) }, [&](const AutoArgString & arg) { v->mkString(arg.s); + }, + [&](const AutoArgFile & arg) { + v->mkString(readFile(arg.path)); } }, arg); res.insert(state.symbols.create(name), v); diff --git a/src/libcmd/common-eval-args.hh b/src/libcmd/common-eval-args.hh index 2e2f18385..9f4da4231 100644 --- a/src/libcmd/common-eval-args.hh +++ b/src/libcmd/common-eval-args.hh @@ -28,8 +28,9 @@ struct MixEvalArgs : virtual Args, virtual MixRepair private: struct AutoArgExpr { std::string expr; }; struct AutoArgString { std::string s; }; + struct AutoArgFile { std::filesystem::path path; }; - using AutoArg = std::variant; + using AutoArg = std::variant; std::map autoArgs; }; diff --git a/tests/functional/eval.sh b/tests/functional/eval.sh index b81bb1e2c..321593670 100644 --- a/tests/functional/eval.sh +++ b/tests/functional/eval.sh @@ -41,3 +41,11 @@ mkdir -p $TEST_ROOT/xyzzy $TEST_ROOT/foo ln -sfn ../xyzzy $TEST_ROOT/foo/bar printf 123 > $TEST_ROOT/xyzzy/default.nix [[ $(nix eval --impure --expr "import $TEST_ROOT/foo/bar") = 123 ]] + +# Test --arg-from-file. +[[ "$(nix eval --raw --arg-from-file foo config.nix --expr '{ foo }: { inherit foo; }' foo)" = "$(cat config.nix)" ]] + +# Check that special(-ish) files are drained. +if [[ -e /proc/version ]]; then + [[ "$(nix eval --raw --arg-from-file foo /proc/version --expr '{ foo }: { inherit foo; }' foo)" = "$(cat /proc/version)" ]] +fi From 8ce1f6800b9eef394d2cb9dffdf99e7a6ffec64a Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 1 Mar 2024 14:39:42 +0100 Subject: [PATCH 3/5] Add --arg-from-stdin to read an argument from stdin --- src/libcmd/common-eval-args.cc | 11 +++++++++++ src/libcmd/common-eval-args.hh | 3 ++- tests/functional/eval.sh | 3 +++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/libcmd/common-eval-args.cc b/src/libcmd/common-eval-args.cc index 89df67406..b87bbbc27 100644 --- a/src/libcmd/common-eval-args.cc +++ b/src/libcmd/common-eval-args.cc @@ -40,6 +40,14 @@ MixEvalArgs::MixEvalArgs() .completer = completePath }); + addFlag({ + .longName = "arg-from-stdin", + .description = "Pass the contents of stdin as the argument *name* to Nix functions.", + .category = category, + .labels = {"name"}, + .handler = {[&](std::string name) { autoArgs.insert_or_assign(name, AutoArg{AutoArgStdin{}}); }}, + }); + addFlag({ .longName = "include", .shortName = 'I', @@ -174,6 +182,9 @@ Bindings * MixEvalArgs::getAutoArgs(EvalState & state) }, [&](const AutoArgFile & arg) { v->mkString(readFile(arg.path)); + }, + [&](const AutoArgStdin & arg) { + v->mkString(readFile(STDIN_FILENO)); } }, arg); res.insert(state.symbols.create(name), v); diff --git a/src/libcmd/common-eval-args.hh b/src/libcmd/common-eval-args.hh index 9f4da4231..7548bd3b7 100644 --- a/src/libcmd/common-eval-args.hh +++ b/src/libcmd/common-eval-args.hh @@ -29,8 +29,9 @@ private: struct AutoArgExpr { std::string expr; }; struct AutoArgString { std::string s; }; struct AutoArgFile { std::filesystem::path path; }; + struct AutoArgStdin { }; - using AutoArg = std::variant; + using AutoArg = std::variant; std::map autoArgs; }; diff --git a/tests/functional/eval.sh b/tests/functional/eval.sh index 321593670..c6a475cd0 100644 --- a/tests/functional/eval.sh +++ b/tests/functional/eval.sh @@ -49,3 +49,6 @@ printf 123 > $TEST_ROOT/xyzzy/default.nix if [[ -e /proc/version ]]; then [[ "$(nix eval --raw --arg-from-file foo /proc/version --expr '{ foo }: { inherit foo; }' foo)" = "$(cat /proc/version)" ]] fi + +# Test --arg-from-stdin. +[[ "$(echo bla | nix eval --raw --arg-from-stdin foo --expr '{ foo }: { inherit foo; }' foo)" = bla ]] From e6b9432542673a451b058ad2f0a7f1b4c20d3fbf Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 4 Mar 2024 12:48:21 +0100 Subject: [PATCH 4/5] Add release note --- doc/manual/rl-next/arg-from-file.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 doc/manual/rl-next/arg-from-file.md diff --git a/doc/manual/rl-next/arg-from-file.md b/doc/manual/rl-next/arg-from-file.md new file mode 100644 index 000000000..5849b11a3 --- /dev/null +++ b/doc/manual/rl-next/arg-from-file.md @@ -0,0 +1,9 @@ +--- +synopsis: "CLI options `--arg-from-file` and `--arg-from-stdin`" +prs: 10122 +--- + +The new CLI option `--arg-from-file` *name* *path* passes the contents +of file *path* as a string value via the function argument *name* to a +Nix expression. Similarly, the new option `--arg-from-stdin` *name* +reads the contents of the string from standard input. From cbfd211b39fe053bb8a7ff416a7bf1c09b3d1fbf Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 4 Mar 2024 12:49:32 +0100 Subject: [PATCH 5/5] Fix build --- src/libcmd/common-eval-args.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libcmd/common-eval-args.hh b/src/libcmd/common-eval-args.hh index 7548bd3b7..25ce5b9da 100644 --- a/src/libcmd/common-eval-args.hh +++ b/src/libcmd/common-eval-args.hh @@ -6,6 +6,8 @@ #include "common-args.hh" #include "search-path.hh" +#include + namespace nix { class Store;