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")]
|
#[cfg(feature = "uuid_crate")]
|
||||||
whole_stream_command(RandomUUID),
|
whole_stream_command(RandomUUID),
|
||||||
// Path
|
// Path
|
||||||
whole_stream_command(PathCommand),
|
|
||||||
whole_stream_command(PathExtension),
|
|
||||||
whole_stream_command(PathBasename),
|
whole_stream_command(PathBasename),
|
||||||
whole_stream_command(PathExpand),
|
whole_stream_command(PathCommand),
|
||||||
|
whole_stream_command(PathDirname),
|
||||||
whole_stream_command(PathExists),
|
whole_stream_command(PathExists),
|
||||||
|
whole_stream_command(PathExpand),
|
||||||
|
whole_stream_command(PathExtension),
|
||||||
|
whole_stream_command(PathFilestem),
|
||||||
whole_stream_command(PathType),
|
whole_stream_command(PathType),
|
||||||
// Url
|
// Url
|
||||||
whole_stream_command(UrlCommand),
|
whole_stream_command(UrlCommand),
|
||||||
|
@ -207,7 +207,10 @@ pub(crate) use next::Next;
|
|||||||
pub(crate) use nth::Nth;
|
pub(crate) use nth::Nth;
|
||||||
pub(crate) use open::Open;
|
pub(crate) use open::Open;
|
||||||
pub(crate) use parse::Parse;
|
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 pivot::Pivot;
|
||||||
pub(crate) use prepend::Prepend;
|
pub(crate) use prepend::Prepend;
|
||||||
pub(crate) use prev::Previous;
|
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 basename;
|
||||||
mod command;
|
mod command;
|
||||||
|
mod dirname;
|
||||||
mod exists;
|
mod exists;
|
||||||
mod expand;
|
mod expand;
|
||||||
mod extension;
|
mod extension;
|
||||||
|
mod filestem;
|
||||||
mod r#type;
|
mod r#type;
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
@ -13,9 +15,11 @@ use std::path::Path;
|
|||||||
|
|
||||||
pub use basename::PathBasename;
|
pub use basename::PathBasename;
|
||||||
pub use command::Path as PathCommand;
|
pub use command::Path as PathCommand;
|
||||||
|
pub use dirname::PathDirname;
|
||||||
pub use exists::PathExists;
|
pub use exists::PathExists;
|
||||||
pub use expand::PathExpand;
|
pub use expand::PathExpand;
|
||||||
pub use extension::PathExtension;
|
pub use extension::PathExtension;
|
||||||
|
pub use filestem::PathFilestem;
|
||||||
pub use r#type::PathType;
|
pub use r#type::PathType;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -34,7 +34,7 @@ impl Completer {
|
|||||||
// These is_executable/pathext implementations are copied from ichwh and modified
|
// These is_executable/pathext implementations are copied from ichwh and modified
|
||||||
// to not be async
|
// to not be async
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(all(windows, feature = "ichwh"))]
|
||||||
fn pathext() -> IchwhResult<Vec<String>> {
|
fn pathext() -> IchwhResult<Vec<String>> {
|
||||||
Ok(std::env::var_os("PATHEXT")
|
Ok(std::env::var_os("PATHEXT")
|
||||||
.ok_or(IchwhError::PathextNotDefined)?
|
.ok_or(IchwhError::PathextNotDefined)?
|
||||||
@ -45,6 +45,11 @@ fn pathext() -> IchwhResult<Vec<String>> {
|
|||||||
.collect::<Vec<_>>())
|
.collect::<Vec<_>>())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(windows, not(feature = "ichwh")))]
|
||||||
|
fn pathext() -> Result<Vec<String>, ()> {
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn is_executable(file: &DirEntry) -> bool {
|
fn is_executable(file: &DirEntry) -> bool {
|
||||||
if let Ok(metadata) = file.metadata() {
|
if let Ok(metadata) = file.metadata() {
|
||||||
|
Loading…
Reference in New Issue
Block a user