1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-27 12:41:15 +02:00

Merge pull request #12254 from DeterminateSystems/fix-relative-path-on-cli

Fix relative 'path:' flakerefs in the CLI
This commit is contained in:
John Ericson 2025-01-15 15:19:56 -05:00 committed by GitHub
commit e02026adae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 22 additions and 14 deletions

View file

@ -406,7 +406,7 @@ void EvalState::checkURI(const std::string & uri)
/* If the URI is a path, then check it against allowedPaths as /* If the URI is a path, then check it against allowedPaths as
well. */ well. */
if (hasPrefix(uri, "/")) { if (isAbsolute(uri)) {
if (auto rootFS2 = rootFS.dynamic_pointer_cast<AllowListSourceAccessor>()) if (auto rootFS2 = rootFS.dynamic_pointer_cast<AllowListSourceAccessor>())
rootFS2->checkAccess(CanonPath(uri)); rootFS2->checkAccess(CanonPath(uri));
return; return;

View file

@ -97,7 +97,7 @@ struct PathInputScheme : InputScheme
std::optional<std::string> isRelative(const Input & input) const std::optional<std::string> isRelative(const Input & input) const
{ {
auto path = getStrAttr(input.attrs, "path"); auto path = getStrAttr(input.attrs, "path");
if (hasPrefix(path, "/")) if (isAbsolute(path))
return std::nullopt; return std::nullopt;
else else
return path; return path;

View file

@ -153,7 +153,7 @@ static std::shared_ptr<Registry> getGlobalRegistry(const Settings & settings, re
return std::make_shared<Registry>(settings, Registry::Global); // empty registry return std::make_shared<Registry>(settings, Registry::Global); // empty registry
} }
if (!hasPrefix(path, "/")) { if (!isAbsolute(path)) {
auto storePath = downloadFile(store, path, "flake-registry.json").storePath; auto storePath = downloadFile(store, path, "flake-registry.json").storePath;
if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>()) if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>())
store2->addPermRoot(storePath, getCacheDir() + "/flake-registry.json"); store2->addPermRoot(storePath, getCacheDir() + "/flake-registry.json");

View file

@ -102,8 +102,8 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
if (baseDir) { if (baseDir) {
/* Check if 'url' is a path (either absolute or relative /* Check if 'url' is a path (either absolute or relative
to 'baseDir'). If so, search upward to the root of the to 'baseDir'). If so, search upward to the root of the
repo (i.e. the directory containing .git). */ repo (i.e. the directory containing .git). */
path = absPath(path, baseDir); path = absPath(path, baseDir);
@ -178,7 +178,7 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
} }
} else { } else {
if (!hasPrefix(path, "/")) if (!isAbsolute(path))
throw BadURL("flake reference '%s' is not an absolute path", url); throw BadURL("flake reference '%s' is not an absolute path", url);
path = canonPath(path + "/" + getOr(query, "dir", "")); path = canonPath(path + "/" + getOr(query, "dir", ""));
} }
@ -232,7 +232,12 @@ std::optional<std::pair<FlakeRef, std::string>> parseURLFlakeRef(
) )
{ {
try { try {
return fromParsedURL(fetchSettings, parseURL(url), isFlake); auto parsed = parseURL(url);
if (baseDir
&& (parsed.scheme == "path" || parsed.scheme == "git+file")
&& !isAbsolute(parsed.path))
parsed.path = absPath(parsed.path, *baseDir);
return fromParsedURL(fetchSettings, std::move(parsed), isFlake);
} catch (BadURL &) { } catch (BadURL &) {
return std::nullopt; return std::nullopt;
} }

View file

@ -31,12 +31,7 @@ namespace nix {
namespace fs { using namespace std::filesystem; } namespace fs { using namespace std::filesystem; }
/** bool isAbsolute(PathView path)
* Treat the string as possibly an absolute path, by inspecting the
* start of it. Return whether it was probably intended to be
* absolute.
*/
static bool isAbsolute(PathView path)
{ {
return fs::path { path }.is_absolute(); return fs::path { path }.is_absolute();
} }

View file

@ -42,6 +42,11 @@ namespace nix {
struct Sink; struct Sink;
struct Source; struct Source;
/**
* Return whether the path denotes an absolute path.
*/
bool isAbsolute(PathView path);
/** /**
* @return An absolutized path, resolving paths relative to the * @return An absolutized path, resolving paths relative to the
* specified directory, or the current directory otherwise. The path * specified directory, or the current directory otherwise. The path

View file

@ -115,7 +115,7 @@ CanonPath SourceAccessor::resolveSymlinks(
throw Error("infinite symlink recursion in path '%s'", showPath(path)); throw Error("infinite symlink recursion in path '%s'", showPath(path));
auto target = readLink(res); auto target = readLink(res);
res.pop(); res.pop();
if (hasPrefix(target, "/")) if (isAbsolute(target))
res = CanonPath::root; res = CanonPath::root;
todo.splice(todo.begin(), tokenizeString<std::list<std::string>>(target, "/")); todo.splice(todo.begin(), tokenizeString<std::list<std::string>>(target, "/"));
} }

View file

@ -97,6 +97,9 @@ nix build -o "$TEST_ROOT/result" flake1
nix build -o "$TEST_ROOT/result" "$flake1Dir" nix build -o "$TEST_ROOT/result" "$flake1Dir"
nix build -o "$TEST_ROOT/result" "git+file://$flake1Dir" nix build -o "$TEST_ROOT/result" "git+file://$flake1Dir"
(cd "$flake1Dir" && nix build -o "$TEST_ROOT/result" ".")
(cd "$flake1Dir" && nix build -o "$TEST_ROOT/result" "path:.")
(cd "$flake1Dir" && nix build -o "$TEST_ROOT/result" "git+file:.")
# Test explicit packages.default. # Test explicit packages.default.
nix build -o "$TEST_ROOT/result" "$flake1Dir#default" nix build -o "$TEST_ROOT/result" "$flake1Dir#default"