2023-05-11 22:01:41 +00:00
|
|
|
#pragma once
|
|
|
|
///@file
|
|
|
|
|
|
|
|
#include "hash.hh"
|
|
|
|
#include "path.hh"
|
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-15 22:39:04 +00:00
|
|
|
#include "derived-path.hh"
|
2023-05-11 22:01:41 +00:00
|
|
|
|
|
|
|
namespace nix {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Downstream Placeholders are opaque and almost certainly unique values
|
|
|
|
* used to allow derivations to refer to store objects which are yet to
|
|
|
|
* be built and for we do not yet have store paths for.
|
|
|
|
*
|
|
|
|
* They correspond to `DerivedPaths` that are not `DerivedPath::Opaque`,
|
|
|
|
* except for the cases involving input addressing or fixed outputs
|
|
|
|
* where we do know a store path for the derivation output in advance.
|
|
|
|
*
|
|
|
|
* Unlike `DerivationPath`, however, `DownstreamPlaceholder` is
|
|
|
|
* purposefully opaque and obfuscated. This is so they are hard to
|
|
|
|
* create by accident, and so substituting them (once we know what the
|
|
|
|
* path to store object is) is unlikely to capture other stuff it
|
|
|
|
* shouldn't.
|
|
|
|
*
|
|
|
|
* We use them with `Derivation`: the `render()` method is called to
|
|
|
|
* render an opaque string which can be used in the derivation, and the
|
|
|
|
* resolving logic can substitute those strings for store paths when
|
|
|
|
* resolving `Derivation.inputDrvs` to `BasicDerivation.inputSrcs`.
|
|
|
|
*/
|
|
|
|
class DownstreamPlaceholder
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* `DownstreamPlaceholder` is just a newtype of `Hash`.
|
|
|
|
* This its only field.
|
|
|
|
*/
|
|
|
|
Hash hash;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Newtype constructor
|
|
|
|
*/
|
|
|
|
DownstreamPlaceholder(Hash hash) : hash(hash) { }
|
|
|
|
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* This creates an opaque and almost certainly unique string
|
|
|
|
* deterministically from the placeholder.
|
|
|
|
*/
|
|
|
|
std::string render() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a placeholder for an unknown output of a content-addressed
|
|
|
|
* derivation.
|
|
|
|
*
|
|
|
|
* The derivation itself is known (we have a store path for it), but
|
|
|
|
* the output doesn't yet have a known store path.
|
2023-07-13 03:33:43 +00:00
|
|
|
*
|
|
|
|
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
2023-05-11 22:01:41 +00:00
|
|
|
*/
|
|
|
|
static DownstreamPlaceholder unknownCaOutput(
|
|
|
|
const StorePath & drvPath,
|
2023-08-25 13:53:12 +00:00
|
|
|
OutputNameView outputName,
|
2023-07-13 03:33:43 +00:00
|
|
|
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
2023-05-11 22:01:41 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a placehold for the output of an unknown derivation.
|
|
|
|
*
|
|
|
|
* The derivation is not yet known because it is a dynamic
|
|
|
|
* derivaiton --- it is itself an output of another derivation ---
|
|
|
|
* and we just have (another) placeholder for it.
|
|
|
|
*
|
|
|
|
* @param xpSettings Stop-gap to avoid globals during unit tests.
|
|
|
|
*/
|
|
|
|
static DownstreamPlaceholder unknownDerivation(
|
|
|
|
const DownstreamPlaceholder & drvPlaceholder,
|
2023-08-25 13:53:12 +00:00
|
|
|
OutputNameView outputName,
|
2023-05-11 22:01:41 +00:00
|
|
|
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
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-15 22:39:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Convenience constructor that handles both cases (unknown
|
|
|
|
* content-addressed output and unknown derivation), delegating as
|
|
|
|
* needed to `unknownCaOutput` and `unknownDerivation`.
|
|
|
|
*
|
|
|
|
* Recursively builds up a placeholder from a
|
|
|
|
* `SingleDerivedPath::Built.drvPath` chain.
|
|
|
|
*/
|
|
|
|
static DownstreamPlaceholder fromSingleDerivedPathBuilt(
|
2021-03-10 04:22:56 +00:00
|
|
|
const SingleDerivedPath::Built & built,
|
|
|
|
const ExperimentalFeatureSettings & xpSettings = experimentalFeatureSettings);
|
2023-05-11 22:01:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|