Merge branch 'main' into P11c
This commit is contained in:
commit
d3fe116bc5
3 files changed
+34
-13
No files matched your search
@@ -505,7 +505,9 @@ fn a_mutating_call_answers_with_the_head_and_a_refusal_names_its_remedy() {
|
|||||||
|
|
||||||
/// Done-when (3): `books.start` is at most 8 KiB on the demo company too
|
/// Done-when (3): `books.start` is at most 8 KiB on the demo company too
|
||||||
/// (the books the viewer ships with, a loose end of every kind), and says
|
/// (the books the viewer ships with, a loose end of every kind), and says
|
||||||
/// what it cut.
|
/// what it cut. (The demo books are the viewer's: not in the server-only
|
||||||
|
/// build.)
|
||||||
|
#[cfg(feature = "gui")]
|
||||||
#[test]
|
#[test]
|
||||||
fn books_start_fits_8_kib_on_the_demo_books() {
|
fn books_start_fits_8_kib_on_the_demo_books() {
|
||||||
let today = ledger_core::settings::today_in(None);
|
let today = ledger_core::settings::today_in(None);
|
||||||
|
|||||||
@@ -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
|
||||||
Some((scheme, _)) => scheme != "file",
|
// reads it the same way), and `/srv/books` is rooted on every
|
||||||
None => s
|
// system git runs on (on Windows through its own shell).
|
||||||
.split_once(':')
|
let drive_path = s.len() > 2
|
||||||
.is_some_and(|(host, _)| !host.contains('/')),
|
&& s.as_bytes()[0].is_ascii_alphabetic()
|
||||||
};
|
&& &s[1..2] == ":"
|
||||||
if !networked && !s.starts_with("file://") && !std::path::Path::new(&s).is_absolute() {
|
&& matches!(&s[2..3], "\\" | "/");
|
||||||
|
let networked = !drive_path
|
||||||
|
&& match s.split_once("://") {
|
||||||
|
Some((scheme, _)) => scheme != "file",
|
||||||
|
None => s
|
||||||
|
.split_once(':')
|
||||||
|
.is_some_and(|(host, _)| !host.contains('/')),
|
||||||
|
};
|
||||||
|
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}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ fn the_root_is_found_without_the_environment() {
|
|||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
default_root(home.path()),
|
default_root(home.path()),
|
||||||
home.path().join(".local/share/wanderbooks")
|
platform_data_dir(home.path()).join("wanderbooks")
|
||||||
);
|
);
|
||||||
// An explicit root wins.
|
// An explicit root wins.
|
||||||
let elsewhere = home.path().join("elsewhere");
|
let elsewhere = home.path().join("elsewhere");
|
||||||
@@ -203,6 +203,8 @@ fn setup_records_a_root_chosen_elsewhere_and_forgets_it_when_back_to_default() {
|
|||||||
let home = tmp("setup-elsewhere");
|
let home = tmp("setup-elsewhere");
|
||||||
let chosen = home.path().join("my books");
|
let chosen = home.path().join("my books");
|
||||||
let (_, report) = Root::setup(home.path(), Some(&chosen), None).unwrap();
|
let (_, report) = Root::setup(home.path(), Some(&chosen), None).unwrap();
|
||||||
|
// Roots are kept as the system spells them (macOS: /tmp is /private/tmp).
|
||||||
|
let chosen = std::fs::canonicalize(&chosen).unwrap();
|
||||||
assert!(report.recorded);
|
assert!(report.recorded);
|
||||||
let pointer = platform_data_dir(home.path()).join(LOCATION_FILE);
|
let pointer = platform_data_dir(home.path()).join(LOCATION_FILE);
|
||||||
assert_eq!(mode(&pointer), 0o600);
|
assert_eq!(mode(&pointer), 0o600);
|
||||||
@@ -605,6 +607,7 @@ fn setup_run_again_keeps_the_recorded_root_and_never_moves_books() {
|
|||||||
let home = tmp("setup-keep");
|
let home = tmp("setup-keep");
|
||||||
let chosen = home.path().join("chosen");
|
let chosen = home.path().join("chosen");
|
||||||
let (root, _) = Root::setup(home.path(), Some(&chosen), None).unwrap();
|
let (root, _) = Root::setup(home.path(), Some(&chosen), None).unwrap();
|
||||||
|
let chosen = std::fs::canonicalize(&chosen).unwrap();
|
||||||
drop(root.create_book(&id("acme"), Currency::USD).unwrap());
|
drop(root.create_book(&id("acme"), Currency::USD).unwrap());
|
||||||
// Run again with nothing given (and XDG set): the recorded root stays.
|
// Run again with nothing given (and XDG set): the recorded root stays.
|
||||||
let (again, report) = Root::setup(home.path(), None, Some(&home.path().join("xdg"))).unwrap();
|
let (again, report) = Root::setup(home.path(), None, Some(&home.path().join("xdg"))).unwrap();
|
||||||
@@ -669,8 +672,12 @@ fn a_root_another_user_could_swap_is_refused() {
|
|||||||
fn missing_folders_above_the_root_are_made_private() {
|
fn missing_folders_above_the_root_are_made_private() {
|
||||||
let home = tmp("parents");
|
let home = tmp("parents");
|
||||||
let (root, _) = Root::setup(home.path(), None, None).unwrap();
|
let (root, _) = Root::setup(home.path(), None, None).unwrap();
|
||||||
assert_eq!(mode(&home.path().join(".local")), 0o700);
|
// Every folder setup made between the home and the root (`.local` and
|
||||||
assert_eq!(mode(&home.path().join(".local/share")), 0o700);
|
// `.local/share` on Linux; `Library/Application Support` on macOS).
|
||||||
|
let data = platform_data_dir(home.path());
|
||||||
|
for dir in data.ancestors().take_while(|d| *d != home.path()) {
|
||||||
|
assert_eq!(mode(dir), 0o700, "{}", dir.display());
|
||||||
|
}
|
||||||
assert_eq!(mode(&root.path().join(MARKER_FILE)), 0o600);
|
assert_eq!(mode(&root.path().join(MARKER_FILE)), 0o600);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1119,8 +1126,9 @@ fn errors_other_than_not_found_are_never_taken_for_it() {
|
|||||||
));
|
));
|
||||||
// The data folder is a file: finding the root fails, never falls back.
|
// The data folder is a file: finding the root fails, never falls back.
|
||||||
let odd = tmp("not-not-found-home");
|
let odd = tmp("not-not-found-home");
|
||||||
std::fs::create_dir(odd.path().join(".local")).unwrap();
|
let data = platform_data_dir(odd.path());
|
||||||
std::fs::write(odd.path().join(".local/share"), "x").unwrap();
|
std::fs::create_dir_all(data.parent().unwrap()).unwrap();
|
||||||
|
std::fs::write(&data, "x").unwrap();
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
Root::locate(odd.path(), None),
|
Root::locate(odd.path(), None),
|
||||||
Err(RootError::Io(..))
|
Err(RootError::Io(..))
|
||||||
|
|||||||
Reference in new issue
Block a user