fix(settings): a repository on this computer may be a Windows drive path or a rooted Unix path on any system
The portable Windows job (P11c run 6) failed ledger-core's `where_backups_go_is_checked`: `/srv/books.git` is not an absolute path to Windows, and `C:\books` was read as the host `C` of a networked address. `backup.git_remote` now reads a drive path (one letter, a colon, a slash or backslash) as a path on this computer, as git does, and a path from `/` as rooted on every system git runs on; the test holds the three forms on every OS. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
This commit is contained in:
1 parent
8ba104a15a
commit
8cd2d2f80f
1 file changed
+13
-2
@@ -1198,13 +1198,22 @@ pub fn check(key: &Key, v: &Value) -> Result<Value, String> {
|
|||||||
}
|
}
|
||||||
// A path on this computer is named from the root of its disk:
|
// A path on this computer is named from the root of its disk:
|
||||||
// the server's working folder is no place to name one from.
|
// the server's working folder is no place to name one from.
|
||||||
let networked = match s.split_once("://") {
|
// `C:\books` is a Windows drive path, not the host `C` (git
|
||||||
|
// reads it the same way), and `/srv/books` is rooted on every
|
||||||
|
// system git runs on (on Windows through its own shell).
|
||||||
|
let drive_path = s.len() > 2
|
||||||
|
&& s.as_bytes()[0].is_ascii_alphabetic()
|
||||||
|
&& &s[1..2] == ":"
|
||||||
|
&& matches!(&s[2..3], "\\" | "/");
|
||||||
|
let networked = !drive_path
|
||||||
|
&& match s.split_once("://") {
|
||||||
Some((scheme, _)) => scheme != "file",
|
Some((scheme, _)) => scheme != "file",
|
||||||
None => s
|
None => s
|
||||||
.split_once(':')
|
.split_once(':')
|
||||||
.is_some_and(|(host, _)| !host.contains('/')),
|
.is_some_and(|(host, _)| !host.contains('/')),
|
||||||
};
|
};
|
||||||
if !networked && !s.starts_with("file://") && !std::path::Path::new(&s).is_absolute() {
|
let rooted = drive_path || s.starts_with('/') || std::path::Path::new(&s).is_absolute();
|
||||||
|
if !networked && !s.starts_with("file://") && !rooted {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"{name} {s:?}: a repository on this computer is named from the root of its disk (such as /srv/books)"
|
"{name} {s:?}: a repository on this computer is named from the root of its disk (such as /srv/books)"
|
||||||
));
|
));
|
||||||
@@ -1854,6 +1863,8 @@ mod tests {
|
|||||||
"git@host:owner/books.git",
|
"git@host:owner/books.git",
|
||||||
"https://host/owner/books",
|
"https://host/owner/books",
|
||||||
"/srv/books.git",
|
"/srv/books.git",
|
||||||
|
"C:\\books\\acme.git",
|
||||||
|
"D:/books/acme.git",
|
||||||
] {
|
] {
|
||||||
assert_eq!(check(remote, &json!(ok)).unwrap(), json!(ok), "{ok}");
|
assert_eq!(check(remote, &json!(ok)).unwrap(), json!(ok), "{ok}");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user