#include "path-with-outputs.hh" #include "store-api.hh" #include namespace nix { std::string StorePathWithOutputs::to_string(const Store & 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 toDerivedPaths(const std::vector ss) { std::vector reqs; 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(outputs); }, }, bfd.outputs.raw), }; }, [&](const SingleDerivedPath::Built &) -> StorePathWithOutputs::ParseResult { return std::monostate {}; }, }, bfd.drvPath->raw()); }, }, p.raw()); } std::pair parsePathWithOutputs(std::string_view s) { size_t n = s.find("!"); return n == s.npos ? std::make_pair(s, std::set()) : std::make_pair(s.substr(0, n), tokenizeString>(s.substr(n + 1), ",")); } StorePathWithOutputs parsePathWithOutputs(const Store & 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) }; } }