From 269caa531729524915761f8a71e47e59e6a8598d Mon Sep 17 00:00:00 2001 From: Timothy DeHerrera Date: Thu, 12 Jan 2023 12:35:22 -0700 Subject: [PATCH 1/3] feat: read installable paths from stdin Resolves #7437 for new `nix` commands only by adding a `--stdin` flag. If paths are also passed on the cli they will be combined with the ones from standard input. --- src/libcmd/command.hh | 2 ++ src/libcmd/installables.cc | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh index b6d554aab..49c7b4f9b 100644 --- a/src/libcmd/command.hh +++ b/src/libcmd/command.hh @@ -128,6 +128,8 @@ struct InstallablesCommand : virtual Args, SourceExprCommand virtual bool useDefaultInstallables() { return true; } + bool readFromStdIn; + std::vector getFlakesForCompletion() override; protected: diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 00c6f9516..a67841bb6 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -691,6 +691,13 @@ StorePathSet Installable::toDerivations( InstallablesCommand::InstallablesCommand() { + + addFlag({ + .longName = "stdin", + .description = "Read installables from the standard input.", + .handler = {&readFromStdIn, true} + }); + expectArgs({ .label = "installables", .handler = {&_installables}, @@ -707,10 +714,18 @@ void InstallablesCommand::prepare() Installables InstallablesCommand::load() { - if (_installables.empty() && useDefaultInstallables()) + if (_installables.empty() && useDefaultInstallables() && !readFromStdIn) // FIXME: commands like "nix profile install" should not have a // default, probably. _installables.push_back("."); + + if (readFromStdIn && !isatty(STDIN_FILENO)) { + std::string word; + while (std::cin >> word) { + _installables.emplace_back(std::move(word)); + } + } + return parseInstallables(getStore(), _installables); } From df643051e282465b73fc29e3f223b4fd497137d7 Mon Sep 17 00:00:00 2001 From: Timothy DeHerrera Date: Thu, 12 Jan 2023 12:45:45 -0700 Subject: [PATCH 2/3] nix-store: read paths from standard input Resolves #7437 for new `nix-store` by adding a `--stdin` flag. --- doc/manual/src/command-ref/nix-store.md | 5 +++++ src/nix-store/nix-store.cc | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/doc/manual/src/command-ref/nix-store.md b/doc/manual/src/command-ref/nix-store.md index 31fdd7806..17cbd0461 100644 --- a/doc/manual/src/command-ref/nix-store.md +++ b/doc/manual/src/command-ref/nix-store.md @@ -54,6 +54,11 @@ have an effect. created by sequentially numbering symlinks beyond the first one (e.g., `foo`, `foo-2`, `foo-3`, and so on). + - [`--stdin`](#opt-stdin) + + Read *paths…* from the standard input. + Useful for chaining nix-store commands. + # Operation `--realise` ## Synopsis diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 3bbefedbe..d4218550a 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -1020,6 +1020,7 @@ static int main_nix_store(int argc, char * * argv) { Strings opFlags, opArgs; Operation op = 0; + bool readFromStdIn; parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) { Operation oldOp = op; @@ -1078,6 +1079,8 @@ static int main_nix_store(int argc, char * * argv) op = opGenerateBinaryCacheKey; else if (*arg == "--add-root") gcRoot = absPath(getArg(*arg, arg, end)); + else if (*arg == "--stdin" && !isatty(STDIN_FILENO)) + readFromStdIn = true; else if (*arg == "--indirect") ; else if (*arg == "--no-output") @@ -1090,6 +1093,13 @@ static int main_nix_store(int argc, char * * argv) else opArgs.push_back(*arg); + if (readFromStdIn && op != opImport && op != opRestore && op != opServe) { + std::string word; + while (std::cin >> word) { + opArgs.emplace_back(std::move(word)); + }; + } + if (oldOp && oldOp != op) throw UsageError("only one operation may be specified"); From 639659dec22ed0016ce83dce79ff2aa46d83b0ab Mon Sep 17 00:00:00 2001 From: Timothy DeHerrera Date: Sat, 11 Feb 2023 11:00:05 -0700 Subject: [PATCH 3/3] doc/manual: add release note for `--stdin` flag --- doc/manual/src/release-notes/rl-next.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md index 78ae99f4b..dbd2e88f7 100644 --- a/doc/manual/src/release-notes/rl-next.md +++ b/doc/manual/src/release-notes/rl-next.md @@ -1,2 +1,5 @@ # Release X.Y (202?-??-??) +* Commands which take installables on the command line can now read them from the standard input if + passed the `--stdin` flag. This is primarily useful when you have a large amount of paths which + exceed the OS arg limit.