forked from extern/nushell
Path dirname and filestem (#2428)
* add dirname and filestem to path commands * hacked around with gedge's help to get it to compile with cargo b * fmt
This commit is contained in:
parent
781e423a97
commit
766533aafb
@ -455,11 +455,13 @@ pub fn create_default_context(
|
||||
#[cfg(feature = "uuid_crate")]
|
||||
whole_stream_command(RandomUUID),
|
||||
// Path
|
||||
whole_stream_command(PathCommand),
|
||||
whole_stream_command(PathExtension),
|
||||
whole_stream_command(PathBasename),
|
||||
whole_stream_command(PathExpand),
|
||||
whole_stream_command(PathCommand),
|
||||
whole_stream_command(PathDirname),
|
||||
whole_stream_command(PathExists),
|
||||
whole_stream_command(PathExpand),
|
||||
whole_stream_command(PathExtension),
|
||||
whole_stream_command(PathFilestem),
|
||||
whole_stream_command(PathType),
|
||||
// Url
|
||||
whole_stream_command(UrlCommand),
|
||||
|
@ -207,7 +207,10 @@ pub(crate) use next::Next;
|
||||
pub(crate) use nth::Nth;
|
||||
pub(crate) use open::Open;
|
||||
pub(crate) use parse::Parse;
|
||||
pub(crate) use path::{PathBasename, PathCommand, PathExists, PathExpand, PathExtension, PathType};
|
||||
pub(crate) use path::{
|
||||
PathBasename, PathCommand, PathDirname, PathExists, PathExpand, PathExtension, PathFilestem,
|
||||
PathType,
|
||||
};
|
||||
pub(crate) use pivot::Pivot;
|
||||
pub(crate) use prepend::Prepend;
|
||||
pub(crate) use prev::Previous;
|
||||
|
60
crates/nu-cli/src/commands/path/dirname.rs
Normal file
60
crates/nu-cli/src/commands/path/dirname.rs
Normal file
@ -0,0 +1,60 @@
|
||||
use super::{operate, DefaultArguments};
|
||||
use crate::commands::WholeStreamCommand;
|
||||
use crate::prelude::*;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use std::path::Path;
|
||||
|
||||
pub struct PathDirname;
|
||||
|
||||
#[async_trait]
|
||||
impl WholeStreamCommand for PathDirname {
|
||||
fn name(&self) -> &str {
|
||||
"path dirname"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("path dirname").rest(SyntaxShape::ColumnPath, "optionally operate by path")
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"gets the dirname of a path"
|
||||
}
|
||||
|
||||
async fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let tag = args.call_info.name_tag.clone();
|
||||
let (DefaultArguments { rest }, input) = args.process(®istry).await?;
|
||||
operate(input, rest, &action, tag.span).await
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Get dirname of a path",
|
||||
example: "echo '/home/joe/test.txt' | path dirname",
|
||||
result: Some(vec![Value::from("/home/joe")]),
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
fn action(path: &Path) -> UntaggedValue {
|
||||
UntaggedValue::string(match path.parent() {
|
||||
Some(dirname) => dirname.to_string_lossy().to_string(),
|
||||
_ => "".to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::PathDirname;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() {
|
||||
use crate::examples::test as test_examples;
|
||||
|
||||
test_examples(PathDirname {})
|
||||
}
|
||||
}
|
61
crates/nu-cli/src/commands/path/filestem.rs
Normal file
61
crates/nu-cli/src/commands/path/filestem.rs
Normal file
@ -0,0 +1,61 @@
|
||||
use super::{operate, DefaultArguments};
|
||||
use crate::commands::WholeStreamCommand;
|
||||
use crate::prelude::*;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use std::path::Path;
|
||||
|
||||
pub struct PathFilestem;
|
||||
|
||||
#[async_trait]
|
||||
impl WholeStreamCommand for PathFilestem {
|
||||
fn name(&self) -> &str {
|
||||
"path filestem"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("path filestem")
|
||||
.rest(SyntaxShape::ColumnPath, "optionally operate by path")
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"gets the filestem of a path"
|
||||
}
|
||||
|
||||
async fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let tag = args.call_info.name_tag.clone();
|
||||
let (DefaultArguments { rest }, input) = args.process(®istry).await?;
|
||||
operate(input, rest, &action, tag.span).await
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Get filestem of a path",
|
||||
example: "echo '/home/joe/test.txt' | path filestem",
|
||||
result: Some(vec![Value::from("test")]),
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
fn action(path: &Path) -> UntaggedValue {
|
||||
UntaggedValue::string(match path.file_stem() {
|
||||
Some(stem) => stem.to_string_lossy().to_string(),
|
||||
_ => "".to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::PathFilestem;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() {
|
||||
use crate::examples::test as test_examples;
|
||||
|
||||
test_examples(PathFilestem {})
|
||||
}
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
mod basename;
|
||||
mod command;
|
||||
mod dirname;
|
||||
mod exists;
|
||||
mod expand;
|
||||
mod extension;
|
||||
mod filestem;
|
||||
mod r#type;
|
||||
|
||||
use crate::prelude::*;
|
||||
@ -13,9 +15,11 @@ use std::path::Path;
|
||||
|
||||
pub use basename::PathBasename;
|
||||
pub use command::Path as PathCommand;
|
||||
pub use dirname::PathDirname;
|
||||
pub use exists::PathExists;
|
||||
pub use expand::PathExpand;
|
||||
pub use extension::PathExtension;
|
||||
pub use filestem::PathFilestem;
|
||||
pub use r#type::PathType;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
@ -34,7 +34,7 @@ impl Completer {
|
||||
// These is_executable/pathext implementations are copied from ichwh and modified
|
||||
// to not be async
|
||||
|
||||
#[cfg(windows)]
|
||||
#[cfg(all(windows, feature = "ichwh"))]
|
||||
fn pathext() -> IchwhResult<Vec<String>> {
|
||||
Ok(std::env::var_os("PATHEXT")
|
||||
.ok_or(IchwhError::PathextNotDefined)?
|
||||
@ -45,6 +45,11 @@ fn pathext() -> IchwhResult<Vec<String>> {
|
||||
.collect::<Vec<_>>())
|
||||
}
|
||||
|
||||
#[cfg(all(windows, not(feature = "ichwh")))]
|
||||
fn pathext() -> Result<Vec<String>, ()> {
|
||||
Err(())
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn is_executable(file: &DirEntry) -> bool {
|
||||
if let Ok(metadata) = file.metadata() {
|
||||
|
Loading…
Reference in New Issue
Block a user