Skip to content

Commit 28caa35

Browse files
committed
parsePathFlakeRefWithFragment(): Handle 'path?query' without a fragment
Commands like `nix flake metadata '.?submodules=1'` ignored the query part of the URL, while `nix build '.?submodules=1#foo'` did work correctly because of the presence of the fragment part.
1 parent 5230d3e commit 28caa35

File tree

2 files changed

+23
-17
lines changed

2 files changed

+23
-17
lines changed

src/libflake/flake/flakeref.cc

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -89,23 +89,16 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
8989
bool allowMissing,
9090
bool isFlake)
9191
{
92-
std::string path = url;
93-
std::string fragment = "";
94-
std::map<std::string, std::string> query;
95-
auto pathEnd = url.find_first_of("#?");
96-
auto fragmentStart = pathEnd;
97-
if (pathEnd != std::string::npos && url[pathEnd] == '?') {
98-
fragmentStart = url.find("#");
99-
}
100-
if (pathEnd != std::string::npos) {
101-
path = url.substr(0, pathEnd);
102-
}
103-
if (fragmentStart != std::string::npos) {
104-
fragment = percentDecode(url.substr(fragmentStart+1));
105-
}
106-
if (pathEnd != std::string::npos && fragmentStart != std::string::npos && url[pathEnd] == '?') {
107-
query = decodeQuery(url.substr(pathEnd + 1, fragmentStart - pathEnd - 1));
108-
}
92+
static std::regex pathFlakeRegex(
93+
R"(([^?#]*)(\?([^#]*))?(#(.*))?)",
94+
std::regex::ECMAScript);
95+
96+
std::smatch match;
97+
auto succeeds = std::regex_match(url, match, pathFlakeRegex);
98+
assert(succeeds);
99+
auto path = match[1].str();
100+
auto query = decodeQuery(match[3]);
101+
auto fragment = percentDecode(match[5].str());
109102

110103
if (baseDir) {
111104
/* Check if 'url' is a path (either absolute or relative

tests/functional/flakes/flake-in-submodule.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,16 @@ flakeref=git+file://$rootRepo\?submodules=1\&dir=submodule
6363
echo '"foo"' > "$rootRepo"/submodule/sub.nix
6464
[[ $(nix eval --json "$flakeref#sub" ) = '"foo"' ]]
6565
[[ $(nix flake metadata --json "$flakeref" | jq -r .locked.rev) = null ]]
66+
67+
# Test that `nix flake metadata` parses `submodule` correctly.
68+
cat > "$rootRepo"/flake.nix <<EOF
69+
{
70+
outputs = { self }: {
71+
};
72+
}
73+
EOF
74+
git -C "$rootRepo" add flake.nix
75+
git -C "$rootRepo" commit -m "Add flake.nix"
76+
77+
storePath=$(nix flake metadata --json "$rootRepo?submodules=1" | jq -r .path)
78+
[[ -e "$storePath/submodule" ]]

0 commit comments

Comments
 (0)