Merge branch 'main' into ecow-record

This commit is contained in:
Ian Manske 2024-05-07 16:00:59 -04:00
commit 7099ce0c87
19 changed files with 165 additions and 102 deletions

View File

@ -23,8 +23,7 @@ fn load_bench_commands() -> EngineState {
} }
fn canonicalize_path(engine_state: &EngineState, path: &Path) -> PathBuf { fn canonicalize_path(engine_state: &EngineState, path: &Path) -> PathBuf {
#[allow(deprecated)] let cwd = engine_state.cwd_as_string(None).unwrap();
let cwd = engine_state.current_work_dir();
if path.exists() { if path.exists() {
match nu_path::canonicalize_with(path, cwd) { match nu_path::canonicalize_with(path, cwd) {

View File

@ -177,36 +177,36 @@ pub fn add_plugin_file(
use std::path::Path; use std::path::Path;
let working_set = StateWorkingSet::new(engine_state); let working_set = StateWorkingSet::new(engine_state);
#[allow(deprecated)]
let cwd = working_set.get_cwd();
if let Some(plugin_file) = plugin_file { if let Ok(cwd) = engine_state.cwd_as_string(None) {
let path = Path::new(&plugin_file.item); if let Some(plugin_file) = plugin_file {
let path_dir = path.parent().unwrap_or(path); let path = Path::new(&plugin_file.item);
// Just try to canonicalize the directory of the plugin file first. let path_dir = path.parent().unwrap_or(path);
if let Ok(path_dir) = canonicalize_with(path_dir, &cwd) { // Just try to canonicalize the directory of the plugin file first.
// Try to canonicalize the actual filename, but it's ok if that fails. The file doesn't if let Ok(path_dir) = canonicalize_with(path_dir, &cwd) {
// have to exist. // Try to canonicalize the actual filename, but it's ok if that fails. The file doesn't
let path = path_dir.join(path.file_name().unwrap_or(path.as_os_str())); // have to exist.
let path = canonicalize_with(&path, &cwd).unwrap_or(path); let path = path_dir.join(path.file_name().unwrap_or(path.as_os_str()));
engine_state.plugin_path = Some(path) let path = canonicalize_with(&path, &cwd).unwrap_or(path);
} else { engine_state.plugin_path = Some(path)
// It's an error if the directory for the plugin file doesn't exist. } else {
report_error( // It's an error if the directory for the plugin file doesn't exist.
&working_set, report_error(
&ParseError::FileNotFound( &working_set,
path_dir.to_string_lossy().into_owned(), &ParseError::FileNotFound(
plugin_file.span, path_dir.to_string_lossy().into_owned(),
), plugin_file.span,
); ),
);
}
} else if let Some(mut plugin_path) = nu_path::config_dir() {
// Path to store plugins signatures
plugin_path.push(storage_path);
let mut plugin_path = canonicalize_with(&plugin_path, &cwd).unwrap_or(plugin_path);
plugin_path.push(PLUGIN_FILE);
let plugin_path = canonicalize_with(&plugin_path, &cwd).unwrap_or(plugin_path);
engine_state.plugin_path = Some(plugin_path);
} }
} else if let Some(mut plugin_path) = nu_path::config_dir() {
// Path to store plugins signatures
plugin_path.push(storage_path);
let mut plugin_path = canonicalize_with(&plugin_path, &cwd).unwrap_or(plugin_path);
plugin_path.push(PLUGIN_FILE);
let plugin_path = canonicalize_with(&plugin_path, &cwd).unwrap_or(plugin_path);
engine_state.plugin_path = Some(plugin_path);
} }
} }
@ -236,8 +236,7 @@ pub fn eval_config_contents(
engine_state.file = prev_file; engine_state.file = prev_file;
// Merge the environment in case env vars changed in the config // Merge the environment in case env vars changed in the config
#[allow(deprecated)] match engine_state.cwd(Some(stack)) {
match nu_engine::env::current_dir(engine_state, stack) {
Ok(cwd) => { Ok(cwd) => {
if let Err(e) = engine_state.merge_env(stack, cwd) { if let Err(e) = engine_state.merge_env(stack, cwd) {
let working_set = StateWorkingSet::new(engine_state); let working_set = StateWorkingSet::new(engine_state);
@ -274,8 +273,9 @@ pub fn migrate_old_plugin_file(engine_state: &EngineState, storage_path: &str) -
let start_time = std::time::Instant::now(); let start_time = std::time::Instant::now();
#[allow(deprecated)] let Ok(cwd) = engine_state.cwd_as_string(None) else {
let cwd = engine_state.current_work_dir(); return false;
};
let Some(config_dir) = nu_path::config_dir().and_then(|mut dir| { let Some(config_dir) = nu_path::config_dir().and_then(|mut dir| {
dir.push(storage_path); dir.push(storage_path);

View File

@ -1,8 +1,7 @@
use crate::util::eval_source; use crate::util::eval_source;
use log::{info, trace}; use log::{info, trace};
use miette::{IntoDiagnostic, Result}; use miette::{IntoDiagnostic, Result};
#[allow(deprecated)] use nu_engine::{convert_env_values, eval_block};
use nu_engine::{convert_env_values, current_dir, eval_block};
use nu_parser::parse; use nu_parser::parse;
use nu_path::canonicalize_with; use nu_path::canonicalize_with;
use nu_protocol::{ use nu_protocol::{
@ -30,8 +29,7 @@ pub fn evaluate_file(
std::process::exit(1); std::process::exit(1);
} }
#[allow(deprecated)] let cwd = engine_state.cwd_as_string(Some(stack))?;
let cwd = current_dir(engine_state, stack)?;
let file_path = canonicalize_with(&path, cwd).unwrap_or_else(|e| { let file_path = canonicalize_with(&path, cwd).unwrap_or_else(|e| {
let working_set = StateWorkingSet::new(engine_state); let working_set = StateWorkingSet::new(engine_state);

View File

@ -13,8 +13,7 @@ pub fn get_init_cwd() -> PathBuf {
} }
pub fn get_guaranteed_cwd(engine_state: &EngineState, stack: &Stack) -> PathBuf { pub fn get_guaranteed_cwd(engine_state: &EngineState, stack: &Stack) -> PathBuf {
#[allow(deprecated)] engine_state.cwd(Some(stack)).unwrap_or_else(|e| {
nu_engine::env::current_dir(engine_state, stack).unwrap_or_else(|e| {
let working_set = StateWorkingSet::new(engine_state); let working_set = StateWorkingSet::new(engine_state);
report_error(&working_set, &e); report_error(&working_set, &e);
crate::util::get_init_cwd() crate::util::get_init_cwd()

View File

@ -1,5 +1,4 @@
#[allow(deprecated)] use nu_engine::command_prelude::*;
use nu_engine::{command_prelude::*, current_dir};
use nu_plugin_engine::{GetPlugin, PersistentPlugin}; use nu_plugin_engine::{GetPlugin, PersistentPlugin};
use nu_protocol::{PluginGcConfig, PluginIdentity, PluginRegistryItem, RegisteredPlugin}; use nu_protocol::{PluginGcConfig, PluginIdentity, PluginRegistryItem, RegisteredPlugin};
use std::sync::Arc; use std::sync::Arc;
@ -82,8 +81,7 @@ apparent the next time `nu` is next launched with that plugin registry file.
let filename: Spanned<String> = call.req(engine_state, stack, 0)?; let filename: Spanned<String> = call.req(engine_state, stack, 0)?;
let shell: Option<Spanned<String>> = call.get_flag(engine_state, stack, "shell")?; let shell: Option<Spanned<String>> = call.get_flag(engine_state, stack, "shell")?;
#[allow(deprecated)] let cwd = engine_state.cwd(Some(stack))?;
let cwd = current_dir(engine_state, stack)?;
// Check the current directory, or fall back to NU_PLUGIN_DIRS // Check the current directory, or fall back to NU_PLUGIN_DIRS
let filename_expanded = nu_path::locate_in_dirs(&filename.item, &cwd, || { let filename_expanded = nu_path::locate_in_dirs(&filename.item, &cwd, || {

View File

@ -125,6 +125,7 @@ pub fn add_shell_command_context(mut engine_state: EngineState) -> EngineState {
SysMem, SysMem,
SysNet, SysNet,
SysTemp, SysTemp,
SysUsers,
UName, UName,
}; };

View File

@ -1,5 +1,4 @@
#[allow(deprecated)] use nu_engine::command_prelude::*;
use nu_engine::{command_prelude::*, env::current_dir};
use std::sync::{atomic::AtomicBool, Arc}; use std::sync::{atomic::AtomicBool, Arc};
use wax::{Glob as WaxGlob, WalkBehavior, WalkEntry}; use wax::{Glob as WaxGlob, WalkBehavior, WalkEntry};
@ -179,8 +178,7 @@ impl Command for Glob {
} }
}; };
#[allow(deprecated)] let path = engine_state.cwd_as_string(Some(stack))?;
let path = current_dir(engine_state, stack)?;
let path = match nu_path::canonicalize_with(prefix, path) { let path = match nu_path::canonicalize_with(prefix, path) {
Ok(path) => path, Ok(path) => path,
Err(e) if e.to_string().contains("os error 2") => Err(e) if e.to_string().contains("os error 2") =>

View File

@ -5,8 +5,7 @@ use notify_debouncer_full::{
EventKind, RecursiveMode, Watcher, EventKind, RecursiveMode, Watcher,
}, },
}; };
#[allow(deprecated)] use nu_engine::{command_prelude::*, ClosureEval};
use nu_engine::{command_prelude::*, current_dir, ClosureEval};
use nu_protocol::{ use nu_protocol::{
engine::{Closure, StateWorkingSet}, engine::{Closure, StateWorkingSet},
format_error, format_error,
@ -74,8 +73,7 @@ impl Command for Watch {
_input: PipelineData, _input: PipelineData,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
let head = call.head; let head = call.head;
#[allow(deprecated)] let cwd = engine_state.cwd_as_string(Some(stack))?;
let cwd = current_dir(engine_state, stack)?;
let path_arg: Spanned<String> = call.req(engine_state, stack, 0)?; let path_arg: Spanned<String> = call.req(engine_state, stack, 0)?;
let path_no_whitespace = &path_arg let path_no_whitespace = &path_arg

View File

@ -26,7 +26,8 @@ impl Command for SysHost {
call: &Call, call: &Call,
_input: PipelineData, _input: PipelineData,
) -> Result<PipelineData, ShellError> { ) -> Result<PipelineData, ShellError> {
Ok(super::host(call.head).into_pipeline_data()) let host = super::host(call.head);
Ok(Value::record(host, call.head).into_pipeline_data())
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {

View File

@ -5,6 +5,7 @@ mod mem;
mod net; mod net;
mod sys_; mod sys_;
mod temp; mod temp;
mod users;
pub use cpu::SysCpu; pub use cpu::SysCpu;
pub use disks::SysDisks; pub use disks::SysDisks;
@ -13,6 +14,7 @@ pub use mem::SysMem;
pub use net::SysNet; pub use net::SysNet;
pub use sys_::Sys; pub use sys_::Sys;
pub use temp::SysTemp; pub use temp::SysTemp;
pub use users::SysUsers;
use chrono::{DateTime, Local}; use chrono::{DateTime, Local};
use nu_protocol::{record, Record, Span, Value}; use nu_protocol::{record, Record, Span, Value};
@ -122,7 +124,29 @@ pub fn mem(span: Span) -> Value {
Value::record(record, span) Value::record(record, span)
} }
pub fn host(span: Span) -> Value { pub fn users(span: Span) -> Value {
let users = Users::new_with_refreshed_list()
.iter()
.map(|user| {
let groups = user
.groups()
.iter()
.map(|group| Value::string(trim_cstyle_null(group.name()), span))
.collect();
let record = record! {
"name" => Value::string(trim_cstyle_null(user.name()), span),
"groups" => Value::list(groups, span),
};
Value::record(record, span)
})
.collect();
Value::list(users, span)
}
pub fn host(span: Span) -> Record {
let mut record = Record::new(); let mut record = Record::new();
if let Some(name) = System::name() { if let Some(name) = System::name() {
@ -160,27 +184,7 @@ pub fn host(span: Span) -> Value {
let timestamp_str = datetime.with_timezone(datetime.offset()).to_rfc3339(); let timestamp_str = datetime.with_timezone(datetime.offset()).to_rfc3339();
record.push("boot_time", Value::string(timestamp_str, span)); record.push("boot_time", Value::string(timestamp_str, span));
let users = Users::new_with_refreshed_list() record
.iter()
.map(|user| {
let groups = user
.groups()
.iter()
.map(|group| Value::string(trim_cstyle_null(group.name()), span))
.collect();
let record = record! {
"name" => Value::string(trim_cstyle_null(user.name()), span),
"groups" => Value::list(groups, span),
};
Value::record(record, span)
})
.collect();
record.push("sessions", Value::list(users, span));
Value::record(record, span)
} }
pub fn temp(span: Span) -> Value { pub fn temp(span: Span) -> Value {

View File

@ -43,8 +43,11 @@ impl Command for Sys {
); );
let head = call.head; let head = call.head;
let mut host = super::host(head);
host.push("sessions", super::users(head));
let record = record! { let record = record! {
"host" => super::host(head), "host" => Value::record(host, head),
"cpu" => super::cpu(head), "cpu" => super::cpu(head),
"disks" => super::disks(head), "disks" => super::disks(head),
"mem" => super::mem(head), "mem" => super::mem(head),

View File

@ -0,0 +1,38 @@
use nu_engine::command_prelude::*;
#[derive(Clone)]
pub struct SysUsers;
impl Command for SysUsers {
fn name(&self) -> &str {
"sys users"
}
fn signature(&self) -> Signature {
Signature::build("sys users")
.category(Category::System)
.input_output_types(vec![(Type::Nothing, Type::record())])
}
fn usage(&self) -> &str {
"View information about the users on the system."
}
fn run(
&self,
_engine_state: &EngineState,
_stack: &mut Stack,
call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
Ok(super::users(call.head).into_pipeline_data())
}
fn examples(&self) -> Vec<Example> {
vec![Example {
description: "Show info about the system users",
example: "sys users",
result: None,
}]
}
}

View File

@ -286,8 +286,7 @@ pub fn find_in_dirs_env(
Err(e) => return Err(e), Err(e) => return Err(e),
} }
} else { } else {
#[allow(deprecated)] engine_state.cwd_as_string(Some(stack))?
current_dir_str(engine_state, stack)?
}; };
let check_dir = |lib_dirs: Option<Value>| -> Option<PathBuf> { let check_dir = |lib_dirs: Option<Value>| -> Option<PathBuf> {

View File

@ -385,12 +385,23 @@ fn flatten_expression_into(
output.extend(flattened); output.extend(flattened);
} }
ListItem::Spread(_, expr) => { ListItem::Spread(op_span, expr) => {
output.push(( if op_span.start > last_end {
Span::new(expr.span.start, expr.span.start + 3), output.push((Span::new(last_end, op_span.start), FlatShape::List));
FlatShape::Operator, }
)); output.push((*op_span, FlatShape::Operator));
flatten_expression_into(working_set, expr, output); last_end = op_span.end;
let flattened_inner = flatten_expression(working_set, expr);
if let Some(first) = flattened_inner.first() {
if first.0.start > last_end {
output.push((Span::new(last_end, first.0.start), FlatShape::List));
}
}
if let Some(last) = flattened_inner.last() {
last_end = last.0.end;
}
output.extend(flattened_inner);
} }
} }
} }

View File

@ -3895,7 +3895,7 @@ pub fn parse_list_expression(
Type::List(elem_ty) => *elem_ty.clone(), Type::List(elem_ty) => *elem_ty.clone(),
_ => Type::Any, _ => Type::Any,
}; };
let span = Span::new(curr_span.start, spread_arg.span.end); let span = Span::new(curr_span.start, curr_span.start + 3);
(ListItem::Spread(span, spread_arg), elem_ty) (ListItem::Spread(span, spread_arg), elem_ty)
} else { } else {
let arg = parse_multispan_value( let arg = parse_multispan_value(

View File

@ -984,6 +984,20 @@ impl EngineState {
} }
} }
/// Like `EngineState::cwd()`, but returns a String instead of a PathBuf for convenience.
pub fn cwd_as_string(&self, stack: Option<&Stack>) -> Result<String, ShellError> {
let cwd = self.cwd(stack)?;
cwd.into_os_string()
.into_string()
.map_err(|err| ShellError::NonUtf8Custom {
msg: format!(
"The current working directory is not a valid utf-8 string: {:?}",
err
),
span: Span::unknown(),
})
}
// TODO: see if we can completely get rid of this // TODO: see if we can completely get rid of this
pub fn get_file_contents(&self) -> &[CachedFile] { pub fn get_file_contents(&self) -> &[CachedFile] {
&self.files &self.files

View File

@ -1,6 +1,5 @@
use log::trace; use log::trace;
#[allow(deprecated)] use nu_engine::eval_block;
use nu_engine::{env::current_dir, eval_block};
use nu_parser::parse; use nu_parser::parse;
use nu_protocol::{ use nu_protocol::{
debugger::WithoutDebug, debugger::WithoutDebug,
@ -99,8 +98,7 @@ use std pwd
eval_block::<WithoutDebug>(engine_state, &mut stack, &block, pipeline_data)?; eval_block::<WithoutDebug>(engine_state, &mut stack, &block, pipeline_data)?;
#[allow(deprecated)] let cwd = engine_state.cwd(Some(&stack))?;
let cwd = current_dir(engine_state, &stack)?;
engine_state.merge_env(&mut stack, cwd)?; engine_state.merge_env(&mut stack, cwd)?;
Ok(()) Ok(())

View File

@ -31,14 +31,19 @@ pub(crate) fn read_config_file(
// Load config startup file // Load config startup file
if let Some(file) = config_file { if let Some(file) = config_file {
let working_set = StateWorkingSet::new(engine_state); let working_set = StateWorkingSet::new(engine_state);
#[allow(deprecated)]
let cwd = working_set.get_cwd();
if let Ok(path) = canonicalize_with(&file.item, cwd) { match engine_state.cwd_as_string(Some(stack)) {
eval_config_contents(path, engine_state, stack); Ok(cwd) => {
} else { if let Ok(path) = canonicalize_with(&file.item, cwd) {
let e = ParseError::FileNotFound(file.item, file.span); eval_config_contents(path, engine_state, stack);
report_error(&working_set, &e); } else {
let e = ParseError::FileNotFound(file.item, file.span);
report_error(&working_set, &e);
}
}
Err(e) => {
report_error(&working_set, &e);
}
} }
} else if let Some(mut config_path) = nu_path::config_dir() { } else if let Some(mut config_path) = nu_path::config_dir() {
config_path.push(NUSHELL_FOLDER); config_path.push(NUSHELL_FOLDER);
@ -144,8 +149,7 @@ pub(crate) fn read_default_env_file(engine_state: &mut EngineState, stack: &mut
info!("read_config_file {}:{}:{}", file!(), line!(), column!()); info!("read_config_file {}:{}:{}", file!(), line!(), column!());
// Merge the environment in case env vars changed in the config // Merge the environment in case env vars changed in the config
#[allow(deprecated)] match engine_state.cwd(Some(stack)) {
match nu_engine::env::current_dir(engine_state, stack) {
Ok(cwd) => { Ok(cwd) => {
if let Err(e) = engine_state.merge_env(stack, cwd) { if let Err(e) = engine_state.merge_env(stack, cwd) {
let working_set = StateWorkingSet::new(engine_state); let working_set = StateWorkingSet::new(engine_state);
@ -186,8 +190,7 @@ fn eval_default_config(
); );
// Merge the environment in case env vars changed in the config // Merge the environment in case env vars changed in the config
#[allow(deprecated)] match engine_state.cwd(Some(stack)) {
match nu_engine::env::current_dir(engine_state, stack) {
Ok(cwd) => { Ok(cwd) => {
if let Err(e) = engine_state.merge_env(stack, cwd) { if let Err(e) = engine_state.merge_env(stack, cwd) {
let working_set = StateWorkingSet::new(engine_state); let working_set = StateWorkingSet::new(engine_state);

View File

@ -249,8 +249,9 @@ pub fn nu_repl() {
for (i, line) in source_lines.iter().enumerate() { for (i, line) in source_lines.iter().enumerate() {
let mut stack = Stack::with_parent(top_stack.clone()); let mut stack = Stack::with_parent(top_stack.clone());
#[allow(deprecated)]
let cwd = nu_engine::env::current_dir(&engine_state, &stack) let cwd = engine_state
.cwd(Some(&stack))
.unwrap_or_else(|err| outcome_err(&engine_state, &err)); .unwrap_or_else(|err| outcome_err(&engine_state, &err));
// Before doing anything, merge the environment from the previous REPL iteration into the // Before doing anything, merge the environment from the previous REPL iteration into the