mirror of
https://github.com/NixOS/nix
synced 2025-06-29 19:03:16 +02:00
Encode virtual paths as /nix/store/virtual000<N>
This makes lib.isStorePath in nixpkgs return true for source trees and fixes some cases where /__nix_virtual__ showed up in the NixOS manual.
This commit is contained in:
parent
e424a8b196
commit
a653e98f55
4 changed files with 19 additions and 10 deletions
|
@ -500,6 +500,7 @@ EvalState::EvalState(
|
||||||
, valueAllocCache(std::make_shared<void *>(nullptr))
|
, valueAllocCache(std::make_shared<void *>(nullptr))
|
||||||
, env1AllocCache(std::make_shared<void *>(nullptr))
|
, env1AllocCache(std::make_shared<void *>(nullptr))
|
||||||
#endif
|
#endif
|
||||||
|
, virtualPathMarker(settings.nixStore + "/virtual00000000000000000")
|
||||||
, baseEnv(allocEnv(128))
|
, baseEnv(allocEnv(128))
|
||||||
, staticBaseEnv{std::make_shared<StaticEnv>(false, nullptr)}
|
, staticBaseEnv{std::make_shared<StaticEnv>(false, nullptr)}
|
||||||
{
|
{
|
||||||
|
|
|
@ -227,14 +227,16 @@ public:
|
||||||
void registerAccessor(ref<InputAccessor> accessor);
|
void registerAccessor(ref<InputAccessor> accessor);
|
||||||
|
|
||||||
/* Convert a path to a string representation of the format
|
/* Convert a path to a string representation of the format
|
||||||
`/__nix_virtual__/<accessor-number>/<path>`. */
|
`/nix/store/virtual000...<accessor-number>/<path>`. */
|
||||||
std::string encodePath(const SourcePath & path);
|
std::string encodePath(const SourcePath & path);
|
||||||
|
|
||||||
/* Decode a path encoded by `encodePath()`. */
|
/* Decode a path encoded by `encodePath()`. */
|
||||||
SourcePath decodePath(std::string_view s, PosIdx pos = noPos);
|
SourcePath decodePath(std::string_view s, PosIdx pos = noPos);
|
||||||
|
|
||||||
|
const std::string virtualPathMarker;
|
||||||
|
|
||||||
/* Decode all virtual paths in a string, i.e. all
|
/* Decode all virtual paths in a string, i.e. all
|
||||||
/__nix_virtual__/... substrings are replaced by the
|
/nix/store/virtual000... substrings are replaced by the
|
||||||
corresponding input accessor. */
|
corresponding input accessor. */
|
||||||
std::string decodePaths(std::string_view s);
|
std::string decodePaths(std::string_view s);
|
||||||
|
|
||||||
|
|
|
@ -14,18 +14,16 @@ void EvalState::registerAccessor(ref<InputAccessor> accessor)
|
||||||
inputAccessors.emplace(accessor->number, accessor);
|
inputAccessors.emplace(accessor->number, accessor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr std::string_view marker = "/__nix_virtual__/";
|
|
||||||
|
|
||||||
std::string EvalState::encodePath(const SourcePath & path)
|
std::string EvalState::encodePath(const SourcePath & path)
|
||||||
{
|
{
|
||||||
/* For backward compatibility, return paths in the root FS
|
/* For backward compatibility, return paths in the root FS
|
||||||
normally. Encoding any other path is not very reproducible (due
|
normally. Encoding any other path is not very reproducible (due
|
||||||
to /__nix_virtual__/<N>) and we should depreceate it
|
to /nix/store/virtual000...<N>) and we should deprecate it
|
||||||
eventually. So print a warning about use of an encoded path in
|
eventually. So print a warning about use of an encoded path in
|
||||||
decodePath(). */
|
decodePath(). */
|
||||||
return path.accessor == rootFS
|
return path.accessor == rootFS
|
||||||
? path.path.abs()
|
? path.path.abs()
|
||||||
: std::string(marker) + std::to_string(path.accessor->number) + path.path.abs();
|
: fmt("%s%08x-source%s", virtualPathMarker, path.accessor->number, path.path.absOrEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
SourcePath EvalState::decodePath(std::string_view s, PosIdx pos)
|
SourcePath EvalState::decodePath(std::string_view s, PosIdx pos)
|
||||||
|
@ -33,17 +31,17 @@ SourcePath EvalState::decodePath(std::string_view s, PosIdx pos)
|
||||||
if (!hasPrefix(s, "/"))
|
if (!hasPrefix(s, "/"))
|
||||||
throwEvalError(pos, "string '%1%' doesn't represent an absolute path", s);
|
throwEvalError(pos, "string '%1%' doesn't represent an absolute path", s);
|
||||||
|
|
||||||
if (hasPrefix(s, marker)) {
|
if (hasPrefix(s, virtualPathMarker)) {
|
||||||
auto fail = [s]() {
|
auto fail = [s]() {
|
||||||
throw Error("cannot decode virtual path '%s'", s);
|
throw Error("cannot decode virtual path '%s'", s);
|
||||||
};
|
};
|
||||||
|
|
||||||
s = s.substr(marker.size());
|
s = s.substr(virtualPathMarker.size());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto slash = s.find('/');
|
auto slash = s.find('/');
|
||||||
if (slash == std::string::npos) fail();
|
if (slash == std::string::npos) fail();
|
||||||
size_t number = std::stoi(std::string(s, 0, slash));
|
size_t number = std::stoi(std::string(s, 0, slash), nullptr, 16);
|
||||||
s = s.substr(slash);
|
s = s.substr(slash);
|
||||||
|
|
||||||
auto accessor = inputAccessors.find(number);
|
auto accessor = inputAccessors.find(number);
|
||||||
|
@ -70,7 +68,7 @@ std::string EvalState::decodePaths(std::string_view s)
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
auto m = s.find(marker, pos);
|
auto m = s.find(virtualPathMarker, pos);
|
||||||
if (m == s.npos) {
|
if (m == s.npos) {
|
||||||
res.append(s.substr(pos));
|
res.append(s.substr(pos));
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -58,6 +58,14 @@ public:
|
||||||
const std::string & abs() const
|
const std::string & abs() const
|
||||||
{ return path; }
|
{ return path; }
|
||||||
|
|
||||||
|
/* Like abs(), but return an empty string if this path is
|
||||||
|
'/'. Thus the returned string never ends in a slash. */
|
||||||
|
const std::string & absOrEmpty() const
|
||||||
|
{
|
||||||
|
const static std::string epsilon;
|
||||||
|
return isRoot() ? epsilon : path;
|
||||||
|
}
|
||||||
|
|
||||||
const char * c_str() const
|
const char * c_str() const
|
||||||
{ return path.c_str(); }
|
{ return path.c_str(); }
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue