fix: guard git init parent folders

This commit is contained in:
lucaronin
2026-04-28 02:38:32 +02:00
parent e912ab9a9f
commit a3ca78fced
2 changed files with 81 additions and 0 deletions

View File

@@ -158,10 +158,62 @@ pub fn is_git_repo(vault_path: VaultPathArg) -> bool {
.is_dir()
}
#[cfg(desktop)]
fn validate_git_init_target(vault_path: &str) -> Result<(), String> {
let path = std::path::Path::new(vault_path);
if !path.exists() {
return Err("Choose an existing vault folder before initializing Git".to_string());
}
if !path.is_dir() {
return Err("Choose a folder before initializing Git".to_string());
}
if is_broad_personal_folder(path) && !has_tolaria_vault_marker(path) {
return Err(format!(
"Choose a dedicated vault folder before initializing Git. '{}' looks like a broad personal folder; create or select a subfolder such as '{}' instead.",
path.display(),
path.join("Tolaria").display()
));
}
Ok(())
}
#[cfg(desktop)]
fn is_broad_personal_folder(path: &std::path::Path) -> bool {
let Some(name) = path.file_name().and_then(|name| name.to_str()) else {
return false;
};
matches!(
name.to_ascii_lowercase().as_str(),
"desktop"
| "documents"
| "downloads"
| "movies"
| "music"
| "pictures"
| "public"
| "templates"
| "videos"
)
}
#[cfg(desktop)]
fn has_tolaria_vault_marker(path: &std::path::Path) -> bool {
["AGENTS.md", "CLAUDE.md", "type.md", "note.md"]
.iter()
.any(|file| path.join(file).is_file())
|| ["attachments", "type", "views"]
.iter()
.any(|dir| path.join(dir).is_dir())
}
#[cfg(desktop)]
#[tauri::command]
pub fn init_git_repo(vault_path: VaultPathArg) -> Result<(), String> {
let vault_path = expand_tilde(&vault_path);
validate_git_init_target(&vault_path)?;
crate::git::init_repo(&vault_path)
}
@@ -374,6 +426,33 @@ mod tests {
);
}
#[test]
fn init_git_repo_rejects_broad_personal_folders() {
let dir = TempDir::new().unwrap();
let documents = dir.path().join("Documents");
fs::create_dir_all(&documents).unwrap();
fs::write(documents.join("unrelated.txt"), "not a vault").unwrap();
let err = init_git_repo(documents.to_string_lossy().into_owned())
.expect_err("expected Documents itself to be rejected before git init");
assert!(err.contains("dedicated vault folder"));
assert!(!documents.join(".git").exists());
}
#[test]
fn init_git_repo_allows_named_vault_subfolder_under_documents() {
let dir = TempDir::new().unwrap();
let vault = dir.path().join("Documents").join("Tolaria");
fs::create_dir_all(&vault).unwrap();
fs::write(vault.join("note.md"), "# Note\n").unwrap();
let vault = vault.to_string_lossy().into_owned();
init_git_repo(vault.clone()).unwrap();
assert!(is_git_repo(vault));
}
#[tokio::test]
async fn desktop_remote_commands_report_no_remote() {
let (_dir, vault) = create_initialized_vault();