forked from lix-project/lix
allow ^ in URLs
Users may select specific outputs using the ^output syntax or selecting any output using ^*. URL parsing currently doesn't support these kinds of output references: parsing will fail. Currently `queryRegex` was reused for URL fragments, which didn't include support for ^. Now queryRegex has been split from fragmentRegex, where only the fragmentRegex supports ^.
This commit is contained in:
parent
257b768436
commit
9c0a09f09f
|
@ -190,7 +190,7 @@ std::optional<std::pair<FlakeRef, std::string>> parseFlakeIdRef(
|
||||||
|
|
||||||
static std::regex flakeRegex(
|
static std::regex flakeRegex(
|
||||||
"((" + flakeIdRegexS + ")(?:/(?:" + refAndOrRevRegex + "))?)"
|
"((" + flakeIdRegexS + ")(?:/(?:" + refAndOrRevRegex + "))?)"
|
||||||
+ "(?:#(" + queryRegex + "))?",
|
+ "(?:#(" + fragmentRegex + "))?",
|
||||||
std::regex::ECMAScript);
|
std::regex::ECMAScript);
|
||||||
|
|
||||||
if (std::regex_match(url, match, flakeRegex)) {
|
if (std::regex_match(url, match, flakeRegex)) {
|
||||||
|
|
|
@ -10,6 +10,8 @@ namespace nix {
|
||||||
ASSERT_EQ(getNameFromURL(parseURL("path:~/repos/nixpkgs#packages.x86_64-linux.hello")), "hello");
|
ASSERT_EQ(getNameFromURL(parseURL("path:~/repos/nixpkgs#packages.x86_64-linux.hello")), "hello");
|
||||||
ASSERT_EQ(getNameFromURL(parseURL("path:.#nonStandardAttr.mylaptop")), "nonStandardAttr.mylaptop");
|
ASSERT_EQ(getNameFromURL(parseURL("path:.#nonStandardAttr.mylaptop")), "nonStandardAttr.mylaptop");
|
||||||
ASSERT_EQ(getNameFromURL(parseURL("path:./repos/myflake#nonStandardAttr.mylaptop")), "nonStandardAttr.mylaptop");
|
ASSERT_EQ(getNameFromURL(parseURL("path:./repos/myflake#nonStandardAttr.mylaptop")), "nonStandardAttr.mylaptop");
|
||||||
|
ASSERT_EQ(getNameFromURL(parseURL("path:./nixpkgs#packages.x86_64-linux.complex^bin,man")), "complex");
|
||||||
|
ASSERT_EQ(getNameFromURL(parseURL("path:./myproj#packages.x86_64-linux.default^*")), "myproj");
|
||||||
|
|
||||||
ASSERT_EQ(getNameFromURL(parseURL("github:NixOS/nixpkgs#packages.x86_64-linux.hello")), "hello");
|
ASSERT_EQ(getNameFromURL(parseURL("github:NixOS/nixpkgs#packages.x86_64-linux.hello")), "hello");
|
||||||
ASSERT_EQ(getNameFromURL(parseURL("github:NixOS/nixpkgs#hello")), "hello");
|
ASSERT_EQ(getNameFromURL(parseURL("github:NixOS/nixpkgs#hello")), "hello");
|
||||||
|
@ -60,5 +62,6 @@ namespace nix {
|
||||||
ASSERT_EQ(getNameFromURL(parseURL("path:.")), std::nullopt);
|
ASSERT_EQ(getNameFromURL(parseURL("path:.")), std::nullopt);
|
||||||
ASSERT_EQ(getNameFromURL(parseURL("file:.#")), std::nullopt);
|
ASSERT_EQ(getNameFromURL(parseURL("file:.#")), std::nullopt);
|
||||||
ASSERT_EQ(getNameFromURL(parseURL("path:.#packages.x86_64-linux.default")), std::nullopt);
|
ASSERT_EQ(getNameFromURL(parseURL("path:.#packages.x86_64-linux.default")), std::nullopt);
|
||||||
|
ASSERT_EQ(getNameFromURL(parseURL("path:.#packages.x86_64-linux.default^*")), std::nullopt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,13 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
static const std::string attributeNamePattern("[a-z0-9_-]+");
|
static const std::string attributeNamePattern("[a-z0-9_-]+");
|
||||||
static const std::regex lastAttributeRegex("(?:" + attributeNamePattern + "\\.)*(?!default)(" + attributeNamePattern +")");
|
static const std::regex lastAttributeRegex("(?:" + attributeNamePattern + "\\.)*(?!default)(" + attributeNamePattern +")(\\^.*)?");
|
||||||
static const std::string pathSegmentPattern("[a-zA-Z0-9_-]+");
|
static const std::string pathSegmentPattern("[a-zA-Z0-9_-]+");
|
||||||
static const std::regex lastPathSegmentRegex(".*/(" + pathSegmentPattern +")");
|
static const std::regex lastPathSegmentRegex(".*/(" + pathSegmentPattern +")");
|
||||||
static const std::regex secondPathSegmentRegex("(?:" + pathSegmentPattern + ")/(" + pathSegmentPattern +")(?:/.*)?");
|
static const std::regex secondPathSegmentRegex("(?:" + pathSegmentPattern + ")/(" + pathSegmentPattern +")(?:/.*)?");
|
||||||
static const std::regex gitProviderRegex("github|gitlab|sourcehut");
|
static const std::regex gitProviderRegex("github|gitlab|sourcehut");
|
||||||
static const std::regex gitSchemeRegex("git($|\\+.*)");
|
static const std::regex gitSchemeRegex("git($|\\+.*)");
|
||||||
|
static const std::regex defaultOutputRegex(".*\\.default($|\\^.*)");
|
||||||
|
|
||||||
std::optional<std::string> getNameFromURL(ParsedURL url) {
|
std::optional<std::string> getNameFromURL(ParsedURL url) {
|
||||||
std::smatch match;
|
std::smatch match;
|
||||||
|
@ -32,7 +33,7 @@ std::optional<std::string> getNameFromURL(ParsedURL url) {
|
||||||
return match.str(1);
|
return match.str(1);
|
||||||
|
|
||||||
/* If everything failed but there is a non-default fragment, use it in full */
|
/* If everything failed but there is a non-default fragment, use it in full */
|
||||||
if (!url.fragment.empty() && !hasSuffix(url.fragment, "default"))
|
if (!url.fragment.empty() && !std::regex_match(url.fragment, defaultOutputRegex))
|
||||||
return url.fragment;
|
return url.fragment;
|
||||||
|
|
||||||
/* If there is no fragment, take the last element of the path */
|
/* If there is no fragment, take the last element of the path */
|
||||||
|
|
|
@ -19,6 +19,7 @@ const static std::string userRegex = "(?:(?:" + unreservedRegex + "|" + pctEncod
|
||||||
const static std::string authorityRegex = "(?:" + userRegex + "@)?" + hostRegex + "(?::[0-9]+)?";
|
const static std::string authorityRegex = "(?:" + userRegex + "@)?" + hostRegex + "(?::[0-9]+)?";
|
||||||
const static std::string pcharRegex = "(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + "|[:@])";
|
const static std::string pcharRegex = "(?:" + unreservedRegex + "|" + pctEncoded + "|" + subdelimsRegex + "|[:@])";
|
||||||
const static std::string queryRegex = "(?:" + pcharRegex + "|[/? \"])*";
|
const static std::string queryRegex = "(?:" + pcharRegex + "|[/? \"])*";
|
||||||
|
const static std::string fragmentRegex = "(?:" + pcharRegex + "|[/? \"^])*";
|
||||||
const static std::string segmentRegex = "(?:" + pcharRegex + "*)";
|
const static std::string segmentRegex = "(?:" + pcharRegex + "*)";
|
||||||
const static std::string absPathRegex = "(?:(?:/" + segmentRegex + ")*/?)";
|
const static std::string absPathRegex = "(?:(?:/" + segmentRegex + ")*/?)";
|
||||||
const static std::string pathRegex = "(?:" + segmentRegex + "(?:/" + segmentRegex + ")*/?)";
|
const static std::string pathRegex = "(?:" + segmentRegex + "(?:/" + segmentRegex + ")*/?)";
|
||||||
|
|
|
@ -15,7 +15,7 @@ ParsedURL parseURL(const std::string & url)
|
||||||
"((" + schemeRegex + "):"
|
"((" + schemeRegex + "):"
|
||||||
+ "(?:(?://(" + authorityRegex + ")(" + absPathRegex + "))|(/?" + pathRegex + ")))"
|
+ "(?:(?://(" + authorityRegex + ")(" + absPathRegex + "))|(/?" + pathRegex + ")))"
|
||||||
+ "(?:\\?(" + queryRegex + "))?"
|
+ "(?:\\?(" + queryRegex + "))?"
|
||||||
+ "(?:#(" + queryRegex + "))?",
|
+ "(?:#(" + fragmentRegex + "))?",
|
||||||
std::regex::ECMAScript);
|
std::regex::ECMAScript);
|
||||||
|
|
||||||
std::smatch match;
|
std::smatch match;
|
||||||
|
|
|
@ -126,6 +126,7 @@ nix profile install "$flake1Dir^*"
|
||||||
[ -e $TEST_HOME/.nix-profile/include ]
|
[ -e $TEST_HOME/.nix-profile/include ]
|
||||||
|
|
||||||
printf Nix > $flake1Dir/who
|
printf Nix > $flake1Dir/who
|
||||||
|
nix profile list
|
||||||
nix profile upgrade flake1
|
nix profile upgrade flake1
|
||||||
[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello Nix" ]]
|
[[ $($TEST_HOME/.nix-profile/bin/hello) = "Hello Nix" ]]
|
||||||
[ -e $TEST_HOME/.nix-profile/share/man ]
|
[ -e $TEST_HOME/.nix-profile/share/man ]
|
||||||
|
|
Loading…
Reference in a new issue