1
0
Fork 0
mirror of https://github.com/imjasonh/testscript-rs synced 2026-07-19 07:06:46 +00:00

Implement symlink built-in command from scratch

Co-authored-by: imjasonh <210737+imjasonh@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2025-09-27 01:42:31 +00:00
parent 7f0380c57d
commit c78f9fca9e
2 changed files with 36 additions and 23 deletions

View file

@ -292,19 +292,12 @@ impl TestEnvironment {
// On Windows, try to create a symlink but fall back gracefully // On Windows, try to create a symlink but fall back gracefully
use std::os::windows::fs::symlink_file; use std::os::windows::fs::symlink_file;
if target_path.is_file() { symlink_file(&target_path, &link_path).map_err(|e| {
symlink_file(&target_path, &link_path).map_err(|e| { Error::command_error(
Error::command_error(
"symlink",
format!("Cannot create symlink '{}' -> '{}': {} (Note: Windows symlinks may require administrator privileges)", link_name, target, e),
)
})?;
} else {
return Err(Error::command_error(
"symlink", "symlink",
"Symlinks on Windows are only supported for files, not directories", format!("Cannot create symlink '{}' -> '{}': {} (Note: Windows symlinks may require administrator privileges)", link_name, target, e),
)); )
} })?;
} }
#[cfg(not(any(unix, windows)))] #[cfg(not(any(unix, windows)))]

View file

@ -190,30 +190,50 @@ fn test_symlink_command() {
let script_content = r#"# Test symlink command let script_content = r#"# Test symlink command
symlink target.txt link.txt symlink target.txt link.txt
exists link.txt exists link.txt
exists target.txt
# Test that symlink content matches target # Test that symlink content matches target
exec cat link.txt exec cat link.txt
stdout "content from target" stdout "target content"
-- target.txt -- -- target.txt --
content from target"#; target content"#;
fs::write(&script_path, script_content).unwrap(); fs::write(&script_path, script_content).unwrap();
let result = run_test(&script_path); let result = run_test(&script_path);
// On Unix systems, this should work
#[cfg(unix)] #[cfg(unix)]
assert!(result.is_ok(), "Symlink test failed on Unix: {:?}", result); {
assert!(
// On Windows, symlinks may fail due to permissions result.is_ok(),
"Symlink test should pass on Unix: {:?}",
result
);
}
#[cfg(windows)] #[cfg(windows)]
{ {
if result.is_err() { // On Windows, symlinks usually fail due to permissions
let error = result.unwrap_err().to_string(); if result.is_ok() {
assert!(error.contains("symlink") || error.contains("privileges"), // If it passes on Windows, that means we have admin privileges - that's okay
"Unexpected error on Windows: {}", error); println!("Symlink test passed on Windows (admin privileges detected)");
} else {
// Expected failure on Windows due to permissions
let error_msg = result.unwrap_err().to_string();
assert!(error_msg.contains("symlink"), "Error should mention symlinks: {}", error_msg);
} }
// If it passes, that's fine too (admin privileges) }
#[cfg(not(any(unix, windows)))]
{
// On other platforms, should fail gracefully
assert!(
result.is_err(),
"Symlink should fail on unsupported platforms"
);
let error_msg = result.unwrap_err().to_string();
assert!(error_msg.contains("not supported"));
} }
} }