mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 20:27:44 +02:00
Refactor/config commands (#3265)
* Use ctx.configs in all config commands * Remove all setting/accessing of vars.("config-path") * Add tests * Add comment * Reload cfg on remove * Hypocratic ws change * Use history_path in hist_or_default * Make clippy happy * Fix rebase stuff * Fix clippy lint
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Primitive, ReturnSuccess, Signature, UntaggedValue, Value};
|
||||
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
@ -32,23 +32,22 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
|
||||
pub fn clear(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let name_span = args.call_info.name_tag.clone();
|
||||
let ctx = EvaluationContext::from_args(&args);
|
||||
|
||||
let path = match args.scope.get_var("config-path") {
|
||||
Some(Value {
|
||||
value: UntaggedValue::Primitive(Primitive::FilePath(path)),
|
||||
..
|
||||
}) => Some(path),
|
||||
_ => nu_data::config::default_path().ok(),
|
||||
let result = if let Some(global_cfg) = &mut args.configs.lock().global_config {
|
||||
global_cfg.vars.clear();
|
||||
global_cfg.write()?;
|
||||
ctx.reload_config(global_cfg)?;
|
||||
Ok(OutputStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::Row(global_cfg.vars.clone().into()).into_value(args.call_info.name_tag),
|
||||
)))
|
||||
} else {
|
||||
Ok(vec![ReturnSuccess::value(UntaggedValue::Error(
|
||||
crate::commands::config::err_no_global_cfg_present(),
|
||||
))]
|
||||
.into_iter()
|
||||
.to_output_stream())
|
||||
};
|
||||
|
||||
let mut result = nu_data::config::read(name_span, &path)?;
|
||||
|
||||
result.clear();
|
||||
|
||||
config::write(&result, &path)?;
|
||||
|
||||
Ok(OutputStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::Row(result.into()).into_value(args.call_info.name_tag),
|
||||
)))
|
||||
result
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ impl WholeStreamCommand for Command {
|
||||
.to_output_stream())
|
||||
} else {
|
||||
Ok(vec![ReturnSuccess::value(UntaggedValue::Error(
|
||||
ShellError::untagged_runtime_error("No global config found!"),
|
||||
crate::commands::config::err_no_global_cfg_present(),
|
||||
))]
|
||||
.into_iter()
|
||||
.to_output_stream())
|
||||
|
@ -1,9 +1,7 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
ColumnPath, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
use nu_protocol::{ColumnPath, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
@ -44,33 +42,27 @@ impl WholeStreamCommand for SubCommand {
|
||||
|
||||
pub fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let name = args.call_info.name_tag.clone();
|
||||
let scope = args.scope.clone();
|
||||
let ctx = EvaluationContext::from_args(&args);
|
||||
|
||||
let (Arguments { column_path }, _) = args.process()?;
|
||||
|
||||
let path = match scope.get_var("config-path") {
|
||||
Some(Value {
|
||||
value: UntaggedValue::Primitive(Primitive::FilePath(path)),
|
||||
..
|
||||
}) => Some(path),
|
||||
_ => nu_data::config::default_path().ok(),
|
||||
let result = if let Some(global_cfg) = &ctx.configs.lock().global_config {
|
||||
let result = UntaggedValue::row(global_cfg.vars.clone()).into_value(&name);
|
||||
let value = crate::commands::get::get_column_path(&column_path, &result)?;
|
||||
Ok(match value {
|
||||
Value {
|
||||
value: UntaggedValue::Table(list),
|
||||
..
|
||||
} => list.into_iter().to_output_stream(),
|
||||
x => OutputStream::one(ReturnSuccess::value(x)),
|
||||
})
|
||||
} else {
|
||||
Ok(vec![ReturnSuccess::value(UntaggedValue::Error(
|
||||
crate::commands::config::err_no_global_cfg_present(),
|
||||
))]
|
||||
.into_iter()
|
||||
.to_output_stream())
|
||||
};
|
||||
|
||||
let result = UntaggedValue::row(nu_data::config::read(&name, &path)?).into_value(&name);
|
||||
|
||||
let value = crate::commands::get::get_column_path(&column_path, &result)?;
|
||||
|
||||
Ok(match value {
|
||||
Value {
|
||||
value: UntaggedValue::Table(list),
|
||||
..
|
||||
} => {
|
||||
let list: Vec<_> = list
|
||||
.iter()
|
||||
.map(|x| ReturnSuccess::value(x.clone()))
|
||||
.collect();
|
||||
|
||||
list.into_iter().to_output_stream()
|
||||
}
|
||||
x => OutputStream::one(ReturnSuccess::value(x)),
|
||||
})
|
||||
result
|
||||
}
|
||||
|
@ -13,3 +13,9 @@ pub use path::SubCommand as ConfigPath;
|
||||
pub use remove::SubCommand as ConfigRemove;
|
||||
pub use set::SubCommand as ConfigSet;
|
||||
pub use set_into::SubCommand as ConfigSetInto;
|
||||
|
||||
use nu_errors::ShellError;
|
||||
|
||||
pub fn err_no_global_cfg_present() -> ShellError {
|
||||
ShellError::untagged_runtime_error("No global config found!")
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Primitive, ReturnSuccess, Signature, UntaggedValue, Value};
|
||||
use nu_protocol::{Primitive, ReturnSuccess, Signature, UntaggedValue};
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
@ -32,18 +32,15 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
|
||||
pub fn path(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
Ok(OutputStream::one(ReturnSuccess::value(
|
||||
match args.scope.get_var("config-path") {
|
||||
Some(
|
||||
path
|
||||
@
|
||||
Value {
|
||||
value: UntaggedValue::Primitive(Primitive::FilePath(_)),
|
||||
..
|
||||
},
|
||||
) => path,
|
||||
_ => UntaggedValue::Primitive(Primitive::FilePath(nu_data::config::default_path()?))
|
||||
.into_value(args.call_info.name_tag),
|
||||
},
|
||||
)))
|
||||
if let Some(global_cfg) = &mut args.configs.lock().global_config {
|
||||
Ok(OutputStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::Primitive(Primitive::FilePath(global_cfg.file_path.clone())),
|
||||
)))
|
||||
} else {
|
||||
Ok(vec![ReturnSuccess::value(UntaggedValue::Error(
|
||||
crate::commands::config::err_no_global_cfg_present(),
|
||||
))]
|
||||
.into_iter()
|
||||
.to_output_stream())
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue};
|
||||
use nu_source::Tagged;
|
||||
|
||||
pub struct SubCommand;
|
||||
@ -42,35 +42,35 @@ impl WholeStreamCommand for SubCommand {
|
||||
}
|
||||
|
||||
pub fn remove(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let name_span = args.call_info.name_tag.clone();
|
||||
let scope = args.scope.clone();
|
||||
let ctx = EvaluationContext::from_args(&args);
|
||||
let (Arguments { remove }, _) = args.process()?;
|
||||
|
||||
let path = match scope.get_var("config-path") {
|
||||
Some(Value {
|
||||
value: UntaggedValue::Primitive(Primitive::FilePath(path)),
|
||||
..
|
||||
}) => Some(path),
|
||||
_ => nu_data::config::default_path().ok(),
|
||||
};
|
||||
|
||||
let mut result = nu_data::config::read(name_span, &path)?;
|
||||
|
||||
let key = remove.to_string();
|
||||
|
||||
if result.contains_key(&key) {
|
||||
result.swap_remove(&key);
|
||||
config::write(&result, &path)?;
|
||||
Ok(vec![ReturnSuccess::value(
|
||||
UntaggedValue::Row(result.into()).into_value(remove.tag()),
|
||||
)]
|
||||
let result = if let Some(global_cfg) = &mut ctx.configs.lock().global_config {
|
||||
if global_cfg.vars.contains_key(&key) {
|
||||
global_cfg.vars.swap_remove(&key);
|
||||
global_cfg.write()?;
|
||||
ctx.reload_config(global_cfg)?;
|
||||
Ok(vec![ReturnSuccess::value(
|
||||
UntaggedValue::row(global_cfg.vars.clone()).into_value(remove.tag()),
|
||||
)]
|
||||
.into_iter()
|
||||
.to_output_stream())
|
||||
} else {
|
||||
Err(ShellError::labeled_error(
|
||||
"Key does not exist in config",
|
||||
"key",
|
||||
remove.tag(),
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Ok(vec![ReturnSuccess::value(UntaggedValue::Error(
|
||||
crate::commands::config::err_no_global_cfg_present(),
|
||||
))]
|
||||
.into_iter()
|
||||
.to_output_stream())
|
||||
} else {
|
||||
Err(ShellError::labeled_error(
|
||||
"Key does not exist in config",
|
||||
"key",
|
||||
remove.tag(),
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
result
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
ColumnPath, ConfigPath, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
use nu_protocol::{ColumnPath, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
@ -61,7 +59,6 @@ impl WholeStreamCommand for SubCommand {
|
||||
pub fn set(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let name = args.call_info.name_tag.clone();
|
||||
let ctx = EvaluationContext::from_args(&args);
|
||||
let scope = args.scope.clone();
|
||||
let (
|
||||
Arguments {
|
||||
column_path,
|
||||
@ -70,38 +67,38 @@ pub fn set(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
_,
|
||||
) = args.process()?;
|
||||
|
||||
let path = match scope.get_var("config-path") {
|
||||
Some(Value {
|
||||
value: UntaggedValue::Primitive(Primitive::FilePath(path)),
|
||||
..
|
||||
}) => Some(path),
|
||||
_ => nu_data::config::default_path().ok(),
|
||||
let result = if let Some(global_cfg) = &mut ctx.configs.lock().global_config {
|
||||
let configuration = UntaggedValue::row(global_cfg.vars.clone()).into_value(&name);
|
||||
|
||||
if let UntaggedValue::Table(rows) = &value.value {
|
||||
if rows.len() == 1 && rows[0].is_row() {
|
||||
value = rows[0].clone();
|
||||
}
|
||||
}
|
||||
|
||||
match configuration.forgiving_insert_data_at_column_path(&column_path, value) {
|
||||
Ok(Value {
|
||||
value: UntaggedValue::Row(changes),
|
||||
..
|
||||
}) => {
|
||||
global_cfg.vars = changes.entries;
|
||||
global_cfg.write()?;
|
||||
ctx.reload_config(global_cfg)?;
|
||||
|
||||
Ok(OutputStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::row(global_cfg.vars.clone()).into_value(name),
|
||||
)))
|
||||
}
|
||||
Ok(_) => Ok(OutputStream::empty()),
|
||||
Err(reason) => Err(reason),
|
||||
}
|
||||
} else {
|
||||
Ok(vec![ReturnSuccess::value(UntaggedValue::Error(
|
||||
crate::commands::config::err_no_global_cfg_present(),
|
||||
))]
|
||||
.into_iter()
|
||||
.to_output_stream())
|
||||
};
|
||||
|
||||
let raw_entries = nu_data::config::read(&name, &path)?;
|
||||
let configuration = UntaggedValue::row(raw_entries).into_value(&name);
|
||||
|
||||
if let UntaggedValue::Table(rows) = &value.value {
|
||||
if rows.len() == 1 && rows[0].is_row() {
|
||||
value = rows[0].clone();
|
||||
}
|
||||
}
|
||||
|
||||
match configuration.forgiving_insert_data_at_column_path(&column_path, value) {
|
||||
Ok(Value {
|
||||
value: UntaggedValue::Row(changes),
|
||||
..
|
||||
}) => {
|
||||
config::write(&changes.entries, &path)?;
|
||||
ctx.reload_config(&ConfigPath::Global(
|
||||
path.expect("Global config path is always some"),
|
||||
))?;
|
||||
|
||||
Ok(OutputStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::Row(changes).into_value(name),
|
||||
)))
|
||||
}
|
||||
Ok(_) => Ok(OutputStream::empty()),
|
||||
Err(reason) => Err(reason),
|
||||
}
|
||||
result
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
ConfigPath, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_source::Tagged;
|
||||
|
||||
pub struct SubCommand;
|
||||
@ -46,55 +44,43 @@ impl WholeStreamCommand for SubCommand {
|
||||
pub fn set_into(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let name = args.call_info.name_tag.clone();
|
||||
let ctx = EvaluationContext::from_args(&args);
|
||||
let scope = args.scope.clone();
|
||||
let (Arguments { set_into: v }, input) = args.process()?;
|
||||
|
||||
let path = match scope.get_var("config-path") {
|
||||
Some(Value {
|
||||
value: UntaggedValue::Primitive(Primitive::FilePath(path)),
|
||||
..
|
||||
}) => Some(path),
|
||||
_ => nu_data::config::default_path().ok(),
|
||||
};
|
||||
|
||||
let mut result = nu_data::config::read(&name, &path)?;
|
||||
|
||||
let rows: Vec<Value> = input.collect();
|
||||
let key = v.to_string();
|
||||
|
||||
Ok(if rows.is_empty() {
|
||||
return Err(ShellError::labeled_error(
|
||||
"No values given for set_into",
|
||||
"needs value(s) from pipeline",
|
||||
v.tag(),
|
||||
));
|
||||
} else if rows.len() == 1 {
|
||||
// A single value
|
||||
let value = &rows[0];
|
||||
let result = if let Some(global_cfg) = &mut ctx.configs.lock().global_config {
|
||||
if rows.is_empty() {
|
||||
return Err(ShellError::labeled_error(
|
||||
"No values given for set_into",
|
||||
"needs value(s) from pipeline",
|
||||
v.tag(),
|
||||
));
|
||||
} else if rows.len() == 1 {
|
||||
// A single value
|
||||
let value = &rows[0];
|
||||
|
||||
result.insert(key, value.clone());
|
||||
global_cfg.vars.insert(key, value.clone());
|
||||
} else {
|
||||
// Take in the pipeline as a table
|
||||
let value = UntaggedValue::Table(rows).into_value(name.clone());
|
||||
|
||||
config::write(&result, &path)?;
|
||||
ctx.reload_config(&ConfigPath::Global(
|
||||
path.expect("Global config path is always some"),
|
||||
))?;
|
||||
global_cfg.vars.insert(key, value);
|
||||
}
|
||||
|
||||
OutputStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::Row(result.into()).into_value(name),
|
||||
))
|
||||
global_cfg.write()?;
|
||||
ctx.reload_config(global_cfg)?;
|
||||
|
||||
Ok(OutputStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::row(global_cfg.vars.clone()).into_value(name),
|
||||
)))
|
||||
} else {
|
||||
// Take in the pipeline as a table
|
||||
let value = UntaggedValue::Table(rows).into_value(name.clone());
|
||||
Ok(vec![ReturnSuccess::value(UntaggedValue::Error(
|
||||
crate::commands::config::err_no_global_cfg_present(),
|
||||
))]
|
||||
.into_iter()
|
||||
.to_output_stream())
|
||||
};
|
||||
|
||||
result.insert(key, value);
|
||||
|
||||
config::write(&result, &path)?;
|
||||
ctx.reload_config(&ConfigPath::Global(
|
||||
path.expect("Global config path is always some"),
|
||||
))?;
|
||||
|
||||
OutputStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::Row(result.into()).into_value(name),
|
||||
))
|
||||
})
|
||||
result
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
use crate::prelude::*;
|
||||
use nu_data::config::{Conf, NuConfig};
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
|
||||
@ -32,11 +31,15 @@ impl WholeStreamCommand for History {
|
||||
}
|
||||
|
||||
fn history(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let config: Box<dyn Conf> = Box::new(NuConfig::new());
|
||||
let tag = args.call_info.name_tag.clone();
|
||||
let ctx = EvaluationContext::from_args(&args);
|
||||
let (Arguments { clear }, _) = args.process()?;
|
||||
|
||||
let path = nu_data::config::path::history_path(&config);
|
||||
let path = if let Some(global_cfg) = &ctx.configs.lock().global_config {
|
||||
nu_data::config::path::history_path_or_default(global_cfg)
|
||||
} else {
|
||||
nu_data::config::path::default_history_path()
|
||||
};
|
||||
|
||||
match clear {
|
||||
Some(_) => {
|
||||
|
Reference in New Issue
Block a user