use std::{fs, path::Path};
use miette::IntoDiagnostic;
#[cfg(target_os = "windows")]
pub fn set_permission(_file: impl AsRef<Path>, _mode: u32) -> miette::Result<()> {
Ok(())
}
#[cfg(not(target_os = "windows"))]
pub fn set_permission(file: impl AsRef<Path>, mode: u32) -> miette::Result<()> {
use std::{fs::Permissions, os::unix::fs::PermissionsExt};
fs::set_permissions(file, Permissions::from_mode(mode)).into_diagnostic()
}
pub fn try_set_file_executable(file: impl AsRef<Path>) -> miette::Result<()> {
let file = file.as_ref();
let metadata = fs::metadata(file).into_diagnostic()?;
if !metadata.is_file() {
miette::bail!("This is not a file: '{}'", file.display());
}
set_permission(file, 0o755)
}
#[cfg(test)]
mod tests_permissions {
use super::*;
use crate::try_create_temp_dir;
#[cfg(target_os = "windows")]
pub fn assert_permissions(_permissions: &std::fs::Permissions, _mode: u32) {}
#[cfg(not(target_os = "windows"))]
pub fn assert_permissions(permissions: &std::fs::Permissions, expected: u32) {
use std::os::unix::fs::PermissionsExt;
assert_eq!(permissions.mode() & 0o777, expected);
}
#[test]
fn test_set_file_executable() {
let root = try_create_temp_dir().unwrap();
let new_dir = root.join("test_set_file_executable");
fs::create_dir_all(&new_dir).unwrap();
let new_file = new_dir.join("test_set_file_executable.sh");
fs::write(&new_file, "echo 'Hello, World!'").unwrap();
try_set_file_executable(&new_file).unwrap();
let metadata = fs::metadata(&new_file).unwrap();
let lhs = metadata.permissions();
assert_permissions(&lhs, 0o755);
}
#[test]
fn test_set_file_executable_on_non_file() {
let root = try_create_temp_dir().unwrap();
let new_dir = root.join("test_set_file_executable_on_non_file");
fs::create_dir_all(&new_dir).unwrap();
let result = try_set_file_executable(&new_dir);
assert!(result.is_err());
}
#[test]
fn test_set_file_executable_on_non_existent_file() {
let root = try_create_temp_dir().unwrap();
let new_dir = root.join("test_set_file_executable_on_non_existent_file");
fs::create_dir_all(&new_dir).unwrap();
let non_existent_file = new_dir.join("non_existent_file.sh");
let result = try_set_file_executable(&non_existent_file);
assert!(result.is_err());
}
}