mirror of
https://github.com/NixOS/nix.git
synced 2025-11-09 12:06:01 +01:00
Move some MixStoreDirMethods members to the right .cc file
I had not wanted to cause unncessary churn before, but now that we've bitten the bullet with the Big Reformat, I feel it is the right time. Future readers will appreciate that the declarations and definitions files are one-to-one as they should be, and `store-api.cc` is good to shrink in any event. I don't think there are outstanding PRs changing this code either. (I had some for a while, but they are all merged.)
This commit is contained in:
parent
9ff4c446df
commit
e07440665c
3 changed files with 170 additions and 168 deletions
|
|
@ -74,58 +74,4 @@ StorePath StorePath::random(std::string_view name)
|
|||
return StorePath(Hash::random(HashAlgorithm::SHA1), name);
|
||||
}
|
||||
|
||||
StorePath MixStoreDirMethods::parseStorePath(std::string_view path) const
|
||||
{
|
||||
// On Windows, `/nix/store` is not a canonical path. More broadly it
|
||||
// is unclear whether this function should be using the native
|
||||
// notion of a canonical path at all. For example, it makes to
|
||||
// support remote stores whose store dir is a non-native path (e.g.
|
||||
// Windows <-> Unix ssh-ing).
|
||||
auto p =
|
||||
#ifdef _WIN32
|
||||
path
|
||||
#else
|
||||
canonPath(std::string(path))
|
||||
#endif
|
||||
;
|
||||
if (dirOf(p) != storeDir)
|
||||
throw BadStorePath("path '%s' is not in the Nix store", p);
|
||||
return StorePath(baseNameOf(p));
|
||||
}
|
||||
|
||||
std::optional<StorePath> MixStoreDirMethods::maybeParseStorePath(std::string_view path) const
|
||||
{
|
||||
try {
|
||||
return parseStorePath(path);
|
||||
} catch (Error &) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
bool MixStoreDirMethods::isStorePath(std::string_view path) const
|
||||
{
|
||||
return (bool) maybeParseStorePath(path);
|
||||
}
|
||||
|
||||
StorePathSet MixStoreDirMethods::parseStorePathSet(const PathSet & paths) const
|
||||
{
|
||||
StorePathSet res;
|
||||
for (auto & i : paths)
|
||||
res.insert(parseStorePath(i));
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string MixStoreDirMethods::printStorePath(const StorePath & path) const
|
||||
{
|
||||
return (storeDir + "/").append(path.to_string());
|
||||
}
|
||||
|
||||
PathSet MixStoreDirMethods::printStorePathSet(const StorePathSet & paths) const
|
||||
{
|
||||
PathSet res;
|
||||
for (auto & i : paths)
|
||||
res.insert(printStorePath(i));
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace nix
|
||||
|
|
|
|||
|
|
@ -64,119 +64,6 @@ StorePath Store::followLinksToStorePath(std::string_view path) const
|
|||
return toStorePath(followLinksToStore(path)).first;
|
||||
}
|
||||
|
||||
/*
|
||||
The exact specification of store paths is in `protocols/store-path.md`
|
||||
in the Nix manual. These few functions implement that specification.
|
||||
|
||||
If changes to these functions go beyond mere implementation changes i.e.
|
||||
also update the user-visible behavior, please update the specification
|
||||
to match.
|
||||
*/
|
||||
|
||||
StorePath MixStoreDirMethods::makeStorePath(std::string_view type, std::string_view hash, std::string_view name) const
|
||||
{
|
||||
/* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */
|
||||
auto s = std::string(type) + ":" + std::string(hash) + ":" + storeDir + ":" + std::string(name);
|
||||
auto h = compressHash(hashString(HashAlgorithm::SHA256, s), 20);
|
||||
return StorePath(h, name);
|
||||
}
|
||||
|
||||
StorePath MixStoreDirMethods::makeStorePath(std::string_view type, const Hash & hash, std::string_view name) const
|
||||
{
|
||||
return makeStorePath(type, hash.to_string(HashFormat::Base16, true), name);
|
||||
}
|
||||
|
||||
StorePath MixStoreDirMethods::makeOutputPath(std::string_view id, const Hash & hash, std::string_view name) const
|
||||
{
|
||||
return makeStorePath("output:" + std::string{id}, hash, outputPathName(name, id));
|
||||
}
|
||||
|
||||
/* Stuff the references (if any) into the type. This is a bit
|
||||
hacky, but we can't put them in, say, <s2> (per the grammar above)
|
||||
since that would be ambiguous. */
|
||||
static std::string makeType(const MixStoreDirMethods & store, std::string && type, const StoreReferences & references)
|
||||
{
|
||||
for (auto & i : references.others) {
|
||||
type += ":";
|
||||
type += store.printStorePath(i);
|
||||
}
|
||||
if (references.self)
|
||||
type += ":self";
|
||||
return std::move(type);
|
||||
}
|
||||
|
||||
StorePath MixStoreDirMethods::makeFixedOutputPath(std::string_view name, const FixedOutputInfo & info) const
|
||||
{
|
||||
if (info.method == FileIngestionMethod::Git
|
||||
&& !(info.hash.algo == HashAlgorithm::SHA1 || info.hash.algo == HashAlgorithm::SHA256)) {
|
||||
throw Error(
|
||||
"Git file ingestion must use SHA-1 or SHA-256 hash, but instead using: %s", printHashAlgo(info.hash.algo));
|
||||
}
|
||||
|
||||
if (info.hash.algo == HashAlgorithm::SHA256 && info.method == FileIngestionMethod::NixArchive) {
|
||||
return makeStorePath(makeType(*this, "source", info.references), info.hash, name);
|
||||
} else {
|
||||
if (!info.references.empty()) {
|
||||
throw Error(
|
||||
"fixed output derivation '%s' is not allowed to refer to other store paths.\nYou may need to use the 'unsafeDiscardReferences' derivation attribute, see the manual for more details.",
|
||||
name);
|
||||
}
|
||||
// make a unique digest based on the parameters for creating this store object
|
||||
auto payload =
|
||||
"fixed:out:" + makeFileIngestionPrefix(info.method) + info.hash.to_string(HashFormat::Base16, true) + ":";
|
||||
auto digest = hashString(HashAlgorithm::SHA256, payload);
|
||||
return makeStorePath("output:out", digest, name);
|
||||
}
|
||||
}
|
||||
|
||||
StorePath
|
||||
MixStoreDirMethods::makeFixedOutputPathFromCA(std::string_view name, const ContentAddressWithReferences & ca) const
|
||||
{
|
||||
// New template
|
||||
return std::visit(
|
||||
overloaded{
|
||||
[&](const TextInfo & ti) {
|
||||
assert(ti.hash.algo == HashAlgorithm::SHA256);
|
||||
return makeStorePath(
|
||||
makeType(
|
||||
*this,
|
||||
"text",
|
||||
StoreReferences{
|
||||
.others = ti.references,
|
||||
.self = false,
|
||||
}),
|
||||
ti.hash,
|
||||
name);
|
||||
},
|
||||
[&](const FixedOutputInfo & foi) { return makeFixedOutputPath(name, foi); }},
|
||||
ca.raw);
|
||||
}
|
||||
|
||||
std::pair<StorePath, Hash> MixStoreDirMethods::computeStorePath(
|
||||
std::string_view name,
|
||||
const SourcePath & path,
|
||||
ContentAddressMethod method,
|
||||
HashAlgorithm hashAlgo,
|
||||
const StorePathSet & references,
|
||||
PathFilter & filter) const
|
||||
{
|
||||
auto [h, size] = hashPath(path, method.getFileIngestionMethod(), hashAlgo, filter);
|
||||
if (settings.warnLargePathThreshold && size && *size >= settings.warnLargePathThreshold)
|
||||
warn("hashed large path '%s' (%s)", path, renderSize(*size));
|
||||
return {
|
||||
makeFixedOutputPathFromCA(
|
||||
name,
|
||||
ContentAddressWithReferences::fromParts(
|
||||
method,
|
||||
h,
|
||||
{
|
||||
.others = references,
|
||||
.self = false,
|
||||
})),
|
||||
h,
|
||||
};
|
||||
}
|
||||
|
||||
StorePath Store::addToStore(
|
||||
std::string_view name,
|
||||
const SourcePath & path,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,178 @@
|
|||
#include "nix/store/store-dir-config.hh"
|
||||
#include "nix/util/source-path.hh"
|
||||
#include "nix/util/util.hh"
|
||||
#include "nix/store/store-dir-config.hh"
|
||||
#include "nix/store/derivations.hh"
|
||||
#include "nix/store/globals.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
StorePath MixStoreDirMethods::parseStorePath(std::string_view path) const
|
||||
{
|
||||
// On Windows, `/nix/store` is not a canonical path. More broadly it
|
||||
// is unclear whether this function should be using the native
|
||||
// notion of a canonical path at all. For example, it makes to
|
||||
// support remote stores whose store dir is a non-native path (e.g.
|
||||
// Windows <-> Unix ssh-ing).
|
||||
auto p =
|
||||
#ifdef _WIN32
|
||||
path
|
||||
#else
|
||||
canonPath(std::string(path))
|
||||
#endif
|
||||
;
|
||||
if (dirOf(p) != storeDir)
|
||||
throw BadStorePath("path '%s' is not in the Nix store", p);
|
||||
return StorePath(baseNameOf(p));
|
||||
}
|
||||
|
||||
std::optional<StorePath> MixStoreDirMethods::maybeParseStorePath(std::string_view path) const
|
||||
{
|
||||
try {
|
||||
return parseStorePath(path);
|
||||
} catch (Error &) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
bool MixStoreDirMethods::isStorePath(std::string_view path) const
|
||||
{
|
||||
return (bool) maybeParseStorePath(path);
|
||||
}
|
||||
|
||||
StorePathSet MixStoreDirMethods::parseStorePathSet(const PathSet & paths) const
|
||||
{
|
||||
StorePathSet res;
|
||||
for (auto & i : paths)
|
||||
res.insert(parseStorePath(i));
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string MixStoreDirMethods::printStorePath(const StorePath & path) const
|
||||
{
|
||||
return (storeDir + "/").append(path.to_string());
|
||||
}
|
||||
|
||||
PathSet MixStoreDirMethods::printStorePathSet(const StorePathSet & paths) const
|
||||
{
|
||||
PathSet res;
|
||||
for (auto & i : paths)
|
||||
res.insert(printStorePath(i));
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
The exact specification of store paths is in `protocols/store-path.md`
|
||||
in the Nix manual. These few functions implement that specification.
|
||||
|
||||
If changes to these functions go beyond mere implementation changes i.e.
|
||||
also update the user-visible behavior, please update the specification
|
||||
to match.
|
||||
*/
|
||||
|
||||
StorePath MixStoreDirMethods::makeStorePath(std::string_view type, std::string_view hash, std::string_view name) const
|
||||
{
|
||||
/* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */
|
||||
auto s = std::string(type) + ":" + std::string(hash) + ":" + storeDir + ":" + std::string(name);
|
||||
auto h = compressHash(hashString(HashAlgorithm::SHA256, s), 20);
|
||||
return StorePath(h, name);
|
||||
}
|
||||
|
||||
StorePath MixStoreDirMethods::makeStorePath(std::string_view type, const Hash & hash, std::string_view name) const
|
||||
{
|
||||
return makeStorePath(type, hash.to_string(HashFormat::Base16, true), name);
|
||||
}
|
||||
|
||||
StorePath MixStoreDirMethods::makeOutputPath(std::string_view id, const Hash & hash, std::string_view name) const
|
||||
{
|
||||
return makeStorePath("output:" + std::string{id}, hash, outputPathName(name, id));
|
||||
}
|
||||
|
||||
/* Stuff the references (if any) into the type. This is a bit
|
||||
hacky, but we can't put them in, say, <s2> (per the grammar above)
|
||||
since that would be ambiguous. */
|
||||
static std::string makeType(const MixStoreDirMethods & store, std::string && type, const StoreReferences & references)
|
||||
{
|
||||
for (auto & i : references.others) {
|
||||
type += ":";
|
||||
type += store.printStorePath(i);
|
||||
}
|
||||
if (references.self)
|
||||
type += ":self";
|
||||
return std::move(type);
|
||||
}
|
||||
|
||||
StorePath MixStoreDirMethods::makeFixedOutputPath(std::string_view name, const FixedOutputInfo & info) const
|
||||
{
|
||||
if (info.method == FileIngestionMethod::Git
|
||||
&& !(info.hash.algo == HashAlgorithm::SHA1 || info.hash.algo == HashAlgorithm::SHA256)) {
|
||||
throw Error(
|
||||
"Git file ingestion must use SHA-1 or SHA-256 hash, but instead using: %s", printHashAlgo(info.hash.algo));
|
||||
}
|
||||
|
||||
if (info.hash.algo == HashAlgorithm::SHA256 && info.method == FileIngestionMethod::NixArchive) {
|
||||
return makeStorePath(makeType(*this, "source", info.references), info.hash, name);
|
||||
} else {
|
||||
if (!info.references.empty()) {
|
||||
throw Error(
|
||||
"fixed output derivation '%s' is not allowed to refer to other store paths.\nYou may need to use the 'unsafeDiscardReferences' derivation attribute, see the manual for more details.",
|
||||
name);
|
||||
}
|
||||
// make a unique digest based on the parameters for creating this store object
|
||||
auto payload =
|
||||
"fixed:out:" + makeFileIngestionPrefix(info.method) + info.hash.to_string(HashFormat::Base16, true) + ":";
|
||||
auto digest = hashString(HashAlgorithm::SHA256, payload);
|
||||
return makeStorePath("output:out", digest, name);
|
||||
}
|
||||
}
|
||||
|
||||
StorePath
|
||||
MixStoreDirMethods::makeFixedOutputPathFromCA(std::string_view name, const ContentAddressWithReferences & ca) const
|
||||
{
|
||||
// New template
|
||||
return std::visit(
|
||||
overloaded{
|
||||
[&](const TextInfo & ti) {
|
||||
assert(ti.hash.algo == HashAlgorithm::SHA256);
|
||||
return makeStorePath(
|
||||
makeType(
|
||||
*this,
|
||||
"text",
|
||||
StoreReferences{
|
||||
.others = ti.references,
|
||||
.self = false,
|
||||
}),
|
||||
ti.hash,
|
||||
name);
|
||||
},
|
||||
[&](const FixedOutputInfo & foi) { return makeFixedOutputPath(name, foi); }},
|
||||
ca.raw);
|
||||
}
|
||||
|
||||
std::pair<StorePath, Hash> MixStoreDirMethods::computeStorePath(
|
||||
std::string_view name,
|
||||
const SourcePath & path,
|
||||
ContentAddressMethod method,
|
||||
HashAlgorithm hashAlgo,
|
||||
const StorePathSet & references,
|
||||
PathFilter & filter) const
|
||||
{
|
||||
auto [h, size] = hashPath(path, method.getFileIngestionMethod(), hashAlgo, filter);
|
||||
if (settings.warnLargePathThreshold && size && *size >= settings.warnLargePathThreshold)
|
||||
warn("hashed large path '%s' (%s)", path, renderSize(*size));
|
||||
return {
|
||||
makeFixedOutputPathFromCA(
|
||||
name,
|
||||
ContentAddressWithReferences::fromParts(
|
||||
method,
|
||||
h,
|
||||
{
|
||||
.others = references,
|
||||
.self = false,
|
||||
})),
|
||||
h,
|
||||
};
|
||||
}
|
||||
|
||||
StoreDirConfig::StoreDirConfig(const Params & params)
|
||||
: StoreDirConfigBase(params)
|
||||
, MixStoreDirMethods{storeDir_}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue