1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 14:51:16 +02:00
nix/src/libstore/path-with-outputs.cc
Sergei Zimmerman 0fe3b54ee1 refactor(treewide): reserve vector capacity when final size is known
In these trivial cases the final vector size (or lower bound on the size) is known,
so we can avoid some vector reallocations. This is not very important, but is just
good practice and general hygiene.
2024-11-09 22:40:49 +03:00

104 lines
3.4 KiB
C++

#include <regex>
#include "path-with-outputs.hh"
#include "store-api.hh"
#include "strings.hh"
namespace nix {
std::string StorePathWithOutputs::to_string(const StoreDirConfig & store) const
{
return outputs.empty()
? store.printStorePath(path)
: store.printStorePath(path) + "!" + concatStringsSep(",", outputs);
}
DerivedPath StorePathWithOutputs::toDerivedPath() const
{
if (!outputs.empty()) {
return DerivedPath::Built {
.drvPath = makeConstantStorePathRef(path),
.outputs = OutputsSpec::Names { outputs },
};
} else if (path.isDerivation()) {
assert(outputs.empty());
return DerivedPath::Built {
.drvPath = makeConstantStorePathRef(path),
.outputs = OutputsSpec::All { },
};
} else {
return DerivedPath::Opaque { path };
}
}
std::vector<DerivedPath> toDerivedPaths(const std::vector<StorePathWithOutputs> ss)
{
std::vector<DerivedPath> reqs;
reqs.reserve(ss.size());
for (auto & s : ss) reqs.push_back(s.toDerivedPath());
return reqs;
}
StorePathWithOutputs::ParseResult StorePathWithOutputs::tryFromDerivedPath(const DerivedPath & p)
{
return std::visit(overloaded {
[&](const DerivedPath::Opaque & bo) -> StorePathWithOutputs::ParseResult {
if (bo.path.isDerivation()) {
// drv path gets interpreted as "build", not "get drv file itself"
return bo.path;
}
return StorePathWithOutputs { bo.path };
},
[&](const DerivedPath::Built & bfd) -> StorePathWithOutputs::ParseResult {
return std::visit(overloaded {
[&](const SingleDerivedPath::Opaque & bo) -> StorePathWithOutputs::ParseResult {
return StorePathWithOutputs {
.path = bo.path,
// Use legacy encoding of wildcard as empty set
.outputs = std::visit(overloaded {
[&](const OutputsSpec::All &) -> StringSet {
return {};
},
[&](const OutputsSpec::Names & outputs) {
return static_cast<StringSet>(outputs);
},
}, bfd.outputs.raw),
};
},
[&](const SingleDerivedPath::Built &) -> StorePathWithOutputs::ParseResult {
return std::monostate {};
},
}, bfd.drvPath->raw());
},
}, p.raw());
}
std::pair<std::string_view, StringSet> parsePathWithOutputs(std::string_view s)
{
size_t n = s.find("!");
return n == s.npos
? std::make_pair(s, std::set<std::string>())
: std::make_pair(s.substr(0, n),
tokenizeString<std::set<std::string>>(s.substr(n + 1), ","));
}
StorePathWithOutputs parsePathWithOutputs(const StoreDirConfig & store, std::string_view pathWithOutputs)
{
auto [path, outputs] = parsePathWithOutputs(pathWithOutputs);
return StorePathWithOutputs { store.parseStorePath(path), std::move(outputs) };
}
StorePathWithOutputs followLinksToStorePathWithOutputs(const Store & store, std::string_view pathWithOutputs)
{
auto [path, outputs] = parsePathWithOutputs(pathWithOutputs);
return StorePathWithOutputs { store.followLinksToStorePath(path), std::move(outputs) };
}
}