mirror of
https://github.com/nushell/nushell
synced 2024-11-15 09:27:08 +00:00
Fix path type
using PWD from the environment (#12975)
This PR fixes the `path type` command so that it resolves relative paths using PWD from the engine state. As a bonus, it also fixes the issue of `path type` returning an empty string instead of an error when it fails.
This commit is contained in:
parent
f38f88d42c
commit
a1fc41db22
2 changed files with 30 additions and 23 deletions
|
@ -1,10 +1,11 @@
|
|||
use super::PathSubcommandArguments;
|
||||
use nu_engine::command_prelude::*;
|
||||
use nu_path::expand_tilde;
|
||||
use nu_protocol::engine::StateWorkingSet;
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
struct Arguments;
|
||||
struct Arguments {
|
||||
pwd: PathBuf,
|
||||
}
|
||||
|
||||
impl PathSubcommandArguments for Arguments {}
|
||||
|
||||
|
@ -45,19 +46,21 @@ If nothing is found, an empty string will be returned."#
|
|||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
let args = Arguments;
|
||||
let args = Arguments {
|
||||
pwd: engine_state.cwd(Some(stack))?,
|
||||
};
|
||||
|
||||
// This doesn't match explicit nulls
|
||||
if matches!(input, PipelineData::Empty) {
|
||||
return Err(ShellError::PipelineEmpty { dst_span: head });
|
||||
}
|
||||
input.map(
|
||||
move |value| super::operate(&r#type, &args, value, head),
|
||||
move |value| super::operate(&path_type, &args, value, head),
|
||||
engine_state.ctrlc.clone(),
|
||||
)
|
||||
}
|
||||
|
@ -69,14 +72,16 @@ If nothing is found, an empty string will be returned."#
|
|||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
let args = Arguments;
|
||||
let args = Arguments {
|
||||
pwd: working_set.permanent().cwd(None)?,
|
||||
};
|
||||
|
||||
// This doesn't match explicit nulls
|
||||
if matches!(input, PipelineData::Empty) {
|
||||
return Err(ShellError::PipelineEmpty { dst_span: head });
|
||||
}
|
||||
input.map(
|
||||
move |value| super::operate(&r#type, &args, value, head),
|
||||
move |value| super::operate(&path_type, &args, value, head),
|
||||
working_set.permanent().ctrlc.clone(),
|
||||
)
|
||||
}
|
||||
|
@ -97,21 +102,12 @@ If nothing is found, an empty string will be returned."#
|
|||
}
|
||||
}
|
||||
|
||||
fn r#type(path: &Path, span: Span, _: &Arguments) -> Value {
|
||||
let meta = if path.starts_with("~") {
|
||||
let p = expand_tilde(path);
|
||||
std::fs::symlink_metadata(p)
|
||||
} else {
|
||||
std::fs::symlink_metadata(path)
|
||||
};
|
||||
|
||||
Value::string(
|
||||
match &meta {
|
||||
Ok(data) => get_file_type(data),
|
||||
Err(_) => "",
|
||||
},
|
||||
span,
|
||||
)
|
||||
fn path_type(path: &Path, span: Span, args: &Arguments) -> Value {
|
||||
let path = nu_path::expand_path_with(path, &args.pwd, true);
|
||||
match std::fs::symlink_metadata(path) {
|
||||
Ok(metadata) => Value::string(get_file_type(&metadata), span),
|
||||
Err(err) => Value::error(err.into(), span),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_file_type(md: &std::fs::Metadata) -> &str {
|
||||
|
|
|
@ -74,3 +74,14 @@ fn returns_type_of_existing_file_const() {
|
|||
assert_eq!(actual.out, "dir");
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn respects_cwd() {
|
||||
Playground::setup("path_type_respects_cwd", |dirs, sandbox| {
|
||||
sandbox.within("foo").with_files(&[EmptyFile("bar.txt")]);
|
||||
|
||||
let actual = nu!(cwd: dirs.test(), "cd foo; 'bar.txt' | path type");
|
||||
|
||||
assert_eq!(actual.out, "file");
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue