mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-05 08:10:39 +00:00
Fix @file references with ~ and .. paths
resolve_file_ref now expands tilde via dirs::home_dir() and uses canonicalize() to resolve .., symlinks, and verify existence in one step. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6803b9ad9a
commit
2864a6b1d1
1 changed files with 76 additions and 4 deletions
|
|
@ -123,10 +123,22 @@ pub fn resolve_file_ref(value: &str, base_dir: &Path) -> String {
|
|||
None => return value.to_string(),
|
||||
};
|
||||
|
||||
let file_path = base_dir.join(path_str);
|
||||
if !file_path.is_file() {
|
||||
return value.to_string();
|
||||
}
|
||||
// Build the raw path: expand ~ then resolve relative to base_dir
|
||||
let raw = Path::new(path_str);
|
||||
let expanded = if raw.starts_with("~") {
|
||||
match dirs::home_dir() {
|
||||
Some(home) => home.join(raw.strip_prefix("~").unwrap()),
|
||||
None => base_dir.join(path_str),
|
||||
}
|
||||
} else {
|
||||
base_dir.join(path_str)
|
||||
};
|
||||
|
||||
// Canonicalize resolves `.`, `..`, symlinks, and checks existence
|
||||
let file_path = match expanded.canonicalize() {
|
||||
Ok(p) if p.is_file() => p,
|
||||
_ => return value.to_string(),
|
||||
};
|
||||
|
||||
// Discover repo root from base_dir
|
||||
let repo_root = std::process::Command::new("git")
|
||||
|
|
@ -726,6 +738,66 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_file_ref_expands_tilde() {
|
||||
let home = dirs::home_dir().expect("home dir must exist");
|
||||
let test_file = home.join(".arc_test_tilde_tmp");
|
||||
std::fs::write(&test_file, "tilde content").unwrap();
|
||||
let _cleanup = scopeguard::guard((), |()| {
|
||||
let _ = std::fs::remove_file(&test_file);
|
||||
});
|
||||
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
// Init repo so the git-tracking check doesn't block inlining
|
||||
std::process::Command::new("git")
|
||||
.args(["init"])
|
||||
.current_dir(dir.path())
|
||||
.output()
|
||||
.unwrap();
|
||||
std::process::Command::new("git")
|
||||
.args([
|
||||
"-c", "user.name=test",
|
||||
"-c", "user.email=test@test",
|
||||
"commit", "--allow-empty", "-m", "init",
|
||||
])
|
||||
.current_dir(dir.path())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
resolve_file_ref("@~/.arc_test_tilde_tmp", dir.path()),
|
||||
"tilde content"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_file_ref_resolves_dotdot() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
// Init repo
|
||||
std::process::Command::new("git")
|
||||
.args(["init"])
|
||||
.current_dir(dir.path())
|
||||
.output()
|
||||
.unwrap();
|
||||
std::process::Command::new("git")
|
||||
.args([
|
||||
"-c", "user.name=test",
|
||||
"-c", "user.email=test@test",
|
||||
"commit", "--allow-empty", "-m", "init",
|
||||
])
|
||||
.current_dir(dir.path())
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
std::fs::write(dir.path().join("file.md"), "dotdot content").unwrap();
|
||||
std::fs::create_dir(dir.path().join("subdir")).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
resolve_file_ref("@subdir/../file.md", dir.path()),
|
||||
"dotdot content"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn file_inlining_transform_leaves_tracked_files() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue