fix(fermata): .botignore no longer stops project-root walk-up
Only .git, botignore.toml, and .botignore.toml define project boundaries. A bare .botignore is a policy file, not a root marker. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
/// Markers checked in priority order when walking up from a target path.
|
/// Markers checked in priority order when walking up from a target path.
|
||||||
const MARKERS: &[&str] = &["botignore.toml", ".botignore", ".git"];
|
const MARKERS: &[&str] = &["botignore.toml", ".botignore.toml", ".git"];
|
||||||
|
|
||||||
/// Walk upward from `target` (or its parent if `target` is a file) looking
|
/// Walk upward from `target` (or its parent if `target` is a file) looking
|
||||||
/// for the nearest project root. Roots are identified by the presence of
|
/// for the nearest project root. Roots are identified by the presence of
|
||||||
|
|||||||
+38
-5
@@ -8,7 +8,7 @@ fn finds_botignore_toml_first() {
|
|||||||
let root = tmp.path();
|
let root = tmp.path();
|
||||||
fs::create_dir_all(root.join("sub/deep")).unwrap();
|
fs::create_dir_all(root.join("sub/deep")).unwrap();
|
||||||
fs::write(root.join("botignore.toml"), "").unwrap();
|
fs::write(root.join("botignore.toml"), "").unwrap();
|
||||||
fs::write(root.join(".botignore"), "").unwrap();
|
fs::write(root.join(".botignore.toml"), "").unwrap();
|
||||||
fs::create_dir_all(root.join(".git")).unwrap();
|
fs::create_dir_all(root.join(".git")).unwrap();
|
||||||
|
|
||||||
let target = root.join("sub/deep/file.rs");
|
let target = root.join("sub/deep/file.rs");
|
||||||
@@ -19,7 +19,40 @@ fn finds_botignore_toml_first() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn falls_back_to_botignore() {
|
fn finds_dot_botignore_toml() {
|
||||||
|
let tmp = TempDir::new().unwrap();
|
||||||
|
let root = tmp.path();
|
||||||
|
fs::create_dir_all(root.join("sub")).unwrap();
|
||||||
|
fs::write(root.join(".botignore.toml"), "").unwrap();
|
||||||
|
|
||||||
|
let target = root.join("sub/file.rs");
|
||||||
|
fs::write(&target, "").unwrap();
|
||||||
|
|
||||||
|
let found = find_project_root(&target).unwrap();
|
||||||
|
assert_eq!(found, root);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn botignore_alone_does_not_stop_walk() {
|
||||||
|
// A bare .botignore is a policy file, not a project boundary.
|
||||||
|
// The walk should continue past it to find a real root marker.
|
||||||
|
let tmp = TempDir::new().unwrap();
|
||||||
|
let root = tmp.path();
|
||||||
|
fs::create_dir_all(root.join("a/b")).unwrap();
|
||||||
|
fs::create_dir_all(root.join(".git")).unwrap();
|
||||||
|
fs::write(root.join("a/.botignore"), "*.secret").unwrap();
|
||||||
|
|
||||||
|
let target = root.join("a/b/file.rs");
|
||||||
|
fs::write(&target, "").unwrap();
|
||||||
|
|
||||||
|
// Should find root (with .git), NOT root/a (with .botignore)
|
||||||
|
let found = find_project_root(&target).unwrap();
|
||||||
|
assert_eq!(found, root);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn botignore_only_returns_none() {
|
||||||
|
// If only .botignore exists with no real root marker, no project root is found.
|
||||||
let tmp = TempDir::new().unwrap();
|
let tmp = TempDir::new().unwrap();
|
||||||
let root = tmp.path();
|
let root = tmp.path();
|
||||||
fs::create_dir_all(root.join("sub")).unwrap();
|
fs::create_dir_all(root.join("sub")).unwrap();
|
||||||
@@ -28,8 +61,8 @@ fn falls_back_to_botignore() {
|
|||||||
let target = root.join("sub/file.rs");
|
let target = root.join("sub/file.rs");
|
||||||
fs::write(&target, "").unwrap();
|
fs::write(&target, "").unwrap();
|
||||||
|
|
||||||
let found = find_project_root(&target).unwrap();
|
// .botignore alone should NOT define a project root
|
||||||
assert_eq!(found, root);
|
assert!(find_project_root(&target).is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -59,7 +92,7 @@ fn walks_up_from_file_path_not_cwd() {
|
|||||||
let tmp = TempDir::new().unwrap();
|
let tmp = TempDir::new().unwrap();
|
||||||
let root = tmp.path();
|
let root = tmp.path();
|
||||||
fs::create_dir_all(root.join("a/b/c")).unwrap();
|
fs::create_dir_all(root.join("a/b/c")).unwrap();
|
||||||
fs::write(root.join("a/.botignore"), "").unwrap();
|
fs::write(root.join("a/botignore.toml"), "").unwrap();
|
||||||
|
|
||||||
let target = root.join("a/b/c/file.rs");
|
let target = root.join("a/b/c/file.rs");
|
||||||
fs::write(&target, "").unwrap();
|
fs::write(&target, "").unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user