about summary refs log tree commit diff
path: root/third_party/nix/src/libstore/derivations.hh
blob: 4966b858d3b3ccb9c08ed7eb866112f30a8c432b (plain) (blame)
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 <map>

#include <absl/container/btree_map.h>

#include "libproto/worker.pb.h"
#include "libstore/store-api.hh"
#include "libutil/hash.hh"
#include "libutil/types.hh"

namespace nix {

/* Extension of derivations in the Nix store. */
const std::string drvExtension = ".drv";

/* Abstract syntax of derivations. */

struct DerivationOutput {
  Path path;
  // TODO(grfn): make these two fields a Hash
  std::string hashAlgo; /* hash used for expected hash computation */
  std::string hash;     /* expected hash, may be null */
  DerivationOutput() {}
  DerivationOutput(Path path, std::string hashAlgo, std::string hash) {
    this->path = path;
    this->hashAlgo = hashAlgo;
    this->hash = hash;
  }

  explicit DerivationOutput(
      const nix::proto::Derivation_DerivationOutput& proto_derivation_output)
      : path(proto_derivation_output.path().path()),
        hashAlgo(proto_derivation_output.hash_algo()),
        hash(proto_derivation_output.hash()) {}

  void parseHashInfo(bool& recursive, Hash& hash) const;

  [[nodiscard]] nix::proto::Derivation_DerivationOutput to_proto() const;
};

// TODO(tazjin): Determine whether this actually needs to be ordered.
using DerivationOutputs = absl::btree_map<std::string, DerivationOutput>;

/* For inputs that are sub-derivations, we specify exactly which
   output IDs we are interested in. */
using DerivationInputs = absl::btree_map<Path, StringSet>;

using StringPairs = absl::btree_map<std::string, std::string>;

struct BasicDerivation {
  DerivationOutputs outputs; /* keyed on symbolic IDs */
  PathSet inputSrcs;         /* inputs that are sources */
  std::string platform;
  Path builder;
  Strings args;
  StringPairs env;

  BasicDerivation() = default;

  // Convert the given proto derivation to a BasicDerivation
  static BasicDerivation from_proto(
      const nix::proto::Derivation* proto_derivation);

  [[nodiscard]] nix::proto::Derivation to_proto() const;

  virtual ~BasicDerivation(){};

  /* Return the path corresponding to the output identifier `id' in
     the given derivation. */
  Path findOutput(const std::string& id) const;

  bool isBuiltin() const;

  /* Return true iff this is a fixed-output derivation. */
  bool isFixedOutput() const;

  /* Return the output paths of a derivation. */
  PathSet outputPaths() const;
};

struct Derivation : BasicDerivation {
  DerivationInputs inputDrvs; /* inputs that are sub-derivations */

  /* Print a derivation. */
  std::string unparse() const;
};

class Store;

/* Write a derivation to the Nix store, and return its path. */
Path writeDerivation(const ref<Store>& store, const Derivation& drv,
                     const std::string& name, RepairFlag repair = NoRepair);

/* Read a derivation from a file. */
Derivation readDerivation(const Path& drvPath);

Derivation parseDerivation(const std::string& s);

/* Check whether a file name ends with the extension for
   derivations. */
bool isDerivation(const std::string& fileName);

Hash hashDerivationModulo(Store& store, Derivation drv);

/* Memoisation of hashDerivationModulo(). */
typedef std::map<Path, Hash> DrvHashes;

extern DrvHashes drvHashes;  // FIXME: global, not thread-safe

/* Split a string specifying a derivation and a set of outputs
   (/nix/store/hash-foo!out1,out2,...) into the derivation path and
   the outputs. */
using DrvPathWithOutputs = std::pair<std::string, std::set<std::string> >;
DrvPathWithOutputs parseDrvPathWithOutputs(absl::string_view path);

Path makeDrvPathWithOutputs(const Path& drvPath,
                            const std::set<std::string>& outputs);

bool wantOutput(const std::string& output, const std::set<std::string>& wanted);

struct Source;
struct Sink;

Source& readDerivation(Source& in, Store& store, BasicDerivation& drv);
Sink& operator<<(Sink& out, const BasicDerivation& drv);

std::string hashPlaceholder(const std::string& outputName);

}  // namespace nix