feat(aquavm-air-cli)!: Usability enhancements (#540)

* Fix aquavm-air-cli release-please config
* Print a prompt when AIR is read from stdin
* Make `run --plain --data` arg optional
* Rename `... --data` to `... --current-data`
* Update AIR cli README
This commit is contained in:
Ivan Boldyrev 2023-03-27 16:27:01 +07:00 committed by GitHub
parent 28cf5045b6
commit 73c1ba70cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 58 additions and 20 deletions

View File

@ -50,7 +50,9 @@
},
"crates/data-store": {},
"crates/testing-framework": {},
"tools/cli/aquavm-air-cli": {},
"tools/cli/air": {
"component": "aquavm-air-cli"
},
"tools/wasm/air-beautify-wasm": {
"component": "air-beautify-wasm"
}

2
Cargo.lock generated
View File

@ -278,12 +278,14 @@ dependencies = [
"air-test-utils",
"anyhow",
"aquavm-air",
"atty",
"avm-data-store",
"avm-interface",
"clap 4.1.11",
"itertools",
"serde",
"serde_json",
"termcolor",
"tracing-subscriber",
]

View File

@ -115,7 +115,7 @@ function main {
eval "${script_cmd}" | \
air run "$@" --repeat 1 --plain \
--prev-data "$prev_data_path" \
--data "$current_data_path"
--current-data "$current_data_path"
done
done
}

View File

@ -23,6 +23,8 @@ itertools = "0.10.5"
serde = { version = "1.0.158", features = ["derive"] }
serde_json = "1.0.94"
tracing-subscriber = { version = "0.3.16", default-features = false, features = [ "env-filter", "json", "smallvec", "time", "fmt" ] }
atty = "0.2.14"
termcolor = "1.2.0"
[features]
default = ["wasm"]

View File

@ -17,7 +17,7 @@ Alias: `air r`.
Executes an AIR script with data in WASM AquaVM. It has two modes of parameter input: plain and anomaly.
### Common parameters
All common parameters are optional. Their position is before the mode selector (`--plain` or `--anomaly`).
All common parameters are optional. Their position is always before the mode selector (`--plain` or `--anomaly`).
+ `--call-results PATH` parameter allows you to provide call results for current execution.
+ `--max-heap-size N` defines maximum heap size for WASM runtime.
@ -31,7 +31,7 @@ The important option is `--native`. It runs the AquaVM as the native code that
Run `air run --help` to see all common parameters.
### Plain mode
In the `--plain` mode, the parameters like AIR script path, data path, previous data path and other particle fields can be provided in separate arguments, of which only `--data` is the required one (and AIR script is read from stdin by default).
In the `--plain` mode, the parameters like AIR script path, data path, previous data path and other particle fields can be provided in separate arguments (all of them are optional, and AIR script is read from stdin by default).
Run `air run --plain --help` to see all plain mode options.
@ -63,17 +63,23 @@ Please, note that currently tracing outputs to stdout, and execution result is a
### AIR interpreter
You need the `marine` tool installed. Run following command in the repo's root directory:
Unless you intend to run AIR in native mode, you will need a AIR interpreter build in WASM. You can build it with the `marine` tool. Run following command in the repo's root directory:
``` sh
marine build --features marine --package air-interpreter --release
```
It will output the binary to default `--interpreter` path at `target/wasm32-wasi/release/air_interpreter_server.wasm`; if you wish to run the `air` from arbitrary place, store the `air_interpreter_server.wasm` binary in a cool dry place and set `AIR_INTERPRETER_WASM_PATH` variable.
It will output the binary to default `--interpreter` path at `target/wasm32-wasi/release/air_interpreter_server.wasm`; if you wish to run the `air` from arbitrary place, store the `air_interpreter_server.wasm` binary in a cool dry place and either set `AIR_INTERPRETER_WASM_PATH` variable or use the `--interpreter` common option of `air run`.
## `air` binary
You need to have Rust toolchain and its `cargo` utility installed. Run this command from the repo's root directory:
You need to have Rust toolchain and its `cargo` utility installed. Run this command to install latest released version from `crates.io`:
``` sh
cargo install aquavm-air-cli
```
You may install developer version from the repo's root:
``` sh
cargo install --path tools/cli/air
@ -81,7 +87,7 @@ cargo install --path tools/cli/air
## `air` CLI native build
You can have fully native or pure WASM `air` CLI build with the following commands:
You can build fully native or pure WASM `air` CLI build with the following commands:
``` sh
cargo build --no-default-features --release -p aquavm-air-cli

View File

@ -163,6 +163,16 @@ fn read_call_results(call_results_path: Option<&Path>) -> anyhow::Result<CallRes
}
}
fn load_data_or_default(
data_path: Option<impl AsRef<Path>>,
default: &str,
) -> anyhow::Result<String> {
match data_path {
None => Ok(default.to_owned()),
Some(data_path) => load_data(data_path.as_ref()),
}
}
fn load_data(data_path: &Path) -> anyhow::Result<String> {
Ok(std::fs::read_to_string(data_path)?)
}

View File

@ -39,20 +39,19 @@ pub(crate) struct PlainDataArgs {
air_script_path: Option<PathBuf>,
#[clap(long = "prev-data")]
prev_data_path: Option<PathBuf>,
#[clap(long = "data")]
data_path: PathBuf,
#[clap(long = "current-data")]
current_data_path: Option<PathBuf>,
}
pub(crate) fn load(args: &PlainDataArgs) -> anyhow::Result<ExecutionData<'_>> {
use super::super::load_data;
use super::super::load_data_or_default;
let air_script =
read_air_script(args.air_script_path.as_deref()).context("failed to read AIR script")?;
let prev_data = match &args.prev_data_path {
None => DEFAULT_DATA.to_owned(),
Some(prev_data_path) => load_data(prev_data_path).context("failed to read prev_data")?,
};
let current_data = load_data(&args.data_path).context("failed to read data")?;
let air_script = read_air_with_prompt(args.air_script_path.as_deref())
.context("failed to read AIR script")?;
let prev_data = load_data_or_default(args.prev_data_path.as_ref(), DEFAULT_DATA)
.context("failed to read prev_data")?;
let current_data = load_data_or_default(args.current_data_path.as_ref(), DEFAULT_DATA)
.context("failed to read data")?;
let timestamp = args.timestamp.unwrap_or_else(unix_timestamp_now);
let ttl = args.ttl.unwrap_or(u32::MAX);
@ -75,7 +74,7 @@ pub(crate) fn load(args: &PlainDataArgs) -> anyhow::Result<ExecutionData<'_>> {
})
}
fn read_air_script(air_input: Option<&Path>) -> anyhow::Result<String> {
fn read_air_with_prompt(air_input: Option<&Path>) -> anyhow::Result<String> {
use std::io::Read;
let air_script = match air_input {
@ -84,6 +83,11 @@ fn read_air_script(air_input: Option<&Path>) -> anyhow::Result<String> {
let mut buffer = String::new();
let mut stdin = std::io::stdin().lock();
// unfortunately, it seems to always return false in WASM mode
if atty::is(atty::Stream::Stdin) {
print_air_prompt();
}
stdin.read_to_string(&mut buffer)?;
buffer
}
@ -91,3 +95,15 @@ fn read_air_script(air_input: Option<&Path>) -> anyhow::Result<String> {
Ok(air_script)
}
fn print_air_prompt() {
use termcolor::{ColorChoice, ColorSpec, StandardStream, WriteColor as _};
let mut stderr = StandardStream::stderr(ColorChoice::Auto);
let mut bold = ColorSpec::new();
bold.set_bold(true);
let _ = stderr.set_color(&bold);
eprintln!("Reading AIR script from stdin...");
let _ = stderr.set_color(&ColorSpec::new());
}

View File

@ -86,7 +86,7 @@ class Bench:
) + [
"--tracing-params", tracing_params,
"--plain",
"--data", self.cur_data_path,
"--current-data", self.cur_data_path,
"--prev-data", self.prev_data_path,
"--script", self.air_script_path,
] + [