aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/derived-path.hh
blob: 903cf1a9e6f936f73fbbc8900d08fd8f8579f080 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#pragma once

#include "util.hh"
#include "path.hh"

#include <optional>
#include <variant>

#include <nlohmann/json_fwd.hpp>

namespace nix {

class Store;

/**
 * An opaque derived path.
 *
 * Opaque derived paths are just store paths, and fully evaluated. They
 * cannot be simplified further. Since they are opaque, they cannot be
 * built, but they can fetched.
 */
struct DerivedPathOpaque {
    StorePath path;

    nlohmann::json toJSON(ref<Store> store) const;
    std::string to_string(const Store & store) const;
    static DerivedPathOpaque parse(const Store & store, std::string_view);
};

/**
 * A derived path that is built from a derivation
 *
 * Built derived paths are pair of a derivation and some output names.
 * They are evaluated by building the derivation, and then replacing the
 * output names with the resulting outputs.
 *
 * Note that does mean a derived store paths evaluates to multiple
 * opaque paths, which is sort of icky as expressions are supposed to
 * evaluate to single values. Perhaps this should have just a single
 * output name.
 */
struct DerivedPathBuilt {
    StorePath drvPath;
    std::set<std::string> outputs;

    std::string to_string(const Store & store) const;
    static DerivedPathBuilt parse(const Store & store, std::string_view);
};

using _DerivedPathRaw = std::variant<
    DerivedPathOpaque,
    DerivedPathBuilt
>;

/**
 * A "derived path" is a very simple sort of expression that evaluates
 * to (concrete) store path. It is either:
 *
 * - opaque, in which case it is just a concrete store path with
 *   possibly no known derivation
 *
 * - built, in which case it is a pair of a derivation path and an
 *   output name.
 */
struct DerivedPath : _DerivedPathRaw {
    using Raw = _DerivedPathRaw;
    using Raw::Raw;

    using Opaque = DerivedPathOpaque;
    using Built = DerivedPathBuilt;

    inline const Raw & raw() const {
        return static_cast<const Raw &>(*this);
    }

    std::string to_string(const Store & store) const;
    static DerivedPath parse(const Store & store, std::string_view);
};

/**
 * A built derived path with hints in the form of optional concrete output paths.
 *
 * See 'DerivedPathWithHints' for more an explanation.
 */
struct DerivedPathWithHintsBuilt {
    StorePath drvPath;
    std::map<std::string, std::optional<StorePath>> outputs;

    nlohmann::json toJSON(ref<Store> store) const;
    static DerivedPathWithHintsBuilt parse(const Store & store, std::string_view);
};

using _DerivedPathWithHintsRaw = std::variant<
    DerivedPath::Opaque,
    DerivedPathWithHintsBuilt
>;

/**
 * A derived path with hints in the form of optional concrete output paths in the built case.
 *
 * This type is currently just used by the CLI. The paths are filled in
 * during evaluation for derivations that know what paths they will
 * produce in advanced, i.e. input-addressed or fixed-output content
 * addressed derivations.
 *
 * That isn't very good, because it puts floating content-addressed
 * derivations "at a disadvantage". It would be better to never rely on
 * the output path of unbuilt derivations, and exclusively use the
 * realizations types to work with built derivations' concrete output
 * paths.
 */
// FIXME Stop using and delete this, or if that is not possible move out of libstore to libcmd.
struct DerivedPathWithHints : _DerivedPathWithHintsRaw {
    using Raw = _DerivedPathWithHintsRaw;
    using Raw::Raw;

    using Opaque = DerivedPathOpaque;
    using Built = DerivedPathWithHintsBuilt;

    inline const Raw & raw() const {
        return static_cast<const Raw &>(*this);
    }

};

typedef std::vector<DerivedPathWithHints> DerivedPathsWithHints;

nlohmann::json derivedPathsWithHintsToJSON(const DerivedPathsWithHints & buildables, ref<Store> store);

}