mirror of
https://github.com/nushell/nushell
synced 2024-12-28 22:13:10 +00:00
Merge main
This commit is contained in:
commit
4d0a253924
6 changed files with 369 additions and 69 deletions
56
Cargo.lock
generated
56
Cargo.lock
generated
|
@ -115,9 +115,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.70"
|
version = "1.0.71"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0"
|
checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
|
@ -435,9 +435,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miette"
|
name = "miette"
|
||||||
version = "3.1.0"
|
version = "3.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4786c5b04c6f73e96d88444e7f37e241d99479ea5dd88a4887363ab2e03b4e53"
|
checksum = "ec47e61dc212c43f44dcd1f2841ccba79c6ec10da357cab7a7859b5f87bd27a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"backtrace",
|
"backtrace",
|
||||||
|
@ -454,9 +454,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miette-derive"
|
name = "miette-derive"
|
||||||
version = "3.1.0"
|
version = "3.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ee63a981bc9cde5f26665ffd756b624963bf0b5956e0df51e52ef8f6b5466d6"
|
checksum = "2c0f0b6f999b9a9f7e86322125583a437cf015054b7aaa9926dff0ff13005b7e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -546,6 +546,7 @@ dependencies = [
|
||||||
"sysinfo",
|
"sysinfo",
|
||||||
"terminal_size",
|
"terminal_size",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"trash",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -715,9 +716,9 @@ checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "predicates"
|
name = "predicates"
|
||||||
version = "2.0.2"
|
version = "2.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c143348f141cc87aab5b950021bac6145d0e5ae754b0591de23244cee42c9308"
|
checksum = "5c6ce811d0b2e103743eec01db1c50612221f173084ce2f7941053e94b6bb474"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"difflib",
|
"difflib",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
@ -732,12 +733,12 @@ checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "predicates-tree"
|
name = "predicates-tree"
|
||||||
version = "1.0.3"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7dd0fd014130206c9352efbdc92be592751b2b9274dff685348341082c6ea3d"
|
checksum = "338c7be2905b732ae3984a2f40032b5e94fd8f52505b186c7d4d68d193445df7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"predicates-core",
|
"predicates-core",
|
||||||
"treeline",
|
"termtree",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -763,9 +764,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.9"
|
version = "1.0.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
@ -857,7 +858,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reedline"
|
name = "reedline"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/nushell/reedline?branch=main#88bded3417e7f6c1242b444f403448de583357f0"
|
source = "git+https://github.com/nushell/reedline?branch=main#6fedafffb7a783949b5e9a86149286014eddba15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
|
@ -1038,9 +1039,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.78"
|
version = "1.0.80"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a4eac2e6c19f5c3abc0c229bea31ff0b9b091c7b14990e8924b92902a303a0c0"
|
checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -1096,6 +1097,12 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "termtree"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78fbf2dd23e79c28ccfa2472d3e6b3b189866ffef1aeb91f17c2d968b6586378"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "textwrap"
|
name = "textwrap"
|
||||||
version = "0.14.2"
|
version = "0.14.2"
|
||||||
|
@ -1109,18 +1116,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.29"
|
version = "1.0.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88"
|
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.29"
|
version = "1.0.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c"
|
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -1139,10 +1146,13 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "treeline"
|
name = "trash"
|
||||||
version = "0.1.0"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
|
checksum = "90df96afb154814e214f37eac04920c66886fd95962f22febb4d537b0dacd512"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-linebreak"
|
name = "unicode-linebreak"
|
||||||
|
|
|
@ -13,6 +13,7 @@ nu-protocol = { path = "../nu-protocol" }
|
||||||
nu-table = { path = "../nu-table" }
|
nu-table = { path = "../nu-table" }
|
||||||
nu-term-grid = { path = "../nu-term-grid" }
|
nu-term-grid = { path = "../nu-term-grid" }
|
||||||
nu-parser = { path = "../nu-parser" }
|
nu-parser = { path = "../nu-parser" }
|
||||||
|
trash = { version = "1.3.0", optional = true }
|
||||||
|
|
||||||
# Potential dependencies for extras
|
# Potential dependencies for extras
|
||||||
glob = "0.3.0"
|
glob = "0.3.0"
|
||||||
|
@ -21,3 +22,6 @@ sysinfo = "0.20.4"
|
||||||
chrono = { version = "0.4.19", features = ["serde"] }
|
chrono = { version = "0.4.19", features = ["serde"] }
|
||||||
terminal_size = "0.1.17"
|
terminal_size = "0.1.17"
|
||||||
lscolors = { version = "0.8.0", features = ["crossterm"] }
|
lscolors = { version = "0.8.0", features = ["crossterm"] }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
trash-support = ["trash"]
|
||||||
|
|
|
@ -13,54 +13,64 @@ pub fn create_default_context() -> Rc<RefCell<EngineState>> {
|
||||||
let engine_state = engine_state.borrow();
|
let engine_state = engine_state.borrow();
|
||||||
let mut working_set = StateWorkingSet::new(&*engine_state);
|
let mut working_set = StateWorkingSet::new(&*engine_state);
|
||||||
|
|
||||||
working_set.add_decl(Box::new(Alias));
|
macro_rules! bind_command {
|
||||||
working_set.add_decl(Box::new(Benchmark));
|
( $command:expr ) => {
|
||||||
working_set.add_decl(Box::new(BuildString));
|
working_set.add_decl(Box::new($command));
|
||||||
working_set.add_decl(Box::new(Cd));
|
};
|
||||||
working_set.add_decl(Box::new(Cp));
|
( $( $command:expr ),* ) => {
|
||||||
working_set.add_decl(Box::new(Def));
|
$( working_set.add_decl(Box::new($command)); )*
|
||||||
working_set.add_decl(Box::new(Do));
|
};
|
||||||
working_set.add_decl(Box::new(Each));
|
}
|
||||||
working_set.add_decl(Box::new(ExportDef));
|
|
||||||
working_set.add_decl(Box::new(External));
|
// TODO: sort items categorically
|
||||||
working_set.add_decl(Box::new(For));
|
bind_command!(
|
||||||
working_set.add_decl(Box::new(From));
|
Alias,
|
||||||
working_set.add_decl(Box::new(FromJson));
|
Benchmark,
|
||||||
working_set.add_decl(Box::new(Get));
|
BuildString,
|
||||||
working_set.add_decl(Box::new(Griddle));
|
Cd,
|
||||||
working_set.add_decl(Box::new(Help));
|
Cp,
|
||||||
working_set.add_decl(Box::new(Hide));
|
Def,
|
||||||
working_set.add_decl(Box::new(If));
|
Do,
|
||||||
working_set.add_decl(Box::new(Into));
|
Each,
|
||||||
working_set.add_decl(Box::new(IntoBinary));
|
ExportDef,
|
||||||
working_set.add_decl(Box::new(IntoFilesize));
|
External,
|
||||||
working_set.add_decl(Box::new(Length));
|
For,
|
||||||
working_set.add_decl(Box::new(Let));
|
From,
|
||||||
working_set.add_decl(Box::new(LetEnv));
|
FromJson,
|
||||||
working_set.add_decl(Box::new(Lines));
|
Get,
|
||||||
working_set.add_decl(Box::new(Ls));
|
Griddle,
|
||||||
working_set.add_decl(Box::new(Mkdir));
|
Help,
|
||||||
working_set.add_decl(Box::new(Module));
|
Hide,
|
||||||
working_set.add_decl(Box::new(Mv));
|
If,
|
||||||
working_set.add_decl(Box::new(Ps));
|
Into,
|
||||||
working_set.add_decl(Box::new(Select));
|
IntoBinary,
|
||||||
working_set.add_decl(Box::new(Split));
|
IntoFilesize,
|
||||||
working_set.add_decl(Box::new(SplitChars));
|
IntoInt,
|
||||||
working_set.add_decl(Box::new(SplitColumn));
|
Length,
|
||||||
working_set.add_decl(Box::new(SplitRow));
|
Let,
|
||||||
working_set.add_decl(Box::new(Sys));
|
LetEnv,
|
||||||
working_set.add_decl(Box::new(Table));
|
Lines,
|
||||||
working_set.add_decl(Box::new(Touch));
|
Ls,
|
||||||
working_set.add_decl(Box::new(Use));
|
Mkdir,
|
||||||
working_set.add_decl(Box::new(Where));
|
Module,
|
||||||
working_set.add_decl(Box::new(Wrap));
|
Mv,
|
||||||
|
Ps,
|
||||||
|
Rm,
|
||||||
|
Select,
|
||||||
|
Split,
|
||||||
|
SplitChars,
|
||||||
|
SplitColumn,
|
||||||
|
SplitRow,
|
||||||
|
Sys,
|
||||||
|
Table,
|
||||||
|
Touch,
|
||||||
|
Use,
|
||||||
|
Where,
|
||||||
|
Wrap
|
||||||
|
);
|
||||||
|
|
||||||
// This is a WIP proof of concept
|
// This is a WIP proof of concept
|
||||||
working_set.add_decl(Box::new(ListGitBranches));
|
bind_command!(ListGitBranches, Git, GitCheckout, Source);
|
||||||
working_set.add_decl(Box::new(Git));
|
|
||||||
working_set.add_decl(Box::new(GitCheckout));
|
|
||||||
|
|
||||||
working_set.add_decl(Box::new(Source));
|
|
||||||
|
|
||||||
let sig = Signature::build("exit");
|
let sig = Signature::build("exit");
|
||||||
working_set.add_decl(sig.predeclare());
|
working_set.add_decl(sig.predeclare());
|
||||||
|
|
|
@ -3,6 +3,7 @@ mod cp;
|
||||||
mod ls;
|
mod ls;
|
||||||
mod mkdir;
|
mod mkdir;
|
||||||
mod mv;
|
mod mv;
|
||||||
|
mod rm;
|
||||||
mod touch;
|
mod touch;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
|
@ -11,4 +12,5 @@ pub use cp::Cp;
|
||||||
pub use ls::Ls;
|
pub use ls::Ls;
|
||||||
pub use mkdir::Mkdir;
|
pub use mkdir::Mkdir;
|
||||||
pub use mv::Mv;
|
pub use mv::Mv;
|
||||||
|
pub use rm::Rm;
|
||||||
pub use touch::Touch;
|
pub use touch::Touch;
|
||||||
|
|
250
crates/nu-command/src/filesystem/rm.rs
Normal file
250
crates/nu-command/src/filesystem/rm.rs
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
use std::env::current_dir;
|
||||||
|
use std::os::unix::prelude::FileTypeExt;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use nu_engine::CallExt;
|
||||||
|
use nu_protocol::ast::Call;
|
||||||
|
use nu_protocol::engine::{Command, EvaluationContext};
|
||||||
|
use nu_protocol::{ShellError, Signature, SyntaxShape, Value, ValueStream};
|
||||||
|
|
||||||
|
pub struct Rm;
|
||||||
|
|
||||||
|
// Where self.0 is the unexpanded target's positional index (i.e. call.positional[self.0].span)
|
||||||
|
struct Target(usize, PathBuf);
|
||||||
|
|
||||||
|
struct RmArgs {
|
||||||
|
targets: Vec<Target>,
|
||||||
|
recursive: bool,
|
||||||
|
trash: bool,
|
||||||
|
permanent: bool,
|
||||||
|
force: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command for Rm {
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"rm"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usage(&self) -> &str {
|
||||||
|
"Remove file(s)."
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> Signature {
|
||||||
|
Signature::build("rm")
|
||||||
|
.switch(
|
||||||
|
"trash",
|
||||||
|
"use the platform's recycle bin instead of permanently deleting",
|
||||||
|
Some('t'),
|
||||||
|
)
|
||||||
|
.switch(
|
||||||
|
"permanent",
|
||||||
|
"don't use recycle bin, delete permanently",
|
||||||
|
Some('p'),
|
||||||
|
)
|
||||||
|
.switch("recursive", "delete subdirectories recursively", Some('r'))
|
||||||
|
.switch("force", "suppress error when no file", Some('f'))
|
||||||
|
.rest(
|
||||||
|
"rest",
|
||||||
|
SyntaxShape::GlobPattern,
|
||||||
|
"the file path(s) to remove",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(
|
||||||
|
&self,
|
||||||
|
context: &EvaluationContext,
|
||||||
|
call: &Call,
|
||||||
|
_input: Value,
|
||||||
|
) -> Result<Value, ShellError> {
|
||||||
|
rm(context, call)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rm(context: &EvaluationContext, call: &Call) -> Result<Value, ShellError> {
|
||||||
|
let trash = call.has_flag("trash");
|
||||||
|
let permanent = call.has_flag("permanent");
|
||||||
|
|
||||||
|
if trash && permanent {
|
||||||
|
return Err(ShellError::IncompatibleParametersSingle(
|
||||||
|
"Can't use \"--trash\" with \"--permanent\"".to_string(),
|
||||||
|
call.head,
|
||||||
|
));
|
||||||
|
|
||||||
|
// let trash_span = call.get_flag_expr("trash").unwrap().span;
|
||||||
|
// let perm_span = call.get_flag_expr("permanent").unwrap().span;
|
||||||
|
|
||||||
|
// let left_message = "cannot use".to_string();
|
||||||
|
// let right_message = "with".to_string();
|
||||||
|
// let (left_span, right_span) = match trash_span.start < perm_span.start {
|
||||||
|
// true => (trash_span, perm_span),
|
||||||
|
// false => (perm_span, trash_span),
|
||||||
|
// };
|
||||||
|
|
||||||
|
// return Err(ShellError::IncompatibleParameters {
|
||||||
|
// left_message,
|
||||||
|
// left_span,
|
||||||
|
// right_message,
|
||||||
|
// right_span,
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
let current_path = current_dir()?;
|
||||||
|
let mut paths = call
|
||||||
|
.rest::<String>(context, 0)?
|
||||||
|
.into_iter()
|
||||||
|
.map(|path| current_path.join(path))
|
||||||
|
.peekable();
|
||||||
|
|
||||||
|
if paths.peek().is_none() {
|
||||||
|
return Err(ShellError::FileNotFound(call.positional[0].span));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expand and flatten files
|
||||||
|
let resolve_path = |i: usize, path: PathBuf| {
|
||||||
|
glob::glob(&path.to_string_lossy()).map_or_else(
|
||||||
|
|_| Vec::new(),
|
||||||
|
|path_iter| path_iter.flatten().map(|f| Target(i, f)).collect(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut targets: Vec<Target> = vec![];
|
||||||
|
for (i, path) in paths.enumerate() {
|
||||||
|
let mut paths: Vec<Target> = resolve_path(i, path);
|
||||||
|
|
||||||
|
if paths.is_empty() {
|
||||||
|
return Err(ShellError::FileNotFound(call.positional[i].span));
|
||||||
|
}
|
||||||
|
|
||||||
|
targets.append(paths.as_mut());
|
||||||
|
}
|
||||||
|
|
||||||
|
let recursive = call.has_flag("recursive");
|
||||||
|
let force = call.has_flag("force");
|
||||||
|
|
||||||
|
let args = RmArgs {
|
||||||
|
targets,
|
||||||
|
recursive,
|
||||||
|
trash,
|
||||||
|
permanent,
|
||||||
|
force,
|
||||||
|
};
|
||||||
|
let response = rm_helper(call, args);
|
||||||
|
|
||||||
|
// let temp = rm_helper(call, args).flatten();
|
||||||
|
// let temp = input.flatten(call.head, move |_| rm_helper(call, args));
|
||||||
|
|
||||||
|
Ok(Value::Stream {
|
||||||
|
stream: ValueStream::from_stream(response.into_iter()),
|
||||||
|
span: call.head,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Ok(Value::Nothing { span })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rm_helper(call: &Call, args: RmArgs) -> Vec<Value> {
|
||||||
|
let (targets, recursive, trash, _permanent, force) = (
|
||||||
|
args.targets,
|
||||||
|
args.recursive,
|
||||||
|
args.trash,
|
||||||
|
args.permanent,
|
||||||
|
args.force,
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(not(feature = "trash-support"))]
|
||||||
|
{
|
||||||
|
if trash {
|
||||||
|
return vec![Value::Error {
|
||||||
|
error: ShellError::FeatureNotEnabled(call.get_flag_expr("trash").unwrap().span),
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if targets.is_empty() && !force {
|
||||||
|
return vec![Value::Error {
|
||||||
|
error: ShellError::FileNotFound(call.head),
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
targets
|
||||||
|
.into_iter()
|
||||||
|
.map(move |target| {
|
||||||
|
let (i, f) = (target.0, target.1);
|
||||||
|
|
||||||
|
let is_empty = || match f.read_dir() {
|
||||||
|
Ok(mut p) => p.next().is_none(),
|
||||||
|
Err(_) => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Ok(metadata) = f.symlink_metadata() {
|
||||||
|
#[cfg(unix)]
|
||||||
|
let is_socket = metadata.file_type().is_socket();
|
||||||
|
#[cfg(unix)]
|
||||||
|
let is_fifo = metadata.file_type().is_fifo();
|
||||||
|
|
||||||
|
#[cfg(not(unix))]
|
||||||
|
let is_socket = false;
|
||||||
|
#[cfg(not(unix))]
|
||||||
|
let is_fifo = false;
|
||||||
|
|
||||||
|
if metadata.is_file()
|
||||||
|
|| metadata.file_type().is_symlink()
|
||||||
|
|| recursive
|
||||||
|
|| is_socket
|
||||||
|
|| is_fifo
|
||||||
|
|| is_empty()
|
||||||
|
{
|
||||||
|
let result;
|
||||||
|
#[cfg(feature = "trash-support")]
|
||||||
|
{
|
||||||
|
use std::io::Error;
|
||||||
|
result = if trash {
|
||||||
|
trash::delete(&f).map_err(|e: trash::Error| {
|
||||||
|
Error::new(ErrorKind::Other, format!("{:?}", e))
|
||||||
|
})
|
||||||
|
} else if metadata.is_file() {
|
||||||
|
std::fs::remove_file(&f)
|
||||||
|
} else {
|
||||||
|
std::fs::remove_dir_all(&f)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "trash-support"))]
|
||||||
|
{
|
||||||
|
result = if metadata.is_file() || is_socket || is_fifo {
|
||||||
|
std::fs::remove_file(&f)
|
||||||
|
} else {
|
||||||
|
std::fs::remove_dir_all(&f)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(e) = result {
|
||||||
|
Value::Error {
|
||||||
|
error: ShellError::RemoveNotPossible(
|
||||||
|
format!("Could not delete because: {:}\nTry '--trash' flag", e),
|
||||||
|
call.head,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Value::String {
|
||||||
|
val: format!("deleted {:}", f.to_string_lossy()),
|
||||||
|
span: call.positional[i].span,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Value::Error {
|
||||||
|
error: ShellError::RemoveNotPossible(
|
||||||
|
"Cannot remove. try --recursive".to_string(),
|
||||||
|
call.positional[i].span,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Value::Error {
|
||||||
|
error: ShellError::RemoveNotPossible(
|
||||||
|
"no such file or directory".to_string(),
|
||||||
|
call.positional[i].span,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
|
@ -41,6 +41,26 @@ pub enum ShellError {
|
||||||
#[diagnostic(code(nu::shell::missing_parameter), url(docsrs))]
|
#[diagnostic(code(nu::shell::missing_parameter), url(docsrs))]
|
||||||
MissingParameter(String, #[label = "missing parameter: {0}"] Span),
|
MissingParameter(String, #[label = "missing parameter: {0}"] Span),
|
||||||
|
|
||||||
|
// Be cautious, as flags can share the same span, resulting in a panic (ex: `rm -pt`)
|
||||||
|
#[error("Incompatible parameters.")]
|
||||||
|
#[diagnostic(code(nu::shell::incompatible_parameters), url(docsrs))]
|
||||||
|
IncompatibleParameters {
|
||||||
|
left_message: String,
|
||||||
|
#[label("{left_message}")]
|
||||||
|
left_span: Span,
|
||||||
|
right_message: String,
|
||||||
|
#[label("{right_message}")]
|
||||||
|
right_span: Span,
|
||||||
|
},
|
||||||
|
|
||||||
|
#[error("Incompatible parameters.")]
|
||||||
|
#[diagnostic(code(nu::shell::incompatible_parameters), url(docsrs))]
|
||||||
|
IncompatibleParametersSingle(String, #[label = "{0}"] Span),
|
||||||
|
|
||||||
|
#[error("Feature not enabled.")]
|
||||||
|
#[diagnostic(code(nu::shell::feature_not_enabled), url(docsrs))]
|
||||||
|
FeatureNotEnabled(#[label = "feature not enabled"] Span),
|
||||||
|
|
||||||
#[error("External commands not yet supported")]
|
#[error("External commands not yet supported")]
|
||||||
#[diagnostic(code(nu::shell::external_commands), url(docsrs))]
|
#[diagnostic(code(nu::shell::external_commands), url(docsrs))]
|
||||||
ExternalNotSupported(#[label = "external not supported"] Span),
|
ExternalNotSupported(#[label = "external not supported"] Span),
|
||||||
|
@ -131,6 +151,10 @@ pub enum ShellError {
|
||||||
#[error("Create not possible")]
|
#[error("Create not possible")]
|
||||||
#[diagnostic(code(nu::shell::create_not_possible), url(docsrs))]
|
#[diagnostic(code(nu::shell::create_not_possible), url(docsrs))]
|
||||||
CreateNotPossible(String, #[label("{0}")] Span),
|
CreateNotPossible(String, #[label("{0}")] Span),
|
||||||
|
|
||||||
|
#[error("Remove not possible")]
|
||||||
|
#[diagnostic(code(nu::shell::remove_not_possible), url(docsrs))]
|
||||||
|
RemoveNotPossible(String, #[label("{0}")] Span),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<std::io::Error> for ShellError {
|
impl From<std::io::Error> for ShellError {
|
||||||
|
|
Loading…
Reference in a new issue