mirror of
https://github.com/NixOS/nix.git
synced 2025-11-09 20:16:03 +01:00
This does not yet resolve the coupling between packages and
derivations, but it makes the code more consistent with the
terminology, and it accentuates places where the coupling is
obvious, such as
auto drvPath = packageInfo.queryDrvPath();
if (!drvPath)
throw Error("'%s' is not a derivation", what());
... which isn't wrong, and in my opinion, doesn't even look
wrong, because it just reflects the current logic.
However, I do like that we can now start to see in the code that
this coupling is perhaps a bit arbitrary.
After this rename, we can bring the DerivingPath concept into type
and start to lift this limitation.
122 lines
3.4 KiB
C++
122 lines
3.4 KiB
C++
#include "globals.hh"
|
|
#include "installable-attr-path.hh"
|
|
#include "outputs-spec.hh"
|
|
#include "util.hh"
|
|
#include "command.hh"
|
|
#include "attr-path.hh"
|
|
#include "common-eval-args.hh"
|
|
#include "derivations.hh"
|
|
#include "eval-inline.hh"
|
|
#include "eval.hh"
|
|
#include "get-drvs.hh"
|
|
#include "store-api.hh"
|
|
#include "shared.hh"
|
|
#include "flake/flake.hh"
|
|
#include "eval-cache.hh"
|
|
#include "url.hh"
|
|
#include "registry.hh"
|
|
#include "build-result.hh"
|
|
|
|
#include <regex>
|
|
#include <queue>
|
|
|
|
#include <nlohmann/json.hpp>
|
|
|
|
namespace nix {
|
|
|
|
InstallableAttrPath::InstallableAttrPath(
|
|
ref<EvalState> state,
|
|
SourceExprCommand & cmd,
|
|
Value * v,
|
|
const std::string & attrPath,
|
|
ExtendedOutputsSpec extendedOutputsSpec)
|
|
: InstallableValue(state)
|
|
, cmd(cmd)
|
|
, v(allocRootValue(v))
|
|
, attrPath(attrPath)
|
|
, extendedOutputsSpec(std::move(extendedOutputsSpec))
|
|
{ }
|
|
|
|
std::pair<Value *, PosIdx> InstallableAttrPath::toValue(EvalState & state)
|
|
{
|
|
auto [vRes, pos] = findAlongAttrPath(state, attrPath, *cmd.getAutoArgs(state), **v);
|
|
state.forceValue(*vRes, pos);
|
|
return {vRes, pos};
|
|
}
|
|
|
|
DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths()
|
|
{
|
|
auto [v, pos] = toValue(*state);
|
|
|
|
if (std::optional derivedPathWithInfo = trySinglePathToDerivedPaths(
|
|
*v,
|
|
pos,
|
|
fmt("while evaluating the attribute '%s'", attrPath)))
|
|
{
|
|
return { *derivedPathWithInfo };
|
|
}
|
|
|
|
Bindings & autoArgs = *cmd.getAutoArgs(*state);
|
|
|
|
PackageInfos packageInfos;
|
|
getDerivations(*state, *v, "", autoArgs, packageInfos, false);
|
|
|
|
// Backward compatibility hack: group results by drvPath. This
|
|
// helps keep .all output together.
|
|
std::map<StorePath, OutputsSpec> byDrvPath;
|
|
|
|
for (auto & packageInfo : packageInfos) {
|
|
auto drvPath = packageInfo.queryDrvPath();
|
|
if (!drvPath)
|
|
throw Error("'%s' is not a derivation", what());
|
|
|
|
auto newOutputs = std::visit(overloaded {
|
|
[&](const ExtendedOutputsSpec::Default & d) -> OutputsSpec {
|
|
std::set<std::string> outputsToInstall;
|
|
for (auto & output : packageInfo.queryOutputs(false, true))
|
|
outputsToInstall.insert(output.first);
|
|
return OutputsSpec::Names { std::move(outputsToInstall) };
|
|
},
|
|
[&](const ExtendedOutputsSpec::Explicit & e) -> OutputsSpec {
|
|
return e;
|
|
},
|
|
}, extendedOutputsSpec.raw);
|
|
|
|
auto [iter, didInsert] = byDrvPath.emplace(*drvPath, newOutputs);
|
|
|
|
if (!didInsert)
|
|
iter->second = iter->second.union_(newOutputs);
|
|
}
|
|
|
|
DerivedPathsWithInfo res;
|
|
for (auto & [drvPath, outputs] : byDrvPath)
|
|
res.push_back({
|
|
.path = DerivedPath::Built {
|
|
.drvPath = makeConstantStorePathRef(drvPath),
|
|
.outputs = outputs,
|
|
},
|
|
.info = make_ref<ExtraPathInfoValue>(ExtraPathInfoValue::Value {
|
|
.extendedOutputsSpec = outputs,
|
|
/* FIXME: reconsider backwards compatibility above
|
|
so we can fill in this info. */
|
|
}),
|
|
});
|
|
|
|
return res;
|
|
}
|
|
|
|
InstallableAttrPath InstallableAttrPath::parse(
|
|
ref<EvalState> state,
|
|
SourceExprCommand & cmd,
|
|
Value * v,
|
|
std::string_view prefix,
|
|
ExtendedOutputsSpec extendedOutputsSpec)
|
|
{
|
|
return {
|
|
state, cmd, v,
|
|
prefix == "." ? "" : std::string { prefix },
|
|
std::move(extendedOutputsSpec),
|
|
};
|
|
}
|
|
|
|
}
|