Move nu-data out of nu-cli (#2369)
* WIP for moving nu-data out * Refactor nu-data out of nu-cli * Remove unwraps * Remove unwraps
This commit is contained in:
parent
1d5518a214
commit
738541f727
38
Cargo.lock
generated
38
Cargo.lock
generated
|
@ -593,9 +593,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.13"
|
version = "0.4.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6"
|
checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits 0.2.12",
|
"num-traits 0.2.12",
|
||||||
|
@ -2932,6 +2932,7 @@ dependencies = [
|
||||||
"futures 0.3.5",
|
"futures 0.3.5",
|
||||||
"log 0.4.11",
|
"log 0.4.11",
|
||||||
"nu-cli",
|
"nu-cli",
|
||||||
|
"nu-data",
|
||||||
"nu-errors",
|
"nu-errors",
|
||||||
"nu-parser",
|
"nu-parser",
|
||||||
"nu-plugin",
|
"nu-plugin",
|
||||||
|
@ -3005,6 +3006,7 @@ dependencies = [
|
||||||
"log 0.4.11",
|
"log 0.4.11",
|
||||||
"meval",
|
"meval",
|
||||||
"natural",
|
"natural",
|
||||||
|
"nu-data",
|
||||||
"nu-errors",
|
"nu-errors",
|
||||||
"nu-parser",
|
"nu-parser",
|
||||||
"nu-plugin",
|
"nu-plugin",
|
||||||
|
@ -3058,6 +3060,36 @@ dependencies = [
|
||||||
"zip",
|
"zip",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nu-data"
|
||||||
|
version = "0.18.2"
|
||||||
|
dependencies = [
|
||||||
|
"ansi_term 0.12.1",
|
||||||
|
"bigdecimal",
|
||||||
|
"byte-unit",
|
||||||
|
"chrono",
|
||||||
|
"derive-new",
|
||||||
|
"directories 2.0.2",
|
||||||
|
"dirs 2.0.2",
|
||||||
|
"getset",
|
||||||
|
"indexmap",
|
||||||
|
"log 0.4.11",
|
||||||
|
"nu-errors",
|
||||||
|
"nu-protocol",
|
||||||
|
"nu-source",
|
||||||
|
"nu-table",
|
||||||
|
"nu-value-ext",
|
||||||
|
"num-bigint",
|
||||||
|
"num-format",
|
||||||
|
"num-traits 0.2.12",
|
||||||
|
"parking_lot 0.11.0",
|
||||||
|
"query_interface",
|
||||||
|
"serde 1.0.115",
|
||||||
|
"toml 0.5.6",
|
||||||
|
"umask",
|
||||||
|
"users",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-errors"
|
name = "nu-errors"
|
||||||
version = "0.18.2"
|
version = "0.18.2"
|
||||||
|
@ -3346,7 +3378,7 @@ version = "0.18.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.12.1",
|
"ansi_term 0.12.1",
|
||||||
"bat",
|
"bat",
|
||||||
"nu-cli",
|
"nu-data",
|
||||||
"nu-errors",
|
"nu-errors",
|
||||||
"nu-plugin",
|
"nu-plugin",
|
||||||
"nu-protocol",
|
"nu-protocol",
|
||||||
|
|
|
@ -19,6 +19,7 @@ members = ["crates/*/"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-cli = {version = "0.18.2", path = "./crates/nu-cli"}
|
nu-cli = {version = "0.18.2", path = "./crates/nu-cli"}
|
||||||
|
nu-data = {version = "0.18.2", path = "./crates/nu-data"}
|
||||||
nu-errors = {version = "0.18.2", path = "./crates/nu-errors"}
|
nu-errors = {version = "0.18.2", path = "./crates/nu-errors"}
|
||||||
nu-parser = {version = "0.18.2", path = "./crates/nu-parser"}
|
nu-parser = {version = "0.18.2", path = "./crates/nu-parser"}
|
||||||
nu-plugin = {version = "0.18.2", path = "./crates/nu-plugin"}
|
nu-plugin = {version = "0.18.2", path = "./crates/nu-plugin"}
|
||||||
|
@ -101,7 +102,7 @@ s3 = ["nu_plugin_s3"]
|
||||||
|
|
||||||
clipboard-cli = ["nu-cli/clipboard-cli"]
|
clipboard-cli = ["nu-cli/clipboard-cli"]
|
||||||
ctrlc-support = ["nu-cli/ctrlc"]
|
ctrlc-support = ["nu-cli/ctrlc"]
|
||||||
directories-support = ["nu-cli/directories", "nu-cli/dirs"]
|
directories-support = ["nu-cli/directories", "nu-cli/dirs", "nu-data/directories", "nu-data/dirs"]
|
||||||
git-support = ["nu-cli/git2"]
|
git-support = ["nu-cli/git2"]
|
||||||
ptree-support = ["nu-cli/ptree"]
|
ptree-support = ["nu-cli/ptree"]
|
||||||
term-support = ["nu-cli/term"]
|
term-support = ["nu-cli/term"]
|
||||||
|
|
|
@ -10,6 +10,7 @@ version = "0.18.2"
|
||||||
doctest = false
|
doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
nu-data = {version = "0.18.2", path = "../nu-data"}
|
||||||
nu-errors = {version = "0.18.2", path = "../nu-errors"}
|
nu-errors = {version = "0.18.2", path = "../nu-errors"}
|
||||||
nu-parser = {version = "0.18.2", path = "../nu-parser"}
|
nu-parser = {version = "0.18.2", path = "../nu-parser"}
|
||||||
nu-plugin = {version = "0.18.2", path = "../nu-plugin"}
|
nu-plugin = {version = "0.18.2", path = "../nu-plugin"}
|
||||||
|
|
|
@ -111,7 +111,7 @@ fn search_paths() -> Vec<std::path::PathBuf> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(config) = crate::data::config::config(Tag::unknown()) {
|
if let Ok(config) = nu_data::config::config(Tag::unknown()) {
|
||||||
if let Some(plugin_dirs) = config.get("plugin_dirs") {
|
if let Some(plugin_dirs) = config.get("plugin_dirs") {
|
||||||
if let Value {
|
if let Value {
|
||||||
value: UntaggedValue::Table(pipelines),
|
value: UntaggedValue::Table(pipelines),
|
||||||
|
@ -210,7 +210,7 @@ impl History {
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|_| PathBuf::from(FNAME));
|
.unwrap_or_else(|_| PathBuf::from(FNAME));
|
||||||
|
|
||||||
let cfg = crate::data::config::config(Tag::unknown());
|
let cfg = nu_data::config::config(Tag::unknown());
|
||||||
if let Ok(c) = cfg {
|
if let Ok(c) = cfg {
|
||||||
match &c.get("history-path") {
|
match &c.get("history-path") {
|
||||||
Some(Value {
|
Some(Value {
|
||||||
|
@ -471,7 +471,7 @@ pub async fn run_vec_of_pipelines(
|
||||||
}
|
}
|
||||||
|
|
||||||
// before we start up, let's run our startup commands
|
// before we start up, let's run our startup commands
|
||||||
if let Ok(config) = crate::data::config::config(Tag::unknown()) {
|
if let Ok(config) = nu_data::config::config(Tag::unknown()) {
|
||||||
if let Some(commands) = config.get("startup") {
|
if let Some(commands) = config.get("startup") {
|
||||||
match commands {
|
match commands {
|
||||||
Value {
|
Value {
|
||||||
|
@ -752,7 +752,7 @@ pub async fn cli(
|
||||||
let mut ctrlcbreak = false;
|
let mut ctrlcbreak = false;
|
||||||
|
|
||||||
// before we start up, let's run our startup commands
|
// before we start up, let's run our startup commands
|
||||||
if let Ok(config) = crate::data::config::config(Tag::unknown()) {
|
if let Ok(config) = nu_data::config::config(Tag::unknown()) {
|
||||||
if let Some(commands) = config.get("startup") {
|
if let Some(commands) = config.get("startup") {
|
||||||
match commands {
|
match commands {
|
||||||
Value {
|
Value {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::context::CommandRegistry;
|
use crate::context::CommandRegistry;
|
||||||
use crate::data::config;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use nu_data::config;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
hir::Block, CommandAction, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
hir::Block, CommandAction, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||||
|
@ -82,7 +82,7 @@ pub async fn alias(
|
||||||
let mut processed_args: Vec<String> = vec![];
|
let mut processed_args: Vec<String> = vec![];
|
||||||
|
|
||||||
if let Some(true) = save {
|
if let Some(true) = save {
|
||||||
let mut result = crate::data::config::read(name.clone().tag, &None)?;
|
let mut result = nu_data::config::read(name.clone().tag, &None)?;
|
||||||
|
|
||||||
// process the alias to remove the --save flag
|
// process the alias to remove the --save flag
|
||||||
let left_brace = raw_input.find('{').unwrap_or(0);
|
let left_brace = raw_input.find('{').unwrap_or(0);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::commands::UnevaluatedCallInfo;
|
use crate::commands::UnevaluatedCallInfo;
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::data::config::table::AutoPivotMode;
|
|
||||||
use crate::data::config::table::HasTableProperties;
|
|
||||||
use crate::data::config::NuConfig as Configuration;
|
|
||||||
use crate::data::value::format_leaf;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use nu_data::config::table::AutoPivotMode;
|
||||||
|
use nu_data::config::table::HasTableProperties;
|
||||||
|
use nu_data::config::NuConfig as Configuration;
|
||||||
|
use nu_data::value::format_leaf;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::hir::{self, Expression, ExternalRedirection, Literal, SpannedExpression};
|
use nu_protocol::hir::{self, Expression, ExternalRedirection, Literal, SpannedExpression};
|
||||||
use nu_protocol::{Primitive, Scope, Signature, UntaggedValue, Value};
|
use nu_protocol::{Primitive, Scope, Signature, UntaggedValue, Value};
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
|
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::data::value::format_leaf;
|
use nu_data::value::format_leaf;
|
||||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
|
|
@ -425,7 +425,7 @@ fn spawn(
|
||||||
};
|
};
|
||||||
|
|
||||||
if external_failed {
|
if external_failed {
|
||||||
let cfg = crate::data::config::config(Tag::unknown());
|
let cfg = nu_data::config::config(Tag::unknown());
|
||||||
if let Ok(cfg) = cfg {
|
if let Ok(cfg) = cfg {
|
||||||
if cfg.contains_key("nonzero_exit_errors") {
|
if cfg.contains_key("nonzero_exit_errors") {
|
||||||
let _ = stdout_read_tx.send(Ok(Value {
|
let _ = stdout_read_tx.send(Ok(Value {
|
||||||
|
|
|
@ -45,7 +45,7 @@ pub async fn clear(
|
||||||
|
|
||||||
// NOTE: None because we are not loading a new config file, we just want to read from the
|
// NOTE: None because we are not loading a new config file, we just want to read from the
|
||||||
// existing config
|
// existing config
|
||||||
let mut result = crate::data::config::read(name_span, &None)?;
|
let mut result = nu_data::config::read(name_span, &None)?;
|
||||||
|
|
||||||
result.clear();
|
result.clear();
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ impl WholeStreamCommand for Command {
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
let name_span = args.call_info.name_tag.clone();
|
let name_span = args.call_info.name_tag.clone();
|
||||||
let name = args.call_info.name_tag;
|
let name = args.call_info.name_tag;
|
||||||
let result = crate::data::config::read(name_span, &None)?;
|
let result = nu_data::config::read(name_span, &None)?;
|
||||||
|
|
||||||
Ok(futures::stream::iter(vec![ReturnSuccess::value(
|
Ok(futures::stream::iter(vec![ReturnSuccess::value(
|
||||||
UntaggedValue::Row(result.into()).into_value(name),
|
UntaggedValue::Row(result.into()).into_value(name),
|
||||||
|
|
|
@ -56,7 +56,7 @@ pub async fn get(
|
||||||
|
|
||||||
// NOTE: None because we are not loading a new config file, we just want to read from the
|
// NOTE: None because we are not loading a new config file, we just want to read from the
|
||||||
// existing config
|
// existing config
|
||||||
let result = crate::data::config::read(name_span, &None)?;
|
let result = nu_data::config::read(name_span, &None)?;
|
||||||
|
|
||||||
let key = get.to_string();
|
let key = get.to_string();
|
||||||
let value = result
|
let value = result
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub async fn set(
|
||||||
|
|
||||||
let configuration = load.item().clone();
|
let configuration = load.item().clone();
|
||||||
|
|
||||||
let result = crate::data::config::read(name_span, &Some(configuration))?;
|
let result = nu_data::config::read(name_span, &Some(configuration))?;
|
||||||
|
|
||||||
Ok(futures::stream::iter(vec![ReturnSuccess::value(
|
Ok(futures::stream::iter(vec![ReturnSuccess::value(
|
||||||
UntaggedValue::Row(result.into()).into_value(name),
|
UntaggedValue::Row(result.into()).into_value(name),
|
||||||
|
|
|
@ -54,7 +54,7 @@ pub async fn remove(
|
||||||
let name_span = args.call_info.name_tag.clone();
|
let name_span = args.call_info.name_tag.clone();
|
||||||
let (RemoveArgs { remove }, _) = args.process(®istry).await?;
|
let (RemoveArgs { remove }, _) = args.process(®istry).await?;
|
||||||
|
|
||||||
let mut result = crate::data::config::read(name_span, &None)?;
|
let mut result = nu_data::config::read(name_span, &None)?;
|
||||||
|
|
||||||
let key = remove.to_string();
|
let key = remove.to_string();
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub async fn set(
|
||||||
|
|
||||||
// NOTE: None because we are not loading a new config file, we just want to read from the
|
// NOTE: None because we are not loading a new config file, we just want to read from the
|
||||||
// existing config
|
// existing config
|
||||||
let mut result = crate::data::config::read(name_span, &None)?;
|
let mut result = nu_data::config::read(name_span, &None)?;
|
||||||
|
|
||||||
result.insert(key.to_string(), value.clone());
|
result.insert(key.to_string(), value.clone());
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ pub async fn set_into(
|
||||||
|
|
||||||
// NOTE: None because we are not loading a new config file, we just want to read from the
|
// NOTE: None because we are not loading a new config file, we just want to read from the
|
||||||
// existing config
|
// existing config
|
||||||
let mut result = crate::data::config::read(name_span, &None)?;
|
let mut result = nu_data::config::read(name_span, &None)?;
|
||||||
|
|
||||||
// In the original code, this is set to `Some` if the `load flag is set`
|
// In the original code, this is set to `Some` if the `load flag is set`
|
||||||
let configuration = None;
|
let configuration = None;
|
||||||
|
|
|
@ -102,7 +102,7 @@ impl Iterator for RangeIterator {
|
||||||
if self.curr != self.end {
|
if self.curr != self.end {
|
||||||
let output = UntaggedValue::Primitive(self.curr.clone()).into_value(self.tag.clone());
|
let output = UntaggedValue::Primitive(self.curr.clone()).into_value(self.tag.clone());
|
||||||
|
|
||||||
self.curr = match crate::data::value::compute_values(
|
self.curr = match nu_data::value::compute_values(
|
||||||
Operator::Plus,
|
Operator::Plus,
|
||||||
&UntaggedValue::Primitive(self.curr.clone()),
|
&UntaggedValue::Primitive(self.curr.clone()),
|
||||||
&UntaggedValue::int(1),
|
&UntaggedValue::int(1),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::TaggedListBuilder;
|
|
||||||
use calamine::*;
|
use calamine::*;
|
||||||
|
use nu_data::TaggedListBuilder;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ReturnSuccess, Signature, TaggedDictBuilder, UntaggedValue};
|
use nu_protocol::{ReturnSuccess, Signature, TaggedDictBuilder, UntaggedValue};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::TaggedListBuilder;
|
|
||||||
use calamine::*;
|
use calamine::*;
|
||||||
|
use nu_data::TaggedListBuilder;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ReturnSuccess, Signature, TaggedDictBuilder, UntaggedValue};
|
use nu_protocol::{ReturnSuccess, Signature, TaggedDictBuilder, UntaggedValue};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
|
@ -179,7 +179,7 @@ pub async fn group_by(
|
||||||
None => as_string(row),
|
None => as_string(row),
|
||||||
});
|
});
|
||||||
|
|
||||||
crate::utils::data::group(&values, &Some(block), &name)
|
nu_data::utils::group(&values, &Some(block), &name)
|
||||||
}
|
}
|
||||||
Grouper::ByColumn(column_name) => group(&column_name, &values, name),
|
Grouper::ByColumn(column_name) => group(&column_name, &values, name),
|
||||||
};
|
};
|
||||||
|
@ -234,12 +234,12 @@ pub fn group(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
crate::utils::data::group(&values, &Some(block), &name)
|
nu_data::utils::group(&values, &Some(block), &name)
|
||||||
}
|
}
|
||||||
Grouper::ByColumn(None) => {
|
Grouper::ByColumn(None) => {
|
||||||
let block = Box::new(move |_, row: &Value| as_string(row));
|
let block = Box::new(move |_, row: &Value| as_string(row));
|
||||||
|
|
||||||
crate::utils::data::group(&values, &Some(block), &name)
|
nu_data::utils::group(&values, &Some(block), &name)
|
||||||
}
|
}
|
||||||
Grouper::ByBlock => Err(ShellError::unimplemented(
|
Grouper::ByBlock => Err(ShellError::unimplemented(
|
||||||
"Block not implemented: This should never happen.",
|
"Block not implemented: This should never happen.",
|
||||||
|
@ -250,7 +250,7 @@ pub fn group(
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::group;
|
use super::group;
|
||||||
use crate::utils::data::helpers::{committers, date, int, row, string, table};
|
use nu_data::utils::helpers::{committers, date, int, row, string, table};
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_source::*;
|
use nu_source::*;
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ pub async fn group_by_date(
|
||||||
(Grouper::ByDate(None), GroupByColumn::Name(None)) => {
|
(Grouper::ByDate(None), GroupByColumn::Name(None)) => {
|
||||||
let block = Box::new(move |_, row: &Value| row.format("%Y-%m-%d"));
|
let block = Box::new(move |_, row: &Value| row.format("%Y-%m-%d"));
|
||||||
|
|
||||||
crate::utils::data::group(&values, &Some(block), &name)
|
nu_data::utils::group(&values, &Some(block), &name)
|
||||||
}
|
}
|
||||||
(Grouper::ByDate(None), GroupByColumn::Name(Some(column_name))) => {
|
(Grouper::ByDate(None), GroupByColumn::Name(Some(column_name))) => {
|
||||||
let block = Box::new(move |_, row: &Value| {
|
let block = Box::new(move |_, row: &Value| {
|
||||||
|
@ -113,12 +113,12 @@ pub async fn group_by_date(
|
||||||
group_key?.format("%Y-%m-%d")
|
group_key?.format("%Y-%m-%d")
|
||||||
});
|
});
|
||||||
|
|
||||||
crate::utils::data::group(&values, &Some(block), &name)
|
nu_data::utils::group(&values, &Some(block), &name)
|
||||||
}
|
}
|
||||||
(Grouper::ByDate(Some(fmt)), GroupByColumn::Name(None)) => {
|
(Grouper::ByDate(Some(fmt)), GroupByColumn::Name(None)) => {
|
||||||
let block = Box::new(move |_, row: &Value| row.format(&fmt));
|
let block = Box::new(move |_, row: &Value| row.format(&fmt));
|
||||||
|
|
||||||
crate::utils::data::group(&values, &Some(block), &name)
|
nu_data::utils::group(&values, &Some(block), &name)
|
||||||
}
|
}
|
||||||
(Grouper::ByDate(Some(fmt)), GroupByColumn::Name(Some(column_name))) => {
|
(Grouper::ByDate(Some(fmt)), GroupByColumn::Name(Some(column_name))) => {
|
||||||
let block = Box::new(move |_, row: &Value| {
|
let block = Box::new(move |_, row: &Value| {
|
||||||
|
@ -129,7 +129,7 @@ pub async fn group_by_date(
|
||||||
group_key?.format(&fmt)
|
group_key?.format(&fmt)
|
||||||
});
|
});
|
||||||
|
|
||||||
crate::utils::data::group(&values, &Some(block), &name)
|
nu_data::utils::group(&values, &Some(block), &name)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
use crate::commands::command::Command;
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::data::command_dict;
|
|
||||||
use crate::documentation::{generate_docs, get_documentation, DocumentationConfig};
|
use crate::documentation::{generate_docs, get_documentation, DocumentationConfig};
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use nu_data::command::signature_dict;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue};
|
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value};
|
||||||
use nu_source::{SpannedItem, Tagged};
|
use nu_source::{SpannedItem, Tagged};
|
||||||
use nu_value_ext::get_data_by_key;
|
use nu_value_ext::get_data_by_key;
|
||||||
|
|
||||||
|
@ -38,6 +38,21 @@ impl WholeStreamCommand for Help {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn command_dict(command: Command, tag: impl Into<Tag>) -> Value {
|
||||||
|
let tag = tag.into();
|
||||||
|
|
||||||
|
let mut cmd_dict = TaggedDictBuilder::new(&tag);
|
||||||
|
|
||||||
|
cmd_dict.insert_untagged("name", UntaggedValue::string(command.name()));
|
||||||
|
|
||||||
|
cmd_dict.insert_untagged("type", UntaggedValue::string("Command"));
|
||||||
|
|
||||||
|
cmd_dict.insert_value("signature", signature_dict(command.signature(), tag));
|
||||||
|
cmd_dict.insert_untagged("usage", UntaggedValue::string(command.usage()));
|
||||||
|
|
||||||
|
cmd_dict.into_value()
|
||||||
|
}
|
||||||
|
|
||||||
async fn help(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn help(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let registry = registry.clone();
|
||||||
let name = args.call_info.name_tag.clone();
|
let name = args.call_info.name_tag.clone();
|
||||||
|
|
|
@ -107,9 +107,9 @@ pub async fn histogram(
|
||||||
"value".to_string().tagged(&name)
|
"value".to_string().tagged(&name)
|
||||||
};
|
};
|
||||||
|
|
||||||
let results = crate::utils::data::report(
|
let results = nu_data::utils::report(
|
||||||
&UntaggedValue::table(&values).into_value(&name),
|
&UntaggedValue::table(&values).into_value(&name),
|
||||||
crate::utils::data::Operation {
|
nu_data::utils::Operation {
|
||||||
grouper: Some(Box::new(move |_, _| Ok(String::from("frequencies")))),
|
grouper: Some(Box::new(move |_, _| Ok(String::from("frequencies")))),
|
||||||
splitter: Some(splitter(column_grouper)),
|
splitter: Some(splitter(column_grouper)),
|
||||||
format: None,
|
format: None,
|
||||||
|
|
|
@ -266,7 +266,7 @@ macro_rules! command {
|
||||||
|
|
||||||
Extract {
|
Extract {
|
||||||
$($extract:tt)* {
|
$($extract:tt)* {
|
||||||
use $crate::data::types::ExtractType;
|
use $nu_data::types::ExtractType;
|
||||||
let value = $args.expect_nth($($positional_count)*)?;
|
let value = $args.expect_nth($($positional_count)*)?;
|
||||||
Block::extract(value)?
|
Block::extract(value)?
|
||||||
}
|
}
|
||||||
|
@ -321,7 +321,7 @@ macro_rules! command {
|
||||||
|
|
||||||
Extract {
|
Extract {
|
||||||
$($extract:tt)* {
|
$($extract:tt)* {
|
||||||
use $crate::data::types::ExtractType;
|
use $nu_data::types::ExtractType;
|
||||||
let value = $args.expect_nth($($positional_count)*)?;
|
let value = $args.expect_nth($($positional_count)*)?;
|
||||||
<$param_kind>::extract(&value)?
|
<$param_kind>::extract(&value)?
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@ pub fn average(values: &[Value], name: &Tag) -> Result<Value, ShellError> {
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let left = UntaggedValue::from(Primitive::Int(num.into()));
|
let left = UntaggedValue::from(Primitive::Int(num.into()));
|
||||||
let result = crate::data::value::compute_values(Operator::Divide, &left, &total_rows);
|
let result = nu_data::value::compute_values(Operator::Divide, &left, &total_rows);
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(UntaggedValue::Primitive(Primitive::Decimal(result))) => {
|
Ok(UntaggedValue::Primitive(Primitive::Decimal(result))) => {
|
||||||
|
@ -142,7 +142,7 @@ pub fn average(values: &[Value], name: &Tag) -> Result<Value, ShellError> {
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let left = UntaggedValue::from(other);
|
let left = UntaggedValue::from(other);
|
||||||
let result = crate::data::value::compute_values(Operator::Divide, &left, &total_rows);
|
let result = nu_data::value::compute_values(Operator::Divide, &left, &total_rows);
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(value) => Ok(value.into_value(name)),
|
Ok(value) => Ok(value.into_value(name)),
|
||||||
|
|
|
@ -138,7 +138,7 @@ fn compute_average(values: &[Value], name: impl Into<Tag>) -> Result<Value, Shel
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let left = UntaggedValue::from(Primitive::Int(num.into()));
|
let left = UntaggedValue::from(Primitive::Int(num.into()));
|
||||||
let result = crate::data::value::compute_values(Operator::Divide, &left, &total_rows);
|
let result = nu_data::value::compute_values(Operator::Divide, &left, &total_rows);
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(UntaggedValue::Primitive(Primitive::Decimal(result))) => {
|
Ok(UntaggedValue::Primitive(Primitive::Decimal(result))) => {
|
||||||
|
@ -162,7 +162,7 @@ fn compute_average(values: &[Value], name: impl Into<Tag>) -> Result<Value, Shel
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let left = UntaggedValue::from(other);
|
let left = UntaggedValue::from(other);
|
||||||
let result = crate::data::value::compute_values(Operator::Divide, &left, &total_rows);
|
let result = nu_data::value::compute_values(Operator::Divide, &left, &total_rows);
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(value) => Ok(value.into_value(name)),
|
Ok(value) => Ok(value.into_value(name)),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::data::value::{compare_values, compute_values};
|
use nu_data::value::{compare_values, compute_values};
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::hir::Operator;
|
use nu_protocol::hir::Operator;
|
||||||
use nu_protocol::{UntaggedValue, Value};
|
use nu_protocol::{UntaggedValue, Value};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::data::value::compute_values;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use bigdecimal::FromPrimitive;
|
use bigdecimal::FromPrimitive;
|
||||||
|
use nu_data::value::compute_values;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
hir::Operator, Dictionary, Primitive, ReturnSuccess, Signature, UntaggedValue, Value,
|
hir::Operator, Dictionary, Primitive, ReturnSuccess, Signature, UntaggedValue, Value,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::commands::classified::block::run_block;
|
use crate::commands::classified::block::run_block;
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::context::CommandRegistry;
|
use crate::context::CommandRegistry;
|
||||||
use crate::data::value::merge_values;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use nu_data::value::merge_values;
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::context::CommandRegistry;
|
use crate::context::CommandRegistry;
|
||||||
use crate::data::base::select_fields;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use nu_data::base::select_fields;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ColumnPath, ReturnSuccess, Signature, SyntaxShape, Value};
|
use nu_protocol::{ColumnPath, ReturnSuccess, Signature, SyntaxShape, Value};
|
||||||
use nu_source::span_for_spanned_list;
|
use nu_source::span_for_spanned_list;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::{operate, DefaultArguments};
|
use super::{operate, DefaultArguments};
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::data::files::get_file_type;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use crate::shell::filesystem_shell::get_file_type;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};
|
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::data::base::reject_fields;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use nu_data::base::reject_fields;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape};
|
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape};
|
||||||
use nu_source::Tagged;
|
use nu_source::Tagged;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::data::base::coerce_compare;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use nu_data::base::coerce_compare;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};
|
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
use nu_source::Tagged;
|
use nu_source::Tagged;
|
||||||
|
|
|
@ -86,12 +86,12 @@ pub fn split(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
crate::utils::data::split(&values, &Some(block), &name)
|
nu_data::utils::split(&values, &Some(block), &name)
|
||||||
}
|
}
|
||||||
Grouper::ByColumn(None) => {
|
Grouper::ByColumn(None) => {
|
||||||
let block = Box::new(move |_, row: &Value| as_string(row));
|
let block = Box::new(move |_, row: &Value| as_string(row));
|
||||||
|
|
||||||
crate::utils::data::split(&values, &Some(block), &name)
|
nu_data::utils::split(&values, &Some(block), &name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ pub fn suggestions(tried: Tagged<&str>, for_value: &Value) -> ShellError {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::split;
|
use super::split;
|
||||||
use crate::utils::data::helpers::{committers_grouped_by_date, date, int, row, string, table};
|
use nu_data::utils::helpers::{committers_grouped_by_date, date, int, row, string, table};
|
||||||
use nu_protocol::UntaggedValue;
|
use nu_protocol::UntaggedValue;
|
||||||
use nu_source::*;
|
use nu_source::*;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::data::config::table::HasTableProperties;
|
|
||||||
use crate::data::config::NuConfig as TableConfiguration;
|
|
||||||
use crate::data::value::{format_leaf, style_leaf};
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use nu_data::config::table::HasTableProperties;
|
||||||
|
use nu_data::config::NuConfig as TableConfiguration;
|
||||||
|
use nu_data::value::{format_leaf, style_leaf};
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{Primitive, Signature, SyntaxShape, UntaggedValue, Value};
|
use nu_protocol::{Primitive, Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
use nu_table::{draw_table, Alignment, StyledString, TextStyle};
|
use nu_table::{draw_table, Alignment, StyledString, TextStyle};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::data::value::format_leaf;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
|
use nu_data::value::format_leaf;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
use nu_protocol::{Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
use nu_source::{AnchorLocation, Tagged};
|
use nu_source::{AnchorLocation, Tagged};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::data::value::format_leaf;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
|
use nu_data::value::format_leaf;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue, Value};
|
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue, Value};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::TaggedListBuilder;
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
use nu_data::TaggedListBuilder;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{Dictionary, Signature, UntaggedValue};
|
use nu_protocol::{Dictionary, Signature, UntaggedValue};
|
||||||
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
pub(crate) mod base;
|
|
||||||
pub(crate) mod command;
|
|
||||||
pub mod config;
|
|
||||||
pub(crate) mod dict;
|
|
||||||
pub(crate) mod files;
|
|
||||||
pub mod primitive;
|
|
||||||
pub(crate) mod types;
|
|
||||||
pub mod value;
|
|
||||||
|
|
||||||
pub(crate) use command::command_dict;
|
|
||||||
pub(crate) use dict::TaggedListBuilder;
|
|
||||||
pub(crate) use files::dir_entry_dict;
|
|
|
@ -1,164 +0,0 @@
|
||||||
mod conf;
|
|
||||||
mod nuconfig;
|
|
||||||
pub mod table;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
pub mod tests;
|
|
||||||
|
|
||||||
pub(crate) use conf::Conf;
|
|
||||||
pub(crate) use nuconfig::NuConfig;
|
|
||||||
|
|
||||||
use crate::commands::from_toml::convert_toml_value_to_nu_value;
|
|
||||||
use crate::commands::to_toml::value_to_toml_value;
|
|
||||||
use crate::prelude::*;
|
|
||||||
use indexmap::IndexMap;
|
|
||||||
use log::trace;
|
|
||||||
use nu_errors::ShellError;
|
|
||||||
use nu_protocol::{Dictionary, ShellTypeName, UntaggedValue, Value};
|
|
||||||
use nu_source::Tag;
|
|
||||||
use std::fs::{self, OpenOptions};
|
|
||||||
use std::io;
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
|
|
||||||
#[cfg(feature = "directories")]
|
|
||||||
pub fn config_path() -> Result<PathBuf, ShellError> {
|
|
||||||
use directories::ProjectDirs;
|
|
||||||
|
|
||||||
let dir = ProjectDirs::from("org", "nushell", "nu")
|
|
||||||
.ok_or_else(|| ShellError::untagged_runtime_error("Couldn't find project directory"))?;
|
|
||||||
let path = ProjectDirs::config_dir(&dir).to_owned();
|
|
||||||
std::fs::create_dir_all(&path).map_err(|err| {
|
|
||||||
ShellError::untagged_runtime_error(&format!("Couldn't create {} path:\n{}", "config", err))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "directories"))]
|
|
||||||
pub fn config_path() -> Result<PathBuf, ShellError> {
|
|
||||||
// FIXME: unsure if this should be error or a simple default
|
|
||||||
|
|
||||||
Ok(std::path::PathBuf::from("/"))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn default_path() -> Result<PathBuf, ShellError> {
|
|
||||||
default_path_for(&None)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn default_path_for(file: &Option<PathBuf>) -> Result<PathBuf, ShellError> {
|
|
||||||
let mut filename = config_path()?;
|
|
||||||
let file: &Path = file
|
|
||||||
.as_ref()
|
|
||||||
.map(AsRef::as_ref)
|
|
||||||
.unwrap_or_else(|| "config.toml".as_ref());
|
|
||||||
filename.push(file);
|
|
||||||
|
|
||||||
Ok(filename)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "directories")]
|
|
||||||
pub fn user_data() -> Result<PathBuf, ShellError> {
|
|
||||||
use directories::ProjectDirs;
|
|
||||||
|
|
||||||
let dir = ProjectDirs::from("org", "nushell", "nu")
|
|
||||||
.ok_or_else(|| ShellError::untagged_runtime_error("Couldn't find project directory"))?;
|
|
||||||
let path = ProjectDirs::data_local_dir(&dir).to_owned();
|
|
||||||
std::fs::create_dir_all(&path).map_err(|err| {
|
|
||||||
ShellError::untagged_runtime_error(&format!(
|
|
||||||
"Couldn't create {} path:\n{}",
|
|
||||||
"user data", err
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "directories"))]
|
|
||||||
pub fn user_data() -> Result<PathBuf, ShellError> {
|
|
||||||
// FIXME: unsure if this should be error or a simple default
|
|
||||||
|
|
||||||
Ok(std::path::PathBuf::from("/"))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read(
|
|
||||||
tag: impl Into<Tag>,
|
|
||||||
at: &Option<PathBuf>,
|
|
||||||
) -> Result<IndexMap<String, Value>, ShellError> {
|
|
||||||
let filename = default_path()?;
|
|
||||||
|
|
||||||
let filename = match at {
|
|
||||||
None => filename,
|
|
||||||
Some(ref file) => file.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
if !filename.exists() && touch(&filename).is_err() {
|
|
||||||
// If we can't create configs, let's just return an empty indexmap instead as we may be in
|
|
||||||
// a readonly environment
|
|
||||||
return Ok(IndexMap::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
trace!("config file = {}", filename.display());
|
|
||||||
|
|
||||||
let tag = tag.into();
|
|
||||||
let contents = fs::read_to_string(filename)
|
|
||||||
.map(|v| v.tagged(&tag))
|
|
||||||
.map_err(|err| {
|
|
||||||
ShellError::labeled_error(
|
|
||||||
&format!("Couldn't read config file:\n{}", err),
|
|
||||||
"file name",
|
|
||||||
&tag,
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let parsed: toml::Value = toml::from_str(&contents).map_err(|err| {
|
|
||||||
ShellError::labeled_error(
|
|
||||||
&format!("Couldn't parse config file:\n{}", err),
|
|
||||||
"file name",
|
|
||||||
&tag,
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let value = convert_toml_value_to_nu_value(&parsed, tag);
|
|
||||||
let tag = value.tag();
|
|
||||||
match value.value {
|
|
||||||
UntaggedValue::Row(Dictionary { entries }) => Ok(entries),
|
|
||||||
other => Err(ShellError::type_error(
|
|
||||||
"Dictionary",
|
|
||||||
other.type_name().spanned(tag.span),
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn config(tag: impl Into<Tag>) -> Result<IndexMap<String, Value>, ShellError> {
|
|
||||||
read(tag, &None)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write(config: &IndexMap<String, Value>, at: &Option<PathBuf>) -> Result<(), ShellError> {
|
|
||||||
let filename = &mut default_path()?;
|
|
||||||
let filename = match at {
|
|
||||||
None => filename,
|
|
||||||
Some(file) => {
|
|
||||||
filename.pop();
|
|
||||||
filename.push(file);
|
|
||||||
filename
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let contents = value_to_toml_value(
|
|
||||||
&UntaggedValue::Row(Dictionary::new(config.clone())).into_untagged_value(),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let contents = toml::to_string(&contents)?;
|
|
||||||
|
|
||||||
fs::write(&filename, &contents)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// A simple implementation of `% touch path` (ignores existing files)
|
|
||||||
fn touch(path: &Path) -> io::Result<()> {
|
|
||||||
match OpenOptions::new().create(true).write(true).open(path) {
|
|
||||||
Ok(_) => Ok(()),
|
|
||||||
Err(e) => Err(e),
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,199 +0,0 @@
|
||||||
use crate::commands::du::{DirBuilder, DirInfo};
|
|
||||||
use crate::prelude::*;
|
|
||||||
use nu_errors::ShellError;
|
|
||||||
use nu_protocol::{TaggedDictBuilder, UntaggedValue, Value};
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
use std::os::unix::fs::FileTypeExt;
|
|
||||||
|
|
||||||
pub(crate) fn get_file_type(md: &std::fs::Metadata) -> &str {
|
|
||||||
let ft = md.file_type();
|
|
||||||
let mut file_type = "Unknown";
|
|
||||||
if ft.is_dir() {
|
|
||||||
file_type = "Dir";
|
|
||||||
} else if ft.is_file() {
|
|
||||||
file_type = "File";
|
|
||||||
} else if ft.is_symlink() {
|
|
||||||
file_type = "Symlink";
|
|
||||||
} else {
|
|
||||||
#[cfg(unix)]
|
|
||||||
{
|
|
||||||
if ft.is_block_device() {
|
|
||||||
file_type = "Block device";
|
|
||||||
} else if ft.is_char_device() {
|
|
||||||
file_type = "Char device";
|
|
||||||
} else if ft.is_fifo() {
|
|
||||||
file_type = "Pipe";
|
|
||||||
} else if ft.is_socket() {
|
|
||||||
file_type = "Socket";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_type
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
|
||||||
pub(crate) fn dir_entry_dict(
|
|
||||||
filename: &std::path::Path,
|
|
||||||
metadata: Option<&std::fs::Metadata>,
|
|
||||||
tag: impl Into<Tag>,
|
|
||||||
long: bool,
|
|
||||||
short_name: bool,
|
|
||||||
du: bool,
|
|
||||||
ctrl_c: Arc<AtomicBool>,
|
|
||||||
) -> Result<Value, ShellError> {
|
|
||||||
let tag = tag.into();
|
|
||||||
let mut dict = TaggedDictBuilder::new(&tag);
|
|
||||||
// Insert all columns first to maintain proper table alignment if we can't find (or are not allowed to view) any information
|
|
||||||
if long {
|
|
||||||
#[cfg(windows)]
|
|
||||||
{
|
|
||||||
for column in [
|
|
||||||
"name", "type", "target", "readonly", "size", "created", "accessed", "modified",
|
|
||||||
]
|
|
||||||
.iter()
|
|
||||||
{
|
|
||||||
dict.insert_untagged(*column, UntaggedValue::nothing());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
{
|
|
||||||
for column in [
|
|
||||||
"name", "type", "target", "readonly", "mode", "uid", "group", "size", "created",
|
|
||||||
"accessed", "modified",
|
|
||||||
]
|
|
||||||
.iter()
|
|
||||||
{
|
|
||||||
dict.insert_untagged(&(*column.to_owned()), UntaggedValue::nothing());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for column in ["name", "type", "target", "size", "modified"].iter() {
|
|
||||||
if *column == "target" {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
dict.insert_untagged(*column, UntaggedValue::nothing());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let name = if short_name {
|
|
||||||
filename.file_name().and_then(|s| s.to_str())
|
|
||||||
} else {
|
|
||||||
filename.to_str()
|
|
||||||
}
|
|
||||||
.ok_or_else(|| {
|
|
||||||
ShellError::labeled_error(
|
|
||||||
format!("Invalid file name: {:}", filename.to_string_lossy()),
|
|
||||||
"invalid file name",
|
|
||||||
tag,
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
dict.insert_untagged("name", UntaggedValue::string(name));
|
|
||||||
|
|
||||||
if let Some(md) = metadata {
|
|
||||||
dict.insert_untagged("type", get_file_type(md));
|
|
||||||
}
|
|
||||||
|
|
||||||
if long {
|
|
||||||
if let Some(md) = metadata {
|
|
||||||
if md.file_type().is_symlink() {
|
|
||||||
let symlink_target_untagged_value: UntaggedValue;
|
|
||||||
if let Ok(path_to_link) = filename.read_link() {
|
|
||||||
symlink_target_untagged_value =
|
|
||||||
UntaggedValue::string(path_to_link.to_string_lossy());
|
|
||||||
} else {
|
|
||||||
symlink_target_untagged_value =
|
|
||||||
UntaggedValue::string("Could not obtain target file's path");
|
|
||||||
}
|
|
||||||
dict.insert_untagged("target", symlink_target_untagged_value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if long {
|
|
||||||
if let Some(md) = metadata {
|
|
||||||
dict.insert_untagged(
|
|
||||||
"readonly",
|
|
||||||
UntaggedValue::boolean(md.permissions().readonly()),
|
|
||||||
);
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
{
|
|
||||||
use std::os::unix::fs::MetadataExt;
|
|
||||||
use std::os::unix::fs::PermissionsExt;
|
|
||||||
let mode = md.permissions().mode();
|
|
||||||
dict.insert_untagged(
|
|
||||||
"mode",
|
|
||||||
UntaggedValue::string(umask::Mode::from(mode).to_string()),
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(user) = users::get_user_by_uid(md.uid()) {
|
|
||||||
dict.insert_untagged(
|
|
||||||
"uid",
|
|
||||||
UntaggedValue::string(user.name().to_string_lossy()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(group) = users::get_group_by_gid(md.gid()) {
|
|
||||||
dict.insert_untagged(
|
|
||||||
"group",
|
|
||||||
UntaggedValue::string(group.name().to_string_lossy()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(md) = metadata {
|
|
||||||
let mut size_untagged_value: UntaggedValue = UntaggedValue::nothing();
|
|
||||||
|
|
||||||
if md.is_dir() {
|
|
||||||
let dir_size: u64 = if du {
|
|
||||||
let params = DirBuilder::new(
|
|
||||||
Tag {
|
|
||||||
anchor: None,
|
|
||||||
span: Span::new(0, 2),
|
|
||||||
},
|
|
||||||
None,
|
|
||||||
false,
|
|
||||||
None,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
DirInfo::new(filename, ¶ms, None, ctrl_c).get_size()
|
|
||||||
} else {
|
|
||||||
md.len()
|
|
||||||
};
|
|
||||||
|
|
||||||
size_untagged_value = UntaggedValue::filesize(dir_size);
|
|
||||||
} else if md.is_file() {
|
|
||||||
size_untagged_value = UntaggedValue::filesize(md.len());
|
|
||||||
} else if md.file_type().is_symlink() {
|
|
||||||
if let Ok(symlink_md) = filename.symlink_metadata() {
|
|
||||||
size_untagged_value = UntaggedValue::filesize(symlink_md.len() as u64);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dict.insert_untagged("size", size_untagged_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(md) = metadata {
|
|
||||||
if long {
|
|
||||||
if let Ok(c) = md.created() {
|
|
||||||
dict.insert_untagged("created", UntaggedValue::system_date(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(a) = md.accessed() {
|
|
||||||
dict.insert_untagged("accessed", UntaggedValue::system_date(a));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(m) = md.modified() {
|
|
||||||
dict.insert_untagged("modified", UntaggedValue::system_date(m));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(dict.into_value())
|
|
||||||
}
|
|
4
crates/nu-cli/src/env/environment.rs
vendored
4
crates/nu-cli/src/env/environment.rs
vendored
|
@ -1,6 +1,6 @@
|
||||||
use crate::data::config::Conf;
|
|
||||||
use crate::env::directory_specific_environment::*;
|
use crate::env::directory_specific_environment::*;
|
||||||
use indexmap::{indexmap, IndexSet};
|
use indexmap::{indexmap, IndexSet};
|
||||||
|
use nu_data::config::Conf;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{UntaggedValue, Value};
|
use nu_protocol::{UntaggedValue, Value};
|
||||||
use std::env::*;
|
use std::env::*;
|
||||||
|
@ -154,7 +154,7 @@ impl Env for Environment {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{Env, Environment};
|
use super::{Env, Environment};
|
||||||
use crate::data::config::{tests::FakeConfig, Conf};
|
use nu_data::config::{tests::FakeConfig, Conf};
|
||||||
use nu_protocol::UntaggedValue;
|
use nu_protocol::UntaggedValue;
|
||||||
use nu_test_support::fs::Stub::FileWithContent;
|
use nu_test_support::fs::Stub::FileWithContent;
|
||||||
use nu_test_support::playground::Playground;
|
use nu_test_support::playground::Playground;
|
||||||
|
|
4
crates/nu-cli/src/env/environment_syncer.rs
vendored
4
crates/nu-cli/src/env/environment_syncer.rs
vendored
|
@ -1,5 +1,5 @@
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::data::config::{Conf, NuConfig};
|
use nu_data::config::{Conf, NuConfig};
|
||||||
|
|
||||||
use crate::env::environment::{Env, Environment};
|
use crate::env::environment::{Env, Environment};
|
||||||
use nu_source::Text;
|
use nu_source::Text;
|
||||||
|
@ -128,9 +128,9 @@ impl EnvironmentSyncer {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::EnvironmentSyncer;
|
use super::EnvironmentSyncer;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::data::config::tests::FakeConfig;
|
|
||||||
use crate::env::environment::Env;
|
use crate::env::environment::Env;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
use nu_data::config::tests::FakeConfig;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_test_support::fs::Stub::FileWithContent;
|
use nu_test_support::fs::Stub::FileWithContent;
|
||||||
use nu_test_support::playground::Playground;
|
use nu_test_support::playground::Playground;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::data::value;
|
use nu_data::value;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::hir::Operator;
|
use nu_protocol::hir::Operator;
|
||||||
use nu_protocol::{Primitive, ShellTypeName, UntaggedValue, Value};
|
use nu_protocol::{Primitive, ShellTypeName, UntaggedValue, Value};
|
||||||
|
|
|
@ -17,7 +17,7 @@ pub fn nu(env: &IndexMap<String, String>, tag: impl Into<Tag>) -> Result<Value,
|
||||||
}
|
}
|
||||||
nu_dict.insert_value("env", dict.into_value());
|
nu_dict.insert_value("env", dict.into_value());
|
||||||
|
|
||||||
let config = crate::data::config::read(&tag, &None)?;
|
let config = nu_data::config::read(&tag, &None)?;
|
||||||
nu_dict.insert_value("config", UntaggedValue::row(config).into_value(&tag));
|
nu_dict.insert_value("config", UntaggedValue::row(config).into_value(&tag));
|
||||||
|
|
||||||
let mut table = vec![];
|
let mut table = vec![];
|
||||||
|
@ -39,7 +39,7 @@ pub fn nu(env: &IndexMap<String, String>, tag: impl Into<Tag>) -> Result<Value,
|
||||||
let temp = std::env::temp_dir();
|
let temp = std::env::temp_dir();
|
||||||
nu_dict.insert_value("temp-dir", UntaggedValue::path(temp).into_value(&tag));
|
nu_dict.insert_value("temp-dir", UntaggedValue::path(temp).into_value(&tag));
|
||||||
|
|
||||||
let config = crate::data::config::default_path()?;
|
let config = nu_data::config::default_path()?;
|
||||||
nu_dict.insert_value("config-path", UntaggedValue::path(config).into_value(&tag));
|
nu_dict.insert_value("config-path", UntaggedValue::path(config).into_value(&tag));
|
||||||
|
|
||||||
let keybinding_path = crate::keybinding::keybinding_path()?;
|
let keybinding_path = crate::keybinding::keybinding_path()?;
|
||||||
|
|
|
@ -406,7 +406,7 @@ pub struct Keybinding {
|
||||||
type Keybindings = Vec<Keybinding>;
|
type Keybindings = Vec<Keybinding>;
|
||||||
|
|
||||||
pub(crate) fn keybinding_path() -> Result<std::path::PathBuf, nu_errors::ShellError> {
|
pub(crate) fn keybinding_path() -> Result<std::path::PathBuf, nu_errors::ShellError> {
|
||||||
crate::data::config::default_path_for(&Some(std::path::PathBuf::from("keybindings.yml")))
|
nu_data::config::default_path_for(&Some(std::path::PathBuf::from("keybindings.yml")))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn load_keybindings(
|
pub(crate) fn load_keybindings(
|
||||||
|
|
|
@ -17,7 +17,6 @@ mod cli;
|
||||||
mod commands;
|
mod commands;
|
||||||
mod completion;
|
mod completion;
|
||||||
mod context;
|
mod context;
|
||||||
pub mod data;
|
|
||||||
mod deserializer;
|
mod deserializer;
|
||||||
mod documentation;
|
mod documentation;
|
||||||
mod env;
|
mod env;
|
||||||
|
@ -43,14 +42,14 @@ pub use crate::commands::command::{
|
||||||
};
|
};
|
||||||
pub use crate::commands::help::get_help;
|
pub use crate::commands::help::get_help;
|
||||||
pub use crate::context::{CommandRegistry, Context};
|
pub use crate::context::{CommandRegistry, Context};
|
||||||
pub use crate::data::config;
|
|
||||||
pub use crate::data::dict::TaggedListBuilder;
|
|
||||||
pub use crate::data::primitive;
|
|
||||||
pub use crate::data::value;
|
|
||||||
pub use crate::env::environment_syncer::EnvironmentSyncer;
|
pub use crate::env::environment_syncer::EnvironmentSyncer;
|
||||||
pub use crate::env::host::BasicHost;
|
pub use crate::env::host::BasicHost;
|
||||||
pub use crate::prelude::ToOutputStream;
|
pub use crate::prelude::ToOutputStream;
|
||||||
pub use crate::stream::{InputStream, InterruptibleStream, OutputStream};
|
pub use crate::stream::{InputStream, InterruptibleStream, OutputStream};
|
||||||
|
pub use nu_data::config;
|
||||||
|
pub use nu_data::dict::TaggedListBuilder;
|
||||||
|
pub use nu_data::primitive;
|
||||||
|
pub use nu_data::value;
|
||||||
pub use nu_value_ext::ValueExt;
|
pub use nu_value_ext::ValueExt;
|
||||||
pub use num_traits::cast::ToPrimitive;
|
pub use num_traits::cast::ToPrimitive;
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,8 @@ pub(crate) use crate::commands::command::{CommandArgs, RawCommandArgs, RunnableC
|
||||||
pub(crate) use crate::commands::Example;
|
pub(crate) use crate::commands::Example;
|
||||||
pub(crate) use crate::context::CommandRegistry;
|
pub(crate) use crate::context::CommandRegistry;
|
||||||
pub(crate) use crate::context::Context;
|
pub(crate) use crate::context::Context;
|
||||||
pub(crate) use crate::data::config;
|
pub(crate) use nu_data::config;
|
||||||
pub(crate) use crate::data::value;
|
pub(crate) use nu_data::value;
|
||||||
// pub(crate) use crate::env::host::handle_unexpected;
|
// pub(crate) use crate::env::host::handle_unexpected;
|
||||||
pub(crate) use crate::env::Host;
|
pub(crate) use crate::env::Host;
|
||||||
pub(crate) use crate::shell::filesystem_shell::FilesystemShell;
|
pub(crate) use crate::shell::filesystem_shell::FilesystemShell;
|
||||||
|
@ -87,7 +87,6 @@ pub(crate) use crate::stream::{InputStream, InterruptibleStream, OutputStream};
|
||||||
pub(crate) use bigdecimal::BigDecimal;
|
pub(crate) use bigdecimal::BigDecimal;
|
||||||
pub(crate) use futures::stream::BoxStream;
|
pub(crate) use futures::stream::BoxStream;
|
||||||
pub(crate) use futures::{Stream, StreamExt};
|
pub(crate) use futures::{Stream, StreamExt};
|
||||||
pub(crate) use nu_protocol::MaybeOwned;
|
|
||||||
pub(crate) use nu_source::{
|
pub(crate) use nu_source::{
|
||||||
b, AnchorLocation, DebugDocBuilder, PrettyDebug, PrettyDebugWithSource, Span, SpannedItem, Tag,
|
b, AnchorLocation, DebugDocBuilder, PrettyDebug, PrettyDebugWithSource, Span, SpannedItem, Tag,
|
||||||
TaggedItem, Text,
|
TaggedItem, Text,
|
||||||
|
|
|
@ -13,8 +13,8 @@ use ichwh::{IchwhError, IchwhResult};
|
||||||
|
|
||||||
use crate::completion::{self, Completer};
|
use crate::completion::{self, Completer};
|
||||||
use crate::context;
|
use crate::context;
|
||||||
use crate::data::config;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use nu_data::config;
|
||||||
|
|
||||||
pub(crate) struct NuCompleter {
|
pub(crate) struct NuCompleter {
|
||||||
file_completer: FilenameCompleter,
|
file_completer: FilenameCompleter,
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
use crate::commands::cd::CdArgs;
|
use crate::commands::cd::CdArgs;
|
||||||
use crate::commands::command::EvaluatedWholeStreamCommandArgs;
|
use crate::commands::command::EvaluatedWholeStreamCommandArgs;
|
||||||
use crate::commands::cp::CopyArgs;
|
use crate::commands::cp::CopyArgs;
|
||||||
|
use crate::commands::du::{DirBuilder, DirInfo};
|
||||||
use crate::commands::ls::LsArgs;
|
use crate::commands::ls::LsArgs;
|
||||||
use crate::commands::mkdir::MkdirArgs;
|
use crate::commands::mkdir::MkdirArgs;
|
||||||
use crate::commands::move_::mv::Arguments as MvArgs;
|
use crate::commands::move_::mv::Arguments as MvArgs;
|
||||||
use crate::commands::rm::RemoveArgs;
|
use crate::commands::rm::RemoveArgs;
|
||||||
use crate::data::dir_entry_dict;
|
|
||||||
use crate::path::canonicalize;
|
use crate::path::canonicalize;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::shell::shell::Shell;
|
use crate::shell::shell::Shell;
|
||||||
use crate::utils::FileStructure;
|
use crate::utils::FileStructure;
|
||||||
|
use nu_protocol::{TaggedDictBuilder, Value};
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::{Error, ErrorKind};
|
use std::io::{Error, ErrorKind};
|
||||||
|
@ -790,3 +791,197 @@ fn is_hidden_dir(dir: impl AsRef<Path>) -> bool {
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
use std::os::unix::fs::FileTypeExt;
|
||||||
|
|
||||||
|
pub(crate) fn get_file_type(md: &std::fs::Metadata) -> &str {
|
||||||
|
let ft = md.file_type();
|
||||||
|
let mut file_type = "Unknown";
|
||||||
|
if ft.is_dir() {
|
||||||
|
file_type = "Dir";
|
||||||
|
} else if ft.is_file() {
|
||||||
|
file_type = "File";
|
||||||
|
} else if ft.is_symlink() {
|
||||||
|
file_type = "Symlink";
|
||||||
|
} else {
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
if ft.is_block_device() {
|
||||||
|
file_type = "Block device";
|
||||||
|
} else if ft.is_char_device() {
|
||||||
|
file_type = "Char device";
|
||||||
|
} else if ft.is_fifo() {
|
||||||
|
file_type = "Pipe";
|
||||||
|
} else if ft.is_socket() {
|
||||||
|
file_type = "Socket";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_type
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub(crate) fn dir_entry_dict(
|
||||||
|
filename: &std::path::Path,
|
||||||
|
metadata: Option<&std::fs::Metadata>,
|
||||||
|
tag: impl Into<Tag>,
|
||||||
|
long: bool,
|
||||||
|
short_name: bool,
|
||||||
|
du: bool,
|
||||||
|
ctrl_c: Arc<AtomicBool>,
|
||||||
|
) -> Result<Value, ShellError> {
|
||||||
|
let tag = tag.into();
|
||||||
|
let mut dict = TaggedDictBuilder::new(&tag);
|
||||||
|
// Insert all columns first to maintain proper table alignment if we can't find (or are not allowed to view) any information
|
||||||
|
if long {
|
||||||
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
for column in [
|
||||||
|
"name", "type", "target", "readonly", "size", "created", "accessed", "modified",
|
||||||
|
]
|
||||||
|
.iter()
|
||||||
|
{
|
||||||
|
dict.insert_untagged(*column, UntaggedValue::nothing());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
for column in [
|
||||||
|
"name", "type", "target", "readonly", "mode", "uid", "group", "size", "created",
|
||||||
|
"accessed", "modified",
|
||||||
|
]
|
||||||
|
.iter()
|
||||||
|
{
|
||||||
|
dict.insert_untagged(&(*column.to_owned()), UntaggedValue::nothing());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for column in ["name", "type", "target", "size", "modified"].iter() {
|
||||||
|
if *column == "target" {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dict.insert_untagged(*column, UntaggedValue::nothing());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let name = if short_name {
|
||||||
|
filename.file_name().and_then(|s| s.to_str())
|
||||||
|
} else {
|
||||||
|
filename.to_str()
|
||||||
|
}
|
||||||
|
.ok_or_else(|| {
|
||||||
|
ShellError::labeled_error(
|
||||||
|
format!("Invalid file name: {:}", filename.to_string_lossy()),
|
||||||
|
"invalid file name",
|
||||||
|
tag,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
dict.insert_untagged("name", UntaggedValue::string(name));
|
||||||
|
|
||||||
|
if let Some(md) = metadata {
|
||||||
|
dict.insert_untagged("type", get_file_type(md));
|
||||||
|
}
|
||||||
|
|
||||||
|
if long {
|
||||||
|
if let Some(md) = metadata {
|
||||||
|
if md.file_type().is_symlink() {
|
||||||
|
let symlink_target_untagged_value: UntaggedValue;
|
||||||
|
if let Ok(path_to_link) = filename.read_link() {
|
||||||
|
symlink_target_untagged_value =
|
||||||
|
UntaggedValue::string(path_to_link.to_string_lossy());
|
||||||
|
} else {
|
||||||
|
symlink_target_untagged_value =
|
||||||
|
UntaggedValue::string("Could not obtain target file's path");
|
||||||
|
}
|
||||||
|
dict.insert_untagged("target", symlink_target_untagged_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if long {
|
||||||
|
if let Some(md) = metadata {
|
||||||
|
dict.insert_untagged(
|
||||||
|
"readonly",
|
||||||
|
UntaggedValue::boolean(md.permissions().readonly()),
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
use std::os::unix::fs::MetadataExt;
|
||||||
|
let mode = md.permissions().mode();
|
||||||
|
dict.insert_untagged(
|
||||||
|
"mode",
|
||||||
|
UntaggedValue::string(umask::Mode::from(mode).to_string()),
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(user) = users::get_user_by_uid(md.uid()) {
|
||||||
|
dict.insert_untagged(
|
||||||
|
"uid",
|
||||||
|
UntaggedValue::string(user.name().to_string_lossy()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(group) = users::get_group_by_gid(md.gid()) {
|
||||||
|
dict.insert_untagged(
|
||||||
|
"group",
|
||||||
|
UntaggedValue::string(group.name().to_string_lossy()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(md) = metadata {
|
||||||
|
let mut size_untagged_value: UntaggedValue = UntaggedValue::nothing();
|
||||||
|
|
||||||
|
if md.is_dir() {
|
||||||
|
let dir_size: u64 = if du {
|
||||||
|
let params = DirBuilder::new(
|
||||||
|
Tag {
|
||||||
|
anchor: None,
|
||||||
|
span: Span::new(0, 2),
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
DirInfo::new(filename, ¶ms, None, ctrl_c).get_size()
|
||||||
|
} else {
|
||||||
|
md.len()
|
||||||
|
};
|
||||||
|
|
||||||
|
size_untagged_value = UntaggedValue::filesize(dir_size);
|
||||||
|
} else if md.is_file() {
|
||||||
|
size_untagged_value = UntaggedValue::filesize(md.len());
|
||||||
|
} else if md.file_type().is_symlink() {
|
||||||
|
if let Ok(symlink_md) = filename.symlink_metadata() {
|
||||||
|
size_untagged_value = UntaggedValue::filesize(symlink_md.len() as u64);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dict.insert_untagged("size", size_untagged_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(md) = metadata {
|
||||||
|
if long {
|
||||||
|
if let Ok(c) = md.created() {
|
||||||
|
dict.insert_untagged("created", UntaggedValue::system_date(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(a) = md.accessed() {
|
||||||
|
dict.insert_untagged("accessed", UntaggedValue::system_date(a));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(m) = md.modified() {
|
||||||
|
dict.insert_untagged("modified", UntaggedValue::system_date(m));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(dict.into_value())
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use crate::commands::cd::CdArgs;
|
use crate::commands::cd::CdArgs;
|
||||||
use crate::commands::command::EvaluatedWholeStreamCommandArgs;
|
use crate::commands::command::EvaluatedWholeStreamCommandArgs;
|
||||||
use crate::commands::cp::CopyArgs;
|
use crate::commands::cp::CopyArgs;
|
||||||
|
use crate::commands::help::command_dict;
|
||||||
use crate::commands::ls::LsArgs;
|
use crate::commands::ls::LsArgs;
|
||||||
use crate::commands::mkdir::MkdirArgs;
|
use crate::commands::mkdir::MkdirArgs;
|
||||||
use crate::commands::move_::mv::Arguments as MvArgs;
|
use crate::commands::move_::mv::Arguments as MvArgs;
|
||||||
use crate::commands::rm::RemoveArgs;
|
use crate::commands::rm::RemoveArgs;
|
||||||
use crate::completion;
|
use crate::completion;
|
||||||
use crate::data::command_dict;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::shell::shell::Shell;
|
use crate::shell::shell::Shell;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
pub mod data;
|
|
||||||
pub mod test_bins;
|
pub mod test_bins;
|
||||||
|
|
||||||
use crate::path::canonicalize;
|
use crate::path::canonicalize;
|
||||||
|
|
40
crates/nu-data/Cargo.toml
Normal file
40
crates/nu-data/Cargo.toml
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
[package]
|
||||||
|
authors = ["The Nu Project Contributors"]
|
||||||
|
description = "CLI for nushell"
|
||||||
|
edition = "2018"
|
||||||
|
license = "MIT"
|
||||||
|
name = "nu-data"
|
||||||
|
version = "0.18.2"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
doctest = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
ansi_term = "0.12.1"
|
||||||
|
bigdecimal = "0.1.2"
|
||||||
|
byte-unit = "3.1.3"
|
||||||
|
|
||||||
|
chrono = "0.4.15"
|
||||||
|
derive-new = "0.5.8"
|
||||||
|
directories = {version = "2.0.2", optional = true}
|
||||||
|
dirs = {version = "2.0.2", optional = true}
|
||||||
|
getset = "0.1.1"
|
||||||
|
indexmap = {version = "1.4.0", features = ["serde-1"]}
|
||||||
|
log = "0.4.8"
|
||||||
|
num-bigint = {version = "0.2.6", features = ["serde"]}
|
||||||
|
num-format = {version = "0.4", features = ["with-num-bigint"]}
|
||||||
|
num-traits = "0.2.11"
|
||||||
|
parking_lot = "0.11.0"
|
||||||
|
query_interface = "0.3.5"
|
||||||
|
serde = {version = "1.0.114", features = ["derive"]}
|
||||||
|
toml = "0.5.6"
|
||||||
|
umask = "1.0.0"
|
||||||
|
|
||||||
|
nu-errors = {version = "0.18.2", path = "../nu-errors"}
|
||||||
|
nu-protocol = {version = "0.18.2", path = "../nu-protocol"}
|
||||||
|
nu-source = {version = "0.18.2", path = "../nu-source"}
|
||||||
|
nu-table = {version = "0.18.2", path = "../nu-table"}
|
||||||
|
nu-value-ext = {version = "0.18.2", path = "../nu-value-ext"}
|
||||||
|
|
||||||
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
users = "0.10.0"
|
|
@ -49,7 +49,7 @@ impl std::convert::TryFrom<Option<&Value>> for Switch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn select_fields(obj: &Value, fields: &[String], tag: impl Into<Tag>) -> Value {
|
pub fn select_fields(obj: &Value, fields: &[String], tag: impl Into<Tag>) -> Value {
|
||||||
let mut out = TaggedDictBuilder::new(tag);
|
let mut out = TaggedDictBuilder::new(tag);
|
||||||
|
|
||||||
let descs = obj.data_descriptors();
|
let descs = obj.data_descriptors();
|
||||||
|
@ -64,7 +64,7 @@ pub(crate) fn select_fields(obj: &Value, fields: &[String], tag: impl Into<Tag>)
|
||||||
out.into_value()
|
out.into_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn reject_fields(obj: &Value, fields: &[String], tag: impl Into<Tag>) -> Value {
|
pub fn reject_fields(obj: &Value, fields: &[String], tag: impl Into<Tag>) -> Value {
|
||||||
let mut out = TaggedDictBuilder::new(tag);
|
let mut out = TaggedDictBuilder::new(tag);
|
||||||
|
|
||||||
let descs = obj.data_descriptors();
|
let descs = obj.data_descriptors();
|
||||||
|
@ -80,7 +80,7 @@ pub(crate) fn reject_fields(obj: &Value, fields: &[String], tag: impl Into<Tag>)
|
||||||
out.into_value()
|
out.into_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) enum CompareValues {
|
pub enum CompareValues {
|
||||||
Ints(BigInt, BigInt),
|
Ints(BigInt, BigInt),
|
||||||
Decimals(BigDecimal, BigDecimal),
|
Decimals(BigDecimal, BigDecimal),
|
||||||
String(String, String),
|
String(String, String),
|
||||||
|
@ -113,7 +113,7 @@ impl CompareValues {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn coerce_compare(
|
pub fn coerce_compare(
|
||||||
left: &UntaggedValue,
|
left: &UntaggedValue,
|
||||||
right: &UntaggedValue,
|
right: &UntaggedValue,
|
||||||
) -> Result<CompareValues, (&'static str, &'static str)> {
|
) -> Result<CompareValues, (&'static str, &'static str)> {
|
||||||
|
@ -165,7 +165,7 @@ fn coerce_compare_primitive(
|
||||||
}
|
}
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use indexmap::IndexMap;
|
use indexmap::{indexmap, IndexMap};
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ColumnPath as ColumnPathValue, PathMember, UntaggedValue, Value};
|
use nu_protocol::{ColumnPath as ColumnPathValue, PathMember, UntaggedValue, Value};
|
||||||
use nu_source::*;
|
use nu_source::*;
|
||||||
|
@ -173,19 +173,19 @@ mod tests {
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
|
|
||||||
fn string(input: impl Into<String>) -> Value {
|
fn string(input: impl Into<String>) -> Value {
|
||||||
crate::utils::data::helpers::string(input)
|
crate::utils::helpers::string(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn int(input: impl Into<BigInt>) -> Value {
|
fn int(input: impl Into<BigInt>) -> Value {
|
||||||
crate::utils::data::helpers::int(input)
|
crate::utils::helpers::int(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn row(entries: IndexMap<String, Value>) -> Value {
|
fn row(entries: IndexMap<String, Value>) -> Value {
|
||||||
crate::utils::data::helpers::row(entries)
|
crate::utils::helpers::row(entries)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn table(list: &[Value]) -> Value {
|
fn table(list: &[Value]) -> Value {
|
||||||
crate::utils::data::helpers::table(list)
|
crate::utils::helpers::table(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_callback(
|
fn error_callback(
|
|
@ -1,8 +1,9 @@
|
||||||
use crate::prelude::*;
|
use bigdecimal::BigDecimal;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use nu_protocol::RangeInclusion;
|
use nu_protocol::RangeInclusion;
|
||||||
use nu_protocol::{format_primitive, ColumnPath, Dictionary, Primitive, UntaggedValue, Value};
|
use nu_protocol::{format_primitive, ColumnPath, Dictionary, Primitive, UntaggedValue, Value};
|
||||||
use nu_source::{b, PrettyDebug};
|
use nu_source::{b, DebugDocBuilder, PrettyDebug};
|
||||||
|
use num_bigint::BigInt;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
|
@ -1,23 +1,8 @@
|
||||||
use crate::commands::command::Command;
|
use crate::TaggedListBuilder;
|
||||||
use crate::data::TaggedListBuilder;
|
use nu_source::Tag;
|
||||||
use crate::prelude::*;
|
|
||||||
use nu_protocol::{NamedType, PositionalType, Signature, TaggedDictBuilder, UntaggedValue, Value};
|
use nu_protocol::{NamedType, PositionalType, Signature, TaggedDictBuilder, UntaggedValue, Value};
|
||||||
|
|
||||||
pub(crate) fn command_dict(command: Command, tag: impl Into<Tag>) -> Value {
|
|
||||||
let tag = tag.into();
|
|
||||||
|
|
||||||
let mut cmd_dict = TaggedDictBuilder::new(&tag);
|
|
||||||
|
|
||||||
cmd_dict.insert_untagged("name", UntaggedValue::string(command.name()));
|
|
||||||
|
|
||||||
cmd_dict.insert_untagged("type", UntaggedValue::string("Command"));
|
|
||||||
|
|
||||||
cmd_dict.insert_value("signature", signature_dict(command.signature(), tag));
|
|
||||||
cmd_dict.insert_untagged("usage", UntaggedValue::string(command.usage()));
|
|
||||||
|
|
||||||
cmd_dict.into_value()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn for_spec(name: &str, ty: &str, required: bool, tag: impl Into<Tag>) -> Value {
|
fn for_spec(name: &str, ty: &str, required: bool, tag: impl Into<Tag>) -> Value {
|
||||||
let tag = tag.into();
|
let tag = tag.into();
|
||||||
|
|
||||||
|
@ -33,7 +18,7 @@ fn for_spec(name: &str, ty: &str, required: bool, tag: impl Into<Tag>) -> Value
|
||||||
spec.into_value()
|
spec.into_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signature_dict(signature: Signature, tag: impl Into<Tag>) -> Value {
|
pub fn signature_dict(signature: Signature, tag: impl Into<Tag>) -> Value {
|
||||||
let tag = tag.into();
|
let tag = tag.into();
|
||||||
let mut sig = TaggedListBuilder::new(&tag);
|
let mut sig = TaggedListBuilder::new(&tag);
|
||||||
|
|
289
crates/nu-data/src/config.rs
Normal file
289
crates/nu-data/src/config.rs
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
mod conf;
|
||||||
|
mod nuconfig;
|
||||||
|
pub mod table;
|
||||||
|
|
||||||
|
pub mod tests;
|
||||||
|
|
||||||
|
pub use conf::Conf;
|
||||||
|
pub use nuconfig::NuConfig;
|
||||||
|
|
||||||
|
use indexmap::IndexMap;
|
||||||
|
use log::trace;
|
||||||
|
use nu_errors::{CoerceInto, ShellError};
|
||||||
|
use nu_protocol::{
|
||||||
|
Dictionary, Primitive, ShellTypeName, TaggedDictBuilder, UnspannedPathMember, UntaggedValue,
|
||||||
|
Value,
|
||||||
|
};
|
||||||
|
use nu_source::{SpannedItem, Tag, TaggedItem};
|
||||||
|
use std::fs::{self, OpenOptions};
|
||||||
|
use std::io;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
pub fn convert_toml_value_to_nu_value(v: &toml::Value, tag: impl Into<Tag>) -> Value {
|
||||||
|
let tag = tag.into();
|
||||||
|
|
||||||
|
match v {
|
||||||
|
toml::Value::Boolean(b) => UntaggedValue::boolean(*b).into_value(tag),
|
||||||
|
toml::Value::Integer(n) => UntaggedValue::int(*n).into_value(tag),
|
||||||
|
toml::Value::Float(n) => UntaggedValue::decimal(*n).into_value(tag),
|
||||||
|
toml::Value::String(s) => {
|
||||||
|
UntaggedValue::Primitive(Primitive::String(String::from(s))).into_value(tag)
|
||||||
|
}
|
||||||
|
toml::Value::Array(a) => UntaggedValue::Table(
|
||||||
|
a.iter()
|
||||||
|
.map(|x| convert_toml_value_to_nu_value(x, &tag))
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
.into_value(tag),
|
||||||
|
toml::Value::Datetime(dt) => {
|
||||||
|
UntaggedValue::Primitive(Primitive::String(dt.to_string())).into_value(tag)
|
||||||
|
}
|
||||||
|
toml::Value::Table(t) => {
|
||||||
|
let mut collected = TaggedDictBuilder::new(&tag);
|
||||||
|
|
||||||
|
for (k, v) in t.iter() {
|
||||||
|
collected.insert_value(k.clone(), convert_toml_value_to_nu_value(v, &tag));
|
||||||
|
}
|
||||||
|
|
||||||
|
collected.into_value()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn collect_values(input: &[Value]) -> Result<Vec<toml::Value>, ShellError> {
|
||||||
|
let mut out = vec![];
|
||||||
|
|
||||||
|
for value in input {
|
||||||
|
out.push(helper(value)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(out)
|
||||||
|
}
|
||||||
|
// Helper method to recursively convert nu_protocol::Value -> toml::Value
|
||||||
|
// This shouldn't be called at the top-level
|
||||||
|
fn helper(v: &Value) -> Result<toml::Value, ShellError> {
|
||||||
|
Ok(match &v.value {
|
||||||
|
UntaggedValue::Primitive(Primitive::Boolean(b)) => toml::Value::Boolean(*b),
|
||||||
|
UntaggedValue::Primitive(Primitive::Filesize(b)) => toml::Value::Integer(*b as i64),
|
||||||
|
UntaggedValue::Primitive(Primitive::Duration(i)) => toml::Value::String(i.to_string()),
|
||||||
|
UntaggedValue::Primitive(Primitive::Date(d)) => toml::Value::String(d.to_string()),
|
||||||
|
UntaggedValue::Primitive(Primitive::EndOfStream) => {
|
||||||
|
toml::Value::String("<End of Stream>".to_string())
|
||||||
|
}
|
||||||
|
UntaggedValue::Primitive(Primitive::BeginningOfStream) => {
|
||||||
|
toml::Value::String("<Beginning of Stream>".to_string())
|
||||||
|
}
|
||||||
|
UntaggedValue::Primitive(Primitive::Decimal(f)) => {
|
||||||
|
toml::Value::Float(f.tagged(&v.tag).coerce_into("converting to TOML float")?)
|
||||||
|
}
|
||||||
|
UntaggedValue::Primitive(Primitive::Int(i)) => {
|
||||||
|
toml::Value::Integer(i.tagged(&v.tag).coerce_into("converting to TOML integer")?)
|
||||||
|
}
|
||||||
|
UntaggedValue::Primitive(Primitive::Nothing) => {
|
||||||
|
toml::Value::String("<Nothing>".to_string())
|
||||||
|
}
|
||||||
|
UntaggedValue::Primitive(Primitive::Pattern(s)) => toml::Value::String(s.clone()),
|
||||||
|
UntaggedValue::Primitive(Primitive::String(s)) => toml::Value::String(s.clone()),
|
||||||
|
UntaggedValue::Primitive(Primitive::Line(s)) => toml::Value::String(s.clone()),
|
||||||
|
UntaggedValue::Primitive(Primitive::Path(s)) => {
|
||||||
|
toml::Value::String(s.display().to_string())
|
||||||
|
}
|
||||||
|
UntaggedValue::Primitive(Primitive::ColumnPath(path)) => toml::Value::Array(
|
||||||
|
path.iter()
|
||||||
|
.map(|x| match &x.unspanned {
|
||||||
|
UnspannedPathMember::String(string) => Ok(toml::Value::String(string.clone())),
|
||||||
|
UnspannedPathMember::Int(int) => Ok(toml::Value::Integer(
|
||||||
|
int.tagged(&v.tag)
|
||||||
|
.coerce_into("converting to TOML integer")?,
|
||||||
|
)),
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<toml::Value>, ShellError>>()?,
|
||||||
|
),
|
||||||
|
UntaggedValue::Table(l) => toml::Value::Array(collect_values(l)?),
|
||||||
|
UntaggedValue::Error(e) => return Err(e.clone()),
|
||||||
|
UntaggedValue::Block(_) => toml::Value::String("<Block>".to_string()),
|
||||||
|
UntaggedValue::Primitive(Primitive::Range(_)) => toml::Value::String("<Range>".to_string()),
|
||||||
|
UntaggedValue::Primitive(Primitive::Binary(b)) => {
|
||||||
|
toml::Value::Array(b.iter().map(|x| toml::Value::Integer(*x as i64)).collect())
|
||||||
|
}
|
||||||
|
UntaggedValue::Row(o) => {
|
||||||
|
let mut m = toml::map::Map::new();
|
||||||
|
for (k, v) in o.entries.iter() {
|
||||||
|
m.insert(k.clone(), helper(v)?);
|
||||||
|
}
|
||||||
|
toml::Value::Table(m)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts a nu_protocol::Value into a toml::Value
|
||||||
|
/// Will return a Shell Error, if the Nu Value is not a valid top-level TOML Value
|
||||||
|
pub fn value_to_toml_value(v: &Value) -> Result<toml::Value, ShellError> {
|
||||||
|
match &v.value {
|
||||||
|
UntaggedValue::Row(o) => {
|
||||||
|
let mut m = toml::map::Map::new();
|
||||||
|
for (k, v) in o.entries.iter() {
|
||||||
|
m.insert(k.clone(), helper(v)?);
|
||||||
|
}
|
||||||
|
Ok(toml::Value::Table(m))
|
||||||
|
}
|
||||||
|
UntaggedValue::Primitive(Primitive::String(s)) => {
|
||||||
|
// Attempt to de-serialize the String
|
||||||
|
toml::de::from_str(s).map_err(|_| {
|
||||||
|
ShellError::labeled_error(
|
||||||
|
format!("{:?} unable to de-serialize string to TOML", s),
|
||||||
|
"invalid TOML",
|
||||||
|
v.tag(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => Err(ShellError::labeled_error(
|
||||||
|
format!("{:?} is not a valid top-level TOML", v.value),
|
||||||
|
"invalid TOML",
|
||||||
|
v.tag(),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "directories")]
|
||||||
|
pub fn config_path() -> Result<PathBuf, ShellError> {
|
||||||
|
use directories::ProjectDirs;
|
||||||
|
|
||||||
|
let dir = ProjectDirs::from("org", "nushell", "nu")
|
||||||
|
.ok_or_else(|| ShellError::untagged_runtime_error("Couldn't find project directory"))?;
|
||||||
|
let path = ProjectDirs::config_dir(&dir).to_owned();
|
||||||
|
std::fs::create_dir_all(&path).map_err(|err| {
|
||||||
|
ShellError::untagged_runtime_error(&format!("Couldn't create {} path:\n{}", "config", err))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "directories"))]
|
||||||
|
pub fn config_path() -> Result<PathBuf, ShellError> {
|
||||||
|
// FIXME: unsure if this should be error or a simple default
|
||||||
|
|
||||||
|
Ok(std::path::PathBuf::from("/"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_path() -> Result<PathBuf, ShellError> {
|
||||||
|
default_path_for(&None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_path_for(file: &Option<PathBuf>) -> Result<PathBuf, ShellError> {
|
||||||
|
let mut filename = config_path()?;
|
||||||
|
let file: &Path = file
|
||||||
|
.as_ref()
|
||||||
|
.map(AsRef::as_ref)
|
||||||
|
.unwrap_or_else(|| "config.toml".as_ref());
|
||||||
|
filename.push(file);
|
||||||
|
|
||||||
|
Ok(filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "directories")]
|
||||||
|
pub fn user_data() -> Result<PathBuf, ShellError> {
|
||||||
|
use directories::ProjectDirs;
|
||||||
|
|
||||||
|
let dir = ProjectDirs::from("org", "nushell", "nu")
|
||||||
|
.ok_or_else(|| ShellError::untagged_runtime_error("Couldn't find project directory"))?;
|
||||||
|
let path = ProjectDirs::data_local_dir(&dir).to_owned();
|
||||||
|
std::fs::create_dir_all(&path).map_err(|err| {
|
||||||
|
ShellError::untagged_runtime_error(&format!(
|
||||||
|
"Couldn't create {} path:\n{}",
|
||||||
|
"user data", err
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "directories"))]
|
||||||
|
pub fn user_data() -> Result<PathBuf, ShellError> {
|
||||||
|
// FIXME: unsure if this should be error or a simple default
|
||||||
|
|
||||||
|
Ok(std::path::PathBuf::from("/"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read(
|
||||||
|
tag: impl Into<Tag>,
|
||||||
|
at: &Option<PathBuf>,
|
||||||
|
) -> Result<IndexMap<String, Value>, ShellError> {
|
||||||
|
let filename = default_path()?;
|
||||||
|
|
||||||
|
let filename = match at {
|
||||||
|
None => filename,
|
||||||
|
Some(ref file) => file.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if !filename.exists() && touch(&filename).is_err() {
|
||||||
|
// If we can't create configs, let's just return an empty indexmap instead as we may be in
|
||||||
|
// a readonly environment
|
||||||
|
return Ok(IndexMap::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
trace!("config file = {}", filename.display());
|
||||||
|
|
||||||
|
let tag = tag.into();
|
||||||
|
let contents = fs::read_to_string(filename)
|
||||||
|
.map(|v| v.tagged(&tag))
|
||||||
|
.map_err(|err| {
|
||||||
|
ShellError::labeled_error(
|
||||||
|
&format!("Couldn't read config file:\n{}", err),
|
||||||
|
"file name",
|
||||||
|
&tag,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let parsed: toml::Value = toml::from_str(&contents).map_err(|err| {
|
||||||
|
ShellError::labeled_error(
|
||||||
|
&format!("Couldn't parse config file:\n{}", err),
|
||||||
|
"file name",
|
||||||
|
&tag,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let value = convert_toml_value_to_nu_value(&parsed, tag);
|
||||||
|
let tag = value.tag();
|
||||||
|
match value.value {
|
||||||
|
UntaggedValue::Row(Dictionary { entries }) => Ok(entries),
|
||||||
|
other => Err(ShellError::type_error(
|
||||||
|
"Dictionary",
|
||||||
|
other.type_name().spanned(tag.span),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn config(tag: impl Into<Tag>) -> Result<IndexMap<String, Value>, ShellError> {
|
||||||
|
read(tag, &None)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write(config: &IndexMap<String, Value>, at: &Option<PathBuf>) -> Result<(), ShellError> {
|
||||||
|
let filename = &mut default_path()?;
|
||||||
|
let filename = match at {
|
||||||
|
None => filename,
|
||||||
|
Some(file) => {
|
||||||
|
filename.pop();
|
||||||
|
filename.push(file);
|
||||||
|
filename
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let contents = value_to_toml_value(
|
||||||
|
&UntaggedValue::Row(Dictionary::new(config.clone())).into_untagged_value(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let contents = toml::to_string(&contents)?;
|
||||||
|
|
||||||
|
fs::write(&filename, &contents)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// A simple implementation of `% touch path` (ignores existing files)
|
||||||
|
fn touch(path: &Path) -> io::Result<()> {
|
||||||
|
match OpenOptions::new().create(true).write(true).open(path) {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::data::config::{read, Conf};
|
use crate::config::{read, Conf};
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use nu_protocol::Value;
|
use nu_protocol::Value;
|
||||||
use nu_source::Tag;
|
use nu_source::Tag;
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::data::config::nuconfig::NuConfig;
|
use crate::config::nuconfig::NuConfig;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::data::config::{read, Conf, NuConfig};
|
use crate::config::{read, Conf, NuConfig};
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use nu_protocol::Value;
|
use nu_protocol::Value;
|
||||||
use nu_source::Tag;
|
use nu_source::Tag;
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::prelude::*;
|
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use nu_protocol::{Dictionary, Primitive, UntaggedValue, Value};
|
use nu_protocol::{Dictionary, MaybeOwned, Primitive, UntaggedValue, Value};
|
||||||
use nu_source::{b, PrettyDebug, Spanned};
|
use nu_source::{b, DebugDocBuilder, PrettyDebug, Spanned, Tag};
|
||||||
|
|
||||||
#[derive(Debug, new)]
|
#[derive(Debug, new)]
|
||||||
struct DebugEntry<'a> {
|
struct DebugEntry<'a> {
|
10
crates/nu-data/src/lib.rs
Normal file
10
crates/nu-data/src/lib.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
pub mod base;
|
||||||
|
pub mod command;
|
||||||
|
pub mod config;
|
||||||
|
pub mod dict;
|
||||||
|
pub mod primitive;
|
||||||
|
pub mod types;
|
||||||
|
pub mod utils;
|
||||||
|
pub mod value;
|
||||||
|
|
||||||
|
pub use dict::TaggedListBuilder;
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::data::{TaggedDictBuilder, Value};
|
use nu_data::{TaggedDictBuilder, Value};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use itertools::join;
|
use itertools::join;
|
||||||
use sysinfo::ProcessExt;
|
use sysinfo::ProcessExt;
|
|
@ -1,8 +1,7 @@
|
||||||
use crate::prelude::*;
|
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use nu_errors::{CoerceInto, ShellError};
|
use nu_errors::{CoerceInto, ShellError};
|
||||||
use nu_protocol::{Primitive, SpannedTypeName, UntaggedValue, Value};
|
use nu_protocol::{Primitive, SpannedTypeName, UntaggedValue, Value};
|
||||||
use nu_source::Tagged;
|
use nu_source::{Tagged, TaggedItem};
|
||||||
|
|
||||||
pub trait ExtractType: Sized {
|
pub trait ExtractType: Sized {
|
||||||
fn extract(value: &Value) -> Result<Self, ShellError>;
|
fn extract(value: &Value) -> Result<Self, ShellError>;
|
|
@ -1,6 +1,6 @@
|
||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)]
|
||||||
|
|
||||||
use crate::data::value::compute_values;
|
use crate::value::compute_values;
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::hir::Operator;
|
use nu_protocol::hir::Operator;
|
||||||
|
@ -138,8 +138,7 @@ pub fn sort_columns(
|
||||||
if let Some(fmt) = format {
|
if let Some(fmt) = format {
|
||||||
for k in values.iter() {
|
for k in values.iter() {
|
||||||
let k = k.clone().tagged_unknown();
|
let k = k.clone().tagged_unknown();
|
||||||
let v =
|
let v = crate::value::Date::naive_from_str(k.borrow_tagged())?.into_untagged_value();
|
||||||
crate::data::value::Date::naive_from_str(k.borrow_tagged())?.into_untagged_value();
|
|
||||||
keys.push(fmt(&v, k.to_string())?);
|
keys.push(fmt(&v, k.to_string())?);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
|
@ -3,10 +3,10 @@ pub mod split;
|
||||||
|
|
||||||
mod internal;
|
mod internal;
|
||||||
|
|
||||||
pub use crate::utils::data::group::group;
|
pub use crate::utils::group::group;
|
||||||
pub use crate::utils::data::split::split;
|
pub use crate::utils::split::split;
|
||||||
|
|
||||||
use crate::utils::data::internal::*;
|
use crate::utils::internal::*;
|
||||||
|
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use getset::Getters;
|
use getset::Getters;
|
||||||
|
@ -97,9 +97,8 @@ pub fn report(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
pub mod helpers {
|
pub mod helpers {
|
||||||
use super::{report, Labels, Model, Operation, Range};
|
use super::Model;
|
||||||
use bigdecimal::BigDecimal;
|
use bigdecimal::BigDecimal;
|
||||||
use indexmap::indexmap;
|
use indexmap::indexmap;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
|
@ -132,8 +131,8 @@ pub mod helpers {
|
||||||
|
|
||||||
pub fn date(input: impl Into<String>) -> Value {
|
pub fn date(input: impl Into<String>) -> Value {
|
||||||
let key = input.into().tagged_unknown();
|
let key = input.into().tagged_unknown();
|
||||||
crate::data::value::Date::naive_from_str(key.borrow_tagged())
|
crate::value::Date::naive_from_str(key.borrow_tagged())
|
||||||
.unwrap()
|
.expect("date from string failed")
|
||||||
.into_untagged_value()
|
.into_untagged_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,12 +200,15 @@ pub mod helpers {
|
||||||
|
|
||||||
let grouper = Box::new(move |_, row: &Value| {
|
let grouper = Box::new(move |_, row: &Value| {
|
||||||
let key = String::from("date").tagged_unknown();
|
let key = String::from("date").tagged_unknown();
|
||||||
let group_key = row.get_data_by_key(key.borrow_spanned()).unwrap();
|
let group_key = row
|
||||||
|
.get_data_by_key(key.borrow_spanned())
|
||||||
|
.expect("get key failed");
|
||||||
|
|
||||||
group_key.format("%Y-%m-%d")
|
group_key.format("%Y-%m-%d")
|
||||||
});
|
});
|
||||||
|
|
||||||
crate::utils::data::group(&sample, &Some(grouper), Tag::unknown()).unwrap()
|
crate::utils::group(&sample, &Some(grouper), Tag::unknown())
|
||||||
|
.expect("failed to create group")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn date_formatter(
|
pub fn date_formatter(
|
||||||
|
@ -215,13 +217,24 @@ pub mod helpers {
|
||||||
Box::new(move |date: &Value, _: String| date.format(&fmt))
|
Box::new(move |date: &Value, _: String| date.format(&fmt))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_without_checking_percentages(report_a: Model, report_b: Model) {
|
pub fn assert_without_checking_percentages(report_a: Model, report_b: Model) {
|
||||||
assert_eq!(report_a.labels.x, report_b.labels.x);
|
assert_eq!(report_a.labels.x, report_b.labels.x);
|
||||||
assert_eq!(report_a.labels.y, report_b.labels.y);
|
assert_eq!(report_a.labels.y, report_b.labels.y);
|
||||||
assert_eq!(report_a.ranges, report_b.ranges);
|
assert_eq!(report_a.ranges, report_b.ranges);
|
||||||
assert_eq!(report_a.data, report_b.data);
|
assert_eq!(report_a.data, report_b.data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::helpers::{
|
||||||
|
assert_without_checking_percentages, committers, date_formatter, decimal, int, table,
|
||||||
|
};
|
||||||
|
use super::{report, Labels, Model, Operation, Range};
|
||||||
|
use nu_errors::ShellError;
|
||||||
|
use nu_protocol::Value;
|
||||||
|
use nu_source::{Tag, TaggedItem};
|
||||||
|
use nu_value_ext::ValueExt;
|
||||||
#[test]
|
#[test]
|
||||||
fn prepares_report_using_accumulating_value() {
|
fn prepares_report_using_accumulating_value() {
|
||||||
let committers = table(&committers());
|
let committers = table(&committers());
|
|
@ -2,7 +2,7 @@ use nu_errors::ShellError;
|
||||||
use nu_protocol::{SpannedTypeName, TaggedDictBuilder, UntaggedValue, Value};
|
use nu_protocol::{SpannedTypeName, TaggedDictBuilder, UntaggedValue, Value};
|
||||||
use nu_source::Tag;
|
use nu_source::Tag;
|
||||||
|
|
||||||
use crate::utils::data::group;
|
use crate::utils::group;
|
||||||
|
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub fn split(
|
pub fn split(
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::data::base::coerce_compare;
|
use crate::base::coerce_compare;
|
||||||
use crate::data::base::shape::{Column, InlineShape};
|
use crate::base::shape::{Column, InlineShape};
|
||||||
use crate::data::primitive::style_primitive;
|
use crate::primitive::style_primitive;
|
||||||
use chrono::{DateTime, NaiveDate, Utc};
|
use chrono::{DateTime, NaiveDate, Utc};
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::hir::Operator;
|
use nu_protocol::hir::Operator;
|
|
@ -10,7 +10,7 @@ version = "0.18.2"
|
||||||
doctest = false
|
doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-cli = {path = "../nu-cli", version = "0.18.2"}
|
nu-data = {path = "../nu-data", version = "0.18.2"}
|
||||||
nu-errors = {path = "../nu-errors", version = "0.18.2"}
|
nu-errors = {path = "../nu-errors", version = "0.18.2"}
|
||||||
nu-plugin = {path = "../nu-plugin", version = "0.18.2"}
|
nu-plugin = {path = "../nu-plugin", version = "0.18.2"}
|
||||||
nu-protocol = {path = "../nu-protocol", version = "0.18.2"}
|
nu-protocol = {path = "../nu-protocol", version = "0.18.2"}
|
||||||
|
|
|
@ -32,7 +32,7 @@ pub fn view_text_value(value: &Value) {
|
||||||
let highlight_range_to: u64 = 0;
|
let highlight_range_to: u64 = 0;
|
||||||
let mut theme = "OneHalfDark".to_string();
|
let mut theme = "OneHalfDark".to_string();
|
||||||
|
|
||||||
if let Ok(config) = nu_cli::data::config::config(Tag::unknown()) {
|
if let Ok(config) = nu_data::config::config(Tag::unknown()) {
|
||||||
if let Some(batvars) = config.get("textview") {
|
if let Some(batvars) = config.get("textview") {
|
||||||
for (idx, value) in batvars.row_entries() {
|
for (idx, value) in batvars.row_entries() {
|
||||||
match idx.as_ref() {
|
match idx.as_ref() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user