Add subcommands. Switch from-* and to-* to them (#1708)

This commit is contained in:
Jonathan Turner 2020-05-04 20:44:33 +12:00 committed by GitHub
parent 453087248a
commit a9968046ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
64 changed files with 278 additions and 152 deletions

View File

@ -320,6 +320,7 @@ pub fn create_default_context(
whole_stream_command(Histogram), whole_stream_command(Histogram),
whole_stream_command(Sum), whole_stream_command(Sum),
// File format output // File format output
whole_stream_command(To),
whole_stream_command(ToBSON), whole_stream_command(ToBSON),
whole_stream_command(ToCSV), whole_stream_command(ToCSV),
whole_stream_command(ToHTML), whole_stream_command(ToHTML),
@ -332,6 +333,7 @@ pub fn create_default_context(
whole_stream_command(ToURL), whole_stream_command(ToURL),
whole_stream_command(ToYAML), whole_stream_command(ToYAML),
// File format input // File format input
whole_stream_command(From),
whole_stream_command(FromCSV), whole_stream_command(FromCSV),
whole_stream_command(FromEML), whole_stream_command(FromEML),
whole_stream_command(FromTSV), whole_stream_command(FromTSV),

View File

@ -31,6 +31,7 @@ pub(crate) mod evaluate_by;
pub(crate) mod exit; pub(crate) mod exit;
pub(crate) mod first; pub(crate) mod first;
pub(crate) mod format; pub(crate) mod format;
pub(crate) mod from;
pub(crate) mod from_bson; pub(crate) mod from_bson;
pub(crate) mod from_csv; pub(crate) mod from_csv;
pub(crate) mod from_eml; pub(crate) mod from_eml;
@ -101,6 +102,7 @@ pub(crate) mod sum;
pub(crate) mod t_sort_by; pub(crate) mod t_sort_by;
pub(crate) mod table; pub(crate) mod table;
pub(crate) mod tags; pub(crate) mod tags;
pub(crate) mod to;
pub(crate) mod to_bson; pub(crate) mod to_bson;
pub(crate) mod to_csv; pub(crate) mod to_csv;
pub(crate) mod to_html; pub(crate) mod to_html;
@ -150,6 +152,7 @@ pub(crate) use evaluate_by::EvaluateBy;
pub(crate) use exit::Exit; pub(crate) use exit::Exit;
pub(crate) use first::First; pub(crate) use first::First;
pub(crate) use format::Format; pub(crate) use format::Format;
pub(crate) use from::From;
pub(crate) use from_bson::FromBSON; pub(crate) use from_bson::FromBSON;
pub(crate) use from_csv::FromCSV; pub(crate) use from_csv::FromCSV;
pub(crate) use from_eml::FromEML; pub(crate) use from_eml::FromEML;
@ -219,6 +222,7 @@ pub(crate) use sum::Sum;
pub(crate) use t_sort_by::TSortBy; pub(crate) use t_sort_by::TSortBy;
pub(crate) use table::Table; pub(crate) use table::Table;
pub(crate) use tags::Tags; pub(crate) use tags::Tags;
pub(crate) use to::To;
pub(crate) use to_bson::ToBSON; pub(crate) use to_bson::ToBSON;
pub(crate) use to_csv::ToCSV; pub(crate) use to_csv::ToCSV;
pub(crate) use to_html::ToHTML; pub(crate) use to_html::ToHTML;

View File

@ -51,7 +51,7 @@ pub(crate) fn run_internal_command(
} }
CommandAction::AutoConvert(tagged_contents, extension) => { CommandAction::AutoConvert(tagged_contents, extension) => {
let contents_tag = tagged_contents.tag.clone(); let contents_tag = tagged_contents.tag.clone();
let command_name = format!("from-{}", extension); let command_name = format!("from {}", extension);
let command = command.clone(); let command = command.clone();
if let Some(converter) = context.registry.get_command(&command_name) { if let Some(converter) = context.registry.get_command(&command_name) {
let new_args = RawCommandArgs { let new_args = RawCommandArgs {

View File

@ -407,7 +407,7 @@ impl Command {
pub fn run(&self, args: CommandArgs, registry: &CommandRegistry) -> OutputStream { pub fn run(&self, args: CommandArgs, registry: &CommandRegistry) -> OutputStream {
if args.call_info.switch_present("help") { if args.call_info.switch_present("help") {
get_help(self.name(), self.usage(), self.signature()).into() get_help(self.name(), self.usage(), self.signature(), registry).into()
} else { } else {
match self.0.run(args, registry) { match self.0.run(args, registry) {
Ok(stream) => stream, Ok(stream) => stream,

View File

@ -95,7 +95,7 @@ fn enter(
let tagged_contents = contents.into_value(&contents_tag); let tagged_contents = contents.into_value(&contents_tag);
if let Some(extension) = file_extension { if let Some(extension) = file_extension {
let command_name = format!("from-{}", extension); let command_name = format!("from {}", extension);
if let Some(converter) = if let Some(converter) =
registry.get_command(&command_name) registry.get_command(&command_name)
{ {

View File

@ -0,0 +1,31 @@
use crate::commands::WholeStreamCommand;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::Signature;
pub struct From;
impl WholeStreamCommand for From {
fn name(&self) -> &str {
"from"
}
fn signature(&self) -> Signature {
Signature::build("from")
}
fn usage(&self) -> &str {
"Parse content (string or binary) as a table."
}
fn run(
&self,
_args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
Ok(
crate::commands::help::get_help(self.name(), self.usage(), self.signature(), registry)
.into(),
)
}
}

View File

@ -10,15 +10,15 @@ pub struct FromBSON;
impl WholeStreamCommand for FromBSON { impl WholeStreamCommand for FromBSON {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-bson" "from bson"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-bson") Signature::build("from bson")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {
"Parse text as .bson and create table." "Parse binary as .bson and create table."
} }
fn run( fn run(

View File

@ -14,11 +14,11 @@ pub struct FromCSVArgs {
impl WholeStreamCommand for FromCSV { impl WholeStreamCommand for FromCSV {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-csv" "from csv"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-csv") Signature::build("from csv")
.named( .named(
"separator", "separator",
SyntaxShape::String, SyntaxShape::String,

View File

@ -18,11 +18,11 @@ pub struct FromEMLArgs {
impl WholeStreamCommand for FromEML { impl WholeStreamCommand for FromEML {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-eml" "from eml"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-eml").named( Signature::build("from eml").named(
"preview-body", "preview-body",
SyntaxShape::Int, SyntaxShape::Int,
"How many bytes of the body to preview", "How many bytes of the body to preview",

View File

@ -11,11 +11,11 @@ pub struct FromIcs;
impl WholeStreamCommand for FromIcs { impl WholeStreamCommand for FromIcs {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-ics" "from ics"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-ics") Signature::build("from ics")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -8,11 +8,11 @@ pub struct FromINI;
impl WholeStreamCommand for FromINI { impl WholeStreamCommand for FromINI {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-ini" "from ini"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-ini") Signature::build("from ini")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -12,11 +12,11 @@ pub struct FromJSONArgs {
impl WholeStreamCommand for FromJSON { impl WholeStreamCommand for FromJSON {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-json" "from json"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-json").switch( Signature::build("from json").switch(
"objects", "objects",
"treat each line as a separate value", "treat each line as a separate value",
Some('o'), Some('o'),

View File

@ -15,11 +15,11 @@ pub struct FromODSArgs {
impl WholeStreamCommand for FromODS { impl WholeStreamCommand for FromODS {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-ods" "from ods"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-ods").switch( Signature::build("from ods").switch(
"headerless", "headerless",
"don't treat the first row as column names", "don't treat the first row as column names",
None, None,

View File

@ -10,11 +10,11 @@ pub struct FromSQLite;
impl WholeStreamCommand for FromSQLite { impl WholeStreamCommand for FromSQLite {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-sqlite" "from sqlite"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-sqlite") Signature::build("from sqlite")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {
@ -34,11 +34,11 @@ pub struct FromDB;
impl WholeStreamCommand for FromDB { impl WholeStreamCommand for FromDB {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-db" "from db"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-db") Signature::build("from db")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -17,7 +17,7 @@ pub struct FromSSVArgs {
minimum_spaces: Option<Tagged<usize>>, minimum_spaces: Option<Tagged<usize>>,
} }
const STRING_REPRESENTATION: &str = "from-ssv"; const STRING_REPRESENTATION: &str = "from ssv";
const DEFAULT_MINIMUM_SPACES: usize = 2; const DEFAULT_MINIMUM_SPACES: usize = 2;
impl WholeStreamCommand for FromSSV { impl WholeStreamCommand for FromSSV {

View File

@ -7,11 +7,11 @@ pub struct FromTOML;
impl WholeStreamCommand for FromTOML { impl WholeStreamCommand for FromTOML {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-toml" "from toml"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-toml") Signature::build("from toml")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -13,11 +13,11 @@ pub struct FromTSVArgs {
impl WholeStreamCommand for FromTSV { impl WholeStreamCommand for FromTSV {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-tsv" "from tsv"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-tsv").switch( Signature::build("from tsv").switch(
"headerless", "headerless",
"don't treat the first row as column names", "don't treat the first row as column names",
None, None,

View File

@ -7,11 +7,11 @@ pub struct FromURL;
impl WholeStreamCommand for FromURL { impl WholeStreamCommand for FromURL {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-url" "from url"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-url") Signature::build("from url")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -11,11 +11,11 @@ pub struct FromVcf;
impl WholeStreamCommand for FromVcf { impl WholeStreamCommand for FromVcf {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-vcf" "from vcf"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-vcf") Signature::build("from vcf")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -15,11 +15,11 @@ pub struct FromXLSXArgs {
impl WholeStreamCommand for FromXLSX { impl WholeStreamCommand for FromXLSX {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-xlsx" "from xlsx"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-xlsx").switch( Signature::build("from xlsx").switch(
"headerless", "headerless",
"don't treat the first row as column names", "don't treat the first row as column names",
None, None,

View File

@ -7,11 +7,11 @@ pub struct FromXML;
impl WholeStreamCommand for FromXML { impl WholeStreamCommand for FromXML {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-xml" "from xml"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-xml") Signature::build("from xml")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -7,11 +7,11 @@ pub struct FromYAML;
impl WholeStreamCommand for FromYAML { impl WholeStreamCommand for FromYAML {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-yaml" "from yaml"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-yaml") Signature::build("from yaml")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {
@ -31,11 +31,11 @@ pub struct FromYML;
impl WholeStreamCommand for FromYML { impl WholeStreamCommand for FromYML {
fn name(&self) -> &str { fn name(&self) -> &str {
"from-yml" "from yml"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("from-yml") Signature::build("from yml")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -14,7 +14,7 @@ pub struct Help;
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct HelpArgs { pub struct HelpArgs {
command: Option<Tagged<String>>, rest: Vec<Tagged<String>>,
} }
impl WholeStreamCommand for Help { impl WholeStreamCommand for Help {
@ -23,11 +23,7 @@ impl WholeStreamCommand for Help {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("help").optional( Signature::build("help").rest(SyntaxShape::String, "the name of command to get help on")
"command",
SyntaxShape::String,
"the name of command(s) to get help on",
)
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {
@ -44,15 +40,19 @@ impl WholeStreamCommand for Help {
} }
fn help( fn help(
HelpArgs { command }: HelpArgs, HelpArgs { rest }: HelpArgs,
RunnableContext { registry, name, .. }: RunnableContext, RunnableContext { registry, name, .. }: RunnableContext,
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
if let Some(document) = command { if let Some(document) = rest.get(0) {
let mut help = VecDeque::new(); let mut help = VecDeque::new();
if document.item == "commands" { if document.item == "commands" {
let mut sorted_names = registry.names(); let mut sorted_names = registry.names();
sorted_names.sort(); sorted_names.sort();
for cmd in sorted_names { for cmd in sorted_names {
// If it's a subcommand, don't list it during the commands list
if cmd.contains(' ') {
continue;
}
let mut short_desc = TaggedDictBuilder::new(name.clone()); let mut short_desc = TaggedDictBuilder::new(name.clone());
let document_tag = document.tag.clone(); let document_tag = document.tag.clone();
let value = command_dict( let value = command_dict(
@ -82,13 +82,31 @@ fn help(
help.push_back(ReturnSuccess::value(short_desc.into_value())); help.push_back(ReturnSuccess::value(short_desc.into_value()));
} }
} else if rest.len() == 2 {
// Check for a subcommand
let command_name = format!("{} {}", rest[0].item, rest[1].item);
if let Some(command) = registry.get_command(&command_name) {
return Ok(get_help(
&command.name(),
&command.usage(),
command.signature(),
&registry,
)
.into());
}
} else if let Some(command) = registry.get_command(&document.item) { } else if let Some(command) = registry.get_command(&document.item) {
return Ok(get_help(&command.name(), &command.usage(), command.signature()).into()); return Ok(get_help(
&command.name(),
&command.usage(),
command.signature(),
&registry,
)
.into());
} else { } else {
return Err(ShellError::labeled_error( return Err(ShellError::labeled_error(
"Can't find command (use 'help commands' for full list)", "Can't find command (use 'help commands' for full list)",
"can't find command", "can't find command",
document.tag, document.tag.span,
)); ));
} }
let help = futures::stream::iter(help); let help = futures::stream::iter(help);
@ -128,6 +146,7 @@ pub(crate) fn get_help(
cmd_name: &str, cmd_name: &str,
cmd_usage: &str, cmd_usage: &str,
cmd_sig: Signature, cmd_sig: Signature,
registry: &CommandRegistry,
) -> impl Into<OutputStream> { ) -> impl Into<OutputStream> {
let mut help = VecDeque::new(); let mut help = VecDeque::new();
let mut long_desc = String::new(); let mut long_desc = String::new();
@ -137,6 +156,15 @@ pub(crate) fn get_help(
let signature = cmd_sig; let signature = cmd_sig;
let mut subcommands = String::new();
for name in registry.names() {
if name.starts_with(&format!("{} ", cmd_name)) {
let subcommand = registry.get_command(&name).expect("This shouldn't happen");
subcommands.push_str(&format!(" {} - {}\n", name, subcommand.usage()));
}
}
let mut one_liner = String::new(); let mut one_liner = String::new();
one_liner.push_str(&signature.name); one_liner.push_str(&signature.name);
one_liner.push_str(" "); one_liner.push_str(" ");
@ -156,14 +184,23 @@ pub(crate) fn get_help(
one_liner.push_str(" ...args"); one_liner.push_str(" ...args");
} }
if !subcommands.is_empty() {
one_liner.push_str("<subcommand> ");
}
if !signature.named.is_empty() { if !signature.named.is_empty() {
one_liner.push_str("{flags} "); one_liner.push_str("{flags} ");
} }
long_desc.push_str(&format!("\nUsage:\n > {}\n", one_liner)); long_desc.push_str(&format!("\nUsage:\n > {}\n", one_liner));
if !subcommands.is_empty() {
long_desc.push_str("\nSubcommands:\n");
long_desc.push_str(&subcommands);
}
if !signature.positional.is_empty() || signature.rest_positional.is_some() { if !signature.positional.is_empty() || signature.rest_positional.is_some() {
long_desc.push_str("\nparameters:\n"); long_desc.push_str("\nParameters:\n");
for positional in signature.positional { for positional in signature.positional {
match positional.0 { match positional.0 {
PositionalType::Mandatory(name, _m) => { PositionalType::Mandatory(name, _m) => {
@ -180,7 +217,7 @@ pub(crate) fn get_help(
} }
} }
if !signature.named.is_empty() { if !signature.named.is_empty() {
long_desc.push_str("\nflags:\n"); long_desc.push_str("\nFlags:\n");
for (flag, ty) in signature.named { for (flag, ty) in signature.named {
let msg = match ty.0 { let msg = match ty.0 {
NamedType::Switch(s) => { NamedType::Switch(s) => {

View File

@ -221,7 +221,7 @@ fn save(
let content : Result<Vec<u8>, ShellError> = 'scope: loop { let content : Result<Vec<u8>, ShellError> = 'scope: loop {
break if !save_raw { break if !save_raw {
if let Some(extension) = full_path.extension() { if let Some(extension) = full_path.extension() {
let command_name = format!("to-{}", extension.to_string_lossy()); let command_name = format!("to {}", extension.to_string_lossy());
if let Some(converter) = registry.get_command(&command_name) { if let Some(converter) = registry.get_command(&command_name) {
let new_args = RawCommandArgs { let new_args = RawCommandArgs {
host, host,

View File

@ -0,0 +1,31 @@
use crate::commands::WholeStreamCommand;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::Signature;
pub struct To;
impl WholeStreamCommand for To {
fn name(&self) -> &str {
"to"
}
fn signature(&self) -> Signature {
Signature::build("to")
}
fn usage(&self) -> &str {
"Convert table into an output format."
}
fn run(
&self,
_args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
Ok(
crate::commands::help::get_help(self.name(), self.usage(), self.signature(), registry)
.into(),
)
}
}

View File

@ -12,11 +12,11 @@ pub struct ToBSON;
impl WholeStreamCommand for ToBSON { impl WholeStreamCommand for ToBSON {
fn name(&self) -> &str { fn name(&self) -> &str {
"to-bson" "to bson"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-bson") Signature::build("to bson")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -14,11 +14,11 @@ pub struct ToCSVArgs {
impl WholeStreamCommand for ToCSV { impl WholeStreamCommand for ToCSV {
fn name(&self) -> &str { fn name(&self) -> &str {
"to-csv" "to csv"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-csv") Signature::build("to csv")
.named( .named(
"separator", "separator",
SyntaxShape::String, SyntaxShape::String,

View File

@ -10,11 +10,11 @@ pub struct ToHTML;
impl WholeStreamCommand for ToHTML { impl WholeStreamCommand for ToHTML {
fn name(&self) -> &str { fn name(&self) -> &str {
"to-html" "to html"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-html") Signature::build("to html")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -7,11 +7,11 @@ pub struct ToJSON;
impl WholeStreamCommand for ToJSON { impl WholeStreamCommand for ToJSON {
fn name(&self) -> &str { fn name(&self) -> &str {
"to-json" "to json"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-json") Signature::build("to json")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -9,11 +9,11 @@ pub struct ToMarkdown;
impl WholeStreamCommand for ToMarkdown { impl WholeStreamCommand for ToMarkdown {
fn name(&self) -> &str { fn name(&self) -> &str {
"to-md" "to md"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-md") Signature::build("to md")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -10,11 +10,11 @@ pub struct ToSQLite;
impl WholeStreamCommand for ToSQLite { impl WholeStreamCommand for ToSQLite {
fn name(&self) -> &str { fn name(&self) -> &str {
"to-sqlite" "to sqlite"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-sqlite") Signature::build("to sqlite")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {
@ -38,11 +38,11 @@ pub struct ToDB;
impl WholeStreamCommand for ToDB { impl WholeStreamCommand for ToDB {
fn name(&self) -> &str { fn name(&self) -> &str {
"to-db" "to db"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-db") Signature::build("to db")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -7,11 +7,11 @@ pub struct ToTOML;
impl WholeStreamCommand for ToTOML { impl WholeStreamCommand for ToTOML {
fn name(&self) -> &str { fn name(&self) -> &str {
"to-toml" "to toml"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-toml") Signature::build("to toml")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -13,11 +13,11 @@ pub struct ToTSVArgs {
impl WholeStreamCommand for ToTSV { impl WholeStreamCommand for ToTSV {
fn name(&self) -> &str { fn name(&self) -> &str {
"to-tsv" "to tsv"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-tsv").switch( Signature::build("to tsv").switch(
"headerless", "headerless",
"do not output the column names as the first row", "do not output the column names as the first row",
None, None,

View File

@ -7,11 +7,11 @@ pub struct ToURL;
impl WholeStreamCommand for ToURL { impl WholeStreamCommand for ToURL {
fn name(&self) -> &str { fn name(&self) -> &str {
"to-url" "to url"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-url") Signature::build("to url")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -7,11 +7,11 @@ pub struct ToYAML;
impl WholeStreamCommand for ToYAML { impl WholeStreamCommand for ToYAML {
fn name(&self) -> &str { fn name(&self) -> &str {
"to-yaml" "to yaml"
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("to-yaml") Signature::build("to yaml")
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -8,7 +8,7 @@ fn alias_args_work() {
cwd: dirs.root(), cwd: dirs.root(),
r#" r#"
alias double_echo [a b] {echo $a $b} alias double_echo [a b] {echo $a $b}
double_echo 1 2 | to-json double_echo 1 2 | to json
"# "#
); );

View File

@ -40,7 +40,7 @@ fn discards_empty_rows_by_default() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
echo "[1,2,3,14,null]" echo "[1,2,3,14,null]"
| from-json | from json
| compact | compact
| count | count
| echo $it | echo $it

View File

@ -4,7 +4,7 @@ use nu_test_support::nu;
fn drop_rows() { fn drop_rows() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", cwd: "tests/fixtures/formats",
r#"echo '[{"foo": 3}, {"foo": 8}, {"foo": 4}]' | from-json | drop 2 | get foo | sum | echo $it"# r#"echo '[{"foo": 3}, {"foo": 8}, {"foo": 4}]' | from json | drop 2 | get foo | sum | echo $it"#
); );
assert_eq!(actual, "3"); assert_eq!(actual, "3");

View File

@ -5,7 +5,7 @@ fn each_works_separately() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", pipeline( cwd: "tests/fixtures/formats", pipeline(
r#" r#"
echo [1 2 3] | each { echo $it 10 | sum } | to-json | echo $it echo [1 2 3] | each { echo $it 10 | sum } | to json | echo $it
"# "#
)); ));

View File

@ -240,7 +240,7 @@ fn errors_fetching_by_index_out_of_bounds() {
fn quoted_column_access() { fn quoted_column_access() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", cwd: "tests/fixtures/formats",
r#"echo '[{"foo bar": {"baz": 4}}]' | from-json | get "foo bar".baz | echo $it"# r#"echo '[{"foo bar": {"baz": 4}}]' | from json | get "foo bar".baz | echo $it"#
); );
assert_eq!(actual, "4"); assert_eq!(actual, "4");

View File

@ -9,7 +9,7 @@ fn headers_uses_first_row_as_header() {
| get Sheet1 | get Sheet1
| headers | headers
| get header0 | get header0
| from-json"# | from json"#
)); ));
assert_eq!(actual, "r1c0r2c0") assert_eq!(actual, "r1c0r2c0")
@ -24,7 +24,7 @@ fn headers_adds_missing_column_name() {
| get Sheet1 | get Sheet1
| headers | headers
| get Column1 | get Column1
| from-json"# | from json"#
)); ));
assert_eq!(actual, "r1c1r2c1") assert_eq!(actual, "r1c1r2c1")

View File

@ -125,7 +125,7 @@ fn compound_where() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", pipeline( cwd: "tests/fixtures/formats", pipeline(
r#" r#"
echo '[{"a": 1, "b": 1}, {"a": 2, "b": 1}, {"a": 2, "b": 2}]' | from-json | where a == 2 && b == 1 | to-json echo '[{"a": 1, "b": 1}, {"a": 2, "b": 1}, {"a": 2, "b": 2}]' | from json | where a == 2 && b == 1 | to json
"# "#
)); ));
@ -137,7 +137,7 @@ fn compound_where_paren() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", pipeline( cwd: "tests/fixtures/formats", pipeline(
r#" r#"
echo '[{"a": 1, "b": 1}, {"a": 2, "b": 1}, {"a": 2, "b": 2}]' | from-json | where (a == 2 && b == 1) || b == 2 | to-json echo '[{"a": 1, "b": 1}, {"a": 2, "b": 1}, {"a": 2, "b": 2}]' | from json | where (a == 2 && b == 1) || b == 2 | to json
"# "#
)); ));

View File

@ -131,7 +131,7 @@ fn uniq_when_keys_out_of_order() {
cwd: "tests/fixtures/formats", pipeline( cwd: "tests/fixtures/formats", pipeline(
r#" r#"
echo '[{"a": "a", "b": [1,2,3]},{"b": [1,2,3], "a": "a"}]' echo '[{"a": "a", "b": [1,2,3]},{"b": [1,2,3], "a": "a"}]'
| from-json | from json
| uniq | uniq
| count | count
| echo $it | echo $it

View File

@ -14,7 +14,7 @@ fn filters_by_unit_size_comparison() {
fn filters_with_nothing_comparison() { fn filters_with_nothing_comparison() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", cwd: "tests/fixtures/formats",
r#"echo '[{"foo": 3}, {"foo": null}, {"foo": 4}]' | from-json | where foo > 1 | get foo | sum | echo $it"# r#"echo '[{"foo": 3}, {"foo": null}, {"foo": 4}]' | from json | where foo > 1 | get foo | sum | echo $it"#
); );
assert_eq!(actual, "7"); assert_eq!(actual, "7");
@ -24,7 +24,7 @@ fn filters_with_nothing_comparison() {
fn where_in_table() { fn where_in_table() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", cwd: "tests/fixtures/formats",
r#"echo '[{"name": "foo", "size": 3}, {"name": "foo", "size": 2}, {"name": "bar", "size": 4}]' | from-json | where name in: ["foo"] | get size | sum | echo $it"# r#"echo '[{"name": "foo", "size": 3}, {"name": "foo", "size": 2}, {"name": "bar", "size": 4}]' | from json | where name in: ["foo"] | get size | sum | echo $it"#
); );
assert_eq!(actual, "5"); assert_eq!(actual, "5");
@ -34,7 +34,7 @@ fn where_in_table() {
fn where_not_in_table() { fn where_not_in_table() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", cwd: "tests/fixtures/formats",
r#"echo '[{"name": "foo", "size": 3}, {"name": "foo", "size": 2}, {"name": "bar", "size": 4}]' | from-json | where name not-in: ["foo"] | get size | sum | echo $it"# r#"echo '[{"name": "foo", "size": 3}, {"name": "foo", "size": 2}, {"name": "bar", "size": 4}]' | from json | where name not-in: ["foo"] | get size | sum | echo $it"#
); );
assert_eq!(actual, "4"); assert_eq!(actual, "4");

View File

@ -19,7 +19,7 @@ fn wrap_rows_into_a_row() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open los_tres_caballeros.txt open los_tres_caballeros.txt
| from-csv | from csv
| wrap caballeros | wrap caballeros
| get caballeros | get caballeros
| nth 0 | nth 0
@ -49,7 +49,7 @@ fn wrap_rows_into_a_table() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open los_tres_caballeros.txt open los_tres_caballeros.txt
| from-csv | from csv
| get last_name | get last_name
| wrap caballero | wrap caballero
| nth 2 | nth 2

View File

@ -6,8 +6,8 @@ fn table_to_bson_and_back_into_table() {
cwd: "tests/fixtures/formats", pipeline( cwd: "tests/fixtures/formats", pipeline(
r#" r#"
open sample.bson open sample.bson
| to-bson | to bson
| from-bson | from bson
| get root | get root
| get 1.b | get 1.b
| echo $it | echo $it

View File

@ -6,7 +6,7 @@ use nu_test_support::{nu, pipeline};
fn table_to_csv_text_and_from_csv_text_back_into_table() { fn table_to_csv_text_and_from_csv_text_back_into_table() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", cwd: "tests/fixtures/formats",
"open caco3_plastics.csv | to-csv | from-csv | first 1 | get origin | echo $it" "open caco3_plastics.csv | to csv | from csv | first 1 | get origin | echo $it"
); );
assert_eq!(actual, "SPAIN"); assert_eq!(actual, "SPAIN");
@ -32,7 +32,7 @@ fn table_to_csv_text() {
| trim | trim
| split-column "," a b c d origin | split-column "," a b c d origin
| last 1 | last 1
| to-csv | to csv
| lines | lines
| nth 1 | nth 1
| echo $it | echo $it
@ -63,7 +63,7 @@ fn table_to_csv_text_skipping_headers_after_conversion() {
| trim | trim
| split-column "," a b c d origin | split-column "," a b c d origin
| last 1 | last 1
| to-csv --headerless | to csv --headerless
| echo $it | echo $it
"# "#
)); ));
@ -117,7 +117,7 @@ fn from_csv_text_to_table() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open los_tres_caballeros.txt open los_tres_caballeros.txt
| from-csv | from csv
| get rusty_luck | get rusty_luck
| count | count
| echo $it | echo $it
@ -145,7 +145,7 @@ fn from_csv_text_with_separator_to_table() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open los_tres_caballeros.txt open los_tres_caballeros.txt
| from-csv --separator ';' | from csv --separator ';'
| get rusty_luck | get rusty_luck
| count | count
| echo $it | echo $it
@ -173,7 +173,7 @@ fn from_csv_text_with_tab_separator_to_table() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open los_tres_caballeros.txt open los_tres_caballeros.txt
| from-csv --separator '\t' | from csv --separator '\t'
| get rusty_luck | get rusty_luck
| count | count
| echo $it | echo $it
@ -200,7 +200,7 @@ fn from_csv_text_skipping_headers_to_table() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open los_tres_amigos.txt open los_tres_amigos.txt
| from-csv --headerless | from csv --headerless
| get Column3 | get Column3
| count | count
| echo $it | echo $it

View File

@ -5,7 +5,7 @@ fn out_html_simple() {
let actual = nu!( let actual = nu!(
cwd: ".", pipeline( cwd: ".", pipeline(
r#" r#"
echo 3 | to-html echo 3 | to html
"# "#
)); ));
@ -17,7 +17,7 @@ fn out_html_table() {
let actual = nu!( let actual = nu!(
cwd: ".", pipeline( cwd: ".", pipeline(
r#" r#"
echo '{"name": "jason"}' | from-json | to-html echo '{"name": "jason"}' | from json | to html
"# "#
)); ));

View File

@ -86,7 +86,7 @@ fn from_ics_text_to_table() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open calendar.txt open calendar.txt
| from-ics | from ics
| get events | get events
| get properties | get properties
| where name == "SUMMARY" | where name == "SUMMARY"

View File

@ -8,8 +8,8 @@ fn table_to_json_text_and_from_json_text_back_into_table() {
cwd: "tests/fixtures/formats", pipeline( cwd: "tests/fixtures/formats", pipeline(
r#" r#"
open sgml_description.json open sgml_description.json
| to-json | to json
| from-json | from json
| get glossary.GlossDiv.GlossList.GlossEntry.GlossSee | get glossary.GlossDiv.GlossList.GlossEntry.GlossSee
| echo $it | echo $it
"# "#
@ -37,7 +37,7 @@ fn from_json_text_to_table() {
let actual = nu!( let actual = nu!(
cwd: dirs.test(), cwd: dirs.test(),
"open katz.txt | from-json | get katz | get rusty_luck | count | echo $it" "open katz.txt | from json | get katz | get rusty_luck | count | echo $it"
); );
assert_eq!(actual, "4"); assert_eq!(actual, "4");
@ -61,7 +61,7 @@ fn from_json_text_recognizing_objects_independently_to_table() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open katz.txt open katz.txt
| from-json -o | from json -o
| where name == "GorbyPuff" | where name == "GorbyPuff"
| get rusty_luck | get rusty_luck
| echo $it | echo $it
@ -90,8 +90,8 @@ fn table_to_json_text() {
| lines | lines
| split-column "," name luck | split-column "," name luck
| pick name | pick name
| to-json | to json
| from-json | from json
| nth 0 | nth 0
| get name | get name
| echo $it | echo $it

View File

@ -5,7 +5,7 @@ fn out_md_simple() {
let actual = nu!( let actual = nu!(
cwd: ".", pipeline( cwd: ".", pipeline(
r#" r#"
echo 3 | to-md echo 3 | to md
"# "#
)); ));
@ -17,7 +17,7 @@ fn out_md_table() {
let actual = nu!( let actual = nu!(
cwd: ".", pipeline( cwd: ".", pipeline(
r#" r#"
echo '{"name": "jason"}' | from-json | to-md echo '{"name": "jason"}' | from json | to md
"# "#
)); ));

View File

@ -6,8 +6,8 @@ fn table_to_sqlite_and_back_into_table() {
cwd: "tests/fixtures/formats", pipeline( cwd: "tests/fixtures/formats", pipeline(
r#" r#"
open sample.db open sample.db
| to-sqlite | to sqlite
| from-sqlite | from sqlite
| get table_values | get table_values
| nth 2 | nth 2
| get x | get x

View File

@ -19,7 +19,7 @@ fn from_ssv_text_to_table() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open oc_get_svc.txt open oc_get_svc.txt
| from-ssv | from ssv
| nth 0 | nth 0
| get IP | get IP
| echo $it | echo $it
@ -47,7 +47,7 @@ fn from_ssv_text_to_table_with_separator_specified() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open oc_get_svc.txt open oc_get_svc.txt
| from-ssv --minimum-spaces 3 | from ssv --minimum-spaces 3
| nth 0 | nth 0
| get IP | get IP
| echo $it | echo $it
@ -74,7 +74,7 @@ fn from_ssv_text_treating_first_line_as_data_with_flag() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open oc_get_svc.txt open oc_get_svc.txt
| from-ssv --headerless -a | from ssv --headerless -a
| first | first
| get Column1 | get Column1
| echo $it | echo $it
@ -85,7 +85,7 @@ fn from_ssv_text_treating_first_line_as_data_with_flag() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open oc_get_svc.txt open oc_get_svc.txt
| from-ssv --headerless | from ssv --headerless
| first | first
| get Column1 | get Column1
| echo $it | echo $it

View File

@ -6,8 +6,8 @@ fn table_to_toml_text_and_from_toml_text_back_into_table() {
cwd: "tests/fixtures/formats", pipeline( cwd: "tests/fixtures/formats", pipeline(
r#" r#"
open cargo_sample.toml open cargo_sample.toml
| to-toml | to toml
| from-toml | from toml
| get package.name | get package.name
| echo $it | echo $it
"# "#

View File

@ -6,7 +6,7 @@ use nu_test_support::{nu, pipeline};
fn table_to_tsv_text_and_from_tsv_text_back_into_table() { fn table_to_tsv_text_and_from_tsv_text_back_into_table() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", cwd: "tests/fixtures/formats",
"open caco3_plastics.tsv | to-tsv | from-tsv | first 1 | get origin | echo $it" "open caco3_plastics.tsv | to tsv | from tsv | first 1 | get origin | echo $it"
); );
assert_eq!(actual, "SPAIN"); assert_eq!(actual, "SPAIN");
@ -16,7 +16,7 @@ fn table_to_tsv_text_and_from_tsv_text_back_into_table() {
fn table_to_tsv_text_and_from_tsv_text_back_into_table_using_csv_separator() { fn table_to_tsv_text_and_from_tsv_text_back_into_table_using_csv_separator() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures/formats", cwd: "tests/fixtures/formats",
r"open caco3_plastics.tsv | to-tsv | from-csv --separator '\t' | first 1 | get origin | echo $it" r"open caco3_plastics.tsv | to tsv | from csv --separator '\t' | first 1 | get origin | echo $it"
); );
assert_eq!(actual, "SPAIN"); assert_eq!(actual, "SPAIN");
@ -41,7 +41,7 @@ fn table_to_tsv_text() {
| lines | lines
| split-column "\t" a b c d origin | split-column "\t" a b c d origin
| last 1 | last 1
| to-tsv | to tsv
| lines | lines
| nth 1 | nth 1
| echo $it | echo $it
@ -71,7 +71,7 @@ fn table_to_tsv_text_skipping_headers_after_conversion() {
| lines | lines
| split-column "\t" a b c d origin | split-column "\t" a b c d origin
| last 1 | last 1
| to-tsv --headerless | to tsv --headerless
| echo $it | echo $it
"# "#
)); ));
@ -97,7 +97,7 @@ fn from_tsv_text_to_table() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open los_tres_amigos.txt open los_tres_amigos.txt
| from-tsv | from tsv
| get rusty_luck | get rusty_luck
| count | count
| echo $it | echo $it
@ -124,7 +124,7 @@ fn from_tsv_text_skipping_headers_to_table() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open los_tres_amigos.txt open los_tres_amigos.txt
| from-tsv --headerless | from tsv --headerless
| get Column3 | get Column3
| count | count
| echo $it | echo $it

View File

@ -6,8 +6,8 @@ fn can_encode_and_decode_urlencoding() {
cwd: "tests/fixtures/formats", pipeline( cwd: "tests/fixtures/formats", pipeline(
r#" r#"
open sample.url open sample.url
| to-url | to url
| from-url | from url
| get cheese | get cheese
| echo $it | echo $it
"# "#

View File

@ -70,7 +70,7 @@ fn from_vcf_text_to_table() {
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
open contacts.txt open contacts.txt
| from-vcf | from vcf
| get properties | get properties
| where name == "EMAIL" | where name == "EMAIL"
| first | first

View File

@ -6,8 +6,8 @@ fn table_to_yaml_text_and_from_yaml_text_back_into_table() {
cwd: "tests/fixtures/formats", pipeline( cwd: "tests/fixtures/formats", pipeline(
r#" r#"
open appveyor.yml open appveyor.yml
| to-yaml | to yaml
| from-yaml | from yaml
| get environment.global.PROJECT_NAME | get environment.global.PROJECT_NAME
| echo $it | echo $it
"# "#

View File

@ -848,16 +848,22 @@ fn parse_internal_command(
lite_cmd: &LiteCommand, lite_cmd: &LiteCommand,
registry: &dyn SignatureRegistry, registry: &dyn SignatureRegistry,
signature: &Signature, signature: &Signature,
mut idx: usize,
) -> (InternalCommand, Option<ParseError>) { ) -> (InternalCommand, Option<ParseError>) {
// This is a known internal command, so we need to work with the arguments and parse them according to the expected types // This is a known internal command, so we need to work with the arguments and parse them according to the expected types
let mut internal_command = InternalCommand::new(
lite_cmd.name.item.clone(), let (name, name_span) = if idx == 0 {
lite_cmd.name.span, (lite_cmd.name.item.clone(), lite_cmd.name.span)
lite_cmd.span(), } else {
); (
format!("{} {}", lite_cmd.name.item, lite_cmd.args[0].item),
Span::new(lite_cmd.name.span.start(), lite_cmd.args[0].span.end()),
)
};
let mut internal_command = InternalCommand::new(name, name_span, lite_cmd.span());
internal_command.args.set_initial_flags(&signature); internal_command.args.set_initial_flags(&signature);
let mut idx = 0;
let mut current_positional = 0; let mut current_positional = 0;
let mut named = NamedArguments::new(); let mut named = NamedArguments::new();
let mut positional = vec![]; let mut positional = vec![];
@ -1051,12 +1057,31 @@ fn classify_pipeline(
garbage(lite_cmd.span()) garbage(lite_cmd.span())
}; };
commands.push(ClassifiedCommand::Expr(Box::new(expr))) commands.push(ClassifiedCommand::Expr(Box::new(expr)))
} else if let Some(signature) = registry.get(&lite_cmd.name.item) { } else {
let (internal_command, err) = parse_internal_command(&lite_cmd, registry, &signature); if !lite_cmd.args.is_empty() {
// Check if it's a sub-command
if let Some(signature) =
registry.get(&format!("{} {}", lite_cmd.name.item, lite_cmd.args[0].item))
{
let (internal_command, err) =
parse_internal_command(&lite_cmd, registry, &signature, 1);
error = error.or(err); error = error.or(err);
commands.push(ClassifiedCommand::Internal(internal_command)) commands.push(ClassifiedCommand::Internal(internal_command));
} else { continue;
}
}
// Check if it's an internal command
if let Some(signature) = registry.get(&lite_cmd.name.item) {
let (internal_command, err) =
parse_internal_command(&lite_cmd, registry, &signature, 0);
error = error.or(err);
commands.push(ClassifiedCommand::Internal(internal_command));
continue;
}
let name = lite_cmd.name.clone().map(|v| { let name = lite_cmd.name.clone().map(|v| {
let trimmed = trim_quotes(&v); let trimmed = trim_quotes(&v);
expand_path(&trimmed).to_string() expand_path(&trimmed).to_string()

View File

@ -33,10 +33,13 @@ pub struct InternalCommand {
impl InternalCommand { impl InternalCommand {
pub fn new(name: String, name_span: Span, full_span: Span) -> InternalCommand { pub fn new(name: String, name_span: Span, full_span: Span) -> InternalCommand {
InternalCommand { InternalCommand {
name: name.clone(), name,
name_span, name_span,
args: crate::hir::Call::new( args: crate::hir::Call::new(
Box::new(SpannedExpression::new(Expression::string(name), name_span)), Box::new(SpannedExpression::new(
Expression::Command(name_span),
name_span,
)),
full_span, full_span,
), ),
} }

View File

@ -21,10 +21,10 @@ You can save the name of files in a directory like this:
> ls | where type == File | pick name | save filenames.csv > ls | where type == File | pick name | save filenames.csv
``` ```
Or you can format it in supported formats using one of the `to-*` commands: Or you can format it in supported formats using one of the `to` commands:
```shell ```shell
> ls | where type == File | pick name | to-csv | save filenames > ls | where type == File | pick name | to csv | save filenames
``` ```
`filename.csv` and `filenames` are both `csv` formatted files. Nu auto-converts the format if a supported file extension is given. `filename.csv` and `filenames` are both `csv` formatted files. Nu auto-converts the format if a supported file extension is given.

View File

@ -119,7 +119,7 @@ fn converts_to_int() {
cwd: "tests/fixtures/formats", pipeline( cwd: "tests/fixtures/formats", pipeline(
r#" r#"
echo '{number_as_string: "1"}' echo '{number_as_string: "1"}'
| from-json | from json
| str number_as_string --to-int | str number_as_string --to-int
| rename number | rename number
| where number == 1 | where number == 1

View File

@ -48,13 +48,6 @@ fn automatically_change_directory_with_trailing_slash_and_same_name_as_command()
}) })
} }
// #[test]
// fn correctly_escape_external_arguments() {
// let actual = nu!(cwd: ".", r#"^echo '[{"foo": "bar"}]' | from-json | to-json"#);
// assert_eq!(actual, "{\"foo\":\"bar\"}");
// }
#[test] #[test]
fn correctly_escape_external_arguments() { fn correctly_escape_external_arguments() {
let actual = nu!(cwd: ".", r#"^echo '$0'"#); let actual = nu!(cwd: ".", r#"^echo '$0'"#);

View File

@ -152,7 +152,7 @@ mod tilde_expansion {
let actual = nu!( let actual = nu!(
cwd: dirs.test(), pipeline( cwd: dirs.test(), pipeline(
r#" r#"
ls | sort-by name | group-by type | each { get File.name | echo $it } | to-json ls | sort-by name | group-by type | each { get File.name | echo $it } | to json
"# "#
)); ));