Skip to content

Commit e02026a

Browse files
authored
Merge pull request #12254 from DeterminateSystems/fix-relative-path-on-cli
Fix relative 'path:' flakerefs in the CLI
2 parents c45dfee + ff9d886 commit e02026a

File tree

8 files changed

+22
-14
lines changed

8 files changed

+22
-14
lines changed

src/libexpr/eval.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ void EvalState::checkURI(const std::string & uri)
406406

407407
/* If the URI is a path, then check it against allowedPaths as
408408
well. */
409-
if (hasPrefix(uri, "/")) {
409+
if (isAbsolute(uri)) {
410410
if (auto rootFS2 = rootFS.dynamic_pointer_cast<AllowListSourceAccessor>())
411411
rootFS2->checkAccess(CanonPath(uri));
412412
return;

src/libfetchers/path.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ struct PathInputScheme : InputScheme
9797
std::optional<std::string> isRelative(const Input & input) const
9898
{
9999
auto path = getStrAttr(input.attrs, "path");
100-
if (hasPrefix(path, "/"))
100+
if (isAbsolute(path))
101101
return std::nullopt;
102102
else
103103
return path;

src/libfetchers/registry.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ static std::shared_ptr<Registry> getGlobalRegistry(const Settings & settings, re
153153
return std::make_shared<Registry>(settings, Registry::Global); // empty registry
154154
}
155155

156-
if (!hasPrefix(path, "/")) {
156+
if (!isAbsolute(path)) {
157157
auto storePath = downloadFile(store, path, "flake-registry.json").storePath;
158158
if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>())
159159
store2->addPermRoot(storePath, getCacheDir() + "/flake-registry.json");

src/libflake/flake/flakeref.cc

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
102102

103103
if (baseDir) {
104104
/* Check if 'url' is a path (either absolute or relative
105-
to 'baseDir'). If so, search upward to the root of the
106-
repo (i.e. the directory containing .git). */
105+
to 'baseDir'). If so, search upward to the root of the
106+
repo (i.e. the directory containing .git). */
107107

108108
path = absPath(path, baseDir);
109109

@@ -178,7 +178,7 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
178178
}
179179

180180
} else {
181-
if (!hasPrefix(path, "/"))
181+
if (!isAbsolute(path))
182182
throw BadURL("flake reference '%s' is not an absolute path", url);
183183
path = canonPath(path + "/" + getOr(query, "dir", ""));
184184
}
@@ -232,7 +232,12 @@ std::optional<std::pair<FlakeRef, std::string>> parseURLFlakeRef(
232232
)
233233
{
234234
try {
235-
return fromParsedURL(fetchSettings, parseURL(url), isFlake);
235+
auto parsed = parseURL(url);
236+
if (baseDir
237+
&& (parsed.scheme == "path" || parsed.scheme == "git+file")
238+
&& !isAbsolute(parsed.path))
239+
parsed.path = absPath(parsed.path, *baseDir);
240+
return fromParsedURL(fetchSettings, std::move(parsed), isFlake);
236241
} catch (BadURL &) {
237242
return std::nullopt;
238243
}

src/libutil/file-system.cc

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,7 @@ namespace nix {
3131

3232
namespace fs { using namespace std::filesystem; }
3333

34-
/**
35-
* Treat the string as possibly an absolute path, by inspecting the
36-
* start of it. Return whether it was probably intended to be
37-
* absolute.
38-
*/
39-
static bool isAbsolute(PathView path)
34+
bool isAbsolute(PathView path)
4035
{
4136
return fs::path { path }.is_absolute();
4237
}

src/libutil/file-system.hh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ namespace nix {
4242
struct Sink;
4343
struct Source;
4444

45+
/**
46+
* Return whether the path denotes an absolute path.
47+
*/
48+
bool isAbsolute(PathView path);
49+
4550
/**
4651
* @return An absolutized path, resolving paths relative to the
4752
* specified directory, or the current directory otherwise. The path

src/libutil/source-accessor.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ CanonPath SourceAccessor::resolveSymlinks(
115115
throw Error("infinite symlink recursion in path '%s'", showPath(path));
116116
auto target = readLink(res);
117117
res.pop();
118-
if (hasPrefix(target, "/"))
118+
if (isAbsolute(target))
119119
res = CanonPath::root;
120120
todo.splice(todo.begin(), tokenizeString<std::list<std::string>>(target, "/"));
121121
}

tests/functional/flakes/flakes.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ nix build -o "$TEST_ROOT/result" flake1
9797

9898
nix build -o "$TEST_ROOT/result" "$flake1Dir"
9999
nix build -o "$TEST_ROOT/result" "git+file://$flake1Dir"
100+
(cd "$flake1Dir" && nix build -o "$TEST_ROOT/result" ".")
101+
(cd "$flake1Dir" && nix build -o "$TEST_ROOT/result" "path:.")
102+
(cd "$flake1Dir" && nix build -o "$TEST_ROOT/result" "git+file:.")
100103

101104
# Test explicit packages.default.
102105
nix build -o "$TEST_ROOT/result" "$flake1Dir#default"

0 commit comments

Comments
 (0)