Cleanup ContentAddressMethod to match docs

The old `std::variant` is bad because we aren't adding a new case to
`FileIngestionMethod` so much as we are defining a separate concept ---
store object content addressing rather than file system object content
addressing. As such, it is more correct to just create a fresh
enumeration.

Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
This commit is contained in:
John Ericson 2024-05-16 19:08:28 -04:00
parent 64e599ebe1
commit b51e161af5
25 changed files with 275 additions and 203 deletions

View file

@ -2303,7 +2303,7 @@ StorePath EvalState::copyPathToStore(NixStringContext & context, const SourcePat
path.resolveSymlinks(), path.resolveSymlinks(),
settings.readOnlyMode ? FetchMode::DryRun : FetchMode::Copy, settings.readOnlyMode ? FetchMode::DryRun : FetchMode::Copy,
path.baseName(), path.baseName(),
FileIngestionMethod::NixArchive, ContentAddressMethod::Raw::NixArchive,
nullptr, nullptr,
repair); repair);
allowPath(dstPath); allowPath(dstPath);

View file

@ -1209,7 +1209,7 @@ static void derivationStrictInternal(
auto handleHashMode = [&](const std::string_view s) { auto handleHashMode = [&](const std::string_view s) {
if (s == "recursive") { if (s == "recursive") {
// back compat, new name is "nar" // back compat, new name is "nar"
ingestionMethod = FileIngestionMethod::NixArchive; ingestionMethod = ContentAddressMethod::Raw::NixArchive;
} else try { } else try {
ingestionMethod = ContentAddressMethod::parse(s); ingestionMethod = ContentAddressMethod::parse(s);
} catch (UsageError &) { } catch (UsageError &) {
@ -1217,9 +1217,9 @@ static void derivationStrictInternal(
"invalid value '%s' for 'outputHashMode' attribute", s "invalid value '%s' for 'outputHashMode' attribute", s
).atPos(v).debugThrow(); ).atPos(v).debugThrow();
} }
if (ingestionMethod == TextIngestionMethod {}) if (ingestionMethod == ContentAddressMethod::Raw::Text)
experimentalFeatureSettings.require(Xp::DynamicDerivations); experimentalFeatureSettings.require(Xp::DynamicDerivations);
if (ingestionMethod == FileIngestionMethod::Git) if (ingestionMethod == ContentAddressMethod::Raw::Git)
experimentalFeatureSettings.require(Xp::GitHashing); experimentalFeatureSettings.require(Xp::GitHashing);
}; };
@ -1391,7 +1391,7 @@ static void derivationStrictInternal(
/* Check whether the derivation name is valid. */ /* Check whether the derivation name is valid. */
if (isDerivation(drvName) && if (isDerivation(drvName) &&
!(ingestionMethod == ContentAddressMethod { TextIngestionMethod { } } && !(ingestionMethod == ContentAddressMethod::Raw::Text &&
outputs.size() == 1 && outputs.size() == 1 &&
*(outputs.begin()) == "out")) *(outputs.begin()) == "out"))
{ {
@ -1413,7 +1413,7 @@ static void derivationStrictInternal(
auto h = newHashAllowEmpty(*outputHash, outputHashAlgo); auto h = newHashAllowEmpty(*outputHash, outputHashAlgo);
auto method = ingestionMethod.value_or(FileIngestionMethod::Flat); auto method = ingestionMethod.value_or(ContentAddressMethod::Raw::Flat);
DerivationOutput::CAFixed dof { DerivationOutput::CAFixed dof {
.ca = ContentAddress { .ca = ContentAddress {
@ -1432,7 +1432,7 @@ static void derivationStrictInternal(
.atPos(v).debugThrow(); .atPos(v).debugThrow();
auto ha = outputHashAlgo.value_or(HashAlgorithm::SHA256); auto ha = outputHashAlgo.value_or(HashAlgorithm::SHA256);
auto method = ingestionMethod.value_or(FileIngestionMethod::NixArchive); auto method = ingestionMethod.value_or(ContentAddressMethod::Raw::NixArchive);
for (auto & i : outputs) { for (auto & i : outputs) {
drv.env[i] = hashPlaceholder(i); drv.env[i] = hashPlaceholder(i);
@ -2208,7 +2208,7 @@ static void prim_toFile(EvalState & state, const PosIdx pos, Value * * args, Val
}) })
: ({ : ({
StringSource s { contents }; StringSource s { contents };
state.store->addToStoreFromDump(s, name, FileSerialisationMethod::Flat, TextIngestionMethod {}, HashAlgorithm::SHA256, refs, state.repair); state.store->addToStoreFromDump(s, name, FileSerialisationMethod::Flat, ContentAddressMethod::Raw::Text, HashAlgorithm::SHA256, refs, state.repair);
}); });
/* Note: we don't need to add `context' to the context of the /* Note: we don't need to add `context' to the context of the
@ -2391,7 +2391,7 @@ static void prim_filterSource(EvalState & state, const PosIdx pos, Value * * arg
"while evaluating the second argument (the path to filter) passed to 'builtins.filterSource'"); "while evaluating the second argument (the path to filter) passed to 'builtins.filterSource'");
state.forceFunction(*args[0], pos, "while evaluating the first argument passed to builtins.filterSource"); state.forceFunction(*args[0], pos, "while evaluating the first argument passed to builtins.filterSource");
addPath(state, pos, path.baseName(), path, args[0], FileIngestionMethod::NixArchive, std::nullopt, v, context); addPath(state, pos, path.baseName(), path, args[0], ContentAddressMethod::Raw::NixArchive, std::nullopt, v, context);
} }
static RegisterPrimOp primop_filterSource({ static RegisterPrimOp primop_filterSource({
@ -2454,7 +2454,7 @@ static void prim_path(EvalState & state, const PosIdx pos, Value * * args, Value
std::optional<SourcePath> path; std::optional<SourcePath> path;
std::string name; std::string name;
Value * filterFun = nullptr; Value * filterFun = nullptr;
ContentAddressMethod method = FileIngestionMethod::NixArchive; auto method = ContentAddressMethod::Raw::NixArchive;
std::optional<Hash> expectedHash; std::optional<Hash> expectedHash;
NixStringContext context; NixStringContext context;
@ -2470,8 +2470,8 @@ static void prim_path(EvalState & state, const PosIdx pos, Value * * args, Value
state.forceFunction(*(filterFun = attr.value), attr.pos, "while evaluating the `filter` parameter passed to builtins.path"); state.forceFunction(*(filterFun = attr.value), attr.pos, "while evaluating the `filter` parameter passed to builtins.path");
else if (n == "recursive") else if (n == "recursive")
method = state.forceBool(*attr.value, attr.pos, "while evaluating the `recursive` attribute passed to builtins.path") method = state.forceBool(*attr.value, attr.pos, "while evaluating the `recursive` attribute passed to builtins.path")
? FileIngestionMethod::NixArchive ? ContentAddressMethod::Raw::NixArchive
: FileIngestionMethod::Flat; : ContentAddressMethod::Raw::Flat;
else if (n == "sha256") else if (n == "sha256")
expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, attr.pos, "while evaluating the `sha256` attribute passed to builtins.path"), HashAlgorithm::SHA256); expectedHash = newHashAllowEmpty(state.forceStringNoCtx(*attr.value, attr.pos, "while evaluating the `sha256` attribute passed to builtins.path"), HashAlgorithm::SHA256);
else else

View file

@ -18,7 +18,7 @@ StorePath fetchToStore(
const SourcePath & path, const SourcePath & path,
FetchMode mode, FetchMode mode,
std::string_view name = "source", std::string_view name = "source",
ContentAddressMethod method = FileIngestionMethod::NixArchive, ContentAddressMethod method = ContentAddressMethod::Raw::NixArchive,
PathFilter * filter = nullptr, PathFilter * filter = nullptr,
RepairFlag repair = NoRepair); RepairFlag repair = NoRepair);

View file

@ -213,7 +213,7 @@ struct MercurialInputScheme : InputScheme
auto storePath = store->addToStore( auto storePath = store->addToStore(
input.getName(), input.getName(),
{getFSSourceAccessor(), CanonPath(actualPath)}, {getFSSourceAccessor(), CanonPath(actualPath)},
FileIngestionMethod::NixArchive, HashAlgorithm::SHA256, {}, ContentAddressMethod::Raw::NixArchive, HashAlgorithm::SHA256, {},
filter); filter);
return storePath; return storePath;

View file

@ -8,6 +8,7 @@ std::string_view makeFileIngestionPrefix(FileIngestionMethod m)
{ {
switch (m) { switch (m) {
case FileIngestionMethod::Flat: case FileIngestionMethod::Flat:
// Not prefixed for back compat
return ""; return "";
case FileIngestionMethod::NixArchive: case FileIngestionMethod::NixArchive:
return "r:"; return "r:";
@ -15,91 +16,128 @@ std::string_view makeFileIngestionPrefix(FileIngestionMethod m)
experimentalFeatureSettings.require(Xp::GitHashing); experimentalFeatureSettings.require(Xp::GitHashing);
return "git:"; return "git:";
default: default:
throw Error("impossible, caught both cases"); assert(false);
} }
} }
std::string_view ContentAddressMethod::render() const std::string_view ContentAddressMethod::render() const
{ {
return std::visit(overloaded { switch (raw) {
[](TextIngestionMethod) -> std::string_view { return "text"; }, case ContentAddressMethod::Raw::Text:
[](FileIngestionMethod m2) { return "text";
/* Not prefixed for back compat with things that couldn't produce text before. */ case ContentAddressMethod::Raw::Flat:
return renderFileIngestionMethod(m2); case ContentAddressMethod::Raw::NixArchive:
}, case ContentAddressMethod::Raw::Git:
}, raw); return renderFileIngestionMethod(getFileIngestionMethod());
default:
assert(false);
}
}
/**
* **Not surjective**
*
* This is not exposed because `FileIngestionMethod::Flat` maps to
* `ContentAddressMethod::Raw::Flat` and
* `ContentAddressMethod::Raw::Text` alike. We can thus only safely use
* this when the latter is ruled out (e.g. because it is already
* handled).
*/
static ContentAddressMethod fileIngestionMethodToContentAddressMethod(FileIngestionMethod m)
{
switch (m) {
case FileIngestionMethod::Flat:
return ContentAddressMethod::Raw::Flat;
case FileIngestionMethod::NixArchive:
return ContentAddressMethod::Raw::NixArchive;
case FileIngestionMethod::Git:
return ContentAddressMethod::Raw::Git;
default:
assert(false);
}
} }
ContentAddressMethod ContentAddressMethod::parse(std::string_view m) ContentAddressMethod ContentAddressMethod::parse(std::string_view m)
{ {
if (m == "text") if (m == "text")
return TextIngestionMethod {}; return ContentAddressMethod::Raw::Text;
else else
return parseFileIngestionMethod(m); return fileIngestionMethodToContentAddressMethod(
parseFileIngestionMethod(m));
} }
std::string_view ContentAddressMethod::renderPrefix() const std::string_view ContentAddressMethod::renderPrefix() const
{ {
return std::visit(overloaded { switch (raw) {
[](TextIngestionMethod) -> std::string_view { return "text:"; }, case ContentAddressMethod::Raw::Text:
[](FileIngestionMethod m2) { return "text:";
/* Not prefixed for back compat with things that couldn't produce text before. */ case ContentAddressMethod::Raw::Flat:
return makeFileIngestionPrefix(m2); case ContentAddressMethod::Raw::NixArchive:
}, case ContentAddressMethod::Raw::Git:
}, raw); return makeFileIngestionPrefix(getFileIngestionMethod());
default:
assert(false);
}
} }
ContentAddressMethod ContentAddressMethod::parsePrefix(std::string_view & m) ContentAddressMethod ContentAddressMethod::parsePrefix(std::string_view & m)
{ {
if (splitPrefix(m, "r:")) { if (splitPrefix(m, "r:")) {
return FileIngestionMethod::NixArchive; return ContentAddressMethod::Raw::NixArchive;
} }
else if (splitPrefix(m, "git:")) { else if (splitPrefix(m, "git:")) {
experimentalFeatureSettings.require(Xp::GitHashing); experimentalFeatureSettings.require(Xp::GitHashing);
return FileIngestionMethod::Git; return ContentAddressMethod::Raw::Git;
} }
else if (splitPrefix(m, "text:")) { else if (splitPrefix(m, "text:")) {
return TextIngestionMethod {}; return ContentAddressMethod::Raw::Text;
}
return ContentAddressMethod::Raw::Flat;
}
/**
* This is slightly more mindful of forward compat in that it uses `fixed:`
* rather than just doing a raw empty prefix or `r:`, which doesn't "save room"
* for future changes very well.
*/
static std::string renderPrefixModern(const ContentAddressMethod & ca)
{
switch (ca.raw) {
case ContentAddressMethod::Raw::Text:
return "text:";
case ContentAddressMethod::Raw::Flat:
case ContentAddressMethod::Raw::NixArchive:
case ContentAddressMethod::Raw::Git:
return "fixed:" + makeFileIngestionPrefix(ca.getFileIngestionMethod());
default:
assert(false);
} }
return FileIngestionMethod::Flat;
} }
std::string ContentAddressMethod::renderWithAlgo(HashAlgorithm ha) const std::string ContentAddressMethod::renderWithAlgo(HashAlgorithm ha) const
{ {
return std::visit(overloaded { return renderPrefixModern(*this) + printHashAlgo(ha);
[&](const TextIngestionMethod & th) {
return std::string{"text:"} + printHashAlgo(ha);
},
[&](const FileIngestionMethod & fim) {
return "fixed:" + makeFileIngestionPrefix(fim) + printHashAlgo(ha);
}
}, raw);
} }
FileIngestionMethod ContentAddressMethod::getFileIngestionMethod() const FileIngestionMethod ContentAddressMethod::getFileIngestionMethod() const
{ {
return std::visit(overloaded { switch (raw) {
[&](const TextIngestionMethod & th) { case ContentAddressMethod::Raw::Flat:
return FileIngestionMethod::Flat; return FileIngestionMethod::Flat;
}, case ContentAddressMethod::Raw::NixArchive:
[&](const FileIngestionMethod & fim) { return FileIngestionMethod::NixArchive;
return fim; case ContentAddressMethod::Raw::Git:
} return FileIngestionMethod::Git;
}, raw); case ContentAddressMethod::Raw::Text:
return FileIngestionMethod::Flat;
default:
assert(false);
}
} }
std::string ContentAddress::render() const std::string ContentAddress::render() const
{ {
return std::visit(overloaded { return renderPrefixModern(method) + this->hash.to_string(HashFormat::Nix32, true);
[](const TextIngestionMethod &) -> std::string {
return "text:";
},
[](const FileIngestionMethod & method) {
return "fixed:"
+ makeFileIngestionPrefix(method);
},
}, method.raw)
+ this->hash.to_string(HashFormat::Nix32, true);
} }
/** /**
@ -130,17 +168,17 @@ static std::pair<ContentAddressMethod, HashAlgorithm> parseContentAddressMethodP
// No parsing of the ingestion method, "text" only support flat. // No parsing of the ingestion method, "text" only support flat.
HashAlgorithm hashAlgo = parseHashAlgorithm_(); HashAlgorithm hashAlgo = parseHashAlgorithm_();
return { return {
TextIngestionMethod {}, ContentAddressMethod::Raw::Text,
std::move(hashAlgo), std::move(hashAlgo),
}; };
} else if (prefix == "fixed") { } else if (prefix == "fixed") {
// Parse method // Parse method
auto method = FileIngestionMethod::Flat; auto method = ContentAddressMethod::Raw::Flat;
if (splitPrefix(rest, "r:")) if (splitPrefix(rest, "r:"))
method = FileIngestionMethod::NixArchive; method = ContentAddressMethod::Raw::NixArchive;
else if (splitPrefix(rest, "git:")) { else if (splitPrefix(rest, "git:")) {
experimentalFeatureSettings.require(Xp::GitHashing); experimentalFeatureSettings.require(Xp::GitHashing);
method = FileIngestionMethod::Git; method = ContentAddressMethod::Raw::Git;
} }
HashAlgorithm hashAlgo = parseHashAlgorithm_(); HashAlgorithm hashAlgo = parseHashAlgorithm_();
return { return {
@ -201,57 +239,58 @@ size_t StoreReferences::size() const
ContentAddressWithReferences ContentAddressWithReferences::withoutRefs(const ContentAddress & ca) noexcept ContentAddressWithReferences ContentAddressWithReferences::withoutRefs(const ContentAddress & ca) noexcept
{ {
return std::visit(overloaded { switch (ca.method.raw) {
[&](const TextIngestionMethod &) -> ContentAddressWithReferences { case ContentAddressMethod::Raw::Text:
return TextInfo { return TextInfo {
.hash = ca.hash, .hash = ca.hash,
.references = {}, .references = {},
}; };
}, case ContentAddressMethod::Raw::Flat:
[&](const FileIngestionMethod & method) -> ContentAddressWithReferences { case ContentAddressMethod::Raw::NixArchive:
return FixedOutputInfo { case ContentAddressMethod::Raw::Git:
.method = method, return FixedOutputInfo {
.hash = ca.hash, .method = ca.method.getFileIngestionMethod(),
.references = {}, .hash = ca.hash,
}; .references = {},
}, };
}, ca.method.raw); default:
assert(false);
}
} }
ContentAddressWithReferences ContentAddressWithReferences::fromParts( ContentAddressWithReferences ContentAddressWithReferences::fromParts(
ContentAddressMethod method, Hash hash, StoreReferences refs) ContentAddressMethod method, Hash hash, StoreReferences refs)
{ {
return std::visit(overloaded { switch (method.raw) {
[&](TextIngestionMethod _) -> ContentAddressWithReferences { case ContentAddressMethod::Raw::Text:
if (refs.self) if (refs.self)
throw Error("self-reference not allowed with text hashing"); throw Error("self-reference not allowed with text hashing");
return ContentAddressWithReferences { return TextInfo {
TextInfo { .hash = std::move(hash),
.hash = std::move(hash), .references = std::move(refs.others),
.references = std::move(refs.others), };
} case ContentAddressMethod::Raw::Flat:
}; case ContentAddressMethod::Raw::NixArchive:
}, case ContentAddressMethod::Raw::Git:
[&](FileIngestionMethod m2) -> ContentAddressWithReferences { return FixedOutputInfo {
return ContentAddressWithReferences { .method = method.getFileIngestionMethod(),
FixedOutputInfo { .hash = std::move(hash),
.method = m2, .references = std::move(refs),
.hash = std::move(hash), };
.references = std::move(refs), default:
} assert(false);
}; }
},
}, method.raw);
} }
ContentAddressMethod ContentAddressWithReferences::getMethod() const ContentAddressMethod ContentAddressWithReferences::getMethod() const
{ {
return std::visit(overloaded { return std::visit(overloaded {
[](const TextInfo & th) -> ContentAddressMethod { [](const TextInfo & th) -> ContentAddressMethod {
return TextIngestionMethod {}; return ContentAddressMethod::Raw::Text;
}, },
[](const FixedOutputInfo & fsh) -> ContentAddressMethod { [](const FixedOutputInfo & fsh) -> ContentAddressMethod {
return fsh.method; return fileIngestionMethodToContentAddressMethod(
fsh.method);
}, },
}, raw); }, raw);
} }

View file

@ -5,7 +5,6 @@
#include "hash.hh" #include "hash.hh"
#include "path.hh" #include "path.hh"
#include "file-content-address.hh" #include "file-content-address.hh"
#include "comparator.hh"
#include "variant-wrapper.hh" #include "variant-wrapper.hh"
namespace nix { namespace nix {
@ -14,24 +13,6 @@ namespace nix {
* Content addressing method * Content addressing method
*/ */
/* We only have one way to hash text with references, so this is a single-value
type, mainly useful with std::variant.
*/
/**
* The single way we can serialize "text" file system objects.
*
* Somewhat obscure, used by \ref Derivation derivations and
* `builtins.toFile` currently.
*
* TextIngestionMethod is identical to FileIngestionMethod::Fixed except that
* the former may not have self-references and is tagged `text:${algo}:${hash}`
* rather than `fixed:${algo}:${hash}`. The contents of the store path are
* ingested and hashed identically, aside from the slightly different tag and
* restriction on self-references.
*/
struct TextIngestionMethod : std::monostate { };
/** /**
* Compute the prefix to the hash algorithm which indicates how the * Compute the prefix to the hash algorithm which indicates how the
* files were ingested. * files were ingested.
@ -48,14 +29,51 @@ std::string_view makeFileIngestionPrefix(FileIngestionMethod m);
*/ */
struct ContentAddressMethod struct ContentAddressMethod
{ {
typedef std::variant< enum struct Raw {
TextIngestionMethod, /**
FileIngestionMethod * Calculate a store path using the `FileIngestionMethod::Flat`
> Raw; * 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,
};
Raw raw; Raw raw;
GENERATE_CMP(ContentAddressMethod, me->raw); auto operator <=>(const ContentAddressMethod &) const = default;
MAKE_WRAPPER_CONSTRUCTOR(ContentAddressMethod); MAKE_WRAPPER_CONSTRUCTOR(ContentAddressMethod);
@ -141,7 +159,7 @@ struct ContentAddress
*/ */
Hash hash; Hash hash;
GENERATE_CMP(ContentAddress, me->method, me->hash); auto operator <=>(const ContentAddress &) const = default;
/** /**
* Compute the content-addressability assertion * Compute the content-addressability assertion
@ -200,7 +218,7 @@ struct StoreReferences
*/ */
size_t size() const; size_t size() const;
GENERATE_CMP(StoreReferences, me->self, me->others); auto operator <=>(const StoreReferences &) const = default;
}; };
// This matches the additional info that we need for makeTextPath // This matches the additional info that we need for makeTextPath
@ -217,7 +235,7 @@ struct TextInfo
*/ */
StorePathSet references; StorePathSet references;
GENERATE_CMP(TextInfo, me->hash, me->references); auto operator <=>(const TextInfo &) const = default;
}; };
struct FixedOutputInfo struct FixedOutputInfo
@ -237,7 +255,7 @@ struct FixedOutputInfo
*/ */
StoreReferences references; StoreReferences references;
GENERATE_CMP(FixedOutputInfo, me->hash, me->references); auto operator <=>(const FixedOutputInfo &) const = default;
}; };
/** /**
@ -254,7 +272,7 @@ struct ContentAddressWithReferences
Raw raw; Raw raw;
GENERATE_CMP(ContentAddressWithReferences, me->raw); auto operator <=>(const ContentAddressWithReferences &) const = default;
MAKE_WRAPPER_CONSTRUCTOR(ContentAddressWithReferences); MAKE_WRAPPER_CONSTRUCTOR(ContentAddressWithReferences);

View file

@ -435,19 +435,21 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
} else { } else {
HashAlgorithm hashAlgo; HashAlgorithm hashAlgo;
std::string baseName; std::string baseName;
FileIngestionMethod method; ContentAddressMethod method;
{ {
bool fixed; bool fixed;
uint8_t recursive; uint8_t recursive;
std::string hashAlgoRaw; std::string hashAlgoRaw;
from >> baseName >> fixed /* obsolete */ >> recursive >> hashAlgoRaw; from >> baseName >> fixed /* obsolete */ >> recursive >> hashAlgoRaw;
if (recursive > (uint8_t) FileIngestionMethod::NixArchive) if (recursive > true)
throw Error("unsupported FileIngestionMethod with value of %i; you may need to upgrade nix-daemon", recursive); throw Error("unsupported FileIngestionMethod with value of %i; you may need to upgrade nix-daemon", recursive);
method = FileIngestionMethod { recursive }; method = recursive
? ContentAddressMethod::Raw::NixArchive
: ContentAddressMethod::Raw::Flat;
/* Compatibility hack. */ /* Compatibility hack. */
if (!fixed) { if (!fixed) {
hashAlgoRaw = "sha256"; hashAlgoRaw = "sha256";
method = FileIngestionMethod::NixArchive; method = ContentAddressMethod::Raw::NixArchive;
} }
hashAlgo = parseHashAlgo(hashAlgoRaw); hashAlgo = parseHashAlgo(hashAlgoRaw);
} }
@ -500,7 +502,7 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
logger->startWork(); logger->startWork();
auto path = ({ auto path = ({
StringSource source { s }; StringSource source { s };
store->addToStoreFromDump(source, suffix, FileSerialisationMethod::Flat, TextIngestionMethod {}, HashAlgorithm::SHA256, refs, NoRepair); store->addToStoreFromDump(source, suffix, FileSerialisationMethod::Flat, ContentAddressMethod::Raw::Text, HashAlgorithm::SHA256, refs, NoRepair);
}); });
logger->stopWork(); logger->stopWork();
to << store->printStorePath(path); to << store->printStorePath(path);

View file

@ -150,7 +150,7 @@ StorePath writeDerivation(Store & store,
}) })
: ({ : ({
StringSource s { contents }; StringSource s { contents };
store.addToStoreFromDump(s, suffix, FileSerialisationMethod::Flat, TextIngestionMethod {}, HashAlgorithm::SHA256, references, repair); store.addToStoreFromDump(s, suffix, FileSerialisationMethod::Flat, ContentAddressMethod::Raw::Text, HashAlgorithm::SHA256, references, repair);
}); });
} }
@ -274,7 +274,7 @@ static DerivationOutput parseDerivationOutput(
{ {
if (hashAlgoStr != "") { if (hashAlgoStr != "") {
ContentAddressMethod method = ContentAddressMethod::parsePrefix(hashAlgoStr); ContentAddressMethod method = ContentAddressMethod::parsePrefix(hashAlgoStr);
if (method == TextIngestionMethod {}) if (method == ContentAddressMethod::Raw::Text)
xpSettings.require(Xp::DynamicDerivations); xpSettings.require(Xp::DynamicDerivations);
const auto hashAlgo = parseHashAlgo(hashAlgoStr); const auto hashAlgo = parseHashAlgo(hashAlgoStr);
if (hashS == "impure") { if (hashS == "impure") {
@ -1249,7 +1249,7 @@ DerivationOutput DerivationOutput::fromJSON(
auto methodAlgo = [&]() -> std::pair<ContentAddressMethod, HashAlgorithm> { auto methodAlgo = [&]() -> std::pair<ContentAddressMethod, HashAlgorithm> {
auto & method_ = getString(valueAt(json, "method")); auto & method_ = getString(valueAt(json, "method"));
ContentAddressMethod method = ContentAddressMethod::parse(method_); ContentAddressMethod method = ContentAddressMethod::parse(method_);
if (method == TextIngestionMethod {}) if (method == ContentAddressMethod::Raw::Text)
xpSettings.require(Xp::DynamicDerivations); xpSettings.require(Xp::DynamicDerivations);
auto & hashAlgo_ = getString(valueAt(json, "hashAlgo")); auto & hashAlgo_ = getString(valueAt(json, "hashAlgo"));

View file

@ -1253,7 +1253,7 @@ StorePath LocalStore::addToStoreFromDump(
std::filesystem::path tempDir; std::filesystem::path tempDir;
AutoCloseFD tempDirFd; AutoCloseFD tempDirFd;
bool methodsMatch = ContentAddressMethod(FileIngestionMethod(dumpMethod)) == hashMethod; bool methodsMatch = static_cast<FileIngestionMethod>(dumpMethod) == hashMethod.getFileIngestionMethod();
/* If the methods don't match, our streaming hash of the dump is the /* If the methods don't match, our streaming hash of the dump is the
wrong sort, and we need to rehash. */ wrong sort, and we need to rehash. */

View file

@ -48,15 +48,21 @@ std::optional<ContentAddressWithReferences> ValidPathInfo::contentAddressWithRef
if (! ca) if (! ca)
return std::nullopt; return std::nullopt;
return std::visit(overloaded { switch (ca->method.raw) {
[&](const TextIngestionMethod &) -> ContentAddressWithReferences { case ContentAddressMethod::Raw::Text:
{
assert(references.count(path) == 0); assert(references.count(path) == 0);
return TextInfo { return TextInfo {
.hash = ca->hash, .hash = ca->hash,
.references = references, .references = references,
}; };
}, }
[&](const FileIngestionMethod & m2) -> ContentAddressWithReferences {
case ContentAddressMethod::Raw::Flat:
case ContentAddressMethod::Raw::NixArchive:
case ContentAddressMethod::Raw::Git:
default:
{
auto refs = references; auto refs = references;
bool hasSelfReference = false; bool hasSelfReference = false;
if (refs.count(path)) { if (refs.count(path)) {
@ -64,15 +70,15 @@ std::optional<ContentAddressWithReferences> ValidPathInfo::contentAddressWithRef
refs.erase(path); refs.erase(path);
} }
return FixedOutputInfo { return FixedOutputInfo {
.method = m2, .method = ca->method.getFileIngestionMethod(),
.hash = ca->hash, .hash = ca->hash,
.references = { .references = {
.others = std::move(refs), .others = std::move(refs),
.self = hasSelfReference, .self = hasSelfReference,
}, },
}; };
}, }
}, ca->method.raw); }
} }
bool ValidPathInfo::isContentAddressed(const Store & store) const bool ValidPathInfo::isContentAddressed(const Store & store) const
@ -127,22 +133,18 @@ ValidPathInfo::ValidPathInfo(
: UnkeyedValidPathInfo(narHash) : UnkeyedValidPathInfo(narHash)
, path(store.makeFixedOutputPathFromCA(name, ca)) , path(store.makeFixedOutputPathFromCA(name, ca))
{ {
this->ca = ContentAddress {
.method = ca.getMethod(),
.hash = ca.getHash(),
};
std::visit(overloaded { std::visit(overloaded {
[this](TextInfo && ti) { [this](TextInfo && ti) {
this->references = std::move(ti.references); this->references = std::move(ti.references);
this->ca = ContentAddress {
.method = TextIngestionMethod {},
.hash = std::move(ti.hash),
};
}, },
[this](FixedOutputInfo && foi) { [this](FixedOutputInfo && foi) {
this->references = std::move(foi.references.others); this->references = std::move(foi.references.others);
if (foi.references.self) if (foi.references.self)
this->references.insert(path); this->references.insert(path);
this->ca = ContentAddress {
.method = std::move(foi.method),
.hash = std::move(foi.hash),
};
}, },
}, std::move(ca).raw); }, std::move(ca).raw);
} }

View file

@ -392,8 +392,9 @@ ref<const ValidPathInfo> RemoteStore::addCAToStore(
else { else {
if (repair) throw Error("repairing is not supported when building through the Nix daemon protocol < 1.25"); if (repair) throw Error("repairing is not supported when building through the Nix daemon protocol < 1.25");
std::visit(overloaded { switch (caMethod.raw) {
[&](const TextIngestionMethod & thm) -> void { case ContentAddressMethod::Raw::Text:
{
if (hashAlgo != HashAlgorithm::SHA256) if (hashAlgo != HashAlgorithm::SHA256)
throw UnimplementedError("When adding text-hashed data called '%s', only SHA-256 is supported but '%s' was given", throw UnimplementedError("When adding text-hashed data called '%s', only SHA-256 is supported but '%s' was given",
name, printHashAlgo(hashAlgo)); name, printHashAlgo(hashAlgo));
@ -401,8 +402,14 @@ ref<const ValidPathInfo> RemoteStore::addCAToStore(
conn->to << WorkerProto::Op::AddTextToStore << name << s; conn->to << WorkerProto::Op::AddTextToStore << name << s;
WorkerProto::write(*this, *conn, references); WorkerProto::write(*this, *conn, references);
conn.processStderr(); conn.processStderr();
}, break;
[&](const FileIngestionMethod & fim) -> void { }
case ContentAddressMethod::Raw::Flat:
case ContentAddressMethod::Raw::NixArchive:
case ContentAddressMethod::Raw::Git:
default:
{
auto fim = caMethod.getFileIngestionMethod();
conn->to conn->to
<< WorkerProto::Op::AddToStore << WorkerProto::Op::AddToStore
<< name << name
@ -432,9 +439,9 @@ ref<const ValidPathInfo> RemoteStore::addCAToStore(
} catch (EndOfFile & e) { } } catch (EndOfFile & e) { }
throw; throw;
} }
break;
} }
}, caMethod.raw); }
auto path = parseStorePath(readString(conn->from)); auto path = parseStorePath(readString(conn->from));
// Release our connection to prevent a deadlock in queryPathInfo(). // Release our connection to prevent a deadlock in queryPathInfo().
conn_.reset(); conn_.reset();

View file

@ -356,7 +356,7 @@ ValidPathInfo Store::addToStoreSlow(
RegularFileSink fileSink { caHashSink }; RegularFileSink fileSink { caHashSink };
TeeSink unusualHashTee { narHashSink, caHashSink }; TeeSink unusualHashTee { narHashSink, caHashSink };
auto & narSink = method == FileIngestionMethod::NixArchive && hashAlgo != HashAlgorithm::SHA256 auto & narSink = method == ContentAddressMethod::Raw::NixArchive && hashAlgo != HashAlgorithm::SHA256
? static_cast<Sink &>(unusualHashTee) ? static_cast<Sink &>(unusualHashTee)
: narHashSink; : narHashSink;
@ -384,9 +384,9 @@ ValidPathInfo Store::addToStoreSlow(
finish. */ finish. */
auto [narHash, narSize] = narHashSink.finish(); auto [narHash, narSize] = narHashSink.finish();
auto hash = method == FileIngestionMethod::NixArchive && hashAlgo == HashAlgorithm::SHA256 auto hash = method == ContentAddressMethod::Raw::NixArchive && hashAlgo == HashAlgorithm::SHA256
? narHash ? narHash
: method == FileIngestionMethod::Git : method == ContentAddressMethod::Raw::Git
? git::dumpHash(hashAlgo, srcPath).hash ? git::dumpHash(hashAlgo, srcPath).hash
: caHashSink.finish().first; : caHashSink.finish().first;

View file

@ -441,7 +441,7 @@ public:
virtual StorePath addToStore( virtual StorePath addToStore(
std::string_view name, std::string_view name,
const SourcePath & path, const SourcePath & path,
ContentAddressMethod method = FileIngestionMethod::NixArchive, ContentAddressMethod method = ContentAddressMethod::Raw::NixArchive,
HashAlgorithm hashAlgo = HashAlgorithm::SHA256, HashAlgorithm hashAlgo = HashAlgorithm::SHA256,
const StorePathSet & references = StorePathSet(), const StorePathSet & references = StorePathSet(),
PathFilter & filter = defaultPathFilter, PathFilter & filter = defaultPathFilter,
@ -455,7 +455,7 @@ public:
ValidPathInfo addToStoreSlow( ValidPathInfo addToStoreSlow(
std::string_view name, std::string_view name,
const SourcePath & path, const SourcePath & path,
ContentAddressMethod method = FileIngestionMethod::NixArchive, ContentAddressMethod method = ContentAddressMethod::Raw::NixArchive,
HashAlgorithm hashAlgo = HashAlgorithm::SHA256, HashAlgorithm hashAlgo = HashAlgorithm::SHA256,
const StorePathSet & references = StorePathSet(), const StorePathSet & references = StorePathSet(),
std::optional<Hash> expectedCAHash = {}); std::optional<Hash> expectedCAHash = {});
@ -481,7 +481,7 @@ public:
Source & dump, Source & dump,
std::string_view name, std::string_view name,
FileSerialisationMethod dumpMethod = FileSerialisationMethod::NixArchive, FileSerialisationMethod dumpMethod = FileSerialisationMethod::NixArchive,
ContentAddressMethod hashMethod = FileIngestionMethod::NixArchive, ContentAddressMethod hashMethod = ContentAddressMethod::Raw::NixArchive,
HashAlgorithm hashAlgo = HashAlgorithm::SHA256, HashAlgorithm hashAlgo = HashAlgorithm::SHA256,
const StorePathSet & references = StorePathSet(), const StorePathSet & references = StorePathSet(),
RepairFlag repair = NoRepair) = 0; RepairFlag repair = NoRepair) = 0;

View file

@ -117,6 +117,8 @@ enum struct FileIngestionMethod : uint8_t {
/** /**
* Git hashing. * Git hashing.
* *
* Part of `ExperimentalFeature::GitHashing`.
*
* See `file-system-object/content-address.md#serial-git` in the * See `file-system-object/content-address.md#serial-git` in the
* manual. * manual.
*/ */

View file

@ -115,7 +115,7 @@ bool createUserEnv(EvalState & state, PackageInfos & elems,
std::string str2 = str.str(); std::string str2 = str.str();
StringSource source { str2 }; StringSource source { str2 };
state.store->addToStoreFromDump( state.store->addToStoreFromDump(
source, "env-manifest.nix", FileSerialisationMethod::Flat, TextIngestionMethod {}, HashAlgorithm::SHA256, references); source, "env-manifest.nix", FileSerialisationMethod::Flat, ContentAddressMethod::Raw::Text, HashAlgorithm::SHA256, references);
}); });
/* Get the environment builder expression. */ /* Get the environment builder expression. */

View file

@ -194,10 +194,10 @@ static void opAdd(Strings opFlags, Strings opArgs)
store. */ store. */
static void opAddFixed(Strings opFlags, Strings opArgs) static void opAddFixed(Strings opFlags, Strings opArgs)
{ {
auto method = FileIngestionMethod::Flat; ContentAddressMethod method = ContentAddressMethod::Raw::Flat;
for (auto & i : opFlags) for (auto & i : opFlags)
if (i == "--recursive") method = FileIngestionMethod::NixArchive; if (i == "--recursive") method = ContentAddressMethod::Raw::NixArchive;
else throw UsageError("unknown flag '%1%'", i); else throw UsageError("unknown flag '%1%'", i);
if (opArgs.empty()) if (opArgs.empty())

View file

@ -12,7 +12,7 @@ struct CmdAddToStore : MixDryRun, StoreCommand
{ {
Path path; Path path;
std::optional<std::string> namePart; std::optional<std::string> namePart;
ContentAddressMethod caMethod = FileIngestionMethod::NixArchive; ContentAddressMethod caMethod = ContentAddressMethod::Raw::NixArchive;
HashAlgorithm hashAlgo = HashAlgorithm::SHA256; HashAlgorithm hashAlgo = HashAlgorithm::SHA256;
CmdAddToStore() CmdAddToStore()
@ -68,7 +68,7 @@ struct CmdAddFile : CmdAddToStore
{ {
CmdAddFile() CmdAddFile()
{ {
caMethod = FileIngestionMethod::Flat; caMethod = ContentAddressMethod::Raw::Flat;
} }
std::string description() override std::string description() override

View file

@ -238,7 +238,7 @@ static StorePath getDerivationEnvironment(ref<Store> store, ref<Store> evalStore
auto getEnvShPath = ({ auto getEnvShPath = ({
StringSource source { getEnvSh }; StringSource source { getEnvSh };
evalStore->addToStoreFromDump( evalStore->addToStoreFromDump(
source, "get-env.sh", FileSerialisationMethod::Flat, TextIngestionMethod {}, HashAlgorithm::SHA256, {}); source, "get-env.sh", FileSerialisationMethod::Flat, ContentAddressMethod::Raw::Text, HashAlgorithm::SHA256, {});
}); });
drv.args = {store->printStorePath(getEnvShPath)}; drv.args = {store->printStorePath(getEnvShPath)};

View file

@ -57,7 +57,9 @@ std::tuple<StorePath, Hash> prefetchFile(
bool unpack, bool unpack,
bool executable) bool executable)
{ {
auto ingestionMethod = unpack || executable ? FileIngestionMethod::NixArchive : FileIngestionMethod::Flat; ContentAddressMethod method = unpack || executable
? ContentAddressMethod::Raw::NixArchive
: ContentAddressMethod::Raw::Flat;
/* Figure out a name in the Nix store. */ /* Figure out a name in the Nix store. */
if (!name) { if (!name) {
@ -73,11 +75,10 @@ std::tuple<StorePath, Hash> prefetchFile(
the store. */ the store. */
if (expectedHash) { if (expectedHash) {
hashAlgo = expectedHash->algo; hashAlgo = expectedHash->algo;
storePath = store->makeFixedOutputPath(*name, FixedOutputInfo { storePath = store->makeFixedOutputPathFromCA(*name, ContentAddressWithReferences::fromParts(
.method = ingestionMethod, method,
.hash = *expectedHash, *expectedHash,
.references = {}, {}));
});
if (store->isValidPath(*storePath)) if (store->isValidPath(*storePath))
hash = expectedHash; hash = expectedHash;
else else
@ -128,7 +129,7 @@ std::tuple<StorePath, Hash> prefetchFile(
auto info = store->addToStoreSlow( auto info = store->addToStoreSlow(
*name, PosixSourceAccessor::createAtRoot(tmpFile), *name, PosixSourceAccessor::createAtRoot(tmpFile),
ingestionMethod, hashAlgo, {}, expectedHash); method, hashAlgo, {}, expectedHash);
storePath = info.path; storePath = info.path;
assert(info.ca); assert(info.ca);
hash = info.ca->hash; hash = info.ca->hash;

View file

@ -335,7 +335,7 @@ SV *
StoreWrapper::addToStore(char * srcPath, int recursive, char * algo) StoreWrapper::addToStore(char * srcPath, int recursive, char * algo)
PPCODE: PPCODE:
try { try {
auto method = recursive ? FileIngestionMethod::NixArchive : FileIngestionMethod::Flat; auto method = recursive ? ContentAddressMethod::Raw::NixArchive : ContentAddressMethod::Raw::Flat;
auto path = THIS->store->addToStore( auto path = THIS->store->addToStore(
std::string(baseNameOf(srcPath)), std::string(baseNameOf(srcPath)),
PosixSourceAccessor::createAtRoot(srcPath), PosixSourceAccessor::createAtRoot(srcPath),

View file

@ -83,15 +83,15 @@ CHARACTERIZATION_TEST(
"content-address", "content-address",
(std::tuple<ContentAddress, ContentAddress, ContentAddress> { (std::tuple<ContentAddress, ContentAddress, ContentAddress> {
ContentAddress { ContentAddress {
.method = TextIngestionMethod {}, .method = ContentAddressMethod::Raw::Text,
.hash = hashString(HashAlgorithm::SHA256, "Derive(...)"), .hash = hashString(HashAlgorithm::SHA256, "Derive(...)"),
}, },
ContentAddress { ContentAddress {
.method = FileIngestionMethod::Flat, .method = ContentAddressMethod::Raw::Flat,
.hash = hashString(HashAlgorithm::SHA1, "blob blob..."), .hash = hashString(HashAlgorithm::SHA1, "blob blob..."),
}, },
ContentAddress { ContentAddress {
.method = FileIngestionMethod::NixArchive, .method = ContentAddressMethod::Raw::NixArchive,
.hash = hashString(HashAlgorithm::SHA256, "(...)"), .hash = hashString(HashAlgorithm::SHA256, "(...)"),
}, },
})) }))
@ -178,7 +178,7 @@ CHARACTERIZATION_TEST(
std::nullopt, std::nullopt,
std::optional { std::optional {
ContentAddress { ContentAddress {
.method = FileIngestionMethod::Flat, .method = ContentAddressMethod::Raw::Flat,
.hash = hashString(HashAlgorithm::SHA1, "blob blob..."), .hash = hashString(HashAlgorithm::SHA1, "blob blob..."),
}, },
}, },

View file

@ -9,11 +9,11 @@ namespace nix {
* --------------------------------------------------------------------------*/ * --------------------------------------------------------------------------*/
TEST(ContentAddressMethod, testRoundTripPrintParse_1) { TEST(ContentAddressMethod, testRoundTripPrintParse_1) {
for (const ContentAddressMethod & cam : { for (ContentAddressMethod cam : {
ContentAddressMethod { TextIngestionMethod {} }, ContentAddressMethod::Raw::Text,
ContentAddressMethod { FileIngestionMethod::Flat }, ContentAddressMethod::Raw::Flat,
ContentAddressMethod { FileIngestionMethod::NixArchive }, ContentAddressMethod::Raw::NixArchive,
ContentAddressMethod { FileIngestionMethod::Git }, ContentAddressMethod::Raw::Git,
}) { }) {
EXPECT_EQ(ContentAddressMethod::parse(cam.render()), cam); EXPECT_EQ(ContentAddressMethod::parse(cam.render()), cam);
} }

View file

@ -108,7 +108,7 @@ TEST_JSON(DerivationTest, inputAddressed,
TEST_JSON(DerivationTest, caFixedFlat, TEST_JSON(DerivationTest, caFixedFlat,
(DerivationOutput::CAFixed { (DerivationOutput::CAFixed {
.ca = { .ca = {
.method = FileIngestionMethod::Flat, .method = ContentAddressMethod::Raw::Flat,
.hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="), .hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="),
}, },
}), }),
@ -117,7 +117,7 @@ TEST_JSON(DerivationTest, caFixedFlat,
TEST_JSON(DerivationTest, caFixedNAR, TEST_JSON(DerivationTest, caFixedNAR,
(DerivationOutput::CAFixed { (DerivationOutput::CAFixed {
.ca = { .ca = {
.method = FileIngestionMethod::NixArchive, .method = ContentAddressMethod::Raw::NixArchive,
.hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="), .hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="),
}, },
}), }),
@ -126,6 +126,7 @@ TEST_JSON(DerivationTest, caFixedNAR,
TEST_JSON(DynDerivationTest, caFixedText, TEST_JSON(DynDerivationTest, caFixedText,
(DerivationOutput::CAFixed { (DerivationOutput::CAFixed {
.ca = { .ca = {
.method = ContentAddressMethod::Raw::Text,
.hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="), .hash = Hash::parseAnyPrefixed("sha256-iUUXyRY8iW7DGirb0zwGgf1fRbLA7wimTJKgP7l/OQ8="),
}, },
}), }),
@ -133,7 +134,7 @@ TEST_JSON(DynDerivationTest, caFixedText,
TEST_JSON(CaDerivationTest, caFloating, TEST_JSON(CaDerivationTest, caFloating,
(DerivationOutput::CAFloating { (DerivationOutput::CAFloating {
.method = FileIngestionMethod::NixArchive, .method = ContentAddressMethod::Raw::NixArchive,
.hashAlgo = HashAlgorithm::SHA256, .hashAlgo = HashAlgorithm::SHA256,
}), }),
"drv-name", "output-name") "drv-name", "output-name")
@ -144,7 +145,7 @@ TEST_JSON(DerivationTest, deferred,
TEST_JSON(ImpureDerivationTest, impure, TEST_JSON(ImpureDerivationTest, impure,
(DerivationOutput::Impure { (DerivationOutput::Impure {
.method = FileIngestionMethod::NixArchive, .method = ContentAddressMethod::Raw::NixArchive,
.hashAlgo = HashAlgorithm::SHA256, .hashAlgo = HashAlgorithm::SHA256,
}), }),
"drv-name", "output-name") "drv-name", "output-name")

View file

@ -55,15 +55,15 @@ VERSIONED_CHARACTERIZATION_TEST(
defaultVersion, defaultVersion,
(std::tuple<ContentAddress, ContentAddress, ContentAddress> { (std::tuple<ContentAddress, ContentAddress, ContentAddress> {
ContentAddress { ContentAddress {
.method = TextIngestionMethod {}, .method = ContentAddressMethod::Raw::Text,
.hash = hashString(HashAlgorithm::SHA256, "Derive(...)"), .hash = hashString(HashAlgorithm::SHA256, "Derive(...)"),
}, },
ContentAddress { ContentAddress {
.method = FileIngestionMethod::Flat, .method = ContentAddressMethod::Raw::Flat,
.hash = hashString(HashAlgorithm::SHA1, "blob blob..."), .hash = hashString(HashAlgorithm::SHA1, "blob blob..."),
}, },
ContentAddress { ContentAddress {
.method = FileIngestionMethod::NixArchive, .method = ContentAddressMethod::Raw::NixArchive,
.hash = hashString(HashAlgorithm::SHA256, "(...)"), .hash = hashString(HashAlgorithm::SHA256, "(...)"),
}, },
})) }))
@ -398,7 +398,7 @@ VERSIONED_CHARACTERIZATION_TEST(
std::nullopt, std::nullopt,
std::optional { std::optional {
ContentAddress { ContentAddress {
.method = FileIngestionMethod::Flat, .method = ContentAddressMethod::Raw::Flat,
.hash = hashString(HashAlgorithm::SHA1, "blob blob..."), .hash = hashString(HashAlgorithm::SHA1, "blob blob..."),
}, },
}, },

View file

@ -56,15 +56,15 @@ VERSIONED_CHARACTERIZATION_TEST(
defaultVersion, defaultVersion,
(std::tuple<ContentAddress, ContentAddress, ContentAddress> { (std::tuple<ContentAddress, ContentAddress, ContentAddress> {
ContentAddress { ContentAddress {
.method = TextIngestionMethod {}, .method = ContentAddressMethod::Raw::Text,
.hash = hashString(HashAlgorithm::SHA256, "Derive(...)"), .hash = hashString(HashAlgorithm::SHA256, "Derive(...)"),
}, },
ContentAddress { ContentAddress {
.method = FileIngestionMethod::Flat, .method = ContentAddressMethod::Raw::Flat,
.hash = hashString(HashAlgorithm::SHA1, "blob blob..."), .hash = hashString(HashAlgorithm::SHA1, "blob blob..."),
}, },
ContentAddress { ContentAddress {
.method = FileIngestionMethod::NixArchive, .method = ContentAddressMethod::Raw::NixArchive,
.hash = hashString(HashAlgorithm::SHA256, "(...)"), .hash = hashString(HashAlgorithm::SHA256, "(...)"),
}, },
})) }))
@ -598,7 +598,7 @@ VERSIONED_CHARACTERIZATION_TEST(
std::nullopt, std::nullopt,
std::optional { std::optional {
ContentAddress { ContentAddress {
.method = FileIngestionMethod::Flat, .method = ContentAddressMethod::Raw::Flat,
.hash = hashString(HashAlgorithm::SHA1, "blob blob..."), .hash = hashString(HashAlgorithm::SHA1, "blob blob..."),
}, },
}, },