2021-03-02 05:50:41 +02:00
|
|
|
#include "path-with-outputs.hh"
|
2021-03-02 02:47:00 +02:00
|
|
|
#include "store-api.hh"
|
|
|
|
|
2022-04-22 16:17:01 +03:00
|
|
|
#include <regex>
|
|
|
|
|
2021-03-02 02:47:00 +02:00
|
|
|
namespace nix {
|
|
|
|
|
2022-03-18 17:35:45 +02:00
|
|
|
std::string StorePathWithOutputs::to_string(const StoreDirConfig & store) const
|
2021-03-02 02:47:00 +02:00
|
|
|
{
|
|
|
|
return outputs.empty()
|
|
|
|
? store.printStorePath(path)
|
2024-07-12 23:09:27 +03:00
|
|
|
: store.printStorePath(path) + "!" + dropEmptyInitThenConcatStringsSep(",", outputs);
|
2021-03-02 02:47:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-04-05 16:48:18 +03:00
|
|
|
DerivedPath StorePathWithOutputs::toDerivedPath() const
|
2021-03-02 05:50:41 +02:00
|
|
|
{
|
2023-01-12 01:57:18 +02:00
|
|
|
if (!outputs.empty()) {
|
Make the Derived Path family of types inductive for dynamic derivations
We want to be able to write down `foo.drv^bar.drv^baz`:
`foo.drv^bar.drv` is the dynamic derivation (since it is itself a
derivation output, `bar.drv` from `foo.drv`).
To that end, we create `Single{Derivation,BuiltPath}` types, that are
very similar except instead of having multiple outputs (in a set or
map), they have a single one. This is for everything to the left of the
rightmost `^`.
`NixStringContextElem` has an analogous change, and now can reuse
`SingleDerivedPath` at the top level. In fact, if we ever get rid of
`DrvDeep`, `NixStringContextElem` could be replaced with
`SingleDerivedPath` entirely!
Important note: some JSON formats have changed.
We already can *produce* dynamic derivations, but we can't refer to them
directly. Today, we can merely express building or example at the top
imperatively over time by building `foo.drv^bar.drv`, and then with a
second nix invocation doing `<result-from-first>^baz`, but this is not
declarative. The ethos of Nix of being able to write down the full plan
everything you want to do, and then execute than plan with a single
command, and for that we need the new inductive form of these types.
Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
2023-01-16 00:39:04 +02:00
|
|
|
return DerivedPath::Built {
|
|
|
|
.drvPath = makeConstantStorePathRef(path),
|
|
|
|
.outputs = OutputsSpec::Names { outputs },
|
|
|
|
};
|
2023-01-12 01:57:18 +02:00
|
|
|
} else if (path.isDerivation()) {
|
|
|
|
assert(outputs.empty());
|
Make the Derived Path family of types inductive for dynamic derivations
We want to be able to write down `foo.drv^bar.drv^baz`:
`foo.drv^bar.drv` is the dynamic derivation (since it is itself a
derivation output, `bar.drv` from `foo.drv`).
To that end, we create `Single{Derivation,BuiltPath}` types, that are
very similar except instead of having multiple outputs (in a set or
map), they have a single one. This is for everything to the left of the
rightmost `^`.
`NixStringContextElem` has an analogous change, and now can reuse
`SingleDerivedPath` at the top level. In fact, if we ever get rid of
`DrvDeep`, `NixStringContextElem` could be replaced with
`SingleDerivedPath` entirely!
Important note: some JSON formats have changed.
We already can *produce* dynamic derivations, but we can't refer to them
directly. Today, we can merely express building or example at the top
imperatively over time by building `foo.drv^bar.drv`, and then with a
second nix invocation doing `<result-from-first>^baz`, but this is not
declarative. The ethos of Nix of being able to write down the full plan
everything you want to do, and then execute than plan with a single
command, and for that we need the new inductive form of these types.
Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
2023-01-16 00:39:04 +02:00
|
|
|
return DerivedPath::Built {
|
|
|
|
.drvPath = makeConstantStorePathRef(path),
|
|
|
|
.outputs = OutputsSpec::All { },
|
|
|
|
};
|
2023-01-12 01:57:18 +02:00
|
|
|
} else {
|
2021-04-05 16:48:18 +03:00
|
|
|
return DerivedPath::Opaque { path };
|
2023-01-12 01:57:18 +02:00
|
|
|
}
|
2021-03-02 05:50:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-04-05 16:48:18 +03:00
|
|
|
std::vector<DerivedPath> toDerivedPaths(const std::vector<StorePathWithOutputs> ss)
|
2021-03-02 05:50:41 +02:00
|
|
|
{
|
2022-03-01 20:31:36 +02:00
|
|
|
std::vector<DerivedPath> reqs;
|
|
|
|
for (auto & s : ss) reqs.push_back(s.toDerivedPath());
|
|
|
|
return reqs;
|
2021-03-02 05:50:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
Make the Derived Path family of types inductive for dynamic derivations
We want to be able to write down `foo.drv^bar.drv^baz`:
`foo.drv^bar.drv` is the dynamic derivation (since it is itself a
derivation output, `bar.drv` from `foo.drv`).
To that end, we create `Single{Derivation,BuiltPath}` types, that are
very similar except instead of having multiple outputs (in a set or
map), they have a single one. This is for everything to the left of the
rightmost `^`.
`NixStringContextElem` has an analogous change, and now can reuse
`SingleDerivedPath` at the top level. In fact, if we ever get rid of
`DrvDeep`, `NixStringContextElem` could be replaced with
`SingleDerivedPath` entirely!
Important note: some JSON formats have changed.
We already can *produce* dynamic derivations, but we can't refer to them
directly. Today, we can merely express building or example at the top
imperatively over time by building `foo.drv^bar.drv`, and then with a
second nix invocation doing `<result-from-first>^baz`, but this is not
declarative. The ethos of Nix of being able to write down the full plan
everything you want to do, and then execute than plan with a single
command, and for that we need the new inductive form of these types.
Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
2023-01-16 00:39:04 +02:00
|
|
|
StorePathWithOutputs::ParseResult StorePathWithOutputs::tryFromDerivedPath(const DerivedPath & p)
|
2021-03-02 05:50:41 +02:00
|
|
|
{
|
|
|
|
return std::visit(overloaded {
|
Make the Derived Path family of types inductive for dynamic derivations
We want to be able to write down `foo.drv^bar.drv^baz`:
`foo.drv^bar.drv` is the dynamic derivation (since it is itself a
derivation output, `bar.drv` from `foo.drv`).
To that end, we create `Single{Derivation,BuiltPath}` types, that are
very similar except instead of having multiple outputs (in a set or
map), they have a single one. This is for everything to the left of the
rightmost `^`.
`NixStringContextElem` has an analogous change, and now can reuse
`SingleDerivedPath` at the top level. In fact, if we ever get rid of
`DrvDeep`, `NixStringContextElem` could be replaced with
`SingleDerivedPath` entirely!
Important note: some JSON formats have changed.
We already can *produce* dynamic derivations, but we can't refer to them
directly. Today, we can merely express building or example at the top
imperatively over time by building `foo.drv^bar.drv`, and then with a
second nix invocation doing `<result-from-first>^baz`, but this is not
declarative. The ethos of Nix of being able to write down the full plan
everything you want to do, and then execute than plan with a single
command, and for that we need the new inductive form of these types.
Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
2023-01-16 00:39:04 +02:00
|
|
|
[&](const DerivedPath::Opaque & bo) -> StorePathWithOutputs::ParseResult {
|
2021-03-02 05:50:41 +02:00
|
|
|
if (bo.path.isDerivation()) {
|
|
|
|
// drv path gets interpreted as "build", not "get drv file itself"
|
|
|
|
return bo.path;
|
|
|
|
}
|
|
|
|
return StorePathWithOutputs { bo.path };
|
|
|
|
},
|
Make the Derived Path family of types inductive for dynamic derivations
We want to be able to write down `foo.drv^bar.drv^baz`:
`foo.drv^bar.drv` is the dynamic derivation (since it is itself a
derivation output, `bar.drv` from `foo.drv`).
To that end, we create `Single{Derivation,BuiltPath}` types, that are
very similar except instead of having multiple outputs (in a set or
map), they have a single one. This is for everything to the left of the
rightmost `^`.
`NixStringContextElem` has an analogous change, and now can reuse
`SingleDerivedPath` at the top level. In fact, if we ever get rid of
`DrvDeep`, `NixStringContextElem` could be replaced with
`SingleDerivedPath` entirely!
Important note: some JSON formats have changed.
We already can *produce* dynamic derivations, but we can't refer to them
directly. Today, we can merely express building or example at the top
imperatively over time by building `foo.drv^bar.drv`, and then with a
second nix invocation doing `<result-from-first>^baz`, but this is not
declarative. The ethos of Nix of being able to write down the full plan
everything you want to do, and then execute than plan with a single
command, and for that we need the new inductive form of these types.
Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
2023-01-16 00:39:04 +02:00
|
|
|
[&](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);
|
|
|
|
},
|
2023-08-16 19:29:23 +03:00
|
|
|
}, bfd.outputs.raw),
|
Make the Derived Path family of types inductive for dynamic derivations
We want to be able to write down `foo.drv^bar.drv^baz`:
`foo.drv^bar.drv` is the dynamic derivation (since it is itself a
derivation output, `bar.drv` from `foo.drv`).
To that end, we create `Single{Derivation,BuiltPath}` types, that are
very similar except instead of having multiple outputs (in a set or
map), they have a single one. This is for everything to the left of the
rightmost `^`.
`NixStringContextElem` has an analogous change, and now can reuse
`SingleDerivedPath` at the top level. In fact, if we ever get rid of
`DrvDeep`, `NixStringContextElem` could be replaced with
`SingleDerivedPath` entirely!
Important note: some JSON formats have changed.
We already can *produce* dynamic derivations, but we can't refer to them
directly. Today, we can merely express building or example at the top
imperatively over time by building `foo.drv^bar.drv`, and then with a
second nix invocation doing `<result-from-first>^baz`, but this is not
declarative. The ethos of Nix of being able to write down the full plan
everything you want to do, and then execute than plan with a single
command, and for that we need the new inductive form of these types.
Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
2023-01-16 00:39:04 +02:00
|
|
|
};
|
|
|
|
},
|
|
|
|
[&](const SingleDerivedPath::Built &) -> StorePathWithOutputs::ParseResult {
|
|
|
|
return std::monostate {};
|
|
|
|
},
|
|
|
|
}, bfd.drvPath->raw());
|
2021-03-02 05:50:41 +02:00
|
|
|
},
|
2021-04-05 16:24:42 +03:00
|
|
|
}, p.raw());
|
2021-03-02 05:50:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-03-02 02:47:00 +02:00
|
|
|
std::pair<std::string_view, StringSet> parsePathWithOutputs(std::string_view s)
|
|
|
|
{
|
|
|
|
size_t n = s.find("!");
|
|
|
|
return n == s.npos
|
2022-02-25 17:00:00 +02:00
|
|
|
? std::make_pair(s, std::set<std::string>())
|
2023-01-12 14:23:32 +02:00
|
|
|
: std::make_pair(s.substr(0, n),
|
|
|
|
tokenizeString<std::set<std::string>>(s.substr(n + 1), ","));
|
2021-03-02 02:47:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-03-18 17:35:45 +02:00
|
|
|
StorePathWithOutputs parsePathWithOutputs(const StoreDirConfig & store, std::string_view pathWithOutputs)
|
2021-03-02 02:47:00 +02:00
|
|
|
{
|
2021-03-02 03:06:08 +02:00
|
|
|
auto [path, outputs] = parsePathWithOutputs(pathWithOutputs);
|
|
|
|
return StorePathWithOutputs { store.parseStorePath(path), std::move(outputs) };
|
2021-03-02 02:47:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-03-02 03:06:08 +02:00
|
|
|
StorePathWithOutputs followLinksToStorePathWithOutputs(const Store & store, std::string_view pathWithOutputs)
|
2021-03-02 02:47:00 +02:00
|
|
|
{
|
2021-03-02 03:06:08 +02:00
|
|
|
auto [path, outputs] = parsePathWithOutputs(pathWithOutputs);
|
|
|
|
return StorePathWithOutputs { store.followLinksToStorePath(path), std::move(outputs) };
|
2021-03-02 02:47:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|