forked from lix-project/lix
toStorePath(): Return a StorePath and the suffix
This commit is contained in:
parent
143a5f32ed
commit
c0dd05131e
|
@ -366,7 +366,7 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> store)
|
||||||
|
|
||||||
if (store->isInStore(r.second)) {
|
if (store->isInStore(r.second)) {
|
||||||
StorePathSet closure;
|
StorePathSet closure;
|
||||||
store->computeFSClosure(store->parseStorePath(store->toStorePath(r.second)), closure);
|
store->computeFSClosure(store->toStorePath(r.second).first, closure);
|
||||||
for (auto & path : closure)
|
for (auto & path : closure)
|
||||||
allowedPaths->insert(store->printStorePath(path));
|
allowedPaths->insert(store->printStorePath(path));
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -883,10 +883,10 @@ static void prim_storePath(EvalState & state, const Pos & pos, Value * * args, V
|
||||||
.hint = hintfmt("path '%1%' is not in the Nix store", path),
|
.hint = hintfmt("path '%1%' is not in the Nix store", path),
|
||||||
.errPos = pos
|
.errPos = pos
|
||||||
});
|
});
|
||||||
Path path2 = state.store->toStorePath(path);
|
auto path2 = state.store->toStorePath(path).first;
|
||||||
if (!settings.readOnlyMode)
|
if (!settings.readOnlyMode)
|
||||||
state.store->ensurePath(state.store->parseStorePath(path2));
|
state.store->ensurePath(path2);
|
||||||
context.insert(path2);
|
context.insert(state.store->printStorePath(path2));
|
||||||
mkString(v, path, context);
|
mkString(v, path, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2044,7 +2044,7 @@ void DerivationGoal::startBuilder()
|
||||||
auto storePathS = *i++;
|
auto storePathS = *i++;
|
||||||
if (!worker.store.isInStore(storePathS))
|
if (!worker.store.isInStore(storePathS))
|
||||||
throw BuildError("'exportReferencesGraph' contains a non-store path '%1%'", storePathS);
|
throw BuildError("'exportReferencesGraph' contains a non-store path '%1%'", storePathS);
|
||||||
auto storePath = worker.store.parseStorePath(worker.store.toStorePath(storePathS));
|
auto storePath = worker.store.toStorePath(storePathS).first;
|
||||||
|
|
||||||
/* Write closure info to <fileName>. */
|
/* Write closure info to <fileName>. */
|
||||||
writeFile(tmpDir + "/" + fileName,
|
writeFile(tmpDir + "/" + fileName,
|
||||||
|
@ -2083,7 +2083,7 @@ void DerivationGoal::startBuilder()
|
||||||
for (auto & i : dirsInChroot)
|
for (auto & i : dirsInChroot)
|
||||||
try {
|
try {
|
||||||
if (worker.store.isInStore(i.second.source))
|
if (worker.store.isInStore(i.second.source))
|
||||||
worker.store.computeFSClosure(worker.store.parseStorePath(worker.store.toStorePath(i.second.source)), closure);
|
worker.store.computeFSClosure(worker.store.toStorePath(i.second.source).first, closure);
|
||||||
} catch (InvalidPath & e) {
|
} catch (InvalidPath & e) {
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
throw Error("while processing 'sandbox-paths': %s", e.what());
|
throw Error("while processing 'sandbox-paths': %s", e.what());
|
||||||
|
|
|
@ -262,11 +262,13 @@ void LocalStore::findTempRoots(FDs & fds, Roots & tempRoots, bool censor)
|
||||||
void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
|
void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
|
||||||
{
|
{
|
||||||
auto foundRoot = [&](const Path & path, const Path & target) {
|
auto foundRoot = [&](const Path & path, const Path & target) {
|
||||||
auto storePath = maybeParseStorePath(toStorePath(target));
|
try {
|
||||||
if (storePath && isValidPath(*storePath))
|
auto storePath = toStorePath(target).first;
|
||||||
roots[std::move(*storePath)].emplace(path);
|
if (isValidPath(storePath))
|
||||||
|
roots[std::move(storePath)].emplace(path);
|
||||||
else
|
else
|
||||||
printInfo("skipping invalid root from '%1%' to '%2%'", path, target);
|
printInfo("skipping invalid root from '%1%' to '%2%'", path, target);
|
||||||
|
} catch (BadStorePath &) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -472,15 +474,15 @@ void LocalStore::findRuntimeRoots(Roots & roots, bool censor)
|
||||||
|
|
||||||
for (auto & [target, links] : unchecked) {
|
for (auto & [target, links] : unchecked) {
|
||||||
if (!isInStore(target)) continue;
|
if (!isInStore(target)) continue;
|
||||||
Path pathS = toStorePath(target);
|
try {
|
||||||
if (!isStorePath(pathS)) continue;
|
auto path = toStorePath(target).first;
|
||||||
auto path = parseStorePath(pathS);
|
|
||||||
if (!isValidPath(path)) continue;
|
if (!isValidPath(path)) continue;
|
||||||
debug("got additional root '%1%'", pathS);
|
debug("got additional root '%1%'", printStorePath(path));
|
||||||
if (censor)
|
if (censor)
|
||||||
roots[path].insert(censored);
|
roots[path].insert(censored);
|
||||||
else
|
else
|
||||||
roots[path].insert(links.begin(), links.end());
|
roots[path].insert(links.begin(), links.end());
|
||||||
|
} catch (BadStorePath &) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,9 @@ struct LocalStoreAccessor : public FSAccessor
|
||||||
|
|
||||||
Path toRealPath(const Path & path)
|
Path toRealPath(const Path & path)
|
||||||
{
|
{
|
||||||
Path storePath = store->toStorePath(path);
|
auto storePath = store->toStorePath(path).first;
|
||||||
if (!store->isValidPath(store->parseStorePath(storePath)))
|
if (!store->isValidPath(storePath))
|
||||||
throw InvalidPath("path '%1%' is not a valid store path", storePath);
|
throw InvalidPath("path '%1%' is not a valid store path", store->printStorePath(storePath));
|
||||||
return store->getRealStoreDir() + std::string(path, store->storeDir.size());
|
return store->getRealStoreDir() + std::string(path, store->storeDir.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
MakeError(BadStorePath, Error);
|
|
||||||
|
|
||||||
static void checkName(std::string_view path, std::string_view name)
|
static void checkName(std::string_view path, std::string_view name)
|
||||||
{
|
{
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
|
|
|
@ -16,26 +16,26 @@ RemoteFSAccessor::RemoteFSAccessor(ref<Store> store, const Path & cacheDir)
|
||||||
createDirs(cacheDir);
|
createDirs(cacheDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
Path RemoteFSAccessor::makeCacheFile(const Path & storePath, const std::string & ext)
|
Path RemoteFSAccessor::makeCacheFile(std::string_view hashPart, const std::string & ext)
|
||||||
{
|
{
|
||||||
assert(cacheDir != "");
|
assert(cacheDir != "");
|
||||||
return fmt("%s/%s.%s", cacheDir, store->parseStorePath(storePath).hashPart(), ext);
|
return fmt("%s/%s.%s", cacheDir, hashPart, ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteFSAccessor::addToCache(const Path & storePath, const std::string & nar,
|
void RemoteFSAccessor::addToCache(std::string_view hashPart, const std::string & nar,
|
||||||
ref<FSAccessor> narAccessor)
|
ref<FSAccessor> narAccessor)
|
||||||
{
|
{
|
||||||
nars.emplace(storePath, narAccessor);
|
nars.emplace(hashPart, narAccessor);
|
||||||
|
|
||||||
if (cacheDir != "") {
|
if (cacheDir != "") {
|
||||||
try {
|
try {
|
||||||
std::ostringstream str;
|
std::ostringstream str;
|
||||||
JSONPlaceholder jsonRoot(str);
|
JSONPlaceholder jsonRoot(str);
|
||||||
listNar(jsonRoot, narAccessor, "", true);
|
listNar(jsonRoot, narAccessor, "", true);
|
||||||
writeFile(makeCacheFile(storePath, "ls"), str.str());
|
writeFile(makeCacheFile(hashPart, "ls"), str.str());
|
||||||
|
|
||||||
/* FIXME: do this asynchronously. */
|
/* FIXME: do this asynchronously. */
|
||||||
writeFile(makeCacheFile(storePath, "nar"), nar);
|
writeFile(makeCacheFile(hashPart, "nar"), nar);
|
||||||
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
ignoreException();
|
ignoreException();
|
||||||
|
@ -47,23 +47,22 @@ std::pair<ref<FSAccessor>, Path> RemoteFSAccessor::fetch(const Path & path_)
|
||||||
{
|
{
|
||||||
auto path = canonPath(path_);
|
auto path = canonPath(path_);
|
||||||
|
|
||||||
auto storePath = store->toStorePath(path);
|
auto [storePath, restPath] = store->toStorePath(path);
|
||||||
std::string restPath = std::string(path, storePath.size());
|
|
||||||
|
|
||||||
if (!store->isValidPath(store->parseStorePath(storePath)))
|
if (!store->isValidPath(storePath))
|
||||||
throw InvalidPath("path '%1%' is not a valid store path", storePath);
|
throw InvalidPath("path '%1%' is not a valid store path", store->printStorePath(storePath));
|
||||||
|
|
||||||
auto i = nars.find(storePath);
|
auto i = nars.find(std::string(storePath.hashPart()));
|
||||||
if (i != nars.end()) return {i->second, restPath};
|
if (i != nars.end()) return {i->second, restPath};
|
||||||
|
|
||||||
StringSink sink;
|
StringSink sink;
|
||||||
std::string listing;
|
std::string listing;
|
||||||
Path cacheFile;
|
Path cacheFile;
|
||||||
|
|
||||||
if (cacheDir != "" && pathExists(cacheFile = makeCacheFile(storePath, "nar"))) {
|
if (cacheDir != "" && pathExists(cacheFile = makeCacheFile(storePath.hashPart(), "nar"))) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
listing = nix::readFile(makeCacheFile(storePath, "ls"));
|
listing = nix::readFile(makeCacheFile(storePath.hashPart(), "ls"));
|
||||||
|
|
||||||
auto narAccessor = makeLazyNarAccessor(listing,
|
auto narAccessor = makeLazyNarAccessor(listing,
|
||||||
[cacheFile](uint64_t offset, uint64_t length) {
|
[cacheFile](uint64_t offset, uint64_t length) {
|
||||||
|
@ -81,7 +80,7 @@ std::pair<ref<FSAccessor>, Path> RemoteFSAccessor::fetch(const Path & path_)
|
||||||
return buf;
|
return buf;
|
||||||
});
|
});
|
||||||
|
|
||||||
nars.emplace(storePath, narAccessor);
|
nars.emplace(storePath.hashPart(), narAccessor);
|
||||||
return {narAccessor, restPath};
|
return {narAccessor, restPath};
|
||||||
|
|
||||||
} catch (SysError &) { }
|
} catch (SysError &) { }
|
||||||
|
@ -90,15 +89,15 @@ std::pair<ref<FSAccessor>, Path> RemoteFSAccessor::fetch(const Path & path_)
|
||||||
*sink.s = nix::readFile(cacheFile);
|
*sink.s = nix::readFile(cacheFile);
|
||||||
|
|
||||||
auto narAccessor = makeNarAccessor(sink.s);
|
auto narAccessor = makeNarAccessor(sink.s);
|
||||||
nars.emplace(storePath, narAccessor);
|
nars.emplace(storePath.hashPart(), narAccessor);
|
||||||
return {narAccessor, restPath};
|
return {narAccessor, restPath};
|
||||||
|
|
||||||
} catch (SysError &) { }
|
} catch (SysError &) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
store->narFromPath(store->parseStorePath(storePath), sink);
|
store->narFromPath(storePath, sink);
|
||||||
auto narAccessor = makeNarAccessor(sink.s);
|
auto narAccessor = makeNarAccessor(sink.s);
|
||||||
addToCache(storePath, *sink.s, narAccessor);
|
addToCache(storePath.hashPart(), *sink.s, narAccessor);
|
||||||
return {narAccessor, restPath};
|
return {narAccessor, restPath};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ class RemoteFSAccessor : public FSAccessor
|
||||||
{
|
{
|
||||||
ref<Store> store;
|
ref<Store> store;
|
||||||
|
|
||||||
std::map<Path, ref<FSAccessor>> nars;
|
std::map<std::string, ref<FSAccessor>> nars;
|
||||||
|
|
||||||
Path cacheDir;
|
Path cacheDir;
|
||||||
|
|
||||||
|
@ -18,9 +18,9 @@ class RemoteFSAccessor : public FSAccessor
|
||||||
|
|
||||||
friend class BinaryCacheStore;
|
friend class BinaryCacheStore;
|
||||||
|
|
||||||
Path makeCacheFile(const Path & storePath, const std::string & ext);
|
Path makeCacheFile(std::string_view hashPart, const std::string & ext);
|
||||||
|
|
||||||
void addToCache(const Path & storePath, const std::string & nar,
|
void addToCache(std::string_view hashPart, const std::string & nar,
|
||||||
ref<FSAccessor> narAccessor);
|
ref<FSAccessor> narAccessor);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -21,15 +21,15 @@ bool Store::isInStore(const Path & path) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Path Store::toStorePath(const Path & path) const
|
std::pair<StorePath, Path> Store::toStorePath(const Path & path) const
|
||||||
{
|
{
|
||||||
if (!isInStore(path))
|
if (!isInStore(path))
|
||||||
throw Error("path '%1%' is not in the Nix store", path);
|
throw Error("path '%1%' is not in the Nix store", path);
|
||||||
Path::size_type slash = path.find('/', storeDir.size() + 1);
|
Path::size_type slash = path.find('/', storeDir.size() + 1);
|
||||||
if (slash == Path::npos)
|
if (slash == Path::npos)
|
||||||
return path;
|
return {parseStorePath(path), ""};
|
||||||
else
|
else
|
||||||
return Path(path, 0, slash);
|
return {parseStorePath(std::string_view(path).substr(0, slash)), path.substr(slash)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,14 +42,14 @@ Path Store::followLinksToStore(std::string_view _path) const
|
||||||
path = absPath(target, dirOf(path));
|
path = absPath(target, dirOf(path));
|
||||||
}
|
}
|
||||||
if (!isInStore(path))
|
if (!isInStore(path))
|
||||||
throw NotInStore("path '%1%' is not in the Nix store", path);
|
throw BadStorePath("path '%1%' is not in the Nix store", path);
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
StorePath Store::followLinksToStorePath(std::string_view path) const
|
StorePath Store::followLinksToStorePath(std::string_view path) const
|
||||||
{
|
{
|
||||||
return parseStorePath(toStorePath(followLinksToStore(path)));
|
return toStorePath(followLinksToStore(path)).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ MakeError(InvalidPath, Error);
|
||||||
MakeError(Unsupported, Error);
|
MakeError(Unsupported, Error);
|
||||||
MakeError(SubstituteGone, Error);
|
MakeError(SubstituteGone, Error);
|
||||||
MakeError(SubstituterDisabled, Error);
|
MakeError(SubstituterDisabled, Error);
|
||||||
MakeError(NotInStore, Error);
|
MakeError(BadStorePath, Error);
|
||||||
|
|
||||||
|
|
||||||
class FSAccessor;
|
class FSAccessor;
|
||||||
|
@ -317,9 +317,9 @@ public:
|
||||||
the Nix store. */
|
the Nix store. */
|
||||||
bool isStorePath(std::string_view path) const;
|
bool isStorePath(std::string_view path) const;
|
||||||
|
|
||||||
/* Chop off the parts after the top-level store name, e.g.,
|
/* Split a path like /nix/store/<hash>-<name>/<bla> into
|
||||||
/nix/store/abcd-foo/bar => /nix/store/abcd-foo. */
|
/nix/store/<hash>-<name> and /<bla>. */
|
||||||
Path toStorePath(const Path & path) const;
|
std::pair<StorePath, Path> toStorePath(const Path & path) const;
|
||||||
|
|
||||||
/* Follow symlinks until we end up with a path in the Nix store. */
|
/* Follow symlinks until we end up with a path in the Nix store. */
|
||||||
Path followLinksToStore(std::string_view path) const;
|
Path followLinksToStore(std::string_view path) const;
|
||||||
|
|
|
@ -94,8 +94,8 @@ struct InstallableStorePath : Installable
|
||||||
ref<Store> store;
|
ref<Store> store;
|
||||||
StorePath storePath;
|
StorePath storePath;
|
||||||
|
|
||||||
InstallableStorePath(ref<Store> store, const Path & storePath)
|
InstallableStorePath(ref<Store> store, StorePath && storePath)
|
||||||
: store(store), storePath(store->parseStorePath(storePath)) { }
|
: store(store), storePath(std::move(storePath)) { }
|
||||||
|
|
||||||
std::string what() override { return store->printStorePath(storePath); }
|
std::string what() override { return store->printStorePath(storePath); }
|
||||||
|
|
||||||
|
@ -228,11 +228,11 @@ static std::vector<std::shared_ptr<Installable>> parseInstallables(
|
||||||
result.push_back(std::make_shared<InstallableExpr>(cmd, s));
|
result.push_back(std::make_shared<InstallableExpr>(cmd, s));
|
||||||
|
|
||||||
else if (s.find("/") != std::string::npos) {
|
else if (s.find("/") != std::string::npos) {
|
||||||
|
try {
|
||||||
auto path = store->toStorePath(store->followLinksToStore(s));
|
result.push_back(std::make_shared<InstallableStorePath>(
|
||||||
|
store,
|
||||||
if (store->isStorePath(path))
|
store->toStorePath(store->followLinksToStore(s)).first));
|
||||||
result.push_back(std::make_shared<InstallableStorePath>(store, path));
|
} catch (BadStorePath &) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (s == "" || std::regex_match(s, attrPathRegex))
|
else if (s == "" || std::regex_match(s, attrPathRegex))
|
||||||
|
|
Loading…
Reference in a new issue