forked from lix-project/lix
Merge remote-tracking branch 'me/no-stringly-typed-derivation-output' into validPathInfo-ca-proper-datatype
This commit is contained in:
commit
2f0e395c99
|
@ -776,7 +776,10 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
if (!jsonObject) drv.env["out"] = state.store->printStorePath(outPath);
|
if (!jsonObject) drv.env["out"] = state.store->printStorePath(outPath);
|
||||||
drv.outputs.insert_or_assign("out", DerivationOutput {
|
drv.outputs.insert_or_assign("out", DerivationOutput {
|
||||||
.path = std::move(outPath),
|
.path = std::move(outPath),
|
||||||
.hash = FileSystemHash { ingestionMethod, std::move(h) },
|
.hash = FixedOutputHash {
|
||||||
|
.method = ingestionMethod,
|
||||||
|
.hash = std::move(h),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -792,7 +795,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
drv.outputs.insert_or_assign(i,
|
drv.outputs.insert_or_assign(i,
|
||||||
DerivationOutput {
|
DerivationOutput {
|
||||||
.path = StorePath::dummy,
|
.path = StorePath::dummy,
|
||||||
.hash = std::optional<FileSystemHash> {},
|
.hash = std::optional<FixedOutputHash> {},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -804,7 +807,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
drv.outputs.insert_or_assign(i,
|
drv.outputs.insert_or_assign(i,
|
||||||
DerivationOutput {
|
DerivationOutput {
|
||||||
.path = std::move(outPath),
|
.path = std::move(outPath),
|
||||||
.hash = std::optional<FileSystemHash>(),
|
.hash = std::optional<FixedOutputHash>(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ DownloadFileResult downloadFile(
|
||||||
ValidPathInfo info(store->makeFixedOutputPath(FileIngestionMethod::Flat, hash, name));
|
ValidPathInfo info(store->makeFixedOutputPath(FileIngestionMethod::Flat, hash, name));
|
||||||
info.narHash = hashString(htSHA256, *sink.s);
|
info.narHash = hashString(htSHA256, *sink.s);
|
||||||
info.narSize = sink.s->size();
|
info.narSize = sink.s->size();
|
||||||
info.ca = FileSystemHash {
|
info.ca = FixedOutputHash {
|
||||||
FileIngestionMethod::Flat,
|
FileIngestionMethod::Flat,
|
||||||
hash,
|
hash,
|
||||||
};
|
};
|
||||||
|
|
|
@ -3764,7 +3764,7 @@ void DerivationGoal::registerOutputs()
|
||||||
else
|
else
|
||||||
assert(worker.store.parseStorePath(path) == dest);
|
assert(worker.store.parseStorePath(path) == dest);
|
||||||
|
|
||||||
ca = FileSystemHash { i.second.hash->method, h2 };
|
ca = FixedOutputHash { i.second.hash->method, h2 };
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get rid of all weird permissions. This also checks that
|
/* Get rid of all weird permissions. This also checks that
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
std::string FileSystemHash::printMethodAlgo() const {
|
std::string FixedOutputHash::printMethodAlgo() const {
|
||||||
return makeFileIngestionPrefix(method) + printHashType(*hash.type);
|
return makeFileIngestionPrefix(method) + printHashType(*hash.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ std::string renderContentAddress(ContentAddress ca) {
|
||||||
[](TextHash th) {
|
[](TextHash th) {
|
||||||
return "text:" + th.hash.to_string(Base32, true);
|
return "text:" + th.hash.to_string(Base32, true);
|
||||||
},
|
},
|
||||||
[](FileSystemHash fsh) {
|
[](FixedOutputHash fsh) {
|
||||||
return makeFixedOutputCA(fsh.method, fsh.hash);
|
return makeFixedOutputCA(fsh.method, fsh.hash);
|
||||||
}
|
}
|
||||||
}, ca);
|
}, ca);
|
||||||
|
@ -55,10 +55,10 @@ ContentAddress parseContentAddress(std::string_view rawCa) {
|
||||||
auto methodAndHash = rawCa.substr(prefixSeparator+1, string::npos);
|
auto methodAndHash = rawCa.substr(prefixSeparator+1, string::npos);
|
||||||
if (methodAndHash.substr(0,2) == "r:") {
|
if (methodAndHash.substr(0,2) == "r:") {
|
||||||
std::string_view hashRaw = methodAndHash.substr(2,string::npos);
|
std::string_view hashRaw = methodAndHash.substr(2,string::npos);
|
||||||
return FileSystemHash { FileIngestionMethod::Recursive, Hash(string(hashRaw)) };
|
return FixedOutputHash { FileIngestionMethod::Recursive, Hash(string(hashRaw)) };
|
||||||
} else {
|
} else {
|
||||||
std::string_view hashRaw = methodAndHash;
|
std::string_view hashRaw = methodAndHash;
|
||||||
return FileSystemHash { FileIngestionMethod::Flat, Hash(string(hashRaw)) };
|
return FixedOutputHash { FileIngestionMethod::Flat, Hash(string(hashRaw)) };
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw Error("parseContentAddress: format not recognized; has to be text or fixed");
|
throw Error("parseContentAddress: format not recognized; has to be text or fixed");
|
||||||
|
|
|
@ -12,22 +12,12 @@ enum struct FileIngestionMethod : uint8_t {
|
||||||
|
|
||||||
struct TextHash {
|
struct TextHash {
|
||||||
Hash hash;
|
Hash hash;
|
||||||
TextHash(const TextHash &) = default;
|
|
||||||
TextHash(TextHash &&) = default;
|
|
||||||
TextHash & operator = (const TextHash &) = default;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Pair of a hash, and how the file system was ingested
|
/// Pair of a hash, and how the file system was ingested
|
||||||
struct FileSystemHash {
|
struct FixedOutputHash {
|
||||||
FileIngestionMethod method;
|
FileIngestionMethod method;
|
||||||
Hash hash;
|
Hash hash;
|
||||||
FileSystemHash(FileIngestionMethod method, Hash hash)
|
|
||||||
: method(std::move(method))
|
|
||||||
, hash(std::move(hash))
|
|
||||||
{ }
|
|
||||||
FileSystemHash(const FileSystemHash &) = default;
|
|
||||||
FileSystemHash(FileSystemHash &&) = default;
|
|
||||||
FileSystemHash & operator = (const FileSystemHash &) = default;
|
|
||||||
std::string printMethodAlgo() const;
|
std::string printMethodAlgo() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,7 +34,7 @@ struct FileSystemHash {
|
||||||
*/
|
*/
|
||||||
typedef std::variant<
|
typedef std::variant<
|
||||||
TextHash, // for paths computed by makeTextPath() / addTextToStore
|
TextHash, // for paths computed by makeTextPath() / addTextToStore
|
||||||
FileSystemHash // for path computed by makeFixedOutputPath
|
FixedOutputHash // for path computed by makeFixedOutputPath
|
||||||
> ContentAddress;
|
> ContentAddress;
|
||||||
|
|
||||||
/* Compute the prefix to the hash algorithm which indicates how the files were
|
/* Compute the prefix to the hash algorithm which indicates how the files were
|
||||||
|
|
|
@ -108,7 +108,7 @@ static DerivationOutput parseDerivationOutput(const Store & store, istringstream
|
||||||
expect(str, ","); const auto hash = parseString(str);
|
expect(str, ","); const auto hash = parseString(str);
|
||||||
expect(str, ")");
|
expect(str, ")");
|
||||||
|
|
||||||
std::optional<FileSystemHash> fsh;
|
std::optional<FixedOutputHash> fsh;
|
||||||
if (hashAlgo != "") {
|
if (hashAlgo != "") {
|
||||||
auto method = FileIngestionMethod::Flat;
|
auto method = FileIngestionMethod::Flat;
|
||||||
if (string(hashAlgo, 0, 2) == "r:") {
|
if (string(hashAlgo, 0, 2) == "r:") {
|
||||||
|
@ -116,9 +116,9 @@ static DerivationOutput parseDerivationOutput(const Store & store, istringstream
|
||||||
hashAlgo = string(hashAlgo, 2);
|
hashAlgo = string(hashAlgo, 2);
|
||||||
}
|
}
|
||||||
const HashType hashType = parseHashType(hashAlgo);
|
const HashType hashType = parseHashType(hashAlgo);
|
||||||
fsh = FileSystemHash {
|
fsh = FixedOutputHash {
|
||||||
std::move(method),
|
.method = std::move(method),
|
||||||
Hash(hash, hashType),
|
.hash = Hash(hash, hashType),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,7 +406,7 @@ static DerivationOutput readDerivationOutput(Source & in, const Store & store)
|
||||||
auto hashAlgo = readString(in);
|
auto hashAlgo = readString(in);
|
||||||
const auto hash = readString(in);
|
const auto hash = readString(in);
|
||||||
|
|
||||||
std::optional<FileSystemHash> fsh;
|
std::optional<FixedOutputHash> fsh;
|
||||||
if (hashAlgo != "") {
|
if (hashAlgo != "") {
|
||||||
auto method = FileIngestionMethod::Flat;
|
auto method = FileIngestionMethod::Flat;
|
||||||
if (string(hashAlgo, 0, 2) == "r:") {
|
if (string(hashAlgo, 0, 2) == "r:") {
|
||||||
|
@ -414,9 +414,9 @@ static DerivationOutput readDerivationOutput(Source & in, const Store & store)
|
||||||
hashAlgo = string(hashAlgo, 2);
|
hashAlgo = string(hashAlgo, 2);
|
||||||
}
|
}
|
||||||
const HashType hashType = parseHashType(hashAlgo);
|
const HashType hashType = parseHashType(hashAlgo);
|
||||||
fsh = FileSystemHash {
|
fsh = FixedOutputHash {
|
||||||
std::move(method),
|
.method = std::move(method),
|
||||||
Hash(hash, hashType),
|
.hash = Hash(hash, hashType),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace nix {
|
||||||
struct DerivationOutput
|
struct DerivationOutput
|
||||||
{
|
{
|
||||||
StorePath path;
|
StorePath path;
|
||||||
std::optional<FileSystemHash> hash; /* hash used for expected hash computation */
|
std::optional<FixedOutputHash> hash; /* hash used for expected hash computation */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<string, DerivationOutput> DerivationOutputs;
|
typedef std::map<string, DerivationOutput> DerivationOutputs;
|
||||||
|
|
|
@ -1079,7 +1079,7 @@ StorePath LocalStore::addToStoreFromDump(const string & dump, const string & nam
|
||||||
ValidPathInfo info(dstPath);
|
ValidPathInfo info(dstPath);
|
||||||
info.narHash = hash.first;
|
info.narHash = hash.first;
|
||||||
info.narSize = hash.second;
|
info.narSize = hash.second;
|
||||||
info.ca = FileSystemHash { method, h };
|
info.ca = FixedOutputHash { method, h };
|
||||||
registerValidPath(info);
|
registerValidPath(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -769,7 +769,7 @@ bool ValidPathInfo::isContentAddressed(const Store & store) const
|
||||||
[&](TextHash th) {
|
[&](TextHash th) {
|
||||||
return store.makeTextPath(path.name(), th.hash, references);
|
return store.makeTextPath(path.name(), th.hash, references);
|
||||||
},
|
},
|
||||||
[&](FileSystemHash fsh) {
|
[&](FixedOutputHash fsh) {
|
||||||
auto refs = references;
|
auto refs = references;
|
||||||
bool hasSelfReference = false;
|
bool hasSelfReference = false;
|
||||||
if (refs.count(path)) {
|
if (refs.count(path)) {
|
||||||
|
|
|
@ -48,12 +48,6 @@ struct Hash
|
||||||
// hash type must be part of string
|
// hash type must be part of string
|
||||||
Hash(std::string_view s);
|
Hash(std::string_view s);
|
||||||
|
|
||||||
Hash(const Hash &) = default;
|
|
||||||
|
|
||||||
Hash(Hash &&) = default;
|
|
||||||
|
|
||||||
Hash & operator = (const Hash &) = default;
|
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
/* Check whether a hash is set. */
|
/* Check whether a hash is set. */
|
||||||
|
|
78
src/libutil/tests/compression.cc
Normal file
78
src/libutil/tests/compression.cc
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
#include "compression.hh"
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* compress / decompress
|
||||||
|
* --------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
TEST(compress, compressWithUnknownMethod) {
|
||||||
|
ASSERT_THROW(compress("invalid-method", "something-to-compress"), UnknownCompressionMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(compress, noneMethodDoesNothingToTheInput) {
|
||||||
|
ref<std::string> o = compress("none", "this-is-a-test");
|
||||||
|
|
||||||
|
ASSERT_EQ(*o, "this-is-a-test");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(decompress, decompressXzCompressed) {
|
||||||
|
auto method = "xz";
|
||||||
|
auto str = "slfja;sljfklsa;jfklsjfkl;sdjfkl;sadjfkl;sdjf;lsdfjsadlf";
|
||||||
|
ref<std::string> o = decompress(method, *compress(method, str));
|
||||||
|
|
||||||
|
ASSERT_EQ(*o, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(decompress, decompressBzip2Compressed) {
|
||||||
|
auto method = "bzip2";
|
||||||
|
auto str = "slfja;sljfklsa;jfklsjfkl;sdjfkl;sadjfkl;sdjf;lsdfjsadlf";
|
||||||
|
ref<std::string> o = decompress(method, *compress(method, str));
|
||||||
|
|
||||||
|
ASSERT_EQ(*o, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(decompress, decompressBrCompressed) {
|
||||||
|
auto method = "br";
|
||||||
|
auto str = "slfja;sljfklsa;jfklsjfkl;sdjfkl;sadjfkl;sdjf;lsdfjsadlf";
|
||||||
|
ref<std::string> o = decompress(method, *compress(method, str));
|
||||||
|
|
||||||
|
ASSERT_EQ(*o, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(decompress, decompressInvalidInputThrowsCompressionError) {
|
||||||
|
auto method = "bzip2";
|
||||||
|
auto str = "this is a string that does not qualify as valid bzip2 data";
|
||||||
|
|
||||||
|
ASSERT_THROW(decompress(method, str), CompressionError);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* compression sinks
|
||||||
|
* --------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
TEST(makeCompressionSink, noneSinkDoesNothingToInput) {
|
||||||
|
StringSink strSink;
|
||||||
|
auto inputString = "slfja;sljfklsa;jfklsjfkl;sdjfkl;sadjfkl;sdjf;lsdfjsadlf";
|
||||||
|
auto sink = makeCompressionSink("none", strSink);
|
||||||
|
(*sink)(inputString);
|
||||||
|
sink->finish();
|
||||||
|
|
||||||
|
ASSERT_STREQ((*strSink.s).c_str(), inputString);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(makeCompressionSink, compressAndDecompress) {
|
||||||
|
StringSink strSink;
|
||||||
|
auto inputString = "slfja;sljfklsa;jfklsjfkl;sdjfkl;sadjfkl;sdjf;lsdfjsadlf";
|
||||||
|
auto decompressionSink = makeDecompressionSink("bzip2", strSink);
|
||||||
|
auto sink = makeCompressionSink("bzip2", *decompressionSink);
|
||||||
|
|
||||||
|
(*sink)(inputString);
|
||||||
|
sink->finish();
|
||||||
|
decompressionSink->finish();
|
||||||
|
|
||||||
|
ASSERT_STREQ((*strSink.s).c_str(), inputString);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -48,7 +48,7 @@ struct CmdAddToStore : MixDryRun, StoreCommand
|
||||||
ValidPathInfo info(store->makeFixedOutputPath(FileIngestionMethod::Recursive, narHash, *namePart));
|
ValidPathInfo info(store->makeFixedOutputPath(FileIngestionMethod::Recursive, narHash, *namePart));
|
||||||
info.narHash = narHash;
|
info.narHash = narHash;
|
||||||
info.narSize = sink.s->size();
|
info.narSize = sink.s->size();
|
||||||
info.ca = std::optional { FileSystemHash {
|
info.ca = std::optional { FixedOutputHash {
|
||||||
FileIngestionMethod::Recursive,
|
FileIngestionMethod::Recursive,
|
||||||
info.narHash,
|
info.narHash,
|
||||||
} };
|
} };
|
||||||
|
|
|
@ -137,8 +137,9 @@ StorePath getDerivationEnvironment(ref<Store> store, const StorePath & drvPath)
|
||||||
auto shellOutPath = store->makeOutputPath("out", h, drvName);
|
auto shellOutPath = store->makeOutputPath("out", h, drvName);
|
||||||
drv.outputs.insert_or_assign("out", DerivationOutput {
|
drv.outputs.insert_or_assign("out", DerivationOutput {
|
||||||
.path = shellOutPath,
|
.path = shellOutPath,
|
||||||
.hash = FileSystemHash {
|
.hash = FixedOutputHash {
|
||||||
FileIngestionMethod::Flat, Hash { }
|
.method = FileIngestionMethod::Flat,
|
||||||
|
.hash = Hash { },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
drv.env["out"] = store->printStorePath(shellOutPath);
|
drv.env["out"] = store->printStorePath(shellOutPath);
|
||||||
|
|
|
@ -82,7 +82,7 @@ struct CmdMakeContentAddressable : StorePathsCommand, MixJSON
|
||||||
if (hasSelfReference) info.references.insert(info.path);
|
if (hasSelfReference) info.references.insert(info.path);
|
||||||
info.narHash = narHash;
|
info.narHash = narHash;
|
||||||
info.narSize = sink.s->size();
|
info.narSize = sink.s->size();
|
||||||
info.ca = FileSystemHash {
|
info.ca = FixedOutputHash {
|
||||||
FileIngestionMethod::Recursive,
|
FileIngestionMethod::Recursive,
|
||||||
info.narHash,
|
info.narHash,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue