forked from extern/nushell
Clean up cd.rs
(#7876)
Some general cleanup of `cd.rs`; the permission checking code was a little hard to follow. Reworded comments and variable names, reorganized+renamed the module used for Unix file permissions.
This commit is contained in:
parent
9ae2e528c5
commit
76292ef10c
@ -10,22 +10,16 @@ use nu_protocol::{
|
|||||||
};
|
};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
// when the file under the fold executable
|
// For checking whether we have permission to cd to a directory
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
mod permission_mods {
|
mod file_permissions {
|
||||||
pub type Mode = u32;
|
pub type Mode = u32;
|
||||||
pub mod unix {
|
|
||||||
use super::Mode;
|
|
||||||
pub const USER_EXECUTE: Mode = libc::S_IXUSR as Mode;
|
pub const USER_EXECUTE: Mode = libc::S_IXUSR as Mode;
|
||||||
pub const GROUP_EXECUTE: Mode = libc::S_IXGRP as Mode;
|
pub const GROUP_EXECUTE: Mode = libc::S_IXGRP as Mode;
|
||||||
pub const OTHER_EXECUTE: Mode = libc::S_IXOTH as Mode;
|
pub const OTHER_EXECUTE: Mode = libc::S_IXOTH as Mode;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// use to return the message of the result of change director
|
// The result of checking whether we have permission to cd to a directory
|
||||||
// TODO: windows, maybe should use file_attributes function in https://doc.rust-lang.org/std/os/windows/fs/trait.MetadataExt.html
|
|
||||||
// TODO: the meaning of the result of the function can be found in https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
|
|
||||||
// TODO: if have realize the logic on windows, remove the cfg
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum PermissionResult<'a> {
|
enum PermissionResult<'a> {
|
||||||
PermissionOk,
|
PermissionOk,
|
||||||
@ -169,8 +163,10 @@ impl Command for Cd {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let path_tointo = path.clone();
|
let path_value = Value::String {
|
||||||
let path_value = Value::String { val: path, span };
|
val: path.clone(),
|
||||||
|
span,
|
||||||
|
};
|
||||||
let cwd = Value::string(cwd.to_string_lossy(), call.head);
|
let cwd = Value::string(cwd.to_string_lossy(), call.head);
|
||||||
|
|
||||||
let mut shells = get_shells(engine_state, stack, cwd);
|
let mut shells = get_shells(engine_state, stack, cwd);
|
||||||
@ -193,16 +189,16 @@ impl Command for Cd {
|
|||||||
stack.add_env_var("OLDPWD".into(), oldpwd)
|
stack.add_env_var("OLDPWD".into(), oldpwd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match have_permission(&path) {
|
||||||
//FIXME: this only changes the current scope, but instead this environment variable
|
//FIXME: this only changes the current scope, but instead this environment variable
|
||||||
//should probably be a block that loads the information from the state in the overlay
|
//should probably be a block that loads the information from the state in the overlay
|
||||||
match have_permission(&path_tointo) {
|
|
||||||
PermissionResult::PermissionOk => {
|
PermissionResult::PermissionOk => {
|
||||||
stack.add_env_var("PWD".into(), path_value);
|
stack.add_env_var("PWD".into(), path_value);
|
||||||
Ok(PipelineData::empty())
|
Ok(PipelineData::empty())
|
||||||
}
|
}
|
||||||
PermissionResult::PermissionDenied(reason) => Err(ShellError::IOError(format!(
|
PermissionResult::PermissionDenied(reason) => Err(ShellError::IOError(format!(
|
||||||
"Cannot change directory to {}: {}",
|
"Cannot change directory to {}: {}",
|
||||||
path_tointo, reason
|
path, reason
|
||||||
))),
|
))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,6 +223,9 @@ impl Command for Cd {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Maybe we should use file_attributes() from https://doc.rust-lang.org/std/os/windows/fs/trait.MetadataExt.html
|
||||||
|
// More on that here: https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn have_permission(dir: impl AsRef<Path>) -> PermissionResult<'static> {
|
fn have_permission(dir: impl AsRef<Path>) -> PermissionResult<'static> {
|
||||||
match dir.as_ref().read_dir() {
|
match dir.as_ref().read_dir() {
|
||||||
@ -260,26 +259,26 @@ fn have_permission(dir: impl AsRef<Path>) -> PermissionResult<'static> {
|
|||||||
current_user_gid == owner_group,
|
current_user_gid == owner_group,
|
||||||
) {
|
) {
|
||||||
(true, _) => {
|
(true, _) => {
|
||||||
if has_bit(permission_mods::unix::USER_EXECUTE) {
|
if has_bit(file_permissions::USER_EXECUTE) {
|
||||||
PermissionResult::PermissionOk
|
PermissionResult::PermissionOk
|
||||||
} else {
|
} else {
|
||||||
PermissionResult::PermissionDenied(
|
PermissionResult::PermissionDenied(
|
||||||
"You are the owner but do not have the execute permission",
|
"You are the owner but do not have execute permission",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(false, true) => {
|
(false, true) => {
|
||||||
if has_bit(permission_mods::unix::GROUP_EXECUTE) {
|
if has_bit(file_permissions::GROUP_EXECUTE) {
|
||||||
PermissionResult::PermissionOk
|
PermissionResult::PermissionOk
|
||||||
} else {
|
} else {
|
||||||
PermissionResult::PermissionDenied(
|
PermissionResult::PermissionDenied(
|
||||||
"You are in the group but do not have the execute permission",
|
"You are in the group but do not have execute permission",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(false, false) => {
|
(false, false) => {
|
||||||
if has_bit(permission_mods::unix::OTHER_EXECUTE)
|
if has_bit(file_permissions::OTHER_EXECUTE)
|
||||||
|| (has_bit(permission_mods::unix::GROUP_EXECUTE)
|
|| (has_bit(file_permissions::GROUP_EXECUTE)
|
||||||
&& any_group(current_user_gid, owner_group))
|
&& any_group(current_user_gid, owner_group))
|
||||||
{
|
{
|
||||||
PermissionResult::PermissionOk
|
PermissionResult::PermissionOk
|
||||||
@ -291,7 +290,7 @@ fn have_permission(dir: impl AsRef<Path>) -> PermissionResult<'static> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => PermissionResult::PermissionDenied("Could not retrieve the metadata"),
|
Err(_) => PermissionResult::PermissionDenied("Could not retrieve file metadata"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user