1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-30 07:33:16 +02:00

parseFlakeRefWithFragment() improvements

In particular, plain paths no longer ignore query parameters
(e.g. '/foo/bar?lock=1').
This commit is contained in:
Eelco Dolstra 2022-08-17 15:34:40 +02:00
parent 18c6daf1a8
commit a5fd4ea94e

View file

@ -92,6 +92,15 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
std::smatch match; std::smatch match;
auto fromParsedURL = [&](ParsedURL && parsedURL)
{
auto dir = getOr(parsedURL.query, "dir", "");
parsedURL.query.erase("dir");
std::string fragment;
std::swap(fragment, parsedURL.fragment);
return std::make_pair(FlakeRef(Input::fromURL(parsedURL), dir), fragment);
};
/* Check if 'url' is a flake ID. This is an abbreviated syntax for /* Check if 'url' is a flake ID. This is an abbreviated syntax for
'flake:<flake-id>?ref=<ref>&rev=<rev>'. */ 'flake:<flake-id>?ref=<ref>&rev=<rev>'. */
@ -112,6 +121,7 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
else if (std::regex_match(url, match, pathUrlRegex)) { else if (std::regex_match(url, match, pathUrlRegex)) {
std::string path = match[1]; std::string path = match[1];
std::string fragment = percentDecode(match.str(3)); std::string fragment = percentDecode(match.str(3));
auto query = decodeQuery(match[2]);
if (baseDir) { if (baseDir) {
/* Check if 'url' is a path (either absolute or relative /* Check if 'url' is a path (either absolute or relative
@ -163,7 +173,8 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
.scheme = "git+file", .scheme = "git+file",
.authority = "", .authority = "",
.path = flakeRoot, .path = flakeRoot,
.query = decodeQuery(match[2]), .query = query,
.fragment = fragment,
}; };
if (subdir != "") { if (subdir != "") {
@ -175,9 +186,7 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
if (pathExists(flakeRoot + "/.git/shallow")) if (pathExists(flakeRoot + "/.git/shallow"))
parsedURL.query.insert_or_assign("shallow", "1"); parsedURL.query.insert_or_assign("shallow", "1");
return std::make_pair( return fromParsedURL(std::move(parsedURL));
FlakeRef(Input::fromURL(parsedURL), getOr(parsedURL.query, "dir", "")),
fragment);
} }
subdir = std::string(baseNameOf(flakeRoot)) + (subdir.empty() ? "" : "/" + subdir); subdir = std::string(baseNameOf(flakeRoot)) + (subdir.empty() ? "" : "/" + subdir);
@ -188,26 +197,21 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
} else { } else {
if (!hasPrefix(path, "/")) if (!hasPrefix(path, "/"))
throw BadURL("flake reference '%s' is not an absolute path", url); throw BadURL("flake reference '%s' is not an absolute path", url);
auto query = decodeQuery(match[2]);
path = canonPath(path + "/" + getOr(query, "dir", ""));
} }
fetchers::Attrs attrs; return fromParsedURL({
attrs.insert_or_assign("type", "path"); .url = path, // FIXME
attrs.insert_or_assign("path", path); .base = path,
.scheme = "path",
return std::make_pair(FlakeRef(Input::fromAttrs(std::move(attrs)), ""), fragment); .authority = "",
.path = path,
.query = query,
.fragment = fragment
});
} }
else { else
auto parsedURL = parseURL(url); return fromParsedURL(parseURL(url));
std::string fragment;
std::swap(fragment, parsedURL.fragment);
return std::make_pair(
FlakeRef(Input::fromURL(parsedURL), getOr(parsedURL.query, "dir", "")),
fragment);
}
} }
std::optional<std::pair<FlakeRef, std::string>> maybeParseFlakeRefWithFragment( std::optional<std::pair<FlakeRef, std::string>> maybeParseFlakeRefWithFragment(