mirror of
https://github.com/nushell/nushell.git
synced 2025-04-02 12:19:48 +02: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
@ -1,10 +1,11 @@
|
|||||||
use super::PathSubcommandArguments;
|
use super::PathSubcommandArguments;
|
||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
use nu_path::expand_tilde;
|
|
||||||
use nu_protocol::engine::StateWorkingSet;
|
use nu_protocol::engine::StateWorkingSet;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
struct Arguments;
|
struct Arguments {
|
||||||
|
pwd: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
impl PathSubcommandArguments for Arguments {}
|
impl PathSubcommandArguments for Arguments {}
|
||||||
|
|
||||||
@ -45,19 +46,21 @@ If nothing is found, an empty string will be returned."#
|
|||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
engine_state: &EngineState,
|
engine_state: &EngineState,
|
||||||
_stack: &mut Stack,
|
stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let head = call.head;
|
let head = call.head;
|
||||||
let args = Arguments;
|
let args = Arguments {
|
||||||
|
pwd: engine_state.cwd(Some(stack))?,
|
||||||
|
};
|
||||||
|
|
||||||
// This doesn't match explicit nulls
|
// This doesn't match explicit nulls
|
||||||
if matches!(input, PipelineData::Empty) {
|
if matches!(input, PipelineData::Empty) {
|
||||||
return Err(ShellError::PipelineEmpty { dst_span: head });
|
return Err(ShellError::PipelineEmpty { dst_span: head });
|
||||||
}
|
}
|
||||||
input.map(
|
input.map(
|
||||||
move |value| super::operate(&r#type, &args, value, head),
|
move |value| super::operate(&path_type, &args, value, head),
|
||||||
engine_state.ctrlc.clone(),
|
engine_state.ctrlc.clone(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -69,14 +72,16 @@ If nothing is found, an empty string will be returned."#
|
|||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let head = call.head;
|
let head = call.head;
|
||||||
let args = Arguments;
|
let args = Arguments {
|
||||||
|
pwd: working_set.permanent().cwd(None)?,
|
||||||
|
};
|
||||||
|
|
||||||
// This doesn't match explicit nulls
|
// This doesn't match explicit nulls
|
||||||
if matches!(input, PipelineData::Empty) {
|
if matches!(input, PipelineData::Empty) {
|
||||||
return Err(ShellError::PipelineEmpty { dst_span: head });
|
return Err(ShellError::PipelineEmpty { dst_span: head });
|
||||||
}
|
}
|
||||||
input.map(
|
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(),
|
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 {
|
fn path_type(path: &Path, span: Span, args: &Arguments) -> Value {
|
||||||
let meta = if path.starts_with("~") {
|
let path = nu_path::expand_path_with(path, &args.pwd, true);
|
||||||
let p = expand_tilde(path);
|
match std::fs::symlink_metadata(path) {
|
||||||
std::fs::symlink_metadata(p)
|
Ok(metadata) => Value::string(get_file_type(&metadata), span),
|
||||||
} else {
|
Err(err) => Value::error(err.into(), span),
|
||||||
std::fs::symlink_metadata(path)
|
}
|
||||||
};
|
|
||||||
|
|
||||||
Value::string(
|
|
||||||
match &meta {
|
|
||||||
Ok(data) => get_file_type(data),
|
|
||||||
Err(_) => "",
|
|
||||||
},
|
|
||||||
span,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_file_type(md: &std::fs::Metadata) -> &str {
|
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");
|
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 New Issue
Block a user