#include "path-with-outputs.hh" #include "store-api.hh" #include "nlohmann/json.hpp" #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() || path.isDerivation()) return DerivedPath::Built { path, outputs }; 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; } std::variant StorePathWithOutputs::tryFromDerivedPath(const DerivedPath & p) { return std::visit(overloaded { [&](const DerivedPath::Opaque & bo) -> std::variant { 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) -> std::variant { return StorePathWithOutputs { bfd.drvPath, bfd.outputs }; }, }, 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(((std::string_view) s).substr(0, n), tokenizeString>(((std::string_view) 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) }; } std::pair parseOutputsSpec(const std::string & s) { static std::regex regex(R"((.*)\^((\*)|([a-z]+(,[a-z]+)*)))"); std::smatch match; if (!std::regex_match(s, match, regex)) return {s, DefaultOutputs()}; if (match[3].matched) return {match[1], AllOutputs()}; return {match[1], tokenizeString(match[4].str(), ",")}; } std::string printOutputsSpec(const OutputsSpec & outputsSpec) { if (std::get_if(&outputsSpec)) return ""; if (std::get_if(&outputsSpec)) return "^*"; if (auto outputNames = std::get_if(&outputsSpec)) return "^" + concatStringsSep(",", *outputNames); assert(false); } void to_json(nlohmann::json & json, const OutputsSpec & outputsSpec) { if (std::get_if(&outputsSpec)) json = nullptr; else if (std::get_if(&outputsSpec)) json = std::vector({"*"}); else if (auto outputNames = std::get_if(&outputsSpec)) json = *outputNames; } void from_json(const nlohmann::json & json, OutputsSpec & outputsSpec) { if (json.is_null()) outputsSpec = DefaultOutputs(); else { auto names = json.get(); if (names == OutputNames({"*"})) outputsSpec = AllOutputs(); else outputsSpec = names; } } }