2023-03-11 19:10:32 +01:00
# this module regroups a bunch of development tools to make the development
# process easier for anyone.
#
# the main purpose of `toolkit` is to offer an easy to use interface for the
# developer during a PR cycle, namely to (**1**) format the source base,
# (**2**) catch classical flaws in the new changes with *clippy* and (**3**)
# make sure all the tests pass.
# check standard code formatting and apply the changes
export def fmt [
2023-09-23 10:20:48 +02:00
--check # do not apply the format changes, only check the syntax
--verbose # print extra information about the command's progress
2023-03-11 19:10:32 +01:00
] {
2023-04-13 14:34:23 +02:00
if $verbose {
2023-08-25 19:23:30 +02:00
print $"running ('toolkit fmt' | pretty-format-command)"
2023-04-13 14:34:23 +02:00
}
if $check {
try {
2024-09-27 15:52:48 +02:00
^cargo fmt --all -- --check
2023-04-13 14:34:23 +02:00
} catch {
2023-06-18 16:16:05 +02:00
error make --unspanned {
2023-08-25 19:23:30 +02:00
msg: $"\nplease run ('toolkit fmt' | pretty-format-command) to fix formatting!"
2023-06-18 16:16:05 +02:00
}
2023-04-13 14:34:23 +02:00
}
2023-03-11 19:10:32 +01:00
} else {
2024-09-27 15:52:48 +02:00
^cargo fmt --all
2023-03-11 19:10:32 +01:00
}
}
# check that you're using the standard code style
#
# > it is important to make `clippy` happy :relieved:
2023-04-13 14:34:23 +02:00
export def clippy [
2023-09-23 10:20:48 +02:00
--verbose # print extra information about the command's progress
2023-06-18 16:16:05 +02:00
--features: list<string> # the list of features to run *Clippy* on
2023-04-13 14:34:23 +02:00
] {
if $verbose {
2023-08-25 19:23:30 +02:00
print $"running ('toolkit clippy' | pretty-format-command)"
2023-04-13 14:34:23 +02:00
}
2023-11-09 19:07:15 +01:00
# If changing these settings also change CI settings in .github/workflows/ci.yml
2023-09-29 19:51:19 +02:00
try {(
2024-09-27 15:52:48 +02:00
^cargo clippy
2023-09-29 19:51:19 +02:00
--workspace
2023-11-09 19:07:15 +01:00
--exclude nu_plugin_*
--features ($features | str join ",")
2024-09-27 15:52:48 +02:00
--
2023-11-09 19:07:15 +01:00
-D warnings
-D clippy::unwrap_used
2024-04-17 14:25:16 +02:00
-D clippy::unchecked_duration_subtraction
2023-11-09 19:07:15 +01:00
)
if $verbose {
print $"running ('toolkit clippy' | pretty-format-command) on tests"
}
# In tests we don't have to deny unwrap
(
2024-09-27 15:52:48 +02:00
^cargo clippy
2023-09-29 19:51:19 +02:00
--tests
2023-11-09 19:07:15 +01:00
--workspace
--exclude nu_plugin_*
2023-09-29 19:51:19 +02:00
--features ($features | str join ",")
2024-09-27 15:52:48 +02:00
--
2023-09-29 19:51:19 +02:00
-D warnings
2023-11-09 19:07:15 +01:00
)
if $verbose {
print $"running ('toolkit clippy' | pretty-format-command) on plugins"
}
(
2024-09-27 15:52:48 +02:00
^cargo clippy
2023-11-09 19:07:15 +01:00
--package nu_plugin_*
2024-09-27 15:52:48 +02:00
--
2023-11-09 19:07:15 +01:00
-D warnings
-D clippy::unwrap_used
2024-04-17 14:25:16 +02:00
-D clippy::unchecked_duration_subtraction
2023-11-09 19:07:15 +01:00
)
} catch {
2023-06-18 16:16:05 +02:00
error make --unspanned {
2023-08-25 19:23:30 +02:00
msg: $"\nplease fix the above ('clippy' | pretty-format-command) errors before continuing!"
2023-06-18 16:16:05 +02:00
}
2023-04-13 14:34:23 +02:00
}
2023-03-11 19:10:32 +01:00
}
# check that all the tests pass
export def test [
2023-09-23 10:20:48 +02:00
--fast # use the "nextext" `cargo` subcommand to speed up the tests (see [`cargo-nextest`](https://nexte.st/) and [`nextest-rs/nextest`](https://github.com/nextest-rs/nextest))
2023-06-18 16:16:05 +02:00
--features: list<string> # the list of features to run the tests on
2023-09-23 10:20:48 +02:00
--workspace # run the *Clippy* command on the whole workspace (overrides `--features`)
2023-03-11 19:10:32 +01:00
] {
2023-06-18 16:16:05 +02:00
if $fast {
if $workspace {
2024-09-27 15:52:48 +02:00
^cargo nextest run --all
2023-06-18 16:16:05 +02:00
} else {
2024-09-27 15:52:48 +02:00
^cargo nextest run --features ($features | str join ",")
2023-06-18 16:16:05 +02:00
}
2023-03-11 19:10:32 +01:00
} else {
2023-06-18 16:16:05 +02:00
if $workspace {
2024-09-27 15:52:48 +02:00
^cargo test --workspace
2023-06-18 16:16:05 +02:00
} else {
2024-09-27 15:52:48 +02:00
^cargo test --features ($features | str join ",")
2023-06-18 16:16:05 +02:00
}
2023-03-11 19:10:32 +01:00
}
}
2023-03-30 19:25:42 +02:00
# run the tests for the standard library
2023-07-02 10:41:33 +02:00
export def "test stdlib" [
--extra-args: string = ''
] {
2024-09-27 15:52:48 +02:00
^cargo run -- --no-config-file -c $"
2024-01-25 11:50:07 +01:00
use crates/nu-std/testing.nu
testing run-tests --path crates/nu-std ($extra_args)
"
2023-03-30 19:25:42 +02:00
}
2023-08-25 19:23:30 +02:00
# formats the pipe input inside backticks, dimmed and italic, as a pretty command
def pretty-format-command [] {
2023-03-18 13:58:21 +01:00
$"`(ansi default_dimmed)(ansi default_italic)($in)(ansi reset)`"
}
# return a report about the check stage
#
# - fmt comes first
# - then clippy
# - and finally the tests
#
# without any option, `report` will return an empty report.
# otherwise, the truth values will be incremental, following
# the order above.
def report [
2023-09-23 10:20:48 +02:00
--fail-fmt
--fail-clippy
--fail-test
--fail-test-stdlib
--no-fail
2023-03-18 13:58:21 +01:00
] {
2023-03-30 19:25:42 +02:00
[fmt clippy test "test stdlib"]
| wrap stage
2023-03-18 13:58:21 +01:00
| merge (
2023-03-30 19:25:42 +02:00
if $no_fail { [true true true true] }
2023-09-26 18:49:28 +02:00
else if $fail_fmt { [false null null null] }
else if $fail_clippy { [true false null null] }
else if $fail_test { [true true false null] }
2023-03-30 19:25:42 +02:00
else if $fail_test_stdlib { [true true true false] }
2023-09-26 18:49:28 +02:00
else { [null null null null] }
2023-03-18 13:58:21 +01:00
| wrap success
)
| upsert emoji {|it|
2023-09-26 18:49:28 +02:00
if ($it.success == null) {
2023-03-18 13:58:21 +01:00
":black_circle:"
} else if $it.success {
":green_circle:"
} else {
":red_circle:"
}
}
| each {|it|
$"- ($it.emoji) `toolkit ($it.stage)`"
}
| to text
}
2023-03-11 19:10:32 +01:00
# run all the necessary checks and tests to submit a perfect PR
#
# # Example
# let us say we apply a change that
# - breaks the formatting, e.g. with extra newlines everywhere
# - makes clippy sad, e.g. by adding unnecessary string conversions with `.to_string()`
# - breaks the tests by output bad string data from a data structure conversion
#
# > the following diff breaks all of the three checks!
# > ```diff
# > diff --git a/crates/nu-command/src/formats/to/nuon.rs b/crates/nu-command/src/formats/to/nuon.rs
# > index abe34c054..927d6a3de 100644
# > --- a/crates/nu-command/src/formats/to/nuon.rs
# > +++ b/crates/nu-command/src/formats/to/nuon.rs
# > @@ -131,7 +131,8 @@ pub fn value_to_string(v: &Value, span: Span) -> Result<String, ShellError> {
# > }
# > })
# > .collect();
# > - let headers_output = headers.join(", ");
# > + let headers_output = headers.join(&format!("x {}", "")
# > + .to_string());
# >
# > let mut table_output = vec![];
# > for val in vals {
# > ```
#
2023-03-18 13:58:21 +01:00
# > **Note**
# > at every stage, the `toolkit check pr` will return a report of the few stages being run.
#
2023-03-11 19:10:32 +01:00
# - we run the toolkit once and it fails...
# ```nushell
# >_ toolkit check pr
# running `toolkit fmt`
# Diff in /home/amtoine/.local/share/git/store/github.com/amtoine/nushell/crates/nu-command/src/formats/to/nuon.rs at line 131:
# }
# })
# .collect();
# - let headers_output = headers.join(&format!("x {}", "")
# - .to_string());
# + let headers_output = headers.join(&format!("x {}", "").to_string());
#
# let mut table_output = vec![];
# for val in vals {
#
# please run toolkit fmt to fix the formatting
# ```
# - we run `toolkit fmt` as proposed and rerun the toolkit... to see clippy is sad...
# ```nushell
# running `toolkit fmt`
# running `toolkit clippy`
# ...
# error: redundant clone
# --> crates/nu-command/src/formats/to/nuon.rs:134:71
# |
# 134 | let headers_output = headers.join(&format!("x {}", "").to_string());
# | ^^^^^^^^^^^^ help: remove this
# |
# note: this value is dropped without further use
# --> crates/nu-command/src/formats/to/nuon.rs:134:52
# |
# 134 | let headers_output = headers.join(&format!("x {}", "").to_string());
# | ^^^^^^^^^^^^^^^^^^^
# = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone
# = note: `-D clippy::redundant-clone` implied by `-D warnings`
#
# error: could not compile `nu-command` due to previous error
# ```
2023-09-07 22:46:00 +02:00
# - we remove the useless `.to_string()`, and in that cases, the whole format is useless, only `"x "` is useful!
2023-03-11 19:10:32 +01:00
# but now the tests do not pass :sob:
# ```nushell
# running `toolkit fmt`
# running `toolkit clippy`
# ...
# running `toolkit test`
# ...
# failures:
# commands::insert::insert_uses_enumerate_index
# commands::merge::multi_row_table_overwrite
# commands::merge::single_row_table_no_overwrite
# commands::merge::single_row_table_overwrite
# commands::update::update_uses_enumerate_index
# commands::upsert::upsert_uses_enumerate_index_inserting
# commands::upsert::upsert_uses_enumerate_index_updating
# commands::where_::where_uses_enumerate_index
# format_conversions::nuon::does_not_quote_strings_unnecessarily
# format_conversions::nuon::to_nuon_table
# ```
# - finally let's fix the tests by removing the `x`, essentially removing the whole diff we applied at the top!
#
# now the whole `toolkit check pr` passes! :tada:
export def "check pr" [
2023-09-23 10:20:48 +02:00
--fast # use the "nextext" `cargo` subcommand to speed up the tests (see [`cargo-nextest`](https://nexte.st/) and [`nextest-rs/nextest`](https://github.com/nextest-rs/nextest))
2023-06-18 16:16:05 +02:00
--features: list<string> # the list of features to check the current PR on
2023-03-11 19:10:32 +01:00
] {
2024-01-24 18:55:27 +01:00
$env.NU_TEST_LOCALE_OVERRIDE = 'en_US.utf8'
$env.LANG = 'en_US.UTF-8'
$env.LANGUAGE = 'en'
2023-03-11 19:10:32 +01:00
try {
2023-04-13 14:34:23 +02:00
fmt --check --verbose
2023-03-11 19:10:32 +01:00
} catch {
2023-03-18 13:58:21 +01:00
return (report --fail-fmt)
}
try {
2023-06-18 16:16:05 +02:00
clippy --features $features --verbose
2023-03-18 13:58:21 +01:00
} catch {
return (report --fail-clippy)
2023-03-11 19:10:32 +01:00
}
2023-08-25 19:23:30 +02:00
print $"running ('toolkit test' | pretty-format-command)"
2023-03-18 13:58:21 +01:00
try {
2023-06-18 16:16:05 +02:00
if $fast {
2023-11-21 18:19:35 +01:00
if ($features | is-empty) {
test --workspace --fast
} else {
test --features $features --fast
}
2023-06-10 20:16:17 +02:00
} else {
2023-11-21 18:19:35 +01:00
if ($features | is-empty) {
test --workspace
} else {
test --features $features
}
2023-05-12 19:03:51 +02:00
}
2023-03-18 13:58:21 +01:00
} catch {
return (report --fail-test)
}
2023-03-11 19:10:32 +01:00
2023-08-25 19:23:30 +02:00
print $"running ('toolkit test stdlib' | pretty-format-command)"
2023-03-30 19:25:42 +02:00
try {
test stdlib
} catch {
return (report --fail-test-stdlib)
}
2023-03-18 13:58:21 +01:00
report --no-fail
2023-03-11 19:10:32 +01:00
}
2023-04-13 14:34:23 +02:00
2023-10-20 15:55:46 +02:00
# run Nushell from source with a right indicator
export def run [] {
2024-09-27 15:52:48 +02:00
^cargo run -- ...[
2023-10-20 15:55:46 +02:00
-e "$env.PROMPT_COMMAND_RIGHT = $'(ansi magenta_reverse)trying Nushell inside Cargo(ansi reset)'"
]
}
2023-04-13 14:34:23 +02:00
# set up git hooks to run:
# - `toolkit fmt --check --verbose` on `git commit`
# - `toolkit fmt --check --verbose` and `toolkit clippy --verbose` on `git push`
2023-04-16 03:39:52 +02:00
export def setup-git-hooks [] {
2023-04-13 14:34:23 +02:00
print "This command will change your local git configuration and hence modify your development workflow. Are you sure you want to continue? [y]"
if (input) == "y" {
2023-08-25 19:23:30 +02:00
print $"running ('toolkit setup-git-hooks' | pretty-format-command)"
2023-04-13 14:34:23 +02:00
git config --local core.hooksPath .githooks
} else {
2023-08-25 19:23:30 +02:00
print $"aborting ('toolkit setup-git-hooks' | pretty-format-command)"
2023-04-13 14:34:23 +02:00
}
}
2023-05-08 13:45:29 +02:00
2023-05-26 11:22:34 +02:00
def build-nushell [features: string] {
print $'(char nl)Building nushell'
print '----------------------------'
2024-09-27 15:52:48 +02:00
^cargo build --features $features --locked
2023-05-26 11:22:34 +02:00
}
def build-plugin [] {
let plugin = $in
print $'(char nl)Building ($plugin)'
print '----------------------------'
cd $"crates/($plugin)"
2024-09-27 15:52:48 +02:00
^cargo build
2023-05-26 11:22:34 +02:00
}
# build Nushell and plugins with some features
export def build [
...features: string@"nu-complete list features" # a space-separated list of feature to install with Nushell
2023-09-23 10:20:48 +02:00
--all # build all plugins with Nushell
2023-05-26 11:22:34 +02:00
] {
build-nushell ($features | str join ",")
if not $all {
return
}
let plugins = [
nu_plugin_inc,
nu_plugin_gstat,
nu_plugin_query,
nu_plugin_example,
nu_plugin_custom_values,
nu_plugin_formats,
]
for plugin in $plugins {
$plugin | build-plugin
}
}
Start to Add WASM Support Again (#14418)
<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx
you can also mention related issues, PRs or discussions!
-->
# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.
Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->
The [nushell/demo](https://github.com/nushell/demo) project successfully
demonstrated running Nushell in the browser using WASM. However, the
current version of Nushell cannot be easily built for the
`wasm32-unknown-unknown` target, the default for `wasm-bindgen`.
This PR introduces initial support for the `wasm32-unknown-unknown`
target by disabling OS-dependent features such as filesystem access, IO,
and platform/system-specific functionality. This separation is achieved
using a new `os` feature in the following crates:
- `nu-cmd-lang`
- `nu-command`
- `nu-engine`
- `nu-protocol`
The `os` feature includes all functionality that interacts with an
operating system. It is enabled by default, but can be disabled using
`--no-default-features`. All crates that depend on these core crates now
use `--no-default-features` to allow compilation for WASM.
To demonstrate compatibility, the following script builds all crates
expected to work with WASM. Direct user interaction, running external
commands, working with plugins, and features requiring `openssl` are out
of scope for now due to their complexity or reliance on C libraries,
which are difficult to compile and link in a WASM environment.
```nushell
[ # compatible crates
"nu-cmd-base",
"nu-cmd-extra",
"nu-cmd-lang",
"nu-color-config",
"nu-command",
"nu-derive-value",
"nu-engine",
"nu-glob",
"nu-json",
"nu-parser",
"nu-path",
"nu-pretty-hex",
"nu-protocol",
"nu-std",
"nu-system",
"nu-table",
"nu-term-grid",
"nu-utils",
"nuon"
] | each {cargo build -p $in --target wasm32-unknown-unknown --no-default-features}
```
## Caveats
This PR has a few caveats:
1. **`miette` and `terminal-size` Dependency Issue**
`miette` depends on `terminal-size`, which uses `rustix` when the target
is not Windows. However, `rustix` requires `std::os::unix`, which is
unavailable in WASM. To address this, I opened a
[PR](https://github.com/eminence/terminal-size/pull/68) for
`terminal-size` to conditionally compile `rustix` only when the target
is Unix. For now, the `Cargo.toml` includes patches to:
- Use my forked version of `terminal-size`.
- ~~Use an unreleased version of `miette` that depends on
`terminal-size@0.4`.~~
These patches are temporary and can be removed once the upstream changes
are merged and released.
2. **Test Output Adjustments**
Due to the slight bump in the `miette` version, one test required
adjustments to accommodate minor formatting changes in the error output,
such as shifted newlines.
# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->
This shouldn't break anything but allows using some crates for targeting
`wasm32-unknown-unknown` to revive the demo page eventually.
# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.
Make sure you've run and fixed any issues with these commands:
- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use toolkit.nu; toolkit test stdlib"` to run the
tests for the standard library
> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->
- :green_circle: `toolkit fmt`
- :green_circle: `toolkit clippy`
- :green_circle: `toolkit test`
- :green_circle: `toolkit test stdlib`
I did not add any extra tests, I just checked that compiling works, also
when using the host target but unselecting the `os` feature.
# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
~~Breaking the wasm support can be easily done by adding some `use`s or
by adding a new dependency, we should definitely add some CI that also
at least builds against wasm to make sure that building for it keep
working.~~
I added a job to build wasm.
---------
Co-authored-by: Ian Manske <ian.manske@pm.me>
2024-11-30 14:57:11 +01:00
# build crates for wasm
export def "build wasm" [] {
^rustup target add wasm32-unknown-unknown
# these crates should compile for wasm
let compatible_crates = [
"nu-cmd-base",
"nu-cmd-extra",
"nu-cmd-lang",
"nu-color-config",
"nu-command",
"nu-derive-value",
"nu-engine",
"nu-glob",
"nu-json",
"nu-parser",
"nu-path",
"nu-pretty-hex",
"nu-protocol",
"nu-std",
"nu-system",
"nu-table",
"nu-term-grid",
"nu-utils",
"nuon"
]
for crate in $compatible_crates {
print $'(char nl)Building ($crate) for wasm'
print '----------------------------'
^cargo build -p $crate --target wasm32-unknown-unknown --no-default-features
}
}
2023-05-26 11:22:34 +02:00
def "nu-complete list features" [] {
open Cargo.toml | get features | transpose feature dependencies | get feature
}
2023-06-13 15:28:53 +02:00
def install-plugin [] {
let plugin = $in
print $'(char nl)Installing ($plugin)'
print '----------------------------'
2024-09-27 15:52:48 +02:00
^cargo install --path $"crates/($plugin)"
2023-06-13 15:28:53 +02:00
}
2023-05-26 11:22:34 +02:00
# install Nushell and features you want
export def install [
...features: string@"nu-complete list features" # a space-separated list of feature to install with Nushell
2023-09-23 10:20:48 +02:00
--all # install all plugins with Nushell
2023-05-26 11:22:34 +02:00
] {
2023-08-07 19:25:24 +02:00
touch crates/nu-cmd-lang/build.rs # needed to make sure `version` has the correct `commit_hash`
2024-09-27 15:52:48 +02:00
^cargo install --path . --features ($features | str join ",") --locked --force
2023-06-13 15:28:53 +02:00
if not $all {
return
}
let plugins = [
nu_plugin_inc,
nu_plugin_gstat,
nu_plugin_query,
nu_plugin_example,
nu_plugin_custom_values,
nu_plugin_formats,
]
2023-08-21 19:42:42 +02:00
2023-06-13 15:28:53 +02:00
for plugin in $plugins {
$plugin | install-plugin
}
2023-05-26 11:22:34 +02:00
}
def windows? [] {
$nu.os-info.name == windows
}
# filter out files that end in .d
def keep-plugin-executables [] {
if (windows?) { where name ends-with '.exe' } else { where name !~ '\.d' }
}
2024-04-22 01:23:12 +02:00
# add all installed plugins
export def "add plugins" [] {
2023-05-26 11:22:34 +02:00
let plugin_path = (which nu | get path.0 | path dirname)
2024-04-22 01:23:12 +02:00
let plugins = (ls $plugin_path | where name =~ nu_plugin | keep-plugin-executables | get name)
2023-05-26 11:22:34 +02:00
if ($plugins | is-empty) {
print $"no plugins found in ($plugin_path)..."
return
}
for plugin in $plugins {
2024-04-22 01:23:12 +02:00
try {
print $"> plugin add ($plugin)"
plugin add $plugin
} catch { |err|
print -e $"(ansi rb)Failed to add ($plugin):\n($err.msg)(ansi reset)"
}
2023-05-26 11:22:34 +02:00
}
2024-04-22 01:23:12 +02:00
print $"\n(ansi gb)plugins registered, please restart nushell(ansi reset)"
2023-05-26 11:22:34 +02:00
}
def compute-coverage [] {
print "Setting up environment variables for coverage"
# Enable LLVM coverage tracking through environment variables
# show env outputs .ini/.toml style description of the variables
# In order to use from toml, we need to make sure our string literals are single quoted
# This is especially important when running on Windows since "C:\blah" is treated as an escape
2024-09-27 15:52:48 +02:00
^cargo llvm-cov show-env | str replace (char dq) (char sq) -a | from toml | load-env
2023-05-26 11:22:34 +02:00
print "Cleaning up coverage data"
2024-09-27 15:52:48 +02:00
^cargo llvm-cov clean --workspace
2023-05-26 11:22:34 +02:00
print "Building with workspace and profile=ci"
# Apparently we need to explicitly build the necessary parts
# using the `--profile=ci` is basically `debug` build with unnecessary symbols stripped
# leads to smaller binaries and potential savings when compiling and running
2024-09-27 15:52:48 +02:00
^cargo build --workspace --profile=ci
2023-05-26 11:22:34 +02:00
print "Running tests with --workspace and profile=ci"
2024-09-27 15:52:48 +02:00
^cargo test --workspace --profile=ci
2023-05-26 11:22:34 +02:00
# You need to provide the used profile to find the raw data
print "Generating coverage report as lcov.info"
2024-09-27 15:52:48 +02:00
^cargo llvm-cov report --lcov --output-path lcov.info --profile=ci
2023-05-26 11:22:34 +02:00
}
# Script to generate coverage locally
#
# Output: `lcov.info` file
#
# Relies on `cargo-llvm-cov`. Install via `cargo install cargo-llvm-cov`
# https://github.com/taiki-e/cargo-llvm-cov
#
# You probably have to run `cargo llvm-cov clean` once manually,
# as you have to confirm to install additional tooling for your rustup toolchain.
# Else the script might stall waiting for your `y<ENTER>`
#
# Some of the internal tests rely on the exact cargo profile
# (This is somewhat criminal itself)
# but we have to signal to the tests that we use the `ci` `--profile`
#
# Manual gathering of coverage to catch invocation of the `nu` binary.
# This is relevant for tests using the `nu!` macro from `nu-test-support`
# see: https://github.com/taiki-e/cargo-llvm-cov#get-coverage-of-external-tests
#
# To display the coverage in your editor see:
#
# - https://marketplace.visualstudio.com/items?itemName=ryanluker.vscode-coverage-gutters
# - https://github.com/umaumax/vim-lcov
# - https://github.com/andythigpen/nvim-coverage (probably needs some additional config)
export def cov [] {
let start = (date now)
Fix unit tests on Android (#10224)
# Description
* The path to the binaries for tests is slightly incorrect. It is
missing the build target when it is set with the `CARGO_BUILD_TARGET`
environment variable. For example, when `CARGO_BUILD_TARGET` is set to
`aarch64-linux-android`, the path to the `nu` binary is:
`./target/aarch64-linux-android/debug/nu`
rather than
`./target/debug/nu`
This is common on Termux since the default target that rustc detects can
cause problems on some projects, such as [python's `cryptography`
package](https://github.com/pyca/cryptography/issues/7248).
This technically isn't a problem specific to Android, but is more likely
to happen on Android due to the latter.
* Additionally, the existing variable named `NUSHELL_CARGO_TARGET` is in
fact the profile, not the build target, so this was renamed to
`NUSHELL_CARGO_PROFILE`. This change is included because without the
rename, the build system would be using `CARGO_BUILD_TARGET` for the
build target and `NUSHELL_CARGO_TARGET` for the build profile, which is
confusing.
* `std path add` tests were missing `android` test
# User-Facing Changes
For those who would like to build nushell on Termux, the unit tests will
pass now.
2023-09-05 10:17:34 +02:00
$env.NUSHELL_CARGO_PROFILE = "ci"
2023-05-26 11:22:34 +02:00
compute-coverage
let end = (date now)
print $"Coverage generation took ($end - $start)."
}
2024-06-09 13:03:52 +02:00
# Benchmark a target revision (default: current branch) against a reference revision (default: main branch)
#
# Results are saved in a `./tango` directory
Tango migration (#12469)
# Description
This PR migrates the benchmark suit to Tango. Its different compared to
other framework because it require 2 binaries, to run to do A/B
benchmarking, this is currently limited to Linux, Max, (Windows require
rustc nightly flag), by switching between two suits it can reduce noise
and run the code "almost" concurrently. I have have been in contact with
the maintainer, and bases this on the dev branch, as it had a newer API
simular to criterion. This framework compared to Divan also have a
simple file dump system if we want to generate graphs, do other analysis
on later. I think overall this crate is very nice, a lot faster to
compile and run then criterion, that's for sure.
2024-05-05 17:53:48 +02:00
# Ensure you have `cargo-export` installed to generate separate artifacts for each branch.
2024-06-09 13:03:52 +02:00
export def benchmark-compare [
target?: string # which branch to compare (default: current branch)
reference?: string # the reference to compare against (default: main branch)
] {
let reference = $reference | default "main"
let current = git branch --show-current
let target = $target | default $current
print $'-- Benchmarking ($target) against ($reference)'
let export_dir = $env.PWD | path join "tango"
let ref_bin_dir = $export_dir | path join bin $reference
let tgt_bin_dir = $export_dir | path join bin $target
# benchmark the target revision
print $'-- Running benchmarks for ($target)'
git checkout $target
2024-09-27 15:52:48 +02:00
^cargo export $tgt_bin_dir -- bench
2024-06-09 13:03:52 +02:00
# benchmark the comparison reference revision
print $'-- Running benchmarks for ($reference)'
git checkout $reference
2024-09-27 15:52:48 +02:00
^cargo export $ref_bin_dir -- bench
2024-06-09 13:03:52 +02:00
# return back to the whatever revision before benchmarking
print '-- Done'
git checkout $current
# report results
let reference_bin = $ref_bin_dir | path join benchmarks
let target_bin = $tgt_bin_dir | path join benchmarks
^$target_bin compare $reference_bin -o -s 50 --dump ($export_dir | path join samples)
Tango migration (#12469)
# Description
This PR migrates the benchmark suit to Tango. Its different compared to
other framework because it require 2 binaries, to run to do A/B
benchmarking, this is currently limited to Linux, Max, (Windows require
rustc nightly flag), by switching between two suits it can reduce noise
and run the code "almost" concurrently. I have have been in contact with
the maintainer, and bases this on the dev branch, as it had a newer API
simular to criterion. This framework compared to Divan also have a
simple file dump system if we want to generate graphs, do other analysis
on later. I think overall this crate is very nice, a lot faster to
compile and run then criterion, that's for sure.
2024-05-05 17:53:48 +02:00
}
2024-06-09 13:03:52 +02:00
# Benchmark the current branch and logs the result in `./tango/samples`
#
# Results are saved in a `./tango` directory
Tango migration (#12469)
# Description
This PR migrates the benchmark suit to Tango. Its different compared to
other framework because it require 2 binaries, to run to do A/B
benchmarking, this is currently limited to Linux, Max, (Windows require
rustc nightly flag), by switching between two suits it can reduce noise
and run the code "almost" concurrently. I have have been in contact with
the maintainer, and bases this on the dev branch, as it had a newer API
simular to criterion. This framework compared to Divan also have a
simple file dump system if we want to generate graphs, do other analysis
on later. I think overall this crate is very nice, a lot faster to
compile and run then criterion, that's for sure.
2024-05-05 17:53:48 +02:00
# Ensure you have `cargo-export` installed to generate separate artifacts for each branch.
2024-06-09 13:03:52 +02:00
export def benchmark-log [
target?: string # which branch to compare (default: current branch)
] {
let current = git branch --show-current
let target = $target | default $current
print $'-- Benchmarking ($target)'
let export_dir = $env.PWD | path join "tango"
let bin_dir = ($export_dir | path join bin $target)
# benchmark the target revision
if $target != $current {
git checkout $target
}
2024-09-27 15:52:48 +02:00
^cargo export $bin_dir -- bench
2024-06-09 13:03:52 +02:00
# return back to the whatever revision before benchmarking
print '-- Done'
if $target != $current {
git checkout $current
}
Tango migration (#12469)
# Description
This PR migrates the benchmark suit to Tango. Its different compared to
other framework because it require 2 binaries, to run to do A/B
benchmarking, this is currently limited to Linux, Max, (Windows require
rustc nightly flag), by switching between two suits it can reduce noise
and run the code "almost" concurrently. I have have been in contact with
the maintainer, and bases this on the dev branch, as it had a newer API
simular to criterion. This framework compared to Divan also have a
simple file dump system if we want to generate graphs, do other analysis
on later. I think overall this crate is very nice, a lot faster to
compile and run then criterion, that's for sure.
2024-05-05 17:53:48 +02:00
2024-06-09 13:03:52 +02:00
# report results
let bench_bin = ($bin_dir | path join benchmarks)
^$bench_bin compare -o -s 50 --dump ($export_dir | path join samples)
2024-05-20 19:22:08 +02:00
}
Tango migration (#12469)
# Description
This PR migrates the benchmark suit to Tango. Its different compared to
other framework because it require 2 binaries, to run to do A/B
benchmarking, this is currently limited to Linux, Max, (Windows require
rustc nightly flag), by switching between two suits it can reduce noise
and run the code "almost" concurrently. I have have been in contact with
the maintainer, and bases this on the dev branch, as it had a newer API
simular to criterion. This framework compared to Divan also have a
simple file dump system if we want to generate graphs, do other analysis
on later. I think overall this crate is very nice, a lot faster to
compile and run then criterion, that's for sure.
2024-05-05 17:53:48 +02:00
2024-05-02 01:51:44 +02:00
# Build all Windows archives and MSIs for release manually
#
# This builds std and full distributions for both aarch64 and x86_64.
#
# You need to have the cross-compilers for MSVC installed (see Visual Studio).
# If compiling on x86_64, you need ARM64 compilers and libs too, and vice versa.
export def 'release-pkg windows' [
--artifacts-dir="artifacts" # Where to copy the final msi and zip files to
] {
$env.RUSTFLAGS = ""
$env.CARGO_TARGET_DIR = ""
hide-env RUSTFLAGS
hide-env CARGO_TARGET_DIR
$env.OS = "windows-latest"
$env.GITHUB_WORKSPACE = ("." | path expand)
$env.GITHUB_OUTPUT = ("./output/out.txt" | path expand)
let version = (open Cargo.toml | get package.version)
mkdir $artifacts_dir
for target in ["aarch64" "x86_64"] {
$env.TARGET = $target ++ "-pc-windows-msvc"
2024-05-20 19:22:08 +02:00
rm -rf output
_EXTRA_=bin nu .github/workflows/release-pkg.nu
cp $"output/nu-($version)-($target)-pc-windows-msvc.zip" $artifacts_dir
rm -rf output
_EXTRA_=msi nu .github/workflows/release-pkg.nu
cp $"target/wix/nu-($version)-($target)-pc-windows-msvc.msi" $artifacts_dir
2024-05-02 01:51:44 +02:00
}
}
2023-05-08 13:45:29 +02:00
export def main [] { help toolkit }