diff options
Diffstat (limited to 'src/libcmd')
-rw-r--r-- | src/libcmd/command.hh | 4 | ||||
-rw-r--r-- | src/libcmd/installable-derived-path.cc | 33 | ||||
-rw-r--r-- | src/libcmd/installable-flake.cc | 3 | ||||
-rw-r--r-- | src/libcmd/installables.cc | 30 |
4 files changed, 43 insertions, 27 deletions
diff --git a/src/libcmd/command.hh b/src/libcmd/command.hh index b6d554aab..b8116b151 100644 --- a/src/libcmd/command.hh +++ b/src/libcmd/command.hh @@ -22,7 +22,7 @@ static constexpr Command::Category catSecondary = 100; static constexpr Command::Category catUtility = 101; static constexpr Command::Category catNixInstallation = 102; -static constexpr auto installablesCategory = "Options that change the interpretation of installables"; +static constexpr auto installablesCategory = "Options that change the interpretation of [installables](@docroot@/command-ref/new-cli/nix.md#installables)"; struct NixMultiCommand : virtual MultiCommand, virtual Command { @@ -128,6 +128,8 @@ struct InstallablesCommand : virtual Args, SourceExprCommand virtual bool useDefaultInstallables() { return true; } + bool readFromStdIn; + std::vector<std::string> getFlakesForCompletion() override; protected: diff --git a/src/libcmd/installable-derived-path.cc b/src/libcmd/installable-derived-path.cc index a9921b901..729dc7d31 100644 --- a/src/libcmd/installable-derived-path.cc +++ b/src/libcmd/installable-derived-path.cc @@ -31,27 +31,24 @@ InstallableDerivedPath InstallableDerivedPath::parse( ExtendedOutputsSpec extendedOutputsSpec) { auto derivedPath = std::visit(overloaded { - // If the user did not use ^, we treat the output more liberally. + // If the user did not use ^, we treat the output more + // liberally: we accept a symlink chain or an actual + // store path. [&](const ExtendedOutputsSpec::Default &) -> DerivedPath { - // First, we accept a symlink chain or an actual store path. auto storePath = store->followLinksToStorePath(prefix); - // Second, we see if the store path ends in `.drv` to decide what sort - // of derived path they want. - // - // This handling predates the `^` syntax. The `^*` in - // `/nix/store/hash-foo.drv^*` unambiguously means "do the - // `DerivedPath::Built` case", so plain `/nix/store/hash-foo.drv` could - // also unambiguously mean "do the DerivedPath::Opaque` case". - // - // Issue #7261 tracks reconsidering this `.drv` dispatching. - return storePath.isDerivation() - ? (DerivedPath) DerivedPath::Built { - .drvPath = std::move(storePath), - .outputs = OutputsSpec::All {}, - } - : (DerivedPath) DerivedPath::Opaque { - .path = std::move(storePath), + // Remove this prior to stabilizing the new CLI. + if (storePath.isDerivation()) { + auto oldDerivedPath = DerivedPath::Built { + .drvPath = storePath, + .outputs = OutputsSpec::All { }, }; + warn( + "The interpretation of store paths arguments ending in `.drv` recently changed. If this command is now failing try again with '%s'", + oldDerivedPath.to_string(*store)); + }; + return DerivedPath::Opaque { + .path = std::move(storePath), + }; }, // If the user did use ^, we just do exactly what is written. [&](const ExtendedOutputsSpec::Explicit & outputSpec) -> DerivedPath { diff --git a/src/libcmd/installable-flake.cc b/src/libcmd/installable-flake.cc index 60a97deaf..7b0cc376d 100644 --- a/src/libcmd/installable-flake.cc +++ b/src/libcmd/installable-flake.cc @@ -178,8 +178,7 @@ std::pair<Value *, PosIdx> InstallableFlake::toValue(EvalState & state) std::vector<ref<eval_cache::AttrCursor>> InstallableFlake::getCursors(EvalState & state) { - auto evalCache = openEvalCache(state, - std::make_shared<flake::LockedFlake>(lockFlake(state, flakeRef, lockFlags))); + auto evalCache = openEvalCache(state, getLockedFlake()); auto root = evalCache->getRoot(); diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc index 00c6f9516..5ecf6293f 100644 --- a/src/libcmd/installables.cc +++ b/src/libcmd/installables.cc @@ -153,7 +153,7 @@ SourceExprCommand::SourceExprCommand() .longName = "file", .shortName = 'f', .description = - "Interpret installables as attribute paths relative to the Nix expression stored in *file*. " + "Interpret [*installables*](@docroot@/command-ref/new-cli/nix.md#installables) as attribute paths relative to the Nix expression stored in *file*. " "If *file* is the character -, then a Nix expression will be read from standard input. " "Implies `--impure`.", .category = installablesCategory, @@ -164,7 +164,7 @@ SourceExprCommand::SourceExprCommand() addFlag({ .longName = "expr", - .description = "Interpret installables as attribute paths relative to the Nix expression *expr*.", + .description = "Interpret [*installables*](@docroot@/command-ref/new-cli/nix.md#installables) as attribute paths relative to the Nix expression *expr*.", .category = installablesCategory, .labels = {"expr"}, .handler = {&expr} @@ -677,9 +677,12 @@ StorePathSet Installable::toDerivations( for (const auto & b : i->toDerivedPaths()) std::visit(overloaded { [&](const DerivedPath::Opaque & bo) { - if (!useDeriver) - throw Error("argument '%s' did not evaluate to a derivation", i->what()); - drvPaths.insert(getDeriver(store, *i, bo.path)); + drvPaths.insert( + bo.path.isDerivation() + ? bo.path + : useDeriver + ? getDeriver(store, *i, bo.path) + : throw Error("argument '%s' did not evaluate to a derivation", i->what())); }, [&](const DerivedPath::Built & bfd) { drvPaths.insert(bfd.drvPath); @@ -691,6 +694,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 +717,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); } |