mirror of
https://github.com/NixOS/nix.git
synced 2025-11-20 17:29:36 +01:00
Merge remote-tracking branch 'upstream/master' into ca-drv
This commit is contained in:
commit
93bbe6e8ab
48 changed files with 463 additions and 222 deletions
|
|
@ -388,8 +388,6 @@ void BinaryCacheStore::addSignatures(const StorePath & storePath, const StringSe
|
|||
|
||||
narInfo->sigs.insert(sigs.begin(), sigs.end());
|
||||
|
||||
auto narInfoFile = narInfoFileFor(narInfo->path);
|
||||
|
||||
writeNarInfo(narInfo);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ struct HookInstance;
|
|||
|
||||
|
||||
/* A pointer to a goal. */
|
||||
class Goal;
|
||||
struct Goal;
|
||||
class DerivationGoal;
|
||||
typedef std::shared_ptr<Goal> GoalPtr;
|
||||
typedef std::weak_ptr<Goal> WeakGoalPtr;
|
||||
|
|
@ -1195,6 +1195,12 @@ void DerivationGoal::haveDerivation()
|
|||
|
||||
parsedDrv = std::make_unique<ParsedDerivation>(drvPath, *drv);
|
||||
|
||||
if (parsedDrv->contentAddressed()) {
|
||||
settings.requireExperimentalFeature("ca-derivations");
|
||||
throw Error("ca-derivations isn't implemented yet");
|
||||
}
|
||||
|
||||
|
||||
/* We are first going to try to create the invalid output paths
|
||||
through substitutes. If that doesn't work, we'll build
|
||||
them. */
|
||||
|
|
@ -3712,10 +3718,7 @@ void DerivationGoal::registerOutputs()
|
|||
|
||||
if (derivationIsFixed(derivationType)) {
|
||||
|
||||
FileIngestionMethod outputHashMode; Hash h;
|
||||
i.second.parseHashInfo(outputHashMode, h);
|
||||
|
||||
if (outputHashMode == FileIngestionMethod::Flat) {
|
||||
if (i.second.hash->method == FileIngestionMethod::Flat) {
|
||||
/* The output path should be a regular file without execute permission. */
|
||||
if (!S_ISREG(st.st_mode) || (st.st_mode & S_IXUSR) != 0)
|
||||
throw BuildError(
|
||||
|
|
@ -3726,20 +3729,22 @@ void DerivationGoal::registerOutputs()
|
|||
|
||||
/* Check the hash. In hash mode, move the path produced by
|
||||
the derivation to its content-addressed location. */
|
||||
Hash h2 = outputHashMode == FileIngestionMethod::Recursive
|
||||
? hashPath(h.type, actualPath).first
|
||||
: hashFile(h.type, actualPath);
|
||||
Hash h2 = i.second.hash->method == FileIngestionMethod::Recursive
|
||||
? hashPath(*i.second.hash->hash.type, actualPath).first
|
||||
: hashFile(*i.second.hash->hash.type, actualPath);
|
||||
|
||||
auto dest = worker.store.makeFixedOutputPath(outputHashMode, h2, i.second.path.name());
|
||||
auto dest = worker.store.makeFixedOutputPath(i.second.hash->method, h2, i.second.path.name());
|
||||
|
||||
if (h != h2) {
|
||||
if (i.second.hash->hash != h2) {
|
||||
|
||||
/* Throw an error after registering the path as
|
||||
valid. */
|
||||
worker.hashMismatch = true;
|
||||
delayedException = std::make_exception_ptr(
|
||||
BuildError("hash mismatch in fixed-output derivation '%s':\n wanted: %s\n got: %s",
|
||||
worker.store.printStorePath(dest), h.to_string(SRI, true), h2.to_string(SRI, true)));
|
||||
worker.store.printStorePath(dest),
|
||||
i.second.hash->hash.to_string(SRI, true),
|
||||
h2.to_string(SRI, true)));
|
||||
|
||||
Path actualDest = worker.store.Store::toRealPath(dest);
|
||||
|
||||
|
|
@ -3759,7 +3764,7 @@ void DerivationGoal::registerOutputs()
|
|||
else
|
||||
assert(worker.store.parseStorePath(path) == dest);
|
||||
|
||||
ca = makeFixedOutputCA(outputHashMode, h2);
|
||||
ca = makeFixedOutputCA(i.second.hash->method, h2);
|
||||
}
|
||||
|
||||
/* Get rid of all weird permissions. This also checks that
|
||||
|
|
@ -4992,7 +4997,7 @@ bool Worker::pathContentsGood(const StorePath & path)
|
|||
if (!pathExists(store.printStorePath(path)))
|
||||
res = false;
|
||||
else {
|
||||
HashResult current = hashPath(info->narHash.type, store.printStorePath(path));
|
||||
HashResult current = hashPath(*info->narHash.type, store.printStorePath(path));
|
||||
Hash nullHash(htSHA256);
|
||||
res = info->narHash == nullHash || info->narHash == current.first;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,9 +63,9 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData)
|
|||
for (auto hashedMirror : settings.hashedMirrors.get())
|
||||
try {
|
||||
if (!hasSuffix(hashedMirror, "/")) hashedMirror += '/';
|
||||
auto ht = parseHashType(getAttr("outputHashAlgo"));
|
||||
auto ht = parseHashTypeOpt(getAttr("outputHashAlgo"));
|
||||
auto h = Hash(getAttr("outputHash"), ht);
|
||||
fetch(hashedMirror + printHashType(h.type) + "/" + h.to_string(Base16, false));
|
||||
fetch(hashedMirror + printHashType(*h.type) + "/" + h.to_string(Base16, false));
|
||||
return;
|
||||
} catch (Error & e) {
|
||||
debug(e.what());
|
||||
|
|
|
|||
|
|
@ -8,32 +8,8 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
// Avoid shadow
|
||||
HashType parseHashAlgo(const string & s) {
|
||||
return parseHashType(s);
|
||||
}
|
||||
|
||||
void DerivationOutput::parseHashType(FileIngestionMethod & recursive, HashType & hashType) const
|
||||
{
|
||||
recursive = FileIngestionMethod::Flat;
|
||||
string algo = hashAlgo;
|
||||
|
||||
if (string(algo, 0, 2) == "r:") {
|
||||
recursive = FileIngestionMethod::Recursive;
|
||||
algo = string(algo, 2);
|
||||
}
|
||||
|
||||
HashType hashType_loc = parseHashAlgo(algo);
|
||||
if (hashType_loc == htUnknown)
|
||||
throw Error("unknown hash algorithm '%s'", algo);
|
||||
hashType = hashType_loc;
|
||||
}
|
||||
|
||||
void DerivationOutput::parseHashInfo(FileIngestionMethod & recursive, Hash & hash) const
|
||||
{
|
||||
HashType hashType;
|
||||
parseHashType(recursive, hashType);
|
||||
hash = Hash(this->hash, hashType);
|
||||
std::string DerivationOutputHash::printMethodAlgo() const {
|
||||
return makeFileIngestionPrefix(method) + printHashType(*hash.type);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -156,6 +132,34 @@ static StringSet parseStrings(std::istream & str, bool arePaths)
|
|||
}
|
||||
|
||||
|
||||
static DerivationOutput parseDerivationOutput(const Store & store, istringstream_nocopy & str)
|
||||
{
|
||||
expect(str, ","); auto path = store.parseStorePath(parsePath(str));
|
||||
expect(str, ","); auto hashAlgo = parseString(str);
|
||||
expect(str, ","); const auto hash = parseString(str);
|
||||
expect(str, ")");
|
||||
|
||||
std::optional<DerivationOutputHash> fsh;
|
||||
if (hashAlgo != "") {
|
||||
auto method = FileIngestionMethod::Flat;
|
||||
if (string(hashAlgo, 0, 2) == "r:") {
|
||||
method = FileIngestionMethod::Recursive;
|
||||
hashAlgo = string(hashAlgo, 2);
|
||||
}
|
||||
const HashType hashType = parseHashType(hashAlgo);
|
||||
fsh = DerivationOutputHash {
|
||||
.method = std::move(method),
|
||||
.hash = Hash(hash, hashType),
|
||||
};
|
||||
}
|
||||
|
||||
return DerivationOutput {
|
||||
.path = std::move(path),
|
||||
.hash = std::move(fsh),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
static Derivation parseDerivation(const Store & store, const string & s)
|
||||
{
|
||||
Derivation drv;
|
||||
|
|
@ -165,15 +169,8 @@ static Derivation parseDerivation(const Store & store, const string & s)
|
|||
/* Parse the list of outputs. */
|
||||
while (!endOfList(str)) {
|
||||
expect(str, "("); std::string id = parseString(str);
|
||||
expect(str, ","); auto path = store.parseStorePath(parsePath(str));
|
||||
expect(str, ","); auto hashAlgo = parseString(str);
|
||||
expect(str, ","); auto hash = parseString(str);
|
||||
expect(str, ")");
|
||||
drv.outputs.emplace(id, DerivationOutput {
|
||||
.path = std::move(path),
|
||||
.hashAlgo = std::move(hashAlgo),
|
||||
.hash = std::move(hash)
|
||||
});
|
||||
auto output = parseDerivationOutput(store, str);
|
||||
drv.outputs.emplace(std::move(id), std::move(output));
|
||||
}
|
||||
|
||||
/* Parse the list of input derivations. */
|
||||
|
|
@ -299,8 +296,9 @@ string Derivation::unparse(const Store & store, bool maskOutputs,
|
|||
if (first) first = false; else s += ',';
|
||||
s += '('; printUnquotedString(s, i.first);
|
||||
s += ','; printUnquotedString(s, maskOutputs ? "" : store.printStorePath(i.second.path));
|
||||
s += ','; printUnquotedString(s, i.second.hashAlgo);
|
||||
s += ','; printUnquotedString(s, i.second.hash);
|
||||
s += ','; printUnquotedString(s, i.second.hash ? i.second.hash->printMethodAlgo() : "");
|
||||
s += ','; printUnquotedString(s,
|
||||
i.second.hash ? i.second.hash->hash.to_string(Base16, false) : "");
|
||||
s += ')';
|
||||
}
|
||||
|
||||
|
|
@ -356,7 +354,7 @@ DerivationType BasicDerivation::type() const
|
|||
{
|
||||
if (outputs.size() == 1 &&
|
||||
outputs.begin()->first == "out" &&
|
||||
outputs.begin()->second.hash != "")
|
||||
outputs.begin()->second.hash)
|
||||
{
|
||||
return DerivationType::CAFixed;
|
||||
} else {
|
||||
|
|
@ -395,8 +393,8 @@ Hash hashDerivationModulo(Store & store, const Derivation & drv, bool maskOutput
|
|||
case DerivationType::CAFixed: {
|
||||
DerivationOutputs::const_iterator i = drv.outputs.begin();
|
||||
return hashString(htSHA256, "fixed:out:"
|
||||
+ i->second.hashAlgo + ":"
|
||||
+ i->second.hash + ":"
|
||||
+ i->second.hash->printMethodAlgo() + ":"
|
||||
+ i->second.hash->hash.to_string(Base16, false) + ":"
|
||||
+ store.printStorePath(i->second.path));
|
||||
}
|
||||
default:
|
||||
|
|
@ -442,6 +440,31 @@ StorePathSet BasicDerivation::outputPaths() const
|
|||
return paths;
|
||||
}
|
||||
|
||||
static DerivationOutput readDerivationOutput(Source & in, const Store & store)
|
||||
{
|
||||
auto path = store.parseStorePath(readString(in));
|
||||
auto hashAlgo = readString(in);
|
||||
const auto hash = readString(in);
|
||||
|
||||
std::optional<DerivationOutputHash> fsh;
|
||||
if (hashAlgo != "") {
|
||||
auto method = FileIngestionMethod::Flat;
|
||||
if (string(hashAlgo, 0, 2) == "r:") {
|
||||
method = FileIngestionMethod::Recursive;
|
||||
hashAlgo = string(hashAlgo, 2);
|
||||
}
|
||||
const HashType hashType = parseHashType(hashAlgo);
|
||||
fsh = DerivationOutputHash {
|
||||
.method = std::move(method),
|
||||
.hash = Hash(hash, hashType),
|
||||
};
|
||||
}
|
||||
|
||||
return DerivationOutput {
|
||||
.path = std::move(path),
|
||||
.hash = std::move(fsh),
|
||||
};
|
||||
}
|
||||
|
||||
StringSet BasicDerivation::outputNames() const
|
||||
{
|
||||
|
|
@ -458,14 +481,8 @@ Source & readDerivation(Source & in, const Store & store, BasicDerivation & drv)
|
|||
auto nr = readNum<size_t>(in);
|
||||
for (size_t n = 0; n < nr; n++) {
|
||||
auto name = readString(in);
|
||||
auto path = store.parseStorePath(readString(in));
|
||||
auto hashAlgo = readString(in);
|
||||
auto hash = readString(in);
|
||||
drv.outputs.emplace(name, DerivationOutput {
|
||||
.path = std::move(path),
|
||||
.hashAlgo = std::move(hashAlgo),
|
||||
.hash = std::move(hash)
|
||||
});
|
||||
auto output = readDerivationOutput(in, store);
|
||||
drv.outputs.emplace(std::move(name), std::move(output));
|
||||
}
|
||||
|
||||
drv.inputSrcs = readStorePaths<StorePathSet>(store, in);
|
||||
|
|
@ -487,7 +504,10 @@ void writeDerivation(Sink & out, const Store & store, const BasicDerivation & dr
|
|||
{
|
||||
out << drv.outputs.size();
|
||||
for (auto & i : drv.outputs)
|
||||
out << i.first << store.printStorePath(i.second.path) << i.second.hashAlgo << i.second.hash;
|
||||
out << i.first
|
||||
<< store.printStorePath(i.second.path)
|
||||
<< i.second.hash->printMethodAlgo()
|
||||
<< i.second.hash->hash.to_string(Base16, false);
|
||||
writeStorePaths(store, out, drv.inputSrcs);
|
||||
out << drv.platform << drv.builder << drv.args;
|
||||
out << drv.env.size();
|
||||
|
|
|
|||
|
|
@ -12,12 +12,17 @@ namespace nix {
|
|||
|
||||
/* Abstract syntax of derivations. */
|
||||
|
||||
/// Pair of a hash, and how the file system was ingested
|
||||
struct DerivationOutputHash {
|
||||
FileIngestionMethod method;
|
||||
Hash hash;
|
||||
std::string printMethodAlgo() const;
|
||||
};
|
||||
|
||||
struct DerivationOutput
|
||||
{
|
||||
StorePath path;
|
||||
std::string hashAlgo; /* hash used for expected hash computation */
|
||||
std::string hash; /* expected hash, may be null */
|
||||
void parseHashType(FileIngestionMethod & recursive, HashType & hashType) const;
|
||||
std::optional<DerivationOutputHash> hash; /* hash used for expected hash computation */
|
||||
void parseHashInfo(FileIngestionMethod & recursive, Hash & hash) const;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ void Store::exportPath(const StorePath & path, Sink & sink)
|
|||
filesystem corruption from spreading to other machines.
|
||||
Don't complain if the stored hash is zero (unknown). */
|
||||
Hash hash = hashAndWriteSink.currentHash();
|
||||
if (hash != info->narHash && info->narHash != Hash(info->narHash.type))
|
||||
if (hash != info->narHash && info->narHash != Hash(*info->narHash.type))
|
||||
throw Error("hash of path '%s' has changed from '%s' to '%s'!",
|
||||
printStorePath(path), info->narHash.to_string(Base32, true), hash.to_string(Base32, true));
|
||||
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ struct curlFileTransfer : public FileTransfer
|
|||
|
||||
curl_off_t writtenToSink = 0;
|
||||
|
||||
inline static const std::set<long> successfulStatuses {200, 201, 204, 206, 304, 0 /* other protocol */};
|
||||
/* Get the HTTP status code, or 0 for other protocols. */
|
||||
long getHTTPStatus()
|
||||
{
|
||||
|
|
@ -98,7 +99,7 @@ struct curlFileTransfer : public FileTransfer
|
|||
|
||||
/* Only write data to the sink if this is a
|
||||
successful response. */
|
||||
if (httpStatus == 0 || httpStatus == 200 || httpStatus == 201 || httpStatus == 206) {
|
||||
if (successfulStatuses.count(httpStatus)) {
|
||||
writtenToSink += len;
|
||||
this->request.dataCallback((char *) data, len);
|
||||
}
|
||||
|
|
@ -352,8 +353,7 @@ struct curlFileTransfer : public FileTransfer
|
|||
if (writeException)
|
||||
failEx(writeException);
|
||||
|
||||
else if (code == CURLE_OK &&
|
||||
(httpStatus == 200 || httpStatus == 201 || httpStatus == 204 || httpStatus == 206 || httpStatus == 304 || httpStatus == 0 /* other protocol */))
|
||||
else if (code == CURLE_OK && successfulStatuses.count(httpStatus))
|
||||
{
|
||||
result.cached = httpStatus == 304;
|
||||
act.progress(result.bodySize, result.bodySize);
|
||||
|
|
|
|||
|
|
@ -561,10 +561,12 @@ void LocalStore::checkDerivationOutputs(const StorePath & drvPath, const Derivat
|
|||
if (out == drv.outputs.end())
|
||||
throw Error("derivation '%s' does not have an output named 'out'", printStorePath(drvPath));
|
||||
|
||||
FileIngestionMethod method; Hash h;
|
||||
out->second.parseHashInfo(method, h);
|
||||
|
||||
check(makeFixedOutputPath(method, h, drvName), out->second.path, "out");
|
||||
check(
|
||||
makeFixedOutputPath(
|
||||
out->second.hash->method,
|
||||
out->second.hash->hash,
|
||||
drvName),
|
||||
out->second.path, "out");
|
||||
}
|
||||
|
||||
else {
|
||||
|
|
@ -1253,9 +1255,9 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
|
|||
|
||||
std::unique_ptr<AbstractHashSink> hashSink;
|
||||
if (info->ca == "" || !info->references.count(info->path))
|
||||
hashSink = std::make_unique<HashSink>(info->narHash.type);
|
||||
hashSink = std::make_unique<HashSink>(*info->narHash.type);
|
||||
else
|
||||
hashSink = std::make_unique<HashModuloSink>(info->narHash.type, std::string(info->path.hashPart()));
|
||||
hashSink = std::make_unique<HashModuloSink>(*info->narHash.type, std::string(info->path.hashPart()));
|
||||
|
||||
dumpPath(Store::toRealPath(i), *hashSink);
|
||||
auto current = hashSink->finish();
|
||||
|
|
|
|||
|
|
@ -117,4 +117,9 @@ bool ParsedDerivation::substitutesAllowed() const
|
|||
return getBoolAttr("allowSubstitutes", true);
|
||||
}
|
||||
|
||||
bool ParsedDerivation::contentAddressed() const
|
||||
{
|
||||
return getBoolAttr("__contentAddressed", false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ public:
|
|||
bool willBuildLocally() const;
|
||||
|
||||
bool substitutesAllowed() const;
|
||||
|
||||
bool contentAddressed() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ struct ConnectionHandle
|
|||
|
||||
~ConnectionHandle()
|
||||
{
|
||||
if (!daemonException && std::uncaught_exception()) {
|
||||
if (!daemonException && std::uncaught_exceptions()) {
|
||||
handle.markBad();
|
||||
debug("closing daemon connection because of an exception");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ StorePathWithOutputs Store::followLinksToStorePathWithOutputs(std::string_view p
|
|||
|
||||
/* Store paths have the following form:
|
||||
|
||||
<store>/<h>-<name>
|
||||
<realized-path> = <store>/<h>-<name>
|
||||
|
||||
where
|
||||
|
||||
|
|
@ -85,11 +85,14 @@ StorePathWithOutputs Store::followLinksToStorePathWithOutputs(std::string_view p
|
|||
<type> = one of:
|
||||
"text:<r1>:<r2>:...<rN>"
|
||||
for plain text files written to the store using
|
||||
addTextToStore(); <r1> ... <rN> are the references of the
|
||||
path.
|
||||
"source"
|
||||
addTextToStore(); <r1> ... <rN> are the store paths referenced
|
||||
by this path, in the form described by <realized-path>
|
||||
"source:<r1>:<r2>:...:<rN>:self"
|
||||
for paths copied to the store using addToStore() when recursive
|
||||
= true and hashAlgo = "sha256"
|
||||
= true and hashAlgo = "sha256". Just like in the text case, we
|
||||
can have the store paths referenced by the path.
|
||||
Additionally, we can have an optional :self label to denote self
|
||||
reference.
|
||||
"output:<id>"
|
||||
for either the outputs created by derivations, OR paths copied
|
||||
to the store using addToStore() with recursive != true or
|
||||
|
|
@ -117,6 +120,12 @@ StorePathWithOutputs Store::followLinksToStorePathWithOutputs(std::string_view p
|
|||
the contents of the path (or expected contents of the
|
||||
path for fixed-output derivations)
|
||||
|
||||
Note that since an output derivation has always type output, while
|
||||
something added by addToStore can have type output or source depending
|
||||
on the hash, this means that the same input can be hashed differently
|
||||
if added to the store via addToStore or via a derivation, in the sha256
|
||||
recursive case.
|
||||
|
||||
It would have been nicer to handle fixed-output derivations under
|
||||
"source", e.g. have something like "source:<rec><algo>", but we're
|
||||
stuck with this for now...
|
||||
|
|
@ -164,20 +173,20 @@ static std::string makeType(
|
|||
|
||||
|
||||
StorePath Store::makeFixedOutputPath(
|
||||
FileIngestionMethod recursive,
|
||||
FileIngestionMethod method,
|
||||
const Hash & hash,
|
||||
std::string_view name,
|
||||
const StorePathSet & references,
|
||||
bool hasSelfReference) const
|
||||
{
|
||||
if (hash.type == htSHA256 && recursive == FileIngestionMethod::Recursive) {
|
||||
if (hash.type == htSHA256 && method == FileIngestionMethod::Recursive) {
|
||||
return makeStorePath(makeType(*this, "source", references, hasSelfReference), hash, name);
|
||||
} else {
|
||||
assert(references.empty());
|
||||
return makeStorePath("output:out",
|
||||
hashString(htSHA256,
|
||||
"fixed:out:"
|
||||
+ (recursive == FileIngestionMethod::Recursive ? (string) "r:" : "")
|
||||
+ makeFileIngestionPrefix(method)
|
||||
+ hash.to_string(Base16, true) + ":"),
|
||||
name);
|
||||
}
|
||||
|
|
@ -813,10 +822,21 @@ Strings ValidPathInfo::shortRefs() const
|
|||
}
|
||||
|
||||
|
||||
std::string makeFixedOutputCA(FileIngestionMethod recursive, const Hash & hash)
|
||||
std::string makeFileIngestionPrefix(const FileIngestionMethod m) {
|
||||
switch (m) {
|
||||
case FileIngestionMethod::Flat:
|
||||
return "";
|
||||
case FileIngestionMethod::Recursive:
|
||||
return "r:";
|
||||
default:
|
||||
throw Error("impossible, caught both cases");
|
||||
}
|
||||
}
|
||||
|
||||
std::string makeFixedOutputCA(FileIngestionMethod method, const Hash & hash)
|
||||
{
|
||||
return "fixed:"
|
||||
+ (recursive == FileIngestionMethod::Recursive ? (std::string) "r:" : "")
|
||||
+ makeFileIngestionPrefix(method)
|
||||
+ hash.to_string(Base32, true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -189,9 +189,10 @@ struct ValidPathInfo
|
|||
|
||||
Strings shortRefs() const;
|
||||
|
||||
ValidPathInfo(const StorePath & path) : path(path) { }
|
||||
ValidPathInfo(const ValidPathInfo & other) = default;
|
||||
|
||||
ValidPathInfo(StorePath && path) : path(std::move(path)) { }
|
||||
ValidPathInfo(StorePath && path) : path(std::move(path)) { };
|
||||
ValidPathInfo(const StorePath & path) : path(path) { };
|
||||
|
||||
virtual ~ValidPathInfo() { }
|
||||
};
|
||||
|
|
@ -838,6 +839,9 @@ std::optional<ValidPathInfo> decodeValidPathInfo(
|
|||
std::istream & str,
|
||||
bool hashGiven = false);
|
||||
|
||||
/* Compute the prefix to the hash algorithm which indicates how the files were
|
||||
ingested. */
|
||||
std::string makeFileIngestionPrefix(const FileIngestionMethod m);
|
||||
|
||||
/* Compute the content-addressability assertion (ValidPathInfo::ca)
|
||||
for paths created by makeFixedOutputPath() / addToStore(). */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue