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 {
|
else {
|
||||||
for (auto & p : toStorePaths(store, realiseMode, installables))
|
for (auto & p : toStorePaths(store, realiseMode, operateOn, installables))
|
||||||
storePaths.push_back(p);
|
storePaths.push_back(p);
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
|
@ -80,7 +80,7 @@ void StorePathsCommand::run(ref<Store> store)
|
||||||
|
|
||||||
void StorePathCommand::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)
|
if (storePaths.size() != 1)
|
||||||
throw UsageError("this command requires exactly one store path");
|
throw UsageError("this command requires exactly one store path");
|
||||||
|
|
|
@ -50,11 +50,22 @@ struct MixFlakeOptions : virtual Args, EvalCommand
|
||||||
{ return {}; }
|
{ 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
|
struct SourceExprCommand : virtual Args, MixFlakeOptions
|
||||||
{
|
{
|
||||||
std::optional<Path> file;
|
std::optional<Path> file;
|
||||||
std::optional<std::string> expr;
|
std::optional<std::string> expr;
|
||||||
|
|
||||||
|
// FIXME: move this; not all commands (e.g. 'nix run') use it.
|
||||||
|
OperateOn operateOn = OperateOn::Output;
|
||||||
|
|
||||||
SourceExprCommand();
|
SourceExprCommand();
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Installable>> parseInstallables(
|
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,
|
Buildables build(ref<Store> store, Realise mode,
|
||||||
std::vector<std::shared_ptr<Installable>> installables);
|
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);
|
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::shared_ptr<Installable> installable);
|
||||||
|
|
||||||
std::set<StorePath> toDerivations(ref<Store> store,
|
std::set<StorePath> toDerivations(ref<Store> store,
|
||||||
|
|
|
@ -321,7 +321,8 @@ struct CmdDevelop : Common, MixEnvironment
|
||||||
Strings{"legacyPackages." + settings.thisSystem.get() + "."},
|
Strings{"legacyPackages." + settings.thisSystem.get() + "."},
|
||||||
lockFlags);
|
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 &) {
|
} catch (Error &) {
|
||||||
ignoreException();
|
ignoreException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,12 @@ SourceExprCommand::SourceExprCommand()
|
||||||
.labels = {"expr"},
|
.labels = {"expr"},
|
||||||
.handler = {&expr}
|
.handler = {&expr}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addFlag({
|
||||||
|
.longName ="derivation",
|
||||||
|
.description = "operate on the store derivation rather than its outputs",
|
||||||
|
.handler = {&operateOn, OperateOn::Derivation},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Strings SourceExprCommand::getDefaultFlakeAttrPaths()
|
Strings SourceExprCommand::getDefaultFlakeAttrPaths()
|
||||||
|
@ -667,22 +673,34 @@ Buildables build(ref<Store> store, Realise mode,
|
||||||
return buildables;
|
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)
|
std::vector<std::shared_ptr<Installable>> installables)
|
||||||
{
|
{
|
||||||
StorePathSet outPaths;
|
StorePathSet outPaths;
|
||||||
|
|
||||||
for (auto & b : build(store, mode, installables))
|
if (operateOn == OperateOn::Output) {
|
||||||
for (auto & output : b.outputs)
|
for (auto & b : build(store, mode, installables))
|
||||||
outPaths.insert(output.second);
|
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;
|
return outPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
StorePath toStorePath(ref<Store> store, Realise mode,
|
StorePath toStorePath(ref<Store> store,
|
||||||
|
Realise mode, OperateOn operateOn,
|
||||||
std::shared_ptr<Installable> installable)
|
std::shared_ptr<Installable> installable)
|
||||||
{
|
{
|
||||||
auto paths = toStorePaths(store, mode, {installable});
|
auto paths = toStorePaths(store, mode, operateOn, {installable});
|
||||||
|
|
||||||
if (paths.size() != 1)
|
if (paths.size() != 1)
|
||||||
throw Error("argument '%s' should evaluate to one store path", installable->what());
|
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
|
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();
|
auto accessor = store->getFSAccessor();
|
||||||
|
|
||||||
|
|
|
@ -73,9 +73,9 @@ struct CmdWhyDepends : SourceExprCommand
|
||||||
void run(ref<Store> store) override
|
void run(ref<Store> store) override
|
||||||
{
|
{
|
||||||
auto package = parseInstallable(store, _package);
|
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 dependency = parseInstallable(store, _dependency);
|
||||||
auto dependencyPath = toStorePath(store, Realise::Derivation, dependency);
|
auto dependencyPath = toStorePath(store, Realise::Derivation, operateOn, dependency);
|
||||||
auto dependencyPathHash = dependencyPath.hashPart();
|
auto dependencyPathHash = dependencyPath.hashPart();
|
||||||
|
|
||||||
StorePathSet closure;
|
StorePathSet closure;
|
||||||
|
|
Loading…
Reference in a new issue