str collect => str join (#6531)

* Initialize join.rs as a copy of collect.rs

* Evolve StrCollect into StrJoin

* Replace 'str collect' with 'str join' everywhere

git ls-files | lines | par-each { |it| sed -i 's,str collect,str join,g' $it }

* Deprecate 'str collect'

* Revert "Deprecate 'str collect'"

This reverts commit 959d14203e.

* Change `str collect` help message to say that it is deprecated

We cannot remove `str collect` currently (i.e. via
`nu_protocol::ShellError::DeprecatedCommand` since a prominent project
uses the API:

b85542c31c/src/virtualenv/activation/nushell/activate.nu (L43)
This commit is contained in:
Dan Davison 2022-09-11 04:48:27 -04:00 committed by GitHub
parent 9ee4086dfa
commit 4926865c4e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 173 additions and 68 deletions

View file

@ -76,9 +76,9 @@ cp -v README.release.txt $'($dist)/README.txt'
$'(char nl)Check binary release version detail:'; hr-line
let ver = if $os == 'windows-latest' {
(do -i { ./output/nu.exe -c 'version' }) | str collect
(do -i { ./output/nu.exe -c 'version' }) | str join
} else {
(do -i { ./output/nu -c 'version' }) | str collect
(do -i { ./output/nu -c 'version' }) | str join
}
if ($ver | str trim | is-empty) {
$'(ansi r)Incompatible nu binary...(ansi reset)'

View file

@ -201,6 +201,7 @@ pub fn create_default_context() -> EngineState {
StrDistance,
StrDowncase,
StrEndswith,
StrJoin,
StrReplace,
StrIndexOf,
StrKebabCase,

View file

@ -14,7 +14,7 @@ use crate::To;
#[cfg(test)]
use super::{
Ansi, Date, From, If, Into, LetEnv, Math, Path, Random, Split, SplitColumn, SplitRow, Str,
StrCollect, StrLength, StrReplace, Url, Wrap,
StrJoin, StrLength, StrReplace, Url, Wrap,
};
#[cfg(test)]
@ -29,7 +29,7 @@ pub fn test_examples(cmd: impl Command + 'static) {
// Try to keep this working set small to keep tests running as fast as possible
let mut working_set = StateWorkingSet::new(&*engine_state);
working_set.add_decl(Box::new(Str));
working_set.add_decl(Box::new(StrCollect));
working_set.add_decl(Box::new(StrJoin));
working_set.add_decl(Box::new(StrLength));
working_set.add_decl(Box::new(StrReplace));
working_set.add_decl(Box::new(BuildString));

View file

@ -62,7 +62,7 @@ impl Command for Upsert {
result: Some(Value::List { vals: vec![Value::Record { cols: vec!["count".into(), "fruit".into()], vals: vec![Value::test_int(2), Value::test_string("apple")], span: Span::test_data()}], span: Span::test_data()}),
}, Example {
description: "Use in block form for more involved updating logic",
example: "echo [[project, authors]; ['nu', ['Andrés', 'JT', 'Yehuda']]] | upsert authors {|a| $a.authors | str collect ','}",
example: "echo [[project, authors]; ['nu', ['Andrés', 'JT', 'Yehuda']]] | upsert authors {|a| $a.authors | str join ','}",
result: Some(Value::List { vals: vec![Value::Record { cols: vec!["project".into(), "authors".into()], vals: vec![Value::test_string("nu"), Value::test_string("Andrés,JT,Yehuda")], span: Span::test_data()}], span: Span::test_data()}),
}]
}

View file

@ -141,7 +141,7 @@ lazy_static! {
// Reference for ansi codes https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
// Another good reference http://ascii-table.com/ansi-escape-sequences.php
// For setting title like `echo [(char title) (pwd) (char bel)] | str collect`
// For setting title like `echo [(char title) (pwd) (char bel)] | str join`
AnsiCode{short_name: None, long_name:"title", code: "\x1b]2;".to_string()}, // ESC]2; xterm sets window title using OSC syntax escapes
// Ansi Erase Sequences
@ -258,7 +258,7 @@ following values:
https://en.wikipedia.org/wiki/ANSI_escape_code
OSC: '\x1b]' is not required for --osc parameter
Example: echo [(ansi -o '0') 'some title' (char bel)] | str collect
Example: echo [(ansi -o '0') 'some title' (char bel)] | str join
Format: #
0 Set window title and icon name
1 Set icon name
@ -285,14 +285,14 @@ Format: #
Example {
description:
"Use ansi to color text (rb = red bold, gb = green bold, pb = purple bold)",
example: r#"echo [(ansi rb) Hello " " (ansi gb) Nu " " (ansi pb) World (ansi reset)] | str collect"#,
example: r#"echo [(ansi rb) Hello " " (ansi gb) Nu " " (ansi pb) World (ansi reset)] | str join"#,
result: Some(Value::test_string(
"\u{1b}[1;31mHello \u{1b}[1;32mNu \u{1b}[1;35mWorld\u{1b}[0m",
)),
},
Example {
description: "Use ansi to color text (italic bright yellow on red 'Hello' with green bold 'Nu' and purple bold 'World')",
example: r#"echo [(ansi -e '3;93;41m') Hello (ansi reset) " " (ansi gb) Nu " " (ansi pb) World (ansi reset)] | str collect"#,
example: r#"echo [(ansi -e '3;93;41m') Hello (ansi reset) " " (ansi gb) Nu " " (ansi pb) World (ansi reset)] | str join"#,
result: Some(Value::test_string(
"\u{1b}[3;93;41mHello\u{1b}[0m \u{1b}[1;32mNu \u{1b}[1;35mWorld\u{1b}[0m",
)),

View file

@ -40,7 +40,7 @@ impl Command for SubCommand {
fn examples(&self) -> Vec<Example> {
vec![Example {
description: "Strip ANSI escape sequences from a string",
example: r#"echo [ (ansi green) (ansi cursor_on) "hello" ] | str collect | ansi strip"#,
example: r#"echo [ (ansi green) (ansi cursor_on) "hello" ] | str join | ansi strip"#,
result: Some(Value::test_string("hello")),
}]
}

View file

@ -185,7 +185,7 @@ impl Command for Char {
},
Example {
description: "Output prompt character, newline and a hamburger character",
example: r#"echo [(char prompt) (char newline) (char hamburger)] | str collect"#,
example: r#"echo [(char prompt) (char newline) (char hamburger)] | str join"#,
result: Some(Value::test_string("\u{25b6}\n\u{2261}")),
},
Example {

View file

@ -25,11 +25,7 @@ impl Command for StrCollect {
}
fn usage(&self) -> &str {
"Concatenate multiple strings into a single string, with an optional separator between each"
}
fn search_terms(&self) -> Vec<&str> {
vec!["join", "concatenate"]
"'str collect' is deprecated. Please use 'str join' instead."
}
fn run(

View file

@ -0,0 +1,106 @@
use nu_engine::CallExt;
use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{
Category, Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape,
Value,
};
#[derive(Clone)]
pub struct StrJoin;
impl Command for StrJoin {
fn name(&self) -> &str {
"str join"
}
fn signature(&self) -> Signature {
Signature::build("str join")
.optional(
"separator",
SyntaxShape::String,
"optional separator to use when creating string",
)
.category(Category::Strings)
}
fn usage(&self) -> &str {
"Concatenate multiple strings into a single string, with an optional separator between each"
}
fn search_terms(&self) -> Vec<&str> {
vec!["collect", "concatenate"]
}
fn run(
&self,
engine_state: &EngineState,
stack: &mut Stack,
call: &Call,
input: PipelineData,
) -> Result<PipelineData, ShellError> {
let separator: Option<String> = call.opt(engine_state, stack, 0)?;
let config = engine_state.get_config();
// let output = input.collect_string(&separator.unwrap_or_default(), &config)?;
// Hmm, not sure what we actually want. If you don't use debug_string, Date comes out as human readable
// which feels funny
let mut strings: Vec<String> = vec![];
for value in input {
match value {
Value::Error { error } => {
return Err(error);
}
value => {
strings.push(value.debug_string("\n", config));
}
}
}
let output = if let Some(separator) = separator {
strings.join(&separator)
} else {
strings.join("")
};
Ok(Value::String {
val: output,
span: call.head,
}
.into_pipeline_data())
}
fn examples(&self) -> Vec<Example> {
vec![
Example {
description: "Create a string from input",
example: "['nu', 'shell'] | str join",
result: Some(Value::String {
val: "nushell".to_string(),
span: Span::test_data(),
}),
},
Example {
description: "Create a string from input with a separator",
example: "['nu', 'shell'] | str join '-'",
result: Some(Value::String {
val: "nu-shell".to_string(),
span: Span::test_data(),
}),
},
]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_examples() {
use crate::test_examples;
test_examples(StrJoin {})
}
}

View file

@ -4,6 +4,7 @@ mod contains;
mod distance;
mod ends_with;
mod index_of;
mod join;
mod length;
mod lpad;
mod replace;
@ -19,6 +20,7 @@ pub use contains::SubCommand as StrContains;
pub use distance::SubCommand as StrDistance;
pub use ends_with::SubCommand as StrEndswith;
pub use index_of::SubCommand as StrIndexOf;
pub use join::*;
pub use length::SubCommand as StrLength;
pub use lpad::SubCommand as StrLpad;
pub use replace::SubCommand as StrReplace;

View file

@ -65,7 +65,7 @@ fn each_implicit_it_in_block() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
echo [[foo bar]; [a b] [c d] [e f]] | each { |it| nu --testbin cococo $it.foo } | str collect
echo [[foo bar]; [a b] [c d] [e f]] | each { |it| nu --testbin cococo $it.foo } | str join
"#
));

View file

@ -11,7 +11,7 @@ fn flatten_nested_tables_with_columns() {
[[origin, people]; [Nu, ('nuno' | wrap name)]]
| flatten --all | flatten --all
| get name
| str collect ','
| str join ','
"#
));
@ -27,7 +27,7 @@ fn flatten_nested_tables_that_have_many_columns() {
[[origin, people]; [USA, (echo [[name, meal]; ['Katz', 'nurepa']])]]
| flatten --all | flatten --all
| get meal
| str collect ','
| str join ','
"#
));

View file

@ -26,7 +26,7 @@ fn moves_a_column_before() {
| rename chars
| get chars
| str trim
| str collect
| str join
"#
));
@ -59,9 +59,9 @@ fn moves_columns_before() {
| move column99 column3 --before column2
| rename _ chars_1 chars_2
| select chars_2 chars_1
| upsert new_col {|f| $f | transpose | get column1 | str trim | str collect}
| upsert new_col {|f| $f | transpose | get column1 | str trim | str join}
| get new_col
| str collect
| str join
"#
));
@ -95,9 +95,9 @@ fn moves_a_column_after() {
| move letters and_more --before column2
| rename _ chars_1 chars_2
| select chars_1 chars_2
| upsert new_col {|f| $f | transpose | get column1 | str trim | str collect}
| upsert new_col {|f| $f | transpose | get column1 | str trim | str join}
| get new_col
| str collect
| str join
"#
));
@ -130,7 +130,7 @@ fn moves_columns_after() {
| move letters and_more --after column1
| columns
| select 1 2
| str collect
| str join
"#
));

View file

@ -13,7 +13,7 @@ fn regular_columns() {
]
| reject type first_name
| columns
| str collect ", "
| str join ", "
"#
));
@ -56,7 +56,7 @@ fn complex_nested_columns() {
| reject nu."0xATYKARNU" nu.committers
| get nu
| columns
| str collect ", "
| str join ", "
"#,
));
@ -75,7 +75,7 @@ fn ignores_duplicate_columns_rejected() {
]
| reject "first name" "first name"
| columns
| str collect ", "
| str join ", "
"#
));

View file

@ -69,7 +69,7 @@ mod columns {
format!("{} | {}", table(), pipeline(r#"
roll left
| columns
| str collect "-"
| str join "-"
"#)));
assert_eq!(actual.out, "origin-stars-commit_author");
@ -82,7 +82,7 @@ mod columns {
format!("{} | {}", table(), pipeline(r#"
roll right --by 2
| columns
| str collect "-"
| str join "-"
"#)));
assert_eq!(actual.out, "origin-stars-commit_author");
@ -97,7 +97,7 @@ mod columns {
let actual = nu!(
cwd: ".",
format!("{} | roll right --by 3 --cells-only | columns | str collect '-' ", four_bitstring)
format!("{} | roll right --by 3 --cells-only | columns | str join '-' ", four_bitstring)
);
assert_eq!(actual.out, expected_value.1);

View file

@ -25,7 +25,7 @@ fn counter_clockwise() {
]
| where column0 == EXPECTED
| get column1 column2 column3
| str collect "-"
| str join "-"
"#,
));
@ -35,7 +35,7 @@ fn counter_clockwise() {
rotate --ccw
| where column0 == EXPECTED
| get column1 column2 column3
| str collect "-"
| str join "-"
"#)));
assert_eq!(actual.out, expected.out);
@ -66,7 +66,7 @@ fn clockwise() {
]
| where column3 == EXPECTED
| get column0 column1 column2
| str collect "-"
| str join "-"
"#,
));
@ -76,7 +76,7 @@ fn clockwise() {
rotate
| where column3 == EXPECTED
| get column0 column1 column2
| str collect "-"
| str join "-"
"#)));
assert_eq!(actual.out, expected.out);

View file

@ -96,7 +96,7 @@ fn column_names_with_spaces() {
]
| select "last name"
| get "last name"
| str collect " "
| str join " "
"#
));
@ -115,7 +115,7 @@ fn ignores_duplicate_columns_selected() {
]
| select "first name" "last name" "first name"
| columns
| str collect " "
| str join " "
"#
));

View file

@ -36,7 +36,7 @@ fn condition_is_met() {
| lines
| skip 2
| str trim
| str collect (char nl)
| str join (char nl)
| from csv
| skip until "Chicken Collection" == "Red Chickens"
| skip 1

View file

@ -36,7 +36,7 @@ fn condition_is_met() {
| lines
| skip 2
| str trim
| str collect (char nl)
| str join (char nl)
| from csv
| skip while "Chicken Collection" != "Red Chickens"
| skip 1

View file

@ -5,7 +5,7 @@ fn test_1() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo 1..5 | into string | str collect
echo 1..5 | into string | str join
"#
)
);
@ -18,7 +18,7 @@ fn test_2() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [a b c d] | str collect "<sep>"
echo [a b c d] | str join "<sep>"
"#
)
);
@ -31,7 +31,7 @@ fn construct_a_path() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [sample txt] | str collect "."
echo [sample txt] | str join "."
"#
)
);
@ -44,7 +44,7 @@ fn sum_one_to_four() {
let actual = nu!(
cwd: ".", pipeline(
r#"
1..4 | each { |it| $it } | into string | str collect "+" | math eval
1..4 | each { |it| $it } | into string | str join "+" | math eval
"#
)
);

View file

@ -36,7 +36,7 @@ fn condition_is_met() {
| lines
| skip 2
| str trim
| str collect (char nl)
| str join (char nl)
| from csv
| skip while "Chicken Collection" != "Blue Chickens"
| take until "Chicken Collection" == "Red Chickens"

View file

@ -36,7 +36,7 @@ fn condition_is_met() {
| lines
| skip 2
| str trim
| str collect (char nl)
| str join (char nl)
| from csv
| skip 1
| take while "Chicken Collection" != "Blue Chickens"

View file

@ -51,7 +51,7 @@ fn zips_two_lists() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [0 2 4 6 8] | zip [1 3 5 7 9] | flatten | into string | str collect '-'
echo [0 2 4 6 8] | zip [1 3 5 7 9] | flatten | into string | str join '-'
"#
));

View file

@ -13,7 +13,7 @@ def create_left_prompt [] {
def create_right_prompt [] {
let time_segment = ([
(date now | date format '%m/%d/%Y %r')
] | str collect)
] | str join)
$time_segment
}
@ -36,11 +36,11 @@ let-env PROMPT_MULTILINE_INDICATOR = { "::: " }
let-env ENV_CONVERSIONS = {
"PATH": {
from_string: { |s| $s | split row (char esep) | path expand -n }
to_string: { |v| $v | path expand -n | str collect (char esep) }
to_string: { |v| $v | path expand -n | str join (char esep) }
}
"Path": {
from_string: { |s| $s | split row (char esep) | path expand -n }
to_string: { |v| $v | path expand -n | str collect (char esep) }
to_string: { |v| $v | path expand -n | str join (char esep) }
}
}

View file

@ -12,7 +12,7 @@ fn bits_and_negative() -> TestResult {
#[test]
fn bits_and_list() -> TestResult {
run_test("[1 2 3 8 9 10] | bits and 2 | str collect '.'", "0.2.2.0.0.2")
run_test("[1 2 3 8 9 10] | bits and 2 | str join '.'", "0.2.2.0.0.2")
}
#[test]
@ -27,7 +27,7 @@ fn bits_or_negative() -> TestResult {
#[test]
fn bits_or_list() -> TestResult {
run_test("[1 2 3 8 9 10] | bits or 2 | str collect '.'", "3.2.3.10.11.10")
run_test("[1 2 3 8 9 10] | bits or 2 | str join '.'", "3.2.3.10.11.10")
}
#[test]
@ -42,7 +42,7 @@ fn bits_xor_negative() -> TestResult {
#[test]
fn bits_xor_list() -> TestResult {
run_test("[1 2 3 8 9 10] | bits xor 2 | str collect '.'", "3.0.1.10.11.8")
run_test("[1 2 3 8 9 10] | bits xor 2 | str join '.'", "3.0.1.10.11.8")
}
#[test]
@ -57,7 +57,7 @@ fn bits_shift_left_negative() -> TestResult {
#[test]
fn bits_shift_left_list() -> TestResult {
run_test("[1 2 7 32 9 10] | bits shl 3 | str collect '.'", "8.16.56.256.72.80")
run_test("[1 2 7 32 9 10] | bits shl 3 | str join '.'", "8.16.56.256.72.80")
}
#[test]
@ -72,7 +72,7 @@ fn bits_shift_right_negative() -> TestResult {
#[test]
fn bits_shift_right_list() -> TestResult {
run_test("[12 98 7 64 900 10] | bits shr 3 | str collect '.'", "1.12.0.8.112.1")
run_test("[12 98 7 64 900 10] | bits shr 3 | str join '.'", "1.12.0.8.112.1")
}
#[test]
@ -87,7 +87,7 @@ fn bits_rotate_left_negative() -> TestResult {
#[test]
fn bits_rotate_left_list() -> TestResult {
run_test("[1 2 7 32 9 10] | bits rol 3 | str collect '.'", "8.16.56.256.72.80")
run_test("[1 2 7 32 9 10] | bits rol 3 | str join '.'", "8.16.56.256.72.80")
}
#[test]
@ -102,5 +102,5 @@ fn bits_rotate_right_negative() -> TestResult {
#[test]
fn bits_rotate_right_list() -> TestResult {
run_test("[1 2 7 32 23 10] | bits ror 60 | str collect '.'", "16.32.112.512.368.160")
run_test("[1 2 7 32 23 10] | bits ror 60 | str join '.'", "16.32.112.512.368.160")
}

View file

@ -335,7 +335,7 @@ fn in_means_input() -> TestResult {
#[test]
fn in_iteration() -> TestResult {
run_test(
r#"[3, 4, 5] | each { echo $"hi ($in)" } | str collect"#,
r#"[3, 4, 5] | each { echo $"hi ($in)" } | str join"#,
"hi 3hi 4hi 5",
)
}

View file

@ -245,7 +245,7 @@ def 'call-me' [] {
echo $CONST_A
}
[(say-hi) (call-me)] | str collect
[(say-hi) (call-me)] | str join
"#,
"HelloHello",
@ -266,7 +266,7 @@ def 'say-hi' [] {
echo (call-me)
}
[(say-hi) (call-me)] | str collect
[(say-hi) (call-me)] | str join
"#,
"HelloHello",
@ -287,7 +287,7 @@ def 'call-me' [] {
echo $CONST_A
}
[(call-me) (say-hi)] | str collect
[(call-me) (say-hi)] | str join
"#,
"HelloHello",
@ -308,7 +308,7 @@ def 'say-hi' [] {
echo (call-me)
}
[(call-me) (say-hi)] | str collect
[(call-me) (say-hi)] | str join
"#,
"HelloHello",
@ -318,7 +318,7 @@ def 'say-hi' [] {
#[test]
fn capture_row_condition() -> TestResult {
run_test(
r#"let name = "foo"; [foo] | where $'($name)' =~ $it | str collect"#,
r#"let name = "foo"; [foo] | where $'($name)' =~ $it | str join"#,
"foo",
)
}
@ -326,7 +326,7 @@ fn capture_row_condition() -> TestResult {
#[test]
fn starts_with_operator_succeeds() -> TestResult {
run_test(
r#"[Moe Larry Curly] | where $it starts-with L | str collect"#,
r#"[Moe Larry Curly] | where $it starts-with L | str join"#,
"Larry",
)
}
@ -334,7 +334,7 @@ fn starts_with_operator_succeeds() -> TestResult {
#[test]
fn ends_with_operator_succeeds() -> TestResult {
run_test(
r#"[Moe Larry Curly] | where $it ends-with ly | str collect"#,
r#"[Moe Larry Curly] | where $it ends-with ly | str join"#,
"Curly",
)
}

View file

@ -23,7 +23,7 @@ fn cell_path_var2() -> TestResult {
#[test]
fn flatten_simple_list() -> TestResult {
run_test(
"[[N, u, s, h, e, l, l]] | flatten | str collect (char nl)",
"[[N, u, s, h, e, l, l]] | flatten | str join (char nl)",
"N\nu\ns\nh\ne\nl\nl",
)
}

View file

@ -64,7 +64,7 @@ fn subexpression_properly_redirects() {
let actual = nu!(
cwd: ".",
r#"
echo (nu --testbin cococo "hello") | str collect
echo (nu --testbin cococo "hello") | str join
"#
);
@ -215,7 +215,7 @@ fn run_custom_subcommand() {
let actual = nu!(
cwd: ".",
r#"
def "str double" [x] { echo $x $x | str collect }; str double bob
def "str double" [x] { echo $x $x | str join }; str double bob
"#
);
@ -306,7 +306,7 @@ fn run_custom_command_with_rest_other_name() {
greeting:string,
...names:string # All of the names
] {
echo $"($greeting), ($names | sort-by | str collect)"
echo $"($greeting), ($names | sort-by | str join)"
}
say-hello Salutations E D C A B
"#