Skip to content

Commit

Permalink
Fixing NixOS#7479: OutputsSpec and ExtendedOutputsSpec
Browse files Browse the repository at this point in the history
See that issue for details.
  • Loading branch information
Ericson2314 committed Aug 16, 2023
1 parent 40aeff8 commit 989d7fe
Show file tree
Hide file tree
Showing 15 changed files with 86 additions and 81 deletions.
9 changes: 5 additions & 4 deletions src/libcmd/installable-attr-path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths()
[&](const ExtendedOutputsSpec::Explicit & e) -> OutputsSpec {
return e;
},
}, extendedOutputsSpec.raw());
}, extendedOutputsSpec.raw);

auto [iter, didInsert] = byDrvPath.emplace(*drvPath, newOutputs);
auto [iter, didInsert] = byDrvPath.emplace(*drvPath, newOutputs.raw);

if (!didInsert)
iter->second = iter->second.union_(newOutputs);
Expand All @@ -93,9 +93,10 @@ DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths()
res.push_back({
.path = DerivedPath::Built {
.drvPath = makeConstantStorePathRef(drvPath),
.outputs = outputs,
.outputs = outputs.raw,
},
.info = make_ref<ExtraPathInfoValue>(ExtraPathInfoValue::Value {
.extendedOutputsSpec = outputs.raw,
/* FIXME: reconsider backwards compatibility above
so we can fill in this info. */
}),
Expand All @@ -114,7 +115,7 @@ InstallableAttrPath InstallableAttrPath::parse(
return {
state, cmd, v,
prefix == "." ? "" : std::string { prefix },
extendedOutputsSpec
std::move(extendedOutputsSpec),
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/libcmd/installable-derived-path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ InstallableDerivedPath InstallableDerivedPath::parse(
.outputs = outputSpec,
};
},
}, extendedOutputsSpec.raw());
}, extendedOutputsSpec.raw);
return InstallableDerivedPath {
store,
std::move(derivedPath),
Expand Down
4 changes: 2 additions & 2 deletions src/libcmd/installable-flake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,13 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
[&](const ExtendedOutputsSpec::Explicit & e) -> OutputsSpec {
return e;
},
}, extendedOutputsSpec.raw()),
}, extendedOutputsSpec.raw),
},
.info = make_ref<ExtraPathInfoFlake>(
ExtraPathInfoValue::Value {
.priority = priority,
.attrPath = attrPath,
.extendedOutputsSpec = extendedOutputsSpec,
.extendedOutputsSpec = extendedOutputsSpec.raw,
},
ExtraPathInfoFlake::Flake {
.originalRef = flakeRef,
Expand Down
6 changes: 3 additions & 3 deletions src/libcmd/installables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ Installables SourceExprCommand::parseInstallables(
result.push_back(
make_ref<InstallableAttrPath>(
InstallableAttrPath::parse(
state, *this, vFile, prefix, extendedOutputsSpec)));
state, *this, vFile, std::move(prefix), std::move(extendedOutputsSpec))));
}

} else {
Expand All @@ -475,7 +475,7 @@ Installables SourceExprCommand::parseInstallables(
if (prefix.find('/') != std::string::npos) {
try {
result.push_back(make_ref<InstallableDerivedPath>(
InstallableDerivedPath::parse(store, prefix, extendedOutputsSpec)));
InstallableDerivedPath::parse(store, prefix, extendedOutputsSpec.raw)));
continue;
} catch (BadStorePath &) {
} catch (...) {
Expand All @@ -491,7 +491,7 @@ Installables SourceExprCommand::parseInstallables(
getEvalState(),
std::move(flakeRef),
fragment,
extendedOutputsSpec,
std::move(extendedOutputsSpec),
getDefaultFlakeAttrPaths(),
getDefaultFlakeAttrPathPrefixes(),
lockFlags));
Expand Down
2 changes: 1 addition & 1 deletion src/libexpr/flake/flakeref.cc
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ std::tuple<FlakeRef, std::string, ExtendedOutputsSpec> parseFlakeRefWithFragment
{
auto [prefix, extendedOutputsSpec] = ExtendedOutputsSpec::parse(url);
auto [flakeRef, fragment] = parseFlakeRefWithFragment(std::string { prefix }, baseDir, allowMissing, isFlake);
return {std::move(flakeRef), fragment, extendedOutputsSpec};
return {std::move(flakeRef), fragment, std::move(extendedOutputsSpec)};
}

}
2 changes: 1 addition & 1 deletion src/libstore/build/derivation-goal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1358,7 +1358,7 @@ std::pair<bool, SingleDrvOutputs> DerivationGoal::checkPathValidity()
[&](const OutputsSpec::Names & names) {
return static_cast<StringSet>(names);
},
}, wantedOutputs.raw());
}, wantedOutputs.raw);
SingleDrvOutputs validOutputs;

for (auto & i : queryPartialDerivationOutputMap()) {
Expand Down
5 changes: 4 additions & 1 deletion src/libstore/build/worker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,10 @@ void Worker::run(const Goals & _topGoals)
for (auto & i : _topGoals) {
topGoals.insert(i);
if (auto goal = dynamic_cast<DerivationGoal *>(i.get())) {
topPaths.push_back(DerivedPath::Built{makeConstantStorePathRef(goal->drvPath), goal->wantedOutputs});
topPaths.push_back(DerivedPath::Built {
.drvPath = makeConstantStorePathRef(goal->drvPath),
.outputs = goal->wantedOutputs.raw,
});
} else if (auto goal = dynamic_cast<PathSubstitutionGoal *>(i.get())) {
topPaths.push_back(DerivedPath::Opaque{goal->storePath});
}
Expand Down
6 changes: 3 additions & 3 deletions src/libstore/misc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ OutputPathMap resolveDerivedPath(Store & store, const DerivedPath::Built & bfd,
}
return outputsOpt;
},
}, bfd.outputs.raw());
}, bfd.outputs.raw);

OutputPathMap outputs;
for (auto & [outputName, outputPathOpt] : outputsOpt) {
Expand Down Expand Up @@ -418,7 +418,7 @@ OutputPathMap resolveDerivedPath(Store & store, const DerivedPath::Built & bfd)
[&](const OutputsSpec::Names & names) {
return static_cast<StringSet>(names);
},
}, bfd.outputs.raw());
}, bfd.outputs.raw);
for (auto iter = outputMap.begin(); iter != outputMap.end();) {
auto & outputName = iter->first;
if (bfd.outputs.contains(outputName)) {
Expand All @@ -431,7 +431,7 @@ OutputPathMap resolveDerivedPath(Store & store, const DerivedPath::Built & bfd)
if (!outputsLeft.empty())
throw Error("derivation '%s' does not have an outputs %s",
store.printStorePath(drvPath),
concatStringsSep(", ", quoteStrings(std::get<OutputsSpec::Names>(bfd.outputs))));
concatStringsSep(", ", quoteStrings(std::get<OutputsSpec::Names>(bfd.outputs.raw))));
return outputMap;
}

Expand Down
20 changes: 10 additions & 10 deletions src/libstore/outputs-spec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ bool OutputsSpec::contains(const std::string & outputName) const
[&](const OutputsSpec::Names & outputNames) {
return outputNames.count(outputName) > 0;
},
}, raw());
}, raw);
}

static std::string outputSpecRegexStr =
Expand Down Expand Up @@ -49,7 +49,7 @@ OutputsSpec OutputsSpec::parse(std::string_view s)
std::optional spec = parseOpt(s);
if (!spec)
throw Error("invalid outputs specifier '%s'", s);
return *spec;
return std::move(*spec);
}


Expand Down Expand Up @@ -85,7 +85,7 @@ std::string OutputsSpec::to_string() const
[&](const OutputsSpec::Names & outputNames) -> std::string {
return concatStringsSep(",", outputNames);
},
}, raw());
}, raw);
}


Expand All @@ -98,7 +98,7 @@ std::string ExtendedOutputsSpec::to_string() const
[&](const ExtendedOutputsSpec::Explicit & outputSpec) -> std::string {
return "^" + outputSpec.to_string();
},
}, raw());
}, raw);
}


Expand All @@ -118,9 +118,9 @@ OutputsSpec OutputsSpec::union_(const OutputsSpec & that) const
ret.insert(thoseNames.begin(), thoseNames.end());
return ret;
},
}, that.raw());
}, that.raw);
},
}, raw());
}, raw);
}


Expand All @@ -142,9 +142,9 @@ bool OutputsSpec::isSubsetOf(const OutputsSpec & that) const
ret = false;
return ret;
},
}, raw());
}, raw);
},
}, that.raw());
}, that.raw);
}

}
Expand All @@ -169,7 +169,7 @@ void adl_serializer<OutputsSpec>::to_json(json & json, OutputsSpec t) {
[&](const OutputsSpec::Names & names) {
json = names;
},
}, t.raw());
}, t.raw);
}


Expand All @@ -189,7 +189,7 @@ void adl_serializer<ExtendedOutputsSpec>::to_json(json & json, ExtendedOutputsSp
[&](const ExtendedOutputsSpec::Explicit & e) {
adl_serializer<OutputsSpec>::to_json(json, e);
},
}, t.raw());
}, t.raw);
}

}
97 changes: 49 additions & 48 deletions src/libstore/outputs-spec.hh
Original file line number Diff line number Diff line change
Expand Up @@ -6,62 +6,58 @@
#include <set>
#include <variant>

#include "comparator.hh"
#include "json-impls.hh"

namespace nix {

/**
* A non-empty set of outputs, specified by name
*/
struct OutputNames : std::set<std::string> {
using std::set<std::string>::set;
struct OutputsSpec {
/**
* A non-empty set of outputs, specified by name
*/
struct Names : std::set<std::string> {
using std::set<std::string>::set;

/* These need to be "inherited manually" */

Names(const std::set<std::string> & s)
: std::set<std::string>(s)
{ assert(!empty()); }

/* These need to be "inherited manually" */
/**
* Needs to be "inherited manually"
*/
Names(std::set<std::string> && s)
: std::set<std::string>(s)
{ assert(!empty()); }

OutputNames(const std::set<std::string> & s)
: std::set<std::string>(s)
{ assert(!empty()); }
/* This set should always be non-empty, so we delete this
constructor in order make creating empty ones by mistake harder.
*/
Names() = delete;
};

/**
* Needs to be "inherited manually"
* The set of all outputs, without needing to name them explicitly
*/
OutputNames(std::set<std::string> && s)
: std::set<std::string>(s)
{ assert(!empty()); }

/* This set should always be non-empty, so we delete this
constructor in order make creating empty ones by mistake harder.
*/
OutputNames() = delete;
};
struct All : std::monostate { };

typedef std::variant<All, Names> Raw;

/**
* The set of all outputs, without needing to name them explicitly
*/
struct AllOutputs : std::monostate { };
Raw raw;

typedef std::variant<AllOutputs, OutputNames> _OutputsSpecRaw;
GENERATE_CMP(OutputsSpec, me->raw);

struct OutputsSpec : _OutputsSpecRaw {
using Raw = _OutputsSpecRaw;
using Raw::Raw;
/* The moral equivalent of `using Raw::Raw;` */
OutputsSpec(auto &&... arg)
: raw(std::forward<decltype(arg)>(arg)...)
{ }

/**
* Force choosing a variant
*/
OutputsSpec() = delete;

using Names = OutputNames;
using All = AllOutputs;

inline const Raw & raw() const {
return static_cast<const Raw &>(*this);
}

inline Raw & raw() {
return static_cast<Raw &>(*this);
}

bool contains(const std::string & output) const;

/**
Expand All @@ -84,20 +80,25 @@ struct OutputsSpec : _OutputsSpecRaw {
std::string to_string() const;
};

struct DefaultOutputs : std::monostate { };
struct ExtendedOutputsSpec {
struct Default : std::monostate { };
using Explicit = OutputsSpec;

typedef std::variant<Default, Explicit> Raw;

typedef std::variant<DefaultOutputs, OutputsSpec> _ExtendedOutputsSpecRaw;
Raw raw;

struct ExtendedOutputsSpec : _ExtendedOutputsSpecRaw {
using Raw = _ExtendedOutputsSpecRaw;
using Raw::Raw;
GENERATE_CMP(ExtendedOutputsSpec, me->raw);

using Default = DefaultOutputs;
using Explicit = OutputsSpec;
/* The moral equivalent of `using Raw::Raw;` */
ExtendedOutputsSpec(auto &&... arg)
: raw(std::forward<decltype(arg)>(arg)...)
{ }

inline const Raw & raw() const {
return static_cast<const Raw &>(*this);
}
/**
* Force choosing a variant
*/
ExtendedOutputsSpec() = delete;

/**
* Parse a string of the form 'prefix^output1,...outputN' or
Expand Down
2 changes: 1 addition & 1 deletion src/libstore/path-with-outputs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ StorePathWithOutputs::ParseResult StorePathWithOutputs::tryFromDerivedPath(const
[&](const OutputsSpec::Names & outputs) {
return static_cast<StringSet>(outputs);
},
}, bfd.outputs.raw()),
}, bfd.outputs.raw),
};
},
[&](const SingleDerivedPath::Built &) -> StorePathWithOutputs::ParseResult {
Expand Down
2 changes: 1 addition & 1 deletion src/nix/bundle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ struct CmdBundle : InstallableValueCommand
auto [bundlerFlakeRef, bundlerName, extendedOutputsSpec] = parseFlakeRefWithFragmentAndExtendedOutputsSpec(bundler, absPath("."));
const flake::LockFlags lockFlags{ .writeLockFile = false };
InstallableFlake bundler{this,
evalState, std::move(bundlerFlakeRef), bundlerName, extendedOutputsSpec,
evalState, std::move(bundlerFlakeRef), bundlerName, std::move(extendedOutputsSpec),
{"bundlers." + settings.thisSystem.get() + ".default",
"defaultBundler." + settings.thisSystem.get()
},
Expand Down
2 changes: 1 addition & 1 deletion src/nix/develop.cc
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ struct CmdDevelop : Common, MixEnvironment
state,
std::move(nixpkgs),
"bashInteractive",
DefaultOutputs(),
ExtendedOutputsSpec::Default(),
Strings{},
Strings{"legacyPackages." + settings.thisSystem.get() + "."},
nixpkgsLockFlags);
Expand Down
2 changes: 1 addition & 1 deletion src/nix/flake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
auto [templateFlakeRef, templateName] = parseFlakeRefWithFragment(templateUrl, absPath("."));

auto installable = InstallableFlake(nullptr,
evalState, std::move(templateFlakeRef), templateName, DefaultOutputs(),
evalState, std::move(templateFlakeRef), templateName, ExtendedOutputsSpec::Default(),
defaultTemplateAttrPaths,
defaultTemplateAttrPathsPrefixes,
lockFlags);
Expand Down
Loading

0 comments on commit 989d7fe

Please sign in to comment.