Merge pull request #15377 from obsidiansystems/fix-windows-url-paths
Fix windows url paths
This commit is contained in:
@@ -84,6 +84,8 @@ test(
|
||||
this_exe,
|
||||
env : {
|
||||
'_NIX_TEST_UNIT_DATA' : meson.current_source_dir() / 'data',
|
||||
'HOME' : meson.current_build_dir() / 'test-home',
|
||||
'NIX_STORE' : '',
|
||||
},
|
||||
protocol : 'gtest',
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "nix/fetchers/fetch-settings.hh"
|
||||
#include "nix/fetchers/fetchers.hh"
|
||||
#include "nix/fetchers/git-utils.hh"
|
||||
#include "nix/util/url.hh"
|
||||
|
||||
#include <git2.h>
|
||||
#include <gtest/gtest.h>
|
||||
@@ -190,7 +191,7 @@ TEST_F(GitTest, submodulePeriodSupport)
|
||||
auto input = fetchers::Input::fromAttrs(
|
||||
settings,
|
||||
{
|
||||
{"url", "file://" + repoPath.string()},
|
||||
{"url", "file://" + encodeUrlPath(pathToUrlPath(repoPath))},
|
||||
{"submodules", Explicit{true}},
|
||||
{"type", "git"},
|
||||
{"ref", "main"},
|
||||
|
||||
@@ -66,6 +66,8 @@ test(
|
||||
this_exe,
|
||||
env : {
|
||||
'_NIX_TEST_UNIT_DATA' : meson.current_source_dir() / 'data',
|
||||
'HOME' : meson.current_build_dir() / 'test-home',
|
||||
'NIX_STORE' : '',
|
||||
},
|
||||
protocol : 'gtest',
|
||||
)
|
||||
|
||||
@@ -95,7 +95,7 @@ struct PathInputScheme : InputScheme
|
||||
query.erase("__final");
|
||||
return ParsedURL{
|
||||
.scheme = "path",
|
||||
.path = splitString<std::vector<std::string>>(getStrAttr(input.attrs, "path"), "/"),
|
||||
.path = pathToUrlPath(std::filesystem::path{getStrAttr(input.attrs, "path")}),
|
||||
.query = query,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ test(
|
||||
'_NIX_TEST_UNIT_DATA' : meson.current_source_dir() / 'data',
|
||||
'NIX_CONFIG' : 'extra-experimental-features = flakes',
|
||||
'HOME' : meson.current_build_dir() / 'test-home',
|
||||
'NIX_STORE' : '',
|
||||
},
|
||||
protocol : 'gtest',
|
||||
)
|
||||
|
||||
@@ -146,7 +146,7 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
|
||||
// Save device to detect filesystem boundary
|
||||
dev_t device = lstat(path).st_dev;
|
||||
bool found = false;
|
||||
while (path != "/") {
|
||||
while (path.parent_path() != path) {
|
||||
if (pathExists(path / "flake.nix")) {
|
||||
found = true;
|
||||
break;
|
||||
@@ -171,7 +171,7 @@ std::pair<FlakeRef, std::string> parsePathFlakeRefWithFragment(
|
||||
auto flakeRoot = path;
|
||||
std::string subdir;
|
||||
|
||||
while (flakeRoot != "/") {
|
||||
while (flakeRoot.parent_path() != flakeRoot) {
|
||||
if (pathExists(flakeRoot / ".git")) {
|
||||
auto parsedURL = ParsedURL{
|
||||
.scheme = "git+file",
|
||||
|
||||
@@ -408,15 +408,22 @@ ParsedURL fixGitURL(std::string url)
|
||||
url = std::regex_replace(url, scpRegex, "ssh://$1@$2/$3");
|
||||
if (!hasPrefix(url, "file:") && !hasPrefix(url, "git+file:") && url.find("://") == std::string::npos) {
|
||||
auto path = splitString<std::vector<std::string>>(url, "/");
|
||||
#ifdef _WIN32
|
||||
// Windows drive letters (e.g., "C:") look like SCP hosts but are local paths
|
||||
bool hasDriveLetter = !path.empty() && path[0].size() == 2
|
||||
&& std::isalpha(static_cast<unsigned char>(path[0][0])) && path[0][1] == ':';
|
||||
#else
|
||||
constexpr bool hasDriveLetter = false;
|
||||
#endif
|
||||
// Reject SCP-like URLs without user (e.g., "github.com:path") - colon in first component
|
||||
if (!path.empty() && path[0].find(':') != std::string::npos)
|
||||
if (!path.empty() && path[0].find(':') != std::string::npos && !hasDriveLetter)
|
||||
throw BadURL("SCP-like URL '%s' is not supported; use SSH URL syntax instead (ssh://...)", url);
|
||||
// Absolute paths get an empty authority (file:///path), relative paths get none (file:path)
|
||||
if (hasPrefix(url, "/"))
|
||||
if (hasPrefix(url, "/") || hasDriveLetter)
|
||||
return ParsedURL{
|
||||
.scheme = "file",
|
||||
.authority = ParsedURL::Authority{},
|
||||
.path = path,
|
||||
.path = hasDriveLetter ? pathToUrlPath(std::filesystem::path(url)) : path,
|
||||
};
|
||||
else
|
||||
return ParsedURL{
|
||||
|
||||
Reference in New Issue
Block a user