Merge pull request #7594 from nrdxp/paths-from-stdin

feat: read installable paths from stdin
This commit is contained in:
Théophane Hufschmitt 2023-03-02 19:56:27 +01:00 committed by GitHub
commit 8730d3002f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 2 deletions

View file

@ -54,6 +54,11 @@ have an effect.
created by sequentially numbering symlinks beyond the first one created by sequentially numbering symlinks beyond the first one
(e.g., `foo`, `foo-2`, `foo-3`, and so on). (e.g., `foo`, `foo-2`, `foo-3`, and so on).
- <span id="opt-stdin">[`--stdin`](#opt-stdin)</span>
Read *paths…* from the standard input.
Useful for chaining nix-store commands.
# Operation `--realise` # Operation `--realise`
## Synopsis ## Synopsis

View file

@ -1,5 +1,9 @@
# Release X.Y (202?-??-??) # 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.
* The special handling of an [installable](../command-ref/new-cli/nix.md#installables) with `.drv` suffix being interpreted as all of the given [store derivation](../glossary.md#gloss-store-derivation)'s output paths is removed, and instead taken as the literal store path that it represents. * The special handling of an [installable](../command-ref/new-cli/nix.md#installables) with `.drv` suffix being interpreted as all of the given [store derivation](../glossary.md#gloss-store-derivation)'s output paths is removed, and instead taken as the literal store path that it represents.
The new `^` syntax for store paths introduced in Nix 2.13 allows explicitly referencing output paths of a derivation. The new `^` syntax for store paths introduced in Nix 2.13 allows explicitly referencing output paths of a derivation.

View file

@ -128,6 +128,8 @@ struct InstallablesCommand : virtual Args, SourceExprCommand
virtual bool useDefaultInstallables() { return true; } virtual bool useDefaultInstallables() { return true; }
bool readFromStdIn;
std::vector<std::string> getFlakesForCompletion() override; std::vector<std::string> getFlakesForCompletion() override;
protected: protected:

View file

@ -694,6 +694,13 @@ StorePathSet Installable::toDerivations(
InstallablesCommand::InstallablesCommand() InstallablesCommand::InstallablesCommand()
{ {
addFlag({
.longName = "stdin",
.description = "Read installables from the standard input.",
.handler = {&readFromStdIn, true}
});
expectArgs({ expectArgs({
.label = "installables", .label = "installables",
.handler = {&_installables}, .handler = {&_installables},
@ -710,10 +717,18 @@ void InstallablesCommand::prepare()
Installables InstallablesCommand::load() Installables InstallablesCommand::load()
{ {
if (_installables.empty() && useDefaultInstallables()) if (_installables.empty() && useDefaultInstallables() && !readFromStdIn)
// FIXME: commands like "nix profile install" should not have a // FIXME: commands like "nix profile install" should not have a
// default, probably. // default, probably.
_installables.push_back("."); _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); return parseInstallables(getStore(), _installables);
} }

View file

@ -1020,6 +1020,7 @@ static int main_nix_store(int argc, char * * argv)
{ {
Strings opFlags, opArgs; Strings opFlags, opArgs;
Operation op = 0; Operation op = 0;
bool readFromStdIn;
parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) { parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
Operation oldOp = op; Operation oldOp = op;
@ -1078,6 +1079,8 @@ static int main_nix_store(int argc, char * * argv)
op = opGenerateBinaryCacheKey; op = opGenerateBinaryCacheKey;
else if (*arg == "--add-root") else if (*arg == "--add-root")
gcRoot = absPath(getArg(*arg, arg, end)); gcRoot = absPath(getArg(*arg, arg, end));
else if (*arg == "--stdin" && !isatty(STDIN_FILENO))
readFromStdIn = true;
else if (*arg == "--indirect") else if (*arg == "--indirect")
; ;
else if (*arg == "--no-output") else if (*arg == "--no-output")
@ -1090,6 +1093,13 @@ static int main_nix_store(int argc, char * * argv)
else else
opArgs.push_back(*arg); 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) if (oldOp && oldOp != op)
throw UsageError("only one operation may be specified"); throw UsageError("only one operation may be specified");