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:
Leonhard Kipp
2021-04-09 08:03:12 +02:00
committed by GitHub
parent 111ad868a7
commit ac070ae942
19 changed files with 357 additions and 254 deletions

View File

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

View File

@ -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())

View File

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

View File

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

View File

@ -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())
}
}

View File

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

View File

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

View File

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

View File

@ -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(_) => {