mirror of
https://github.com/NixOS/nix
synced 2025-07-02 13:31:48 +02:00
Add a new Cmd type working on RealisedPaths
Where a `RealisedPath` is a store path with its history, meaning either an opaque path for stuff that has been directly added to the store, or a `Realisation` for stuff that has been built by a derivation This is a low-level refactoring that doesn't bring anything by itself (except a few dozen extra lines of code :/ ), but raising the abstraction level a bit is important on a number of levels: - Commands like `nix build` have to query for the realisations after the build is finished which is fragile (see 27905f12e4a7207450abe37c9ed78e31603b67e1 for example). Having them oprate directly at the realisation level would avoid that - Others like `nix copy` currently operate directly on (built) store paths, but need a bit more information as they will need to register the realisations on the remote side
This commit is contained in:
parent
b8f345b29a
commit
9355ecd543
6 changed files with 200 additions and 36 deletions
|
@ -3,6 +3,34 @@
|
|||
#include "path.hh"
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
|
||||
/* Awfull hacky generation of the comparison operators by doing a lexicographic
|
||||
* comparison between the choosen fields
|
||||
* ```
|
||||
* GENERATE_CMP(ClassName, my->field1, my->field2, ...)
|
||||
* ```
|
||||
*
|
||||
* will generate comparison operators semantically equivalent to:
|
||||
* ```
|
||||
* bool operator<(const ClassName& other) {
|
||||
* return field1 < other.field1 && field2 < other.field2 && ...;
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
#define GENERATE_ONE_CMP(COMPARATOR, MY_TYPE, FIELDS...) \
|
||||
bool operator COMPARATOR(const MY_TYPE& other) const { \
|
||||
const MY_TYPE* me = this; \
|
||||
auto fields1 = std::make_tuple( FIELDS ); \
|
||||
me = &other; \
|
||||
auto fields2 = std::make_tuple( FIELDS ); \
|
||||
return fields1 COMPARATOR fields2; \
|
||||
}
|
||||
#define GENERATE_EQUAL(args...) GENERATE_ONE_CMP(==, args)
|
||||
#define GENERATE_LEQ(args...) GENERATE_ONE_CMP(<, args)
|
||||
#define GENERATE_CMP(args...) \
|
||||
GENERATE_EQUAL(args) \
|
||||
GENERATE_LEQ(args)
|
||||
|
||||
namespace nix {
|
||||
|
||||
struct DrvOutput {
|
||||
|
@ -17,13 +45,7 @@ struct DrvOutput {
|
|||
|
||||
static DrvOutput parse(const std::string &);
|
||||
|
||||
bool operator<(const DrvOutput& other) const { return to_pair() < other.to_pair(); }
|
||||
bool operator==(const DrvOutput& other) const { return to_pair() == other.to_pair(); }
|
||||
|
||||
private:
|
||||
// Just to make comparison operators easier to write
|
||||
std::pair<Hash, std::string> to_pair() const
|
||||
{ return std::make_pair(drvHash, outputName); }
|
||||
GENERATE_CMP(DrvOutput, me->drvHash, me->outputName);
|
||||
};
|
||||
|
||||
struct Realisation {
|
||||
|
@ -32,8 +54,60 @@ struct Realisation {
|
|||
|
||||
nlohmann::json toJSON() const;
|
||||
static Realisation fromJSON(const nlohmann::json& json, const std::string& whence);
|
||||
|
||||
StorePath getPath() const { return outPath; }
|
||||
|
||||
GENERATE_CMP(Realisation, me->id, me->outPath);
|
||||
};
|
||||
|
||||
typedef std::map<DrvOutput, Realisation> DrvOutputs;
|
||||
struct OpaquePath {
|
||||
StorePath path;
|
||||
|
||||
StorePath getPath() const { return path; }
|
||||
|
||||
GENERATE_CMP(OpaquePath, me->path);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A store path with all the history of how it went into the store
|
||||
*/
|
||||
struct RealisedPath {
|
||||
/*
|
||||
* A path is either the result of the realisation of a derivation or
|
||||
* an opaque blob that has been directly added to the store
|
||||
*/
|
||||
using Raw = std::variant<Realisation, OpaquePath>;
|
||||
Raw raw;
|
||||
|
||||
using Set = std::set<RealisedPath>;
|
||||
|
||||
RealisedPath(StorePath path) : raw(OpaquePath{path}) {}
|
||||
RealisedPath(Realisation r) : raw(r) {}
|
||||
|
||||
/**
|
||||
* Syntactic sugar to run `std::visit` on the raw value:
|
||||
* path.visit(blah) == std::visit(blah, path.raw)
|
||||
*/
|
||||
template <class Visitor>
|
||||
constexpr decltype(auto) visit(Visitor && vis) {
|
||||
return std::visit(vis, raw);
|
||||
}
|
||||
template <class Visitor>
|
||||
constexpr decltype(auto) visit(Visitor && vis) const {
|
||||
return std::visit(vis, raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw store path associated to this
|
||||
*/
|
||||
StorePath path() const;
|
||||
|
||||
void closure(Store& store, Set& ret) const;
|
||||
static void closure(Store& store, const Set& startPaths, Set& ret);
|
||||
Set closure(Store& store) const;
|
||||
|
||||
GENERATE_CMP(RealisedPath, me->raw);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue