forked from lix-project/lix
nix: Add --derivation flag to operate on .drv paths
For instance, 'nix why-depends --use-derivation nixpkgs#hello nixpkgs#glibc' shows why hello's .drv depends on glibc's .drv.
This commit is contained in:
parent
dfe8f3ebc6
commit
3624c042ac
|
@ -63,7 +63,7 @@ void StorePathsCommand::run(ref<Store> store)
|
|||
}
|
||||
|
||||
else {
|
||||
for (auto & p : toStorePaths(store, realiseMode, installables))
|
||||
for (auto & p : toStorePaths(store, realiseMode, operateOn, installables))
|
||||
storePaths.push_back(p);
|
||||
|
||||
if (recursive) {
|
||||
|
@ -80,7 +80,7 @@ void StorePathsCommand::run(ref<Store> store)
|
|||
|
||||
void StorePathCommand::run(ref<Store> store)
|
||||
{
|
||||
auto storePaths = toStorePaths(store, Realise::Nothing, installables);
|
||||
auto storePaths = toStorePaths(store, Realise::Nothing, operateOn, installables);
|
||||
|
||||
if (storePaths.size() != 1)
|
||||
throw UsageError("this command requires exactly one store path");
|
||||
|
|
|
@ -50,11 +50,22 @@ struct MixFlakeOptions : virtual Args, EvalCommand
|
|||
{ return {}; }
|
||||
};
|
||||
|
||||
/* How to handle derivations in commands that operate on store paths. */
|
||||
enum class OperateOn {
|
||||
/* Operate on the output path. */
|
||||
Output,
|
||||
/* Operate on the .drv path. */
|
||||
Derivation
|
||||
};
|
||||
|
||||
struct SourceExprCommand : virtual Args, MixFlakeOptions
|
||||
{
|
||||
std::optional<Path> file;
|
||||
std::optional<std::string> expr;
|
||||
|
||||
// FIXME: move this; not all commands (e.g. 'nix run') use it.
|
||||
OperateOn operateOn = OperateOn::Output;
|
||||
|
||||
SourceExprCommand();
|
||||
|
||||
std::vector<std::shared_ptr<Installable>> parseInstallables(
|
||||
|
@ -176,10 +187,12 @@ static RegisterCommand registerCommand(const std::string & name)
|
|||
Buildables build(ref<Store> store, Realise mode,
|
||||
std::vector<std::shared_ptr<Installable>> installables);
|
||||
|
||||
std::set<StorePath> toStorePaths(ref<Store> store, Realise mode,
|
||||
std::set<StorePath> toStorePaths(ref<Store> store,
|
||||
Realise mode, OperateOn operateOn,
|
||||
std::vector<std::shared_ptr<Installable>> installables);
|
||||
|
||||
StorePath toStorePath(ref<Store> store, Realise mode,
|
||||
StorePath toStorePath(ref<Store> store,
|
||||
Realise mode, OperateOn operateOn,
|
||||
std::shared_ptr<Installable> installable);
|
||||
|
||||
std::set<StorePath> toDerivations(ref<Store> store,
|
||||
|
|
|
@ -321,7 +321,8 @@ struct CmdDevelop : Common, MixEnvironment
|
|||
Strings{"legacyPackages." + settings.thisSystem.get() + "."},
|
||||
lockFlags);
|
||||
|
||||
shell = state->store->printStorePath(toStorePath(state->store, Realise::Outputs, bashInstallable)) + "/bin/bash";
|
||||
shell = state->store->printStorePath(
|
||||
toStorePath(state->store, Realise::Outputs, OperateOn::Output, bashInstallable)) + "/bin/bash";
|
||||
} catch (Error &) {
|
||||
ignoreException();
|
||||
}
|
||||
|
|
|
@ -128,6 +128,12 @@ SourceExprCommand::SourceExprCommand()
|
|||
.labels = {"expr"},
|
||||
.handler = {&expr}
|
||||
});
|
||||
|
||||
addFlag({
|
||||
.longName ="derivation",
|
||||
.description = "operate on the store derivation rather than its outputs",
|
||||
.handler = {&operateOn, OperateOn::Derivation},
|
||||
});
|
||||
}
|
||||
|
||||
Strings SourceExprCommand::getDefaultFlakeAttrPaths()
|
||||
|
@ -667,22 +673,34 @@ Buildables build(ref<Store> store, Realise mode,
|
|||
return buildables;
|
||||
}
|
||||
|
||||
StorePathSet toStorePaths(ref<Store> store, Realise mode,
|
||||
StorePathSet toStorePaths(ref<Store> store,
|
||||
Realise mode, OperateOn operateOn,
|
||||
std::vector<std::shared_ptr<Installable>> installables)
|
||||
{
|
||||
StorePathSet outPaths;
|
||||
|
||||
for (auto & b : build(store, mode, installables))
|
||||
for (auto & output : b.outputs)
|
||||
outPaths.insert(output.second);
|
||||
if (operateOn == OperateOn::Output) {
|
||||
for (auto & b : build(store, mode, installables))
|
||||
for (auto & output : b.outputs)
|
||||
outPaths.insert(output.second);
|
||||
} else {
|
||||
if (mode == Realise::Nothing)
|
||||
settings.readOnlyMode = true;
|
||||
|
||||
for (auto & i : installables)
|
||||
for (auto & b : i->toBuildables())
|
||||
if (b.drvPath)
|
||||
outPaths.insert(*b.drvPath);
|
||||
}
|
||||
|
||||
return outPaths;
|
||||
}
|
||||
|
||||
StorePath toStorePath(ref<Store> store, Realise mode,
|
||||
StorePath toStorePath(ref<Store> store,
|
||||
Realise mode, OperateOn operateOn,
|
||||
std::shared_ptr<Installable> installable)
|
||||
{
|
||||
auto paths = toStorePaths(store, mode, {installable});
|
||||
auto paths = toStorePaths(store, mode, operateOn, {installable});
|
||||
|
||||
if (paths.size() != 1)
|
||||
throw Error("argument '%s' should evaluate to one store path", installable->what());
|
||||
|
|
|
@ -104,7 +104,7 @@ struct CmdShell : InstallablesCommand, RunCommon, MixEnvironment
|
|||
|
||||
void run(ref<Store> store) override
|
||||
{
|
||||
auto outPaths = toStorePaths(store, Realise::Outputs, installables);
|
||||
auto outPaths = toStorePaths(store, Realise::Outputs, OperateOn::Output, installables);
|
||||
|
||||
auto accessor = store->getFSAccessor();
|
||||
|
||||
|
|
|
@ -73,9 +73,9 @@ struct CmdWhyDepends : SourceExprCommand
|
|||
void run(ref<Store> store) override
|
||||
{
|
||||
auto package = parseInstallable(store, _package);
|
||||
auto packagePath = toStorePath(store, Realise::Outputs, package);
|
||||
auto packagePath = toStorePath(store, Realise::Outputs, operateOn, package);
|
||||
auto dependency = parseInstallable(store, _dependency);
|
||||
auto dependencyPath = toStorePath(store, Realise::Derivation, dependency);
|
||||
auto dependencyPath = toStorePath(store, Realise::Derivation, operateOn, dependency);
|
||||
auto dependencyPathHash = dependencyPath.hashPart();
|
||||
|
||||
StorePathSet closure;
|
||||
|
|
Loading…
Reference in a new issue