Implements the first five harness-tools: read, write, bash (with timeout/output truncation), glob, and grep, plus shared path-resolution helpers. Wires them into the core tool registry and processor.
53 lines
1.6 KiB
Rust
53 lines
1.6 KiB
Rust
use std::path::{Path, PathBuf};
|
|
|
|
/// Resolves a (possibly relative) tool-supplied path against `cwd`.
|
|
pub fn resolve(cwd: &Path, file_path: &str) -> PathBuf {
|
|
let path = Path::new(file_path);
|
|
if path.is_absolute() {
|
|
path.to_path_buf()
|
|
} else {
|
|
cwd.join(path)
|
|
}
|
|
}
|
|
|
|
/// Slash-separated path relative to `cwd`, used as the permission pattern — falls back to
|
|
/// the absolute path (still slash-separated) when `path` isn't under `cwd`.
|
|
pub fn relative_pattern(cwd: &Path, path: &Path) -> String {
|
|
let rel = path.strip_prefix(cwd).unwrap_or(path);
|
|
rel.to_string_lossy().replace('\\', "/")
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn resolve_joins_relative_paths_to_cwd() {
|
|
let cwd = Path::new("/home/user/project");
|
|
assert_eq!(
|
|
resolve(cwd, "src/main.rs"),
|
|
PathBuf::from("/home/user/project/src/main.rs")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn resolve_leaves_absolute_paths_untouched() {
|
|
let cwd = Path::new("/home/user/project");
|
|
assert_eq!(resolve(cwd, "/etc/hosts"), PathBuf::from("/etc/hosts"));
|
|
}
|
|
|
|
#[test]
|
|
fn relative_pattern_strips_cwd_prefix() {
|
|
let cwd = Path::new("/home/user/project");
|
|
let path = Path::new("/home/user/project/src/main.rs");
|
|
assert_eq!(relative_pattern(cwd, path), "src/main.rs");
|
|
}
|
|
|
|
#[test]
|
|
fn relative_pattern_falls_back_to_absolute_outside_cwd() {
|
|
let cwd = Path::new("/home/user/project");
|
|
let path = Path::new("/etc/hosts");
|
|
assert_eq!(relative_pattern(cwd, path), "/etc/hosts");
|
|
}
|
|
}
|