diff --git a/.azure/azure-pipelines.yml b/.azure/azure-pipelines.yml index 99f534841..46df33d74 100644 --- a/.azure/azure-pipelines.yml +++ b/.azure/azure-pipelines.yml @@ -1,6 +1,3 @@ -variables: - lkg-rust-nightly: "2019-08-22" - trigger: - master @@ -8,13 +5,10 @@ strategy: matrix: linux-nightly: image: ubuntu-16.04 - toolchain: nightly-$(lkg-rust-nightly) macos-nightly: image: macos-10.14 - toolchain: nightly-$(lkg-rust-nightly) windows-nightly: image: vs2017-win2016 - toolchain: nightly-$(lkg-rust-nightly) pool: vmImage: $(image) @@ -22,10 +16,8 @@ pool: steps: - bash: | set -e - curl https://sh.rustup.rs -sSf | sh -s -- -y --no-modify-path --default-toolchain none + curl https://sh.rustup.rs -sSf | sh -s -- -y --no-modify-path --default-toolchain `cat rust-toolchain` export PATH=$HOME/.cargo/bin:$PATH - rustup install --no-self-update $(toolchain) - rustup default $(toolchain) rustc -Vv echo "##vso[task.prependpath]$HOME/.cargo/bin" displayName: Install Rust diff --git a/README.md b/README.md index dd89a96ed..c94dc5978 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,12 @@ There is also a [book](https://book.nushell.sh) about Nu, currently in progress. Up-to-date installation instructions can be found in the [installation chapter of the book](https://book.nushell.sh/en/installation). +To build Nu, you will need to use the **nightly** version of the compiler. + Required dependencies: -* libssl - * on macOS (via homebrew): `brew install openssl` - * on Linux (on Debian/Ubuntu): `apt install libssl-dev` +* libssl (only needed on Linux) + * on Debian/Ubuntu: `apt install libssl-dev` Optional dependencies: @@ -156,7 +157,7 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat * Nu views data as both structured and unstructured. It is an object shell like PowerShell. -* Finally, Nu views data functionally. Rather than using mutation, pipelines act as a mean to load, change, and save data without mutable state. +* Finally, Nu views data functionally. Rather than using mutation, pipelines act as a means to load, change, and save data without mutable state. # Commands ## Initial commands @@ -184,7 +185,7 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat | pick ...columns | Down-select table to only these columns | | reject ...columns | Remove the given columns from the table | | get column-or-column-path | Open given cells as text | -| sort-by ...columns | Sort by the given columns | +| sort-by ...columns (--reverse) | Sort by the given columns | | where condition | Filter table to match the condition | | inc (field) | Increment a value or version. Optional use the field of a table | | add field value | Add a new field to the table | diff --git a/rust-toolchain b/rust-toolchain new file mode 100644 index 000000000..9647abec0 --- /dev/null +++ b/rust-toolchain @@ -0,0 +1 @@ +nightly-2019-08-22 diff --git a/src/cli.rs b/src/cli.rs index 28fef9556..a04a6211b 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -168,6 +168,8 @@ pub async fn cli() -> Result<(), Box> { whole_stream_command(SortBy), whole_stream_command(Tags), whole_stream_command(First), + whole_stream_command(Last), + whole_stream_command(FromArray), whole_stream_command(FromArray), whole_stream_command(FromCSV), whole_stream_command(FromINI), diff --git a/src/commands.rs b/src/commands.rs index 19995ab7a..3728474f2 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -22,6 +22,7 @@ crate mod from_toml; crate mod from_xml; crate mod from_yaml; crate mod get; +crate mod last; crate mod lines; crate mod ls; crate mod mkdir; @@ -76,6 +77,7 @@ crate use from_toml::FromTOML; crate use from_xml::FromXML; crate use from_yaml::FromYAML; crate use get::Get; +crate use last::Last; crate use lines::Lines; crate use ls::LS; crate use mkdir::Mkdir; diff --git a/src/commands/last.rs b/src/commands/last.rs new file mode 100644 index 000000000..18a2da96a --- /dev/null +++ b/src/commands/last.rs @@ -0,0 +1,59 @@ +use crate::commands::WholeStreamCommand; +use crate::errors::ShellError; +use crate::parser::CommandRegistry; +use crate::prelude::*; + +pub struct Last; + +impl WholeStreamCommand for Last { + fn run( + &self, + args: CommandArgs, + registry: &CommandRegistry, + ) -> Result { + last(args, registry) + } + + fn name(&self) -> &str { + "last" + } + + fn signature(&self) -> Signature { + Signature::build("last").required("amount", SyntaxType::Literal) + } +} + +fn last(args: CommandArgs, registry: &CommandRegistry) -> Result { + let args = args.evaluate_once(registry)?; + + let amount = args.expect_nth(0)?.as_i64(); + + let amount = match amount { + Ok(o) => o, + Err(_) => { + return Err(ShellError::labeled_error( + "Value is not a number", + "expected integer", + args.expect_nth(0)?.span(), + )) + } + }; + + if amount <= 0 { + return Err(ShellError::labeled_error( + "Value is too low", + "expected a positive integer", + args.expect_nth(0)?.span(), + )) + } + + let stream = async_stream_block! { + let v: Vec<_> = args.input.into_vec().await; + let k = v.len() - (amount as usize); + for x in v[k..].iter() { + let y: Tagged = x.clone(); + yield ReturnSuccess::value(y) + } + }; + Ok(stream.to_output_stream()) +} diff --git a/src/commands/sort_by.rs b/src/commands/sort_by.rs index 52d97a595..820e0a471 100644 --- a/src/commands/sort_by.rs +++ b/src/commands/sort_by.rs @@ -18,7 +18,7 @@ impl WholeStreamCommand for SortBy { } fn signature(&self) -> Signature { - Signature::build("sort-by") + Signature::build("sort-by").switch("reverse") } } @@ -37,13 +37,21 @@ fn sort_by(args: CommandArgs, registry: &CommandRegistry) -> Result>(); + let reverse = args.has("reverse"); let output = output.map(move |mut vec| { - vec.sort_by_key(|item| { + let calc_key = |item: &Tagged| { fields .iter() .map(|f| item.get_data_by_key(f).map(|i| i.clone())) .collect::>>>() - }); + }; + if reverse { + vec.sort_by_cached_key(|item| { + std::cmp::Reverse(calc_key(item)) + }); + } else { + vec.sort_by_cached_key(calc_key); + } vec.into_iter().collect::>() }); diff --git a/src/lib.rs b/src/lib.rs index 41185bbc5..a9ef8740f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,6 @@ #![feature(generators)] #![feature(try_trait)] #![feature(bind_by_move_pattern_guards)] -#![feature(core_intrinsics)] #![feature(option_flattening)] #![feature(specialization)] #![feature(proc_macro_hygiene)] diff --git a/src/main.rs b/src/main.rs index 882caaa6a..7f82808e7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ use std::error::Error; fn main() -> Result<(), Box> { let matches = App::new("nushell") - .version("0.1.3") + .version(clap::crate_version!()) .arg( Arg::with_name("loglevel") .short("l") diff --git a/src/object/types.rs b/src/object/types.rs index 8177f23ff..719a990ad 100644 --- a/src/object/types.rs +++ b/src/object/types.rs @@ -14,7 +14,7 @@ pub trait ExtractType: Sized { impl ExtractType for T { default fn extract(_value: &Tagged) -> Result { - let name = std::intrinsics::type_name::(); + let name = std::any::type_name::(); Err(ShellError::unimplemented(format!( " ExtractType for {}", name @@ -32,7 +32,7 @@ impl ExtractType for T { impl ExtractType for Vec> { fn extract(value: &Tagged) -> Result { - let name = std::intrinsics::type_name::(); + let name = std::any::type_name::(); trace!(" Extracting {:?} for Vec<{}>", value, name); match value.item() { @@ -69,8 +69,8 @@ impl ExtractType for Vec> { impl ExtractType for (T, U) { fn extract(value: &Tagged) -> Result<(T, U), ShellError> { - let t_name = std::intrinsics::type_name::(); - let u_name = std::intrinsics::type_name::(); + let t_name = std::any::type_name::(); + let u_name = std::any::type_name::(); trace!("Extracting {:?} for ({}, {})", value, t_name, u_name); @@ -98,7 +98,7 @@ impl ExtractType for (T, U) { impl ExtractType for Option { fn extract(value: &Tagged) -> Result, ShellError> { - let name = std::intrinsics::type_name::(); + let name = std::any::type_name::(); trace!("