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:
YizhePKU 2024-05-27 01:23:52 +08:00 committed by GitHub
parent f38f88d42c
commit a1fc41db22
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 30 additions and 23 deletions

View file

@ -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 {

View file

@ -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");
})
}