mirror of
https://github.com/storytold/designcraft.git
synced 2026-11-15 14:52:31 +00:00
Package: the Windows redirect test falls back to a directory junction
package_refuses_windows_directory_redirects made its redirect with symlink_dir. Without Developer Mode or elevation that call fails with os error 1314 (ERROR_PRIVILEGE_NOT_HELD), which std does not report as PermissionDenied, so the skip arm did not match and the test panicked. When symlink_dir fails, the test now makes a directory junction with mklink /J, which needs no privilege. is_redirect treats a junction as a redirect, so the test still checks that File > Package refuses the redirected folder. It skips only when neither can be made. The package code is unchanged.
This commit is contained in:
1 parent
e651c637f4
commit
333cdf116f
1 file changed
+19
-7
@@ -907,13 +907,12 @@ mod tests {
|
||||
let outside = base.join("separate");
|
||||
std::fs::create_dir_all(&outside).unwrap();
|
||||
let redirected = base.join("Package");
|
||||
match symlink_dir(&outside, &redirected) {
|
||||
Ok(()) => {}
|
||||
Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => {
|
||||
let _ = std::fs::remove_dir_all(&base);
|
||||
return;
|
||||
}
|
||||
Err(e) => panic!("could not create directory redirect: {e}"),
|
||||
// A symbolic link needs Developer Mode or elevation (os error 1314 without them); a
|
||||
// directory junction needs neither, and `is_redirect` treats both as redirects.
|
||||
if symlink_dir(&outside, &redirected).is_err() && !make_junction(&outside, &redirected) {
|
||||
eprintln!("skipped: directory redirects can't be made here");
|
||||
let _ = std::fs::remove_dir_all(&base);
|
||||
return;
|
||||
}
|
||||
let mut s = Session::new();
|
||||
s.execute("file.new", &json!({"title": "Annual"})).unwrap();
|
||||
@@ -922,4 +921,17 @@ mod tests {
|
||||
std::fs::remove_dir(&redirected).unwrap();
|
||||
let _ = std::fs::remove_dir_all(&base);
|
||||
}
|
||||
|
||||
/// Makes `link` a directory junction to `target` with `mklink /J`, and reports whether it was made.
|
||||
#[cfg(windows)]
|
||||
fn make_junction(target: &Path, link: &Path) -> bool {
|
||||
use std::os::windows::process::CommandExt;
|
||||
|
||||
// Windows paths can't hold `"`, so quoting each one keeps `&` and spaces in it literal for cmd.
|
||||
std::process::Command::new("cmd")
|
||||
.args(["/D", "/C"])
|
||||
.raw_arg(format!("mklink /J \"{}\" \"{}\"", link.display(), target.display()))
|
||||
.output()
|
||||
.is_ok_and(|output| output.status.success())
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user