mirror of
https://github.com/NixOS/nix
synced 2025-06-28 05:21:16 +02:00
Merge remote-tracking branch 'origin/master' into flakes
This commit is contained in:
commit
ecb3a1afa2
119 changed files with 3905 additions and 2250 deletions
|
@ -44,6 +44,19 @@ static char * dupString(const char * s)
|
|||
}
|
||||
|
||||
|
||||
static char * dupStringWithLen(const char * s, size_t size)
|
||||
{
|
||||
char * t;
|
||||
#if HAVE_BOEHMGC
|
||||
t = GC_STRNDUP(s, size);
|
||||
#else
|
||||
t = strndup(s, size);
|
||||
#endif
|
||||
if (!t) throw std::bad_alloc();
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
static void printValue(std::ostream & str, std::set<const Value *> & active, const Value & v)
|
||||
{
|
||||
checkInterrupt();
|
||||
|
@ -358,10 +371,10 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> store)
|
|||
auto path = r.second;
|
||||
|
||||
if (store->isInStore(r.second)) {
|
||||
PathSet closure;
|
||||
store->computeFSClosure(store->toStorePath(r.second), closure);
|
||||
StorePathSet closure;
|
||||
store->computeFSClosure(store->parseStorePath(store->toStorePath(r.second)), closure);
|
||||
for (auto & path : closure)
|
||||
allowedPaths->insert(path);
|
||||
allowedPaths->insert(store->printStorePath(path));
|
||||
} else
|
||||
allowedPaths->insert(r.second);
|
||||
}
|
||||
|
@ -585,9 +598,11 @@ void mkString(Value & v, const char * s)
|
|||
}
|
||||
|
||||
|
||||
Value & mkString(Value & v, const string & s, const PathSet & context)
|
||||
Value & mkString(Value & v, std::string_view s, const PathSet & context)
|
||||
{
|
||||
mkString(v, s.c_str());
|
||||
v.type = tString;
|
||||
v.string.s = dupStringWithLen(s.data(), s.size());
|
||||
v.string.context = 0;
|
||||
if (!context.empty()) {
|
||||
size_t n = 0;
|
||||
v.string.context = (const char * *)
|
||||
|
@ -1131,10 +1146,9 @@ void EvalState::callPrimOp(Value & fun, Value & arg, Value & v, const Pos & pos)
|
|||
|
||||
void EvalState::callFunction(Value & fun, Value & arg, Value & v, const Pos & pos)
|
||||
{
|
||||
std::optional<FunctionCallTrace> trace;
|
||||
if (evalSettings.traceFunctionCalls) {
|
||||
trace.emplace(pos);
|
||||
}
|
||||
std::unique_ptr<FunctionCallTrace> trace;
|
||||
if (evalSettings.traceFunctionCalls)
|
||||
trace = std::make_unique<FunctionCallTrace>(pos);
|
||||
|
||||
forceValue(fun, pos);
|
||||
|
||||
|
@ -1680,15 +1694,16 @@ string EvalState::copyPathToStore(PathSet & context, const Path & path)
|
|||
throwEvalError("file names are not allowed to end in '%1%'", drvExtension);
|
||||
|
||||
Path dstPath;
|
||||
if (srcToStore[path] != "")
|
||||
dstPath = srcToStore[path];
|
||||
auto i = srcToStore.find(path);
|
||||
if (i != srcToStore.end())
|
||||
dstPath = store->printStorePath(i->second);
|
||||
else {
|
||||
dstPath = settings.readOnlyMode
|
||||
? store->computeStorePathForPath(baseNameOf(path), checkSourcePath(path)).first
|
||||
: store->addToStore(baseNameOf(path), checkSourcePath(path), true, htSHA256, defaultPathFilter, repair);
|
||||
srcToStore[path] = dstPath;
|
||||
printMsg(lvlChatty, format("copied source '%1%' -> '%2%'")
|
||||
% path % dstPath);
|
||||
auto p = settings.readOnlyMode
|
||||
? store->computeStorePathForPath(std::string(baseNameOf(path)), checkSourcePath(path)).first
|
||||
: store->addToStore(std::string(baseNameOf(path)), checkSourcePath(path), true, htSHA256, defaultPathFilter, repair);
|
||||
dstPath = store->printStorePath(p);
|
||||
srcToStore.insert_or_assign(path, std::move(p));
|
||||
printMsg(lvlChatty, "copied source '%1%' -> '%2%'", path, dstPath);
|
||||
}
|
||||
|
||||
context.insert(dstPath);
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace nix {
|
|||
|
||||
class Store;
|
||||
class EvalState;
|
||||
struct StorePath;
|
||||
enum RepairFlag : bool;
|
||||
|
||||
namespace flake {
|
||||
|
@ -46,14 +47,14 @@ struct Env
|
|||
};
|
||||
|
||||
|
||||
Value & mkString(Value & v, const string & s, const PathSet & context = PathSet());
|
||||
Value & mkString(Value & v, std::string_view s, const PathSet & context = PathSet());
|
||||
|
||||
void copyContext(const Value & v, PathSet & context);
|
||||
|
||||
|
||||
/* Cache for calls to addToStore(); maps source paths to the store
|
||||
paths. */
|
||||
typedef std::map<Path, Path> SrcToStore;
|
||||
typedef std::map<Path, StorePath> SrcToStore;
|
||||
|
||||
|
||||
std::ostream & operator << (std::ostream & str, const Value & v);
|
||||
|
|
|
@ -77,7 +77,7 @@ void EvalCache::addDerivation(
|
|||
(fingerprint.hash, fingerprint.hashSize)
|
||||
(attrPath)
|
||||
(ValueType::Derivation)
|
||||
(drv.drvPath + " " + drv.outPath + " " + drv.outputName).exec();
|
||||
(std::string(drv.drvPath.to_string()) + " " + std::string(drv.outPath.to_string()) + " " + drv.outputName).exec();
|
||||
}
|
||||
|
||||
std::optional<EvalCache::Derivation> EvalCache::getDerivation(
|
||||
|
@ -104,7 +104,7 @@ std::optional<EvalCache::Derivation> EvalCache::getDerivation(
|
|||
|
||||
debug("evaluation cache hit for '%s'", attrPath);
|
||||
|
||||
return Derivation { ss[0], ss[1], ss[2] };
|
||||
return Derivation { StorePath::fromBaseName(ss[0]), StorePath::fromBaseName(ss[1]), ss[2] };
|
||||
}
|
||||
|
||||
EvalCache & EvalCache::singleton()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "sync.hh"
|
||||
#include "flake.hh"
|
||||
#include "path.hh"
|
||||
|
||||
namespace nix { struct SQLite; struct SQLiteStmt; }
|
||||
|
||||
|
@ -19,8 +20,8 @@ public:
|
|||
|
||||
struct Derivation
|
||||
{
|
||||
Path drvPath;
|
||||
Path outPath;
|
||||
StorePath drvPath;
|
||||
StorePath outPath;
|
||||
std::string outputName;
|
||||
};
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ static SourceInfo fetchInput(EvalState & state, const FlakeRef & resolvedRef)
|
|||
SourceInfo info(ref);
|
||||
info.storePath = gitInfo.storePath;
|
||||
info.revCount = gitInfo.revCount;
|
||||
info.narHash = state.store->queryPathInfo(info.storePath)->narHash;
|
||||
info.narHash = state.store->queryPathInfo(state.store->parseStorePath(info.storePath))->narHash;
|
||||
info.lastModified = gitInfo.lastModified;
|
||||
return info;
|
||||
};
|
||||
|
@ -212,7 +212,7 @@ static Flake getFlake(EvalState & state, const FlakeRef & originalRef,
|
|||
refMap.push_back({originalRef, resolvedRef});
|
||||
refMap.push_back({flakeRef, resolvedRef});
|
||||
|
||||
state.store->assertStorePath(sourceInfo.storePath);
|
||||
state.store->parseStorePath(sourceInfo.storePath);
|
||||
|
||||
if (state.allowedPaths)
|
||||
state.allowedPaths->insert(state.store->toRealPath(sourceInfo.storePath));
|
||||
|
@ -334,7 +334,7 @@ static SourceInfo getNonFlake(EvalState & state, const FlakeRef & originalRef,
|
|||
refMap.push_back({originalRef, resolvedRef});
|
||||
refMap.push_back({flakeRef, resolvedRef});
|
||||
|
||||
state.store->assertStorePath(sourceInfo.storePath);
|
||||
state.store->parseStorePath(sourceInfo.storePath);
|
||||
|
||||
if (state.allowedPaths)
|
||||
state.allowedPaths->insert(sourceInfo.storePath);
|
||||
|
@ -490,7 +490,7 @@ void updateLockFile(EvalState & state, const FlakeRef & flakeRef, bool recreateL
|
|||
static void emitSourceInfoAttrs(EvalState & state, const SourceInfo & sourceInfo, Value & vAttrs)
|
||||
{
|
||||
auto & path = sourceInfo.storePath;
|
||||
assert(state.store->isValidPath(path));
|
||||
assert(state.store->isValidPath(state.store->parseStorePath(path)));
|
||||
mkString(*state.allocAttr(vAttrs, state.sOutPath), path, {path});
|
||||
|
||||
if (sourceInfo.resolvedRef.rev) {
|
||||
|
@ -542,7 +542,7 @@ static void prim_callFlake(EvalState & state, const Pos & pos, Value * * args, V
|
|||
|
||||
state.mkAttrs(v, 8);
|
||||
|
||||
assert(state.store->isValidPath(sourceInfo.storePath));
|
||||
assert(state.store->isValidPath(state.store->parseStorePath(sourceInfo.storePath)));
|
||||
|
||||
mkString(*state.allocAttr(v, state.sOutPath),
|
||||
sourceInfo.storePath, {sourceInfo.storePath});
|
||||
|
|
|
@ -161,7 +161,7 @@ FlakeRef::FlakeRef(const std::string & uri_, bool allowRelative)
|
|||
}
|
||||
while (true) {
|
||||
if (pathExists(d.path + "/.git")) break;
|
||||
subdir = baseNameOf(d.path) + (subdir.empty() ? "" : "/" + subdir);
|
||||
subdir = std::string(baseNameOf(d.path)) + (subdir.empty() ? "" : "/" + subdir);
|
||||
d.path = dirOf(d.path);
|
||||
if (d.path == "/")
|
||||
throw MissingFlake("path '%s' is not a flake (because it does not reference a Git repository)", uri);
|
||||
|
|
|
@ -26,7 +26,7 @@ nlohmann::json LockedInput::toJson() const
|
|||
|
||||
Path LockedInput::computeStorePath(Store & store) const
|
||||
{
|
||||
return store.makeFixedOutputPath(true, narHash, "source");
|
||||
return store.printStorePath(store.makeFixedOutputPath(true, narHash, "source"));
|
||||
}
|
||||
|
||||
LockedInputs::LockedInputs(const nlohmann::json & json)
|
||||
|
|
|
@ -19,27 +19,27 @@ DrvInfo::DrvInfo(EvalState & state, const string & attrPath, Bindings * attrs)
|
|||
DrvInfo::DrvInfo(EvalState & state, ref<Store> store, const std::string & drvPathWithOutputs)
|
||||
: state(&state), attrs(nullptr), attrPath("")
|
||||
{
|
||||
auto spec = parseDrvPathWithOutputs(drvPathWithOutputs);
|
||||
auto [drvPath, selectedOutputs] = store->parseDrvPathWithOutputs(drvPathWithOutputs);
|
||||
|
||||
drvPath = spec.first;
|
||||
this->drvPath = store->printStorePath(drvPath);
|
||||
|
||||
auto drv = store->derivationFromPath(drvPath);
|
||||
|
||||
name = storePathToName(drvPath);
|
||||
name = drvPath.name();
|
||||
|
||||
if (spec.second.size() > 1)
|
||||
if (selectedOutputs.size() > 1)
|
||||
throw Error("building more than one derivation output is not supported, in '%s'", drvPathWithOutputs);
|
||||
|
||||
outputName =
|
||||
spec.second.empty()
|
||||
? get(drv.env, "outputName", "out")
|
||||
: *spec.second.begin();
|
||||
selectedOutputs.empty()
|
||||
? get(drv.env, "outputName").value_or("out")
|
||||
: *selectedOutputs.begin();
|
||||
|
||||
auto i = drv.outputs.find(outputName);
|
||||
if (i == drv.outputs.end())
|
||||
throw Error("derivation '%s' does not have output '%s'", drvPath, outputName);
|
||||
throw Error("derivation '%s' does not have output '%s'", store->printStorePath(drvPath), outputName);
|
||||
|
||||
outPath = i->second.path;
|
||||
outPath = store->printStorePath(i->second.path);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ libexpr_SOURCES := \
|
|||
$(d)/lexer-tab.cc \
|
||||
$(d)/parser-tab.cc
|
||||
|
||||
libexpr_LIBS = libutil libstore
|
||||
libexpr_LIBS = libutil libstore libnixrust
|
||||
|
||||
libexpr_LDFLAGS =
|
||||
ifneq ($(OS), FreeBSD)
|
||||
|
|
|
@ -16,14 +16,14 @@ DrvName::DrvName()
|
|||
a letter. The `version' part is the rest (excluding the separating
|
||||
dash). E.g., `apache-httpd-2.0.48' is parsed to (`apache-httpd',
|
||||
'2.0.48'). */
|
||||
DrvName::DrvName(const string & s) : hits(0)
|
||||
DrvName::DrvName(std::string_view s) : hits(0)
|
||||
{
|
||||
name = fullName = s;
|
||||
name = fullName = std::string(s);
|
||||
for (unsigned int i = 0; i < s.size(); ++i) {
|
||||
/* !!! isalpha/isdigit are affected by the locale. */
|
||||
if (s[i] == '-' && i + 1 < s.size() && !isalpha(s[i + 1])) {
|
||||
name = string(s, 0, i);
|
||||
version = string(s, i + 1);
|
||||
name = s.substr(0, i);
|
||||
version = s.substr(i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ struct DrvName
|
|||
unsigned int hits;
|
||||
|
||||
DrvName();
|
||||
DrvName(const string & s);
|
||||
DrvName(std::string_view s);
|
||||
bool matches(DrvName & n);
|
||||
|
||||
private:
|
||||
|
|
|
@ -44,19 +44,19 @@ std::pair<string, string> decodeContext(const string & s)
|
|||
|
||||
|
||||
InvalidPathError::InvalidPathError(const Path & path) :
|
||||
EvalError(format("path '%1%' is not valid") % path), path(path) {}
|
||||
EvalError("path '%s' is not valid", path), path(path) {}
|
||||
|
||||
void EvalState::realiseContext(const PathSet & context)
|
||||
{
|
||||
PathSet drvs;
|
||||
std::vector<StorePathWithOutputs> drvs;
|
||||
|
||||
for (auto & i : context) {
|
||||
auto [ctx, outputName] = decodeContext(i);
|
||||
assert(store->isStorePath(ctx));
|
||||
auto [ctxS, outputName] = decodeContext(i);
|
||||
auto ctx = store->parseStorePath(ctxS);
|
||||
if (!store->isValidPath(ctx))
|
||||
throw InvalidPathError(ctx);
|
||||
if (!outputName.empty() && nix::isDerivation(ctx)) {
|
||||
drvs.insert(ctx + "!" + outputName);
|
||||
throw InvalidPathError(store->printStorePath(ctx));
|
||||
if (!outputName.empty() && ctx.isDerivation()) {
|
||||
drvs.push_back(StorePathWithOutputs{ctx.clone(), {outputName}});
|
||||
|
||||
/* Add the output of this derivation to the allowed
|
||||
paths. */
|
||||
|
@ -64,8 +64,8 @@ void EvalState::realiseContext(const PathSet & context)
|
|||
auto drv = store->derivationFromPath(ctx);
|
||||
DerivationOutputs::iterator i = drv.outputs.find(outputName);
|
||||
if (i == drv.outputs.end())
|
||||
throw Error("derivation '%s' does not have an output named '%s'", ctx, outputName);
|
||||
allowedPaths->insert(i->second.path);
|
||||
throw Error("derivation '%s' does not have an output named '%s'", ctxS, outputName);
|
||||
allowedPaths->insert(store->printStorePath(i->second.path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,10 +73,11 @@ void EvalState::realiseContext(const PathSet & context)
|
|||
if (drvs.empty()) return;
|
||||
|
||||
if (!evalSettings.enableImportFromDerivation)
|
||||
throw EvalError(format("attempted to realize '%1%' during evaluation but 'allow-import-from-derivation' is false") % *(drvs.begin()));
|
||||
throw EvalError("attempted to realize '%1%' during evaluation but 'allow-import-from-derivation' is false",
|
||||
store->printStorePath(drvs.begin()->path));
|
||||
|
||||
/* For performance, prefetch all substitute info. */
|
||||
PathSet willBuild, willSubstitute, unknown;
|
||||
StorePathSet willBuild, willSubstitute, unknown;
|
||||
unsigned long long downloadSize, narSize;
|
||||
store->queryMissing(drvs, willBuild, willSubstitute, unknown, downloadSize, narSize);
|
||||
|
||||
|
@ -100,8 +101,9 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args
|
|||
|
||||
Path realPath = state.checkSourcePath(state.toRealPath(path, context));
|
||||
|
||||
if (state.store->isStorePath(path) && state.store->isValidPath(path) && isDerivation(path)) {
|
||||
Derivation drv = readDerivation(realPath);
|
||||
// FIXME
|
||||
if (state.store->isStorePath(path) && state.store->isValidPath(state.store->parseStorePath(path)) && isDerivation(path)) {
|
||||
Derivation drv = readDerivation(*state.store, realPath);
|
||||
Value & w = *state.allocValue();
|
||||
state.mkAttrs(w, 3 + drv.outputs.size());
|
||||
Value * v2 = state.allocAttr(w, state.sDrvPath);
|
||||
|
@ -115,7 +117,7 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args
|
|||
|
||||
for (const auto & o : drv.outputs) {
|
||||
v2 = state.allocAttr(w, state.symbols.create(o.first));
|
||||
mkString(*v2, o.second.path, {"!" + o.first + "!" + path});
|
||||
mkString(*v2, state.store->printStorePath(o.second.path), {"!" + o.first + "!" + path});
|
||||
outputsVal->listElems()[outputs_index] = state.allocValue();
|
||||
mkString(*(outputsVal->listElems()[outputs_index++]), o.first);
|
||||
}
|
||||
|
@ -676,24 +678,24 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
|||
runs. */
|
||||
if (path.at(0) == '=') {
|
||||
/* !!! This doesn't work if readOnlyMode is set. */
|
||||
PathSet refs;
|
||||
state.store->computeFSClosure(string(path, 1), refs);
|
||||
StorePathSet refs;
|
||||
state.store->computeFSClosure(state.store->parseStorePath(std::string_view(path).substr(1)), refs);
|
||||
for (auto & j : refs) {
|
||||
drv.inputSrcs.insert(j);
|
||||
if (isDerivation(j))
|
||||
drv.inputDrvs[j] = state.store->queryDerivationOutputNames(j);
|
||||
drv.inputSrcs.insert(j.clone());
|
||||
if (j.isDerivation())
|
||||
drv.inputDrvs[j.clone()] = state.store->queryDerivationOutputNames(j);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle derivation outputs of the form ‘!<name>!<path>’. */
|
||||
else if (path.at(0) == '!') {
|
||||
std::pair<string, string> ctx = decodeContext(path);
|
||||
drv.inputDrvs[ctx.first].insert(ctx.second);
|
||||
drv.inputDrvs[state.store->parseStorePath(ctx.first)].insert(ctx.second);
|
||||
}
|
||||
|
||||
/* Otherwise it's a source file. */
|
||||
else
|
||||
drv.inputSrcs.insert(path);
|
||||
drv.inputSrcs.insert(state.store->parseStorePath(path));
|
||||
}
|
||||
|
||||
/* Do we have all required attributes? */
|
||||
|
@ -703,10 +705,8 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
|||
throw EvalError(format("required attribute 'system' missing, at %1%") % posDrvName);
|
||||
|
||||
/* Check whether the derivation name is valid. */
|
||||
checkStoreName(drvName);
|
||||
if (isDerivation(drvName))
|
||||
throw EvalError(format("derivation names are not allowed to end in '%1%', at %2%")
|
||||
% drvExtension % posDrvName);
|
||||
throw EvalError("derivation names are not allowed to end in '%s', at %s", drvExtension, posDrvName);
|
||||
|
||||
if (outputHash) {
|
||||
/* Handle fixed-output derivations. */
|
||||
|
@ -716,52 +716,51 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
|||
HashType ht = outputHashAlgo.empty() ? htUnknown : parseHashType(outputHashAlgo);
|
||||
Hash h(*outputHash, ht);
|
||||
|
||||
Path outPath = state.store->makeFixedOutputPath(outputHashRecursive, h, drvName);
|
||||
if (!jsonObject) drv.env["out"] = outPath;
|
||||
drv.outputs["out"] = DerivationOutput(outPath,
|
||||
(outputHashRecursive ? "r:" : "") + printHashType(h.type),
|
||||
h.to_string(Base16, false));
|
||||
auto outPath = state.store->makeFixedOutputPath(outputHashRecursive, h, drvName);
|
||||
if (!jsonObject) drv.env["out"] = state.store->printStorePath(outPath);
|
||||
drv.outputs.insert_or_assign("out", DerivationOutput(std::move(outPath),
|
||||
(outputHashRecursive ? "r:" : "") + printHashType(h.type),
|
||||
h.to_string(Base16, false)));
|
||||
}
|
||||
|
||||
else {
|
||||
/* Construct the "masked" store derivation, which is the final
|
||||
one except that in the list of outputs, the output paths
|
||||
are empty, and the corresponding environment variables have
|
||||
an empty value. This ensures that changes in the set of
|
||||
output names do get reflected in the hash. */
|
||||
/* Compute a hash over the "masked" store derivation, which is
|
||||
the final one except that in the list of outputs, the
|
||||
output paths are empty strings, and the corresponding
|
||||
environment variables have an empty value. This ensures
|
||||
that changes in the set of output names do get reflected in
|
||||
the hash. */
|
||||
for (auto & i : outputs) {
|
||||
if (!jsonObject) drv.env[i] = "";
|
||||
drv.outputs[i] = DerivationOutput("", "", "");
|
||||
}
|
||||
|
||||
/* Use the masked derivation expression to compute the output
|
||||
path. */
|
||||
Hash h = hashDerivationModulo(*state.store, drv);
|
||||
Hash h = hashDerivationModulo(*state.store, Derivation(drv), true);
|
||||
|
||||
for (auto & i : drv.outputs)
|
||||
if (i.second.path == "") {
|
||||
Path outPath = state.store->makeOutputPath(i.first, h, drvName);
|
||||
if (!jsonObject) drv.env[i.first] = outPath;
|
||||
i.second.path = outPath;
|
||||
}
|
||||
for (auto & i : outputs) {
|
||||
auto outPath = state.store->makeOutputPath(i, h, drvName);
|
||||
if (!jsonObject) drv.env[i] = state.store->printStorePath(outPath);
|
||||
drv.outputs.insert_or_assign(i,
|
||||
DerivationOutput(std::move(outPath), "", ""));
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the resulting term into the Nix store directory. */
|
||||
Path drvPath = writeDerivation(state.store, drv, drvName, state.repair);
|
||||
auto drvPath = writeDerivation(state.store, drv, drvName, state.repair);
|
||||
auto drvPathS = state.store->printStorePath(drvPath);
|
||||
|
||||
printMsg(lvlChatty, format("instantiated '%1%' -> '%2%'")
|
||||
% drvName % drvPath);
|
||||
printMsg(lvlChatty, "instantiated '%1%' -> '%2%'", drvName, drvPathS);
|
||||
|
||||
/* Optimisation, but required in read-only mode! because in that
|
||||
case we don't actually write store derivations, so we can't
|
||||
read them later. */
|
||||
drvHashes[drvPath] = hashDerivationModulo(*state.store, drv);
|
||||
drvHashes.insert_or_assign(drvPath.clone(),
|
||||
hashDerivationModulo(*state.store, Derivation(drv), false));
|
||||
|
||||
state.mkAttrs(v, 1 + drv.outputs.size());
|
||||
mkString(*state.allocAttr(v, state.sDrvPath), drvPath, {"=" + drvPath});
|
||||
mkString(*state.allocAttr(v, state.sDrvPath), drvPathS, {"=" + drvPathS});
|
||||
for (auto & i : drv.outputs) {
|
||||
mkString(*state.allocAttr(v, state.symbols.create(i.first)),
|
||||
i.second.path, {"!" + i.first + "!" + drvPath});
|
||||
state.store->printStorePath(i.second.path), {"!" + i.first + "!" + drvPathS});
|
||||
}
|
||||
v.attrs->sort();
|
||||
}
|
||||
|
@ -814,7 +813,7 @@ static void prim_storePath(EvalState & state, const Pos & pos, Value * * args, V
|
|||
throw EvalError(format("path '%1%' is not in the Nix store, at %2%") % path % pos);
|
||||
Path path2 = state.store->toStorePath(path);
|
||||
if (!settings.readOnlyMode)
|
||||
state.store->ensurePath(path2);
|
||||
state.store->ensurePath(state.store->parseStorePath(path2));
|
||||
context.insert(path2);
|
||||
mkString(v, path, context);
|
||||
}
|
||||
|
@ -1010,17 +1009,17 @@ static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Valu
|
|||
string name = state.forceStringNoCtx(*args[0], pos);
|
||||
string contents = state.forceString(*args[1], context, pos);
|
||||
|
||||
PathSet refs;
|
||||
StorePathSet refs;
|
||||
|
||||
for (auto path : context) {
|
||||
if (path.at(0) != '/')
|
||||
throw EvalError(format("in 'toFile': the file '%1%' cannot refer to derivation outputs, at %2%") % name % pos);
|
||||
refs.insert(path);
|
||||
refs.insert(state.store->parseStorePath(path));
|
||||
}
|
||||
|
||||
Path storePath = settings.readOnlyMode
|
||||
auto storePath = state.store->printStorePath(settings.readOnlyMode
|
||||
? state.store->computeStorePathForText(name, contents, refs)
|
||||
: state.store->addTextToStore(name, contents, refs, state.repair);
|
||||
: state.store->addTextToStore(name, contents, refs, state.repair));
|
||||
|
||||
/* Note: we don't need to add `context' to the context of the
|
||||
result, since `storePath' itself has references to the paths
|
||||
|
@ -1060,21 +1059,18 @@ static void addPath(EvalState & state, const Pos & pos, const string & name, con
|
|||
return state.forceBool(res, pos);
|
||||
}) : defaultPathFilter;
|
||||
|
||||
Path expectedStorePath;
|
||||
if (expectedHash) {
|
||||
expectedStorePath =
|
||||
state.store->makeFixedOutputPath(recursive, expectedHash, name);
|
||||
}
|
||||
std::optional<StorePath> expectedStorePath;
|
||||
if (expectedHash)
|
||||
expectedStorePath = state.store->makeFixedOutputPath(recursive, expectedHash, name);
|
||||
Path dstPath;
|
||||
if (!expectedHash || !state.store->isValidPath(expectedStorePath)) {
|
||||
dstPath = settings.readOnlyMode
|
||||
if (!expectedHash || !state.store->isValidPath(*expectedStorePath)) {
|
||||
dstPath = state.store->printStorePath(settings.readOnlyMode
|
||||
? state.store->computeStorePathForPath(name, path, recursive, htSHA256, filter).first
|
||||
: state.store->addToStore(name, path, recursive, htSHA256, filter, state.repair);
|
||||
if (expectedHash && expectedStorePath != dstPath) {
|
||||
throw Error(format("store path mismatch in (possibly filtered) path added from '%1%'") % path);
|
||||
}
|
||||
: state.store->addToStore(name, path, recursive, htSHA256, filter, state.repair));
|
||||
if (expectedHash && expectedStorePath != state.store->parseStorePath(dstPath))
|
||||
throw Error("store path mismatch in (possibly filtered) path added from '%s'", path);
|
||||
} else
|
||||
dstPath = expectedStorePath;
|
||||
dstPath = state.store->printStorePath(*expectedStorePath);
|
||||
|
||||
mkString(v, dstPath, {dstPath});
|
||||
}
|
||||
|
@ -1091,7 +1087,7 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args
|
|||
if (args[0]->type != tLambda)
|
||||
throw TypeError(format("first argument in call to 'filterSource' is not a function but %1%, at %2%") % showType(*args[0]) % pos);
|
||||
|
||||
addPath(state, pos, baseNameOf(path), path, args[0], true, Hash(), v);
|
||||
addPath(state, pos, std::string(baseNameOf(path)), path, args[0], true, Hash(), v);
|
||||
}
|
||||
|
||||
static void prim_path(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||
|
@ -2151,7 +2147,7 @@ void EvalState::createBaseEnv()
|
|||
}
|
||||
|
||||
if (!evalSettings.pureEval) {
|
||||
mkString(v, settings.thisSystem);
|
||||
mkString(v, settings.thisSystem.get());
|
||||
addConstant("__currentSystem", v);
|
||||
}
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ static void prim_appendContext(EvalState & state, const Pos & pos, Value * * arg
|
|||
if (!state.store->isStorePath(i.name))
|
||||
throw EvalError("Context key '%s' is not a store path, at %s", i.name, i.pos);
|
||||
if (!settings.readOnlyMode)
|
||||
state.store->ensurePath(i.name);
|
||||
state.store->ensurePath(state.store->parseStorePath(i.name));
|
||||
state.forceAttrs(*i.value, *i.pos);
|
||||
auto iter = i.value->attrs->find(sPath);
|
||||
if (iter != i.value->attrs->end()) {
|
||||
|
|
|
@ -56,7 +56,7 @@ static std::optional<GitInfo> lookupGitInfo(
|
|||
|
||||
Path storePath = json["storePath"];
|
||||
|
||||
if (store->isValidPath(storePath)) {
|
||||
if (store->isValidPath(store->parseStorePath(storePath))) {
|
||||
GitInfo gitInfo;
|
||||
gitInfo.storePath = storePath;
|
||||
gitInfo.rev = rev;
|
||||
|
@ -145,7 +145,7 @@ GitInfo exportGit(ref<Store> store, std::string uri,
|
|||
return files.count(file);
|
||||
};
|
||||
|
||||
gitInfo.storePath = store->addToStore("source", uri, true, htSHA256, filter);
|
||||
gitInfo.storePath = store->printStorePath(store->addToStore("source", uri, true, htSHA256, filter));
|
||||
gitInfo.revCount = haveCommits ? std::stoull(runProgram("git", true, { "-C", uri, "rev-list", "--count", "HEAD" })) : 0;
|
||||
// FIXME: maybe we should use the timestamp of the last
|
||||
// modified dirty file?
|
||||
|
@ -265,7 +265,7 @@ GitInfo exportGit(ref<Store> store, std::string uri,
|
|||
|
||||
unpackTarfile(*source, tmpDir);
|
||||
|
||||
gitInfo.storePath = store->addToStore(name, tmpDir);
|
||||
gitInfo.storePath = store->printStorePath(store->addToStore(name, tmpDir));
|
||||
|
||||
gitInfo.revCount = std::stoull(runProgram("git", true, { "-C", repoDir, "rev-list", "--count", gitInfo.rev.gitRev() }));
|
||||
gitInfo.lastModified = std::stoull(runProgram("git", true, { "-C", repoDir, "log", "-1", "--format=%ct", gitInfo.rev.gitRev() }));
|
||||
|
|
|
@ -64,7 +64,7 @@ HgInfo exportMercurial(ref<Store> store, const std::string & uri,
|
|||
return files.count(file);
|
||||
};
|
||||
|
||||
hgInfo.storePath = store->addToStore("source", uri, true, htSHA256, filter);
|
||||
hgInfo.storePath = store->printStorePath(store->addToStore("source", uri, true, htSHA256, filter));
|
||||
|
||||
return hgInfo;
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ HgInfo exportMercurial(ref<Store> store, const std::string & uri,
|
|||
|
||||
hgInfo.storePath = json["storePath"];
|
||||
|
||||
if (store->isValidPath(hgInfo.storePath)) {
|
||||
if (store->isValidPath(store->parseStorePath(hgInfo.storePath))) {
|
||||
printTalkative("using cached Mercurial store path '%s'", hgInfo.storePath);
|
||||
return hgInfo;
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ HgInfo exportMercurial(ref<Store> store, const std::string & uri,
|
|||
|
||||
deletePath(tmpDir + "/.hg_archival.txt");
|
||||
|
||||
hgInfo.storePath = store->addToStore(name, tmpDir);
|
||||
hgInfo.storePath = store->printStorePath(store->addToStore(name, tmpDir));
|
||||
|
||||
nlohmann::json json;
|
||||
json["storePath"] = hgInfo.storePath;
|
||||
|
|
|
@ -38,7 +38,12 @@ public:
|
|||
return s < s2.s;
|
||||
}
|
||||
|
||||
operator const string & () const
|
||||
operator const std::string & () const
|
||||
{
|
||||
return *s;
|
||||
}
|
||||
|
||||
operator const std::string_view () const
|
||||
{
|
||||
return *s;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue