2020-06-01 17:32:27 -04:00
|
|
|
|
#pragma once
|
2023-03-31 23:18:41 -04:00
|
|
|
|
///@file
|
2020-06-01 17:32:27 -04:00
|
|
|
|
|
2020-06-01 18:53:31 -04:00
|
|
|
|
#include <variant>
|
2020-06-01 17:32:27 -04:00
|
|
|
|
#include "hash.hh"
|
2020-10-07 13:52:20 +00:00
|
|
|
|
#include "path.hh"
|
2023-11-04 16:25:41 -04:00
|
|
|
|
#include "file-content-address.hh"
|
2023-08-16 12:29:23 -04:00
|
|
|
|
#include "variant-wrapper.hh"
|
2020-06-01 17:32:27 -04:00
|
|
|
|
|
|
|
|
|
namespace nix {
|
|
|
|
|
|
2020-10-07 13:52:20 +00:00
|
|
|
|
/*
|
2020-10-13 03:30:14 +00:00
|
|
|
|
* Content addressing method
|
2020-10-07 13:52:20 +00:00
|
|
|
|
*/
|
|
|
|
|
|
2023-03-30 16:28:53 -04:00
|
|
|
|
/**
|
|
|
|
|
* Compute the prefix to the hash algorithm which indicates how the
|
|
|
|
|
* files were ingested.
|
|
|
|
|
*/
|
2024-02-13 09:54:07 -05:00
|
|
|
|
std::string_view makeFileIngestionPrefix(FileIngestionMethod m);
|
2020-10-12 23:51:23 +00:00
|
|
|
|
|
2023-03-30 16:28:53 -04:00
|
|
|
|
/**
|
2023-11-04 16:25:41 -04:00
|
|
|
|
* An enumeration of all the ways we can content-address store objects.
|
2023-03-30 16:28:53 -04:00
|
|
|
|
*
|
|
|
|
|
* Just the type of a content address. Combine with the hash itself, and
|
|
|
|
|
* we have a `ContentAddress` as defined below. Combine that, in turn,
|
|
|
|
|
* with info on references, and we have `ContentAddressWithReferences`,
|
|
|
|
|
* as defined further below.
|
|
|
|
|
*/
|
2023-03-30 17:12:49 -04:00
|
|
|
|
struct ContentAddressMethod
|
|
|
|
|
{
|
2024-05-16 19:08:28 -04:00
|
|
|
|
enum struct Raw {
|
|
|
|
|
/**
|
|
|
|
|
* Calculate a store path using the `FileIngestionMethod::Flat`
|
|
|
|
|
* hash of the file system objects, and references.
|
|
|
|
|
*
|
|
|
|
|
* See `store-object/content-address.md#method-flat` in the
|
|
|
|
|
* manual.
|
|
|
|
|
*/
|
|
|
|
|
Flat,
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Calculate a store path using the
|
|
|
|
|
* `FileIngestionMethod::NixArchive` hash of the file system
|
|
|
|
|
* objects, and references.
|
|
|
|
|
*
|
|
|
|
|
* See `store-object/content-address.md#method-flat` in the
|
|
|
|
|
* manual.
|
|
|
|
|
*/
|
|
|
|
|
NixArchive,
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Calculate a store path using the `FileIngestionMethod::Git`
|
|
|
|
|
* hash of the file system objects, and references.
|
|
|
|
|
*
|
|
|
|
|
* Part of `ExperimentalFeature::GitHashing`.
|
|
|
|
|
*
|
|
|
|
|
* See `store-object/content-address.md#method-git` in the
|
|
|
|
|
* manual.
|
|
|
|
|
*/
|
|
|
|
|
Git,
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Calculate a store path using the `FileIngestionMethod::Flat`
|
|
|
|
|
* hash of the file system objects, and references, but in a
|
|
|
|
|
* different way than `ContentAddressMethod::Raw::Flat`.
|
|
|
|
|
*
|
|
|
|
|
* See `store-object/content-address.md#method-text` in the
|
|
|
|
|
* manual.
|
|
|
|
|
*/
|
|
|
|
|
Text,
|
|
|
|
|
};
|
2020-10-12 23:51:23 +00:00
|
|
|
|
|
2023-03-30 17:12:49 -04:00
|
|
|
|
Raw raw;
|
2020-10-12 23:51:23 +00:00
|
|
|
|
|
2024-05-16 18:46:38 -04:00
|
|
|
|
bool operator ==(const ContentAddressMethod &) const = default;
|
2024-05-16 19:08:28 -04:00
|
|
|
|
auto operator <=>(const ContentAddressMethod &) const = default;
|
2020-10-12 23:51:23 +00:00
|
|
|
|
|
2023-08-16 12:29:23 -04:00
|
|
|
|
MAKE_WRAPPER_CONSTRUCTOR(ContentAddressMethod);
|
2020-10-12 23:51:23 +00:00
|
|
|
|
|
2024-02-13 09:54:07 -05:00
|
|
|
|
/**
|
|
|
|
|
* Parse a content addressing method (name).
|
|
|
|
|
*
|
|
|
|
|
* The inverse of `render`.
|
|
|
|
|
*/
|
|
|
|
|
static ContentAddressMethod parse(std::string_view rawCaMethod);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Render a content addressing method (name).
|
|
|
|
|
*
|
|
|
|
|
* The inverse of `parse`.
|
|
|
|
|
*/
|
|
|
|
|
std::string_view render() const;
|
|
|
|
|
|
2023-04-01 16:40:32 -04:00
|
|
|
|
/**
|
2023-05-09 12:45:51 -04:00
|
|
|
|
* Parse the prefix tag which indicates how the files
|
|
|
|
|
* were ingested, with the fixed output case not prefixed for back
|
2023-04-01 16:40:32 -04:00
|
|
|
|
* compat.
|
2023-05-09 13:05:38 -04:00
|
|
|
|
*
|
|
|
|
|
* @param [in] m A string that should begin with the prefix.
|
|
|
|
|
* @param [out] m The remainder of the string after the prefix.
|
2023-04-01 16:40:32 -04:00
|
|
|
|
*/
|
|
|
|
|
static ContentAddressMethod parsePrefix(std::string_view & m);
|
2020-10-12 23:51:23 +00:00
|
|
|
|
|
2023-05-09 13:05:38 -04:00
|
|
|
|
/**
|
|
|
|
|
* Render the prefix tag which indicates how the files wre ingested.
|
|
|
|
|
*
|
|
|
|
|
* The rough inverse of `parsePrefix()`.
|
|
|
|
|
*/
|
2024-02-13 09:54:07 -05:00
|
|
|
|
std::string_view renderPrefix() const;
|
2023-04-01 16:40:32 -04:00
|
|
|
|
|
|
|
|
|
/**
|
2024-02-26 02:04:20 +08:00
|
|
|
|
* Parse a content addressing method and hash algorithm.
|
2023-04-01 16:40:32 -04:00
|
|
|
|
*/
|
2024-02-13 09:54:07 -05:00
|
|
|
|
static std::pair<ContentAddressMethod, HashAlgorithm> parseWithAlgo(std::string_view rawCaMethod);
|
2023-04-01 16:40:32 -04:00
|
|
|
|
|
2023-05-09 13:05:38 -04:00
|
|
|
|
/**
|
2024-02-26 02:04:20 +08:00
|
|
|
|
* Render a content addressing method and hash algorithm in a
|
2023-05-09 13:05:38 -04:00
|
|
|
|
* nicer way, prefixing both cases.
|
|
|
|
|
*
|
|
|
|
|
* The rough inverse of `parse()`.
|
|
|
|
|
*/
|
2024-02-26 02:04:20 +08:00
|
|
|
|
std::string renderWithAlgo(HashAlgorithm ha) const;
|
2023-11-04 16:25:41 -04:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the underlying way to content-address file system objects.
|
|
|
|
|
*
|
|
|
|
|
* Different ways of hashing store objects may use the same method
|
|
|
|
|
* for hashing file systeme objects.
|
|
|
|
|
*/
|
|
|
|
|
FileIngestionMethod getFileIngestionMethod() const;
|
2023-03-30 17:12:49 -04:00
|
|
|
|
};
|
2020-10-12 23:51:23 +00:00
|
|
|
|
|
2020-10-07 13:52:20 +00:00
|
|
|
|
|
2020-10-13 03:30:14 +00:00
|
|
|
|
/*
|
|
|
|
|
* Mini content address
|
|
|
|
|
*/
|
2020-10-07 13:52:20 +00:00
|
|
|
|
|
2023-03-25 19:12:44 -04:00
|
|
|
|
/**
|
|
|
|
|
* We've accumulated several types of content-addressed paths over the
|
|
|
|
|
* years; fixed-output derivations support multiple hash algorithms and
|
|
|
|
|
* serialisation methods (flat file vs NAR). Thus, ‘ca’ has one of the
|
|
|
|
|
* following forms:
|
|
|
|
|
*
|
2023-11-08 21:11:48 -05:00
|
|
|
|
* - `TextIngestionMethod`:
|
|
|
|
|
* ‘text:sha256:<sha256 hash of file contents>’
|
2023-03-25 19:12:44 -04:00
|
|
|
|
*
|
2023-11-08 21:11:48 -05:00
|
|
|
|
* - `FixedIngestionMethod`:
|
2024-02-26 02:04:20 +08:00
|
|
|
|
* ‘fixed:<r?>:<hash algorithm>:<hash of file contents>’
|
2023-03-25 19:12:44 -04:00
|
|
|
|
*/
|
2023-03-30 17:12:49 -04:00
|
|
|
|
struct ContentAddress
|
|
|
|
|
{
|
2023-07-05 18:53:44 -04:00
|
|
|
|
/**
|
|
|
|
|
* How the file system objects are serialized
|
|
|
|
|
*/
|
|
|
|
|
ContentAddressMethod method;
|
2020-06-01 19:26:40 -04:00
|
|
|
|
|
2023-07-05 18:53:44 -04:00
|
|
|
|
/**
|
|
|
|
|
* Hash of that serialization
|
|
|
|
|
*/
|
|
|
|
|
Hash hash;
|
2020-06-01 19:26:40 -04:00
|
|
|
|
|
2024-05-16 18:46:38 -04:00
|
|
|
|
bool operator ==(const ContentAddress &) const = default;
|
2024-05-16 19:08:28 -04:00
|
|
|
|
auto operator <=>(const ContentAddress &) const = default;
|
2020-06-02 00:37:43 +00:00
|
|
|
|
|
2023-03-30 17:12:49 -04:00
|
|
|
|
/**
|
2023-04-19 14:13:30 -04:00
|
|
|
|
* Compute the content-addressability assertion
|
|
|
|
|
* (`ValidPathInfo::ca`) for paths created by
|
|
|
|
|
* `Store::makeFixedOutputPath()` / `Store::addToStore()`.
|
2023-03-30 17:12:49 -04:00
|
|
|
|
*/
|
|
|
|
|
std::string render() const;
|
2020-06-02 00:37:43 +00:00
|
|
|
|
|
2023-03-30 17:12:49 -04:00
|
|
|
|
static ContentAddress parse(std::string_view rawCa);
|
2020-06-02 00:37:43 +00:00
|
|
|
|
|
2023-03-30 17:12:49 -04:00
|
|
|
|
static std::optional<ContentAddress> parseOpt(std::string_view rawCaOpt);
|
2020-07-10 13:21:37 +02:00
|
|
|
|
|
2023-04-19 14:48:53 -04:00
|
|
|
|
std::string printMethodAlgo() const;
|
2023-03-30 17:12:49 -04:00
|
|
|
|
};
|
|
|
|
|
|
2023-05-09 13:05:38 -04:00
|
|
|
|
/**
|
|
|
|
|
* Render the `ContentAddress` if it exists to a string, return empty
|
|
|
|
|
* string otherwise.
|
|
|
|
|
*/
|
2023-03-30 17:12:49 -04:00
|
|
|
|
std::string renderContentAddress(std::optional<ContentAddress> ca);
|
2020-06-02 00:37:43 +00:00
|
|
|
|
|
2020-07-10 13:21:37 +02:00
|
|
|
|
|
2023-03-30 17:12:49 -04:00
|
|
|
|
/*
|
|
|
|
|
* Full content address
|
|
|
|
|
*
|
|
|
|
|
* See the schema for store paths in store-api.cc
|
|
|
|
|
*/
|
2020-09-17 17:15:05 +02:00
|
|
|
|
|
2023-03-30 16:28:53 -04:00
|
|
|
|
/**
|
|
|
|
|
* A set of references to other store objects.
|
|
|
|
|
*
|
|
|
|
|
* References to other store objects are tracked with store paths, self
|
|
|
|
|
* references however are tracked with a boolean.
|
2020-10-07 13:52:20 +00:00
|
|
|
|
*/
|
2023-07-05 18:53:44 -04:00
|
|
|
|
struct StoreReferences
|
|
|
|
|
{
|
2023-03-30 16:28:53 -04:00
|
|
|
|
/**
|
|
|
|
|
* References to other store objects
|
|
|
|
|
*/
|
2023-01-14 16:38:43 -05:00
|
|
|
|
StorePathSet others;
|
2023-03-30 16:28:53 -04:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Reference to this store object
|
|
|
|
|
*/
|
2023-01-14 16:38:43 -05:00
|
|
|
|
bool self = false;
|
|
|
|
|
|
2023-03-30 16:28:53 -04:00
|
|
|
|
/**
|
|
|
|
|
* @return true iff no references, i.e. others is empty and self is
|
|
|
|
|
* false.
|
|
|
|
|
*/
|
2023-01-14 16:38:43 -05:00
|
|
|
|
bool empty() const;
|
2023-03-30 16:28:53 -04:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the numbers of references, i.e. the size of others + 1
|
|
|
|
|
* iff self is true.
|
|
|
|
|
*/
|
2023-01-14 16:38:43 -05:00
|
|
|
|
size_t size() const;
|
2024-05-16 18:46:38 -04:00
|
|
|
|
|
|
|
|
|
bool operator ==(const StoreReferences &) const = default;
|
|
|
|
|
// TODO libc++ 16 (used by darwin) missing `std::map::operator <=>`, can't do yet.
|
|
|
|
|
//auto operator <=>(const StoreReferences &) const = default;
|
2023-01-14 16:38:43 -05:00
|
|
|
|
};
|
2020-10-07 13:52:20 +00:00
|
|
|
|
|
|
|
|
|
// This matches the additional info that we need for makeTextPath
|
2023-07-05 18:53:44 -04:00
|
|
|
|
struct TextInfo
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* Hash of the contents of the text/file.
|
|
|
|
|
*/
|
|
|
|
|
Hash hash;
|
|
|
|
|
|
2023-03-30 16:28:53 -04:00
|
|
|
|
/**
|
|
|
|
|
* References to other store objects only; self references
|
|
|
|
|
* disallowed
|
|
|
|
|
*/
|
2020-10-07 13:52:20 +00:00
|
|
|
|
StorePathSet references;
|
2024-05-16 18:46:38 -04:00
|
|
|
|
|
|
|
|
|
bool operator ==(const TextInfo &) const = default;
|
|
|
|
|
// TODO libc++ 16 (used by darwin) missing `std::map::operator <=>`, can't do yet.
|
|
|
|
|
//auto operator <=>(const TextInfo &) const = default;
|
2020-10-07 13:52:20 +00:00
|
|
|
|
};
|
|
|
|
|
|
2023-07-05 18:53:44 -04:00
|
|
|
|
struct FixedOutputInfo
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* How the file system objects are serialized
|
|
|
|
|
*/
|
|
|
|
|
FileIngestionMethod method;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Hash of that serialization
|
|
|
|
|
*/
|
|
|
|
|
Hash hash;
|
|
|
|
|
|
2023-03-30 16:28:53 -04:00
|
|
|
|
/**
|
|
|
|
|
* References to other store objects or this one.
|
|
|
|
|
*/
|
2023-01-06 15:36:05 -05:00
|
|
|
|
StoreReferences references;
|
2024-05-16 18:46:38 -04:00
|
|
|
|
|
|
|
|
|
bool operator ==(const FixedOutputInfo &) const = default;
|
|
|
|
|
// TODO libc++ 16 (used by darwin) missing `std::map::operator <=>`, can't do yet.
|
|
|
|
|
//auto operator <=>(const FixedOutputInfo &) const = default;
|
2020-10-07 13:52:20 +00:00
|
|
|
|
};
|
|
|
|
|
|
2023-03-25 19:12:44 -04:00
|
|
|
|
/**
|
|
|
|
|
* Ways of content addressing but not a complete ContentAddress.
|
|
|
|
|
*
|
|
|
|
|
* A ContentAddress without a Hash.
|
|
|
|
|
*/
|
2023-03-30 17:12:49 -04:00
|
|
|
|
struct ContentAddressWithReferences
|
|
|
|
|
{
|
|
|
|
|
typedef std::variant<
|
|
|
|
|
TextInfo,
|
|
|
|
|
FixedOutputInfo
|
|
|
|
|
> Raw;
|
2020-10-07 13:52:20 +00:00
|
|
|
|
|
2023-03-30 17:12:49 -04:00
|
|
|
|
Raw raw;
|
2020-10-07 13:52:20 +00:00
|
|
|
|
|
2024-05-16 18:46:38 -04:00
|
|
|
|
bool operator ==(const ContentAddressWithReferences &) const = default;
|
|
|
|
|
// TODO libc++ 16 (used by darwin) missing `std::map::operator <=>`, can't do yet.
|
|
|
|
|
//auto operator <=>(const ContentAddressWithReferences &) const = default;
|
|
|
|
|
|
2023-08-16 12:29:23 -04:00
|
|
|
|
MAKE_WRAPPER_CONSTRUCTOR(ContentAddressWithReferences);
|
2020-10-12 23:51:23 +00:00
|
|
|
|
|
2023-03-30 17:12:49 -04:00
|
|
|
|
/**
|
2023-04-19 14:13:30 -04:00
|
|
|
|
* Create a `ContentAddressWithReferences` from a mere
|
2023-05-09 12:45:51 -04:00
|
|
|
|
* `ContentAddress`, by claiming no references.
|
2023-03-30 17:12:49 -04:00
|
|
|
|
*/
|
2023-05-09 12:45:51 -04:00
|
|
|
|
static ContentAddressWithReferences withoutRefs(const ContentAddress &) noexcept;
|
2023-04-01 16:40:32 -04:00
|
|
|
|
|
|
|
|
|
/**
|
2023-04-19 14:13:30 -04:00
|
|
|
|
* Create a `ContentAddressWithReferences` from 3 parts:
|
2023-04-01 16:40:32 -04:00
|
|
|
|
*
|
|
|
|
|
* @param method Way ingesting the file system data.
|
|
|
|
|
*
|
|
|
|
|
* @param hash Hash of ingested file system data.
|
|
|
|
|
*
|
|
|
|
|
* @param refs References to other store objects or oneself.
|
|
|
|
|
*
|
2023-11-04 16:25:41 -04:00
|
|
|
|
* @note note that all combinations are supported. This is a
|
|
|
|
|
* *partial function* and exceptions will be thrown for invalid
|
|
|
|
|
* combinations.
|
2023-04-01 16:40:32 -04:00
|
|
|
|
*/
|
2023-11-04 16:25:41 -04:00
|
|
|
|
static ContentAddressWithReferences fromParts(
|
|
|
|
|
ContentAddressMethod method, Hash hash, StoreReferences refs);
|
2023-04-01 16:40:32 -04:00
|
|
|
|
|
|
|
|
|
ContentAddressMethod getMethod() const;
|
|
|
|
|
|
|
|
|
|
Hash getHash() const;
|
2023-03-30 17:12:49 -04:00
|
|
|
|
};
|
2020-10-12 23:51:23 +00:00
|
|
|
|
|
2020-06-01 17:32:27 -04:00
|
|
|
|
}
|