From 6e2fcb7e2971561f526cbb332cb323a5d4def336 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 6 Feb 2025 16:31:42 +0100 Subject: [PATCH] Parser: Respect the accessor of the source file for relative paths --- src/libexpr/parser.y | 15 +++++++++++---- src/libflake/flake/flake.cc | 8 ++------ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 944c7b1af..bde721401 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -359,11 +359,18 @@ string_parts_interpolated path_start : PATH { - Path path(absPath(std::string_view{$1.p, $1.l}, state->basePath.path.abs())); + std::string_view literal({$1.p, $1.l}); + Path path(absPath(literal, state->basePath.path.abs())); /* add back in the trailing '/' to the first segment */ - if ($1.p[$1.l-1] == '/' && $1.l > 1) - path += "/"; - $$ = new ExprPath(ref(state->rootFS), std::move(path)); + if (literal.size() > 1 && literal.back() == '/') + path += '/'; + $$ = + /* Absolute paths are always interpreted relative to the + root filesystem accessor, rather than the accessor of the + current Nix expression. */ + literal.front() == '/' + ? new ExprPath(state->rootFS, std::move(path)) + : new ExprPath(state->basePath.accessor, std::move(path)); } | HPATH { if (state->settings.pureEval) { diff --git a/src/libflake/flake/flake.cc b/src/libflake/flake/flake.cc index eee22d516..fcb04ac7f 100644 --- a/src/libflake/flake/flake.cc +++ b/src/libflake/flake/flake.cc @@ -186,9 +186,7 @@ static FlakeInput parseFlakeInput( url = attr.value->string_view(); else if (attr.value->type() == nPath) { auto path = attr.value->path(); - if (path.accessor != flakeDir.accessor - // FIXME: hack necessary since the parser currently stores all paths as inside rootFS. - && flakeDir.accessor == state.rootFS) + if (path.accessor != flakeDir.accessor) throw Error("input attribute path '%s' at %s must be in the same source tree as %s", path, state.positions[attr.pos], flakeDir); url = "path:" + flakeDir.path.makeRelative(path.path); @@ -337,9 +335,7 @@ static Flake readFlake( state.symbols[setting.name], std::string(state.forceStringNoCtx(*setting.value, setting.pos, ""))); else if (setting.value->type() == nPath) { - // FIXME: hack necessary since the parser currently stores all paths as inside rootFS. - SourcePath path(rootDir.accessor, setting.value->path().path); - auto storePath = fetchToStore(*state.store, path, FetchMode::Copy); + auto storePath = fetchToStore(*state.store, setting.value->path(), FetchMode::Copy); flake.config.settings.emplace( state.symbols[setting.name], state.store->toRealPath(storePath));