From 75a0f65ffb0bfa5ee35a34a284de9fee7bdc86de Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Mon, 27 May 2024 19:47:43 +0100 Subject: [PATCH] Move opts to lib --- .cargo/config.toml | 2 + .github/workflows/ci.yml | 17 +++++++ Cargo.toml | 3 ++ README.md | 30 ++++++++++++ xtask/Cargo.toml | 8 +++ xtask/src/main.rs | 102 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 162 insertions(+) create mode 100644 .cargo/config.toml create mode 100644 xtask/Cargo.toml create mode 100644 xtask/src/main.rs diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..35049cb --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[alias] +xtask = "run --package xtask --" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b9ff0b..efe0bde 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,6 +23,23 @@ jobs: with: command: test args: --all --all-features + readme-check: + name: Check README.md + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - name: Check README.md + uses: actions-rs/cargo@v1 + with: + command: xtask + args: gen-help --check macos-stable: name: macOS stable runs-on: macos-latest diff --git a/Cargo.toml b/Cargo.toml index d6804f3..dff48a7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,9 @@ version = "0.0.0" authors = ["Stiopa Koltsov "] edition = "2018" +[workspace] +members = ["xtask"] + [lib] doctest = false diff --git a/README.md b/README.md index aaf115c..7f28451 100644 --- a/README.md +++ b/README.md @@ -26,3 +26,33 @@ cargo install --git https://github.com/stepancheg/absh ``` Cargo is a Rust package manager and build system. It can be downloaded [from rustup.rs](https://rustup.rs/). + +## absh --help + + +``` +absh +A/B testing for shell scripts + +USAGE: + absh [OPTIONS] -a + +OPTIONS: + -a A variant shell script + -A, --a-warmup A variant warmup shell script + -b B variant shell script + -B, --b-warmup B variant warmup shell script + -c C variant shell script + -C, --c-warmup C variant warmup shell script + -d D variant shell script + -D, --d-warmup D variant warmup shell script + -e E variant shell script + -E, --e-warmup E variant warmup shell script + -h, --help Print help information + -i Ignore the results of the first iteration + -m, --mem Also measure max resident set size + --max-time Test is considered failed if it takes longer than this many seconds + -n Stop after n successful iterations (run forever if not specified) + -r Randomise test execution order +``` + diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml new file mode 100644 index 0000000..e89d61e --- /dev/null +++ b/xtask/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "xtask" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1.0.86" +clap = { version = "3.2.25", features = ["derive", "wrap_help"] } \ No newline at end of file diff --git a/xtask/src/main.rs b/xtask/src/main.rs new file mode 100644 index 0000000..9e78a00 --- /dev/null +++ b/xtask/src/main.rs @@ -0,0 +1,102 @@ +use std::fs; +use std::process::Command; +use std::process::Stdio; + +use anyhow::Context; +use clap::Parser; + +/// Regenerate help for absh. +#[derive(clap::Parser, Debug)] +struct GenReadme { + /// Do not regenerate help, just check that it can be generated. + #[clap(long)] + check: bool, +} + +struct ReadmeMd { + orignial: String, + before: String, + after: String, +} + +impl GenReadme { + fn parse_readme_md() -> anyhow::Result { + eprintln!("Reading README.md"); + let readme_md = fs::read_to_string("README.md")?; + let lines = readme_md.lines().collect::>(); + let start = lines + .iter() + .position(|&line| line == "") + .context(" not found in README.md")?; + let end = lines + .iter() + .position(|&line| line == "") + .context(" not found in README.md")?; + let before = lines[..start + 1] + .iter() + .map(|&line| format!("{}\n", line)) + .collect::(); + let after = lines[end..] + .iter() + .map(|&line| format!("{}\n", line)) + .collect::(); + Ok(ReadmeMd { + orignial: readme_md, + before, + after, + }) + } + + fn normalize_help_output(help: &str) -> String { + help.lines() + .map(|line| { + let line = line.trim_end(); + format!("{}\n", line) + }) + .collect() + } + + fn run(&self) -> anyhow::Result<()> { + eprintln!("Running absh --help"); + let out = Command::new("cargo") + .arg("run") + .arg("--bin") + .arg("absh") + .arg("--") + .arg("--help") + .stdin(Stdio::null()) + .stdout(Stdio::piped()) + .output()?; + + let ReadmeMd { + orignial, + before, + after, + } = Self::parse_readme_md()?; + let help = String::from_utf8(out.stdout)?; + let help = Self::normalize_help_output(&help); + + let readme_md = format!("{before}```\n{help}```\n{after}"); + if self.check { + anyhow::ensure!(orignial == readme_md, "README.md is not up to date"); + eprintln!("README.md is up to date"); + } else { + eprintln!("Writing README.md"); + fs::write("README.md", readme_md)?; + } + Ok(()) + } +} + +/// absh build helper. +#[derive(clap::Parser, Debug)] +enum AbshXTaskOpts { + GenHelp(GenReadme), +} + +fn main() -> anyhow::Result<()> { + let opts: AbshXTaskOpts = AbshXTaskOpts::parse(); + match opts { + AbshXTaskOpts::GenHelp(gen_help) => gen_help.run(), + } +}