diff --git a/README.md b/README.md index f0c781f..690c5e4 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ Use `qt show` to inspect a single run, `qt list` to see a list of all runs, and Common commands: ```bash +qt --version qt run qt list qt show diff --git a/cli/README.md b/cli/README.md index 8c75c28..178cc76 100644 --- a/cli/README.md +++ b/cli/README.md @@ -30,6 +30,8 @@ qt show 1 > See the [CLI reference](https://quantiles.io/documentation/reference/cli) for a detailed list of `qt` commands. +Print the installed CLI version with `qt --version`. + ### Custom evaluations Custom evaluations are denoted in the configuration file with `type = "custom_code"`. The `command` array tells the CLI how to execute your eval, and the optional `input` table is merged with any values passed through the `--input` flag, then passed to your script as `QUANTILES_INPUT`. An example is below: diff --git a/cli/src/cli.rs b/cli/src/cli.rs index 8bae80c..4777bfa 100644 --- a/cli/src/cli.rs +++ b/cli/src/cli.rs @@ -1,13 +1,29 @@ use clap::{Parser, Subcommand}; +pub const VERSION: &str = env!("CARGO_PKG_VERSION"); + #[derive(Debug, Parser)] -#[command(name = "qt")] +#[command( + name = "qt", + // By default, clap builds in a `--version` flag that produces output with the version number + // prefixed by the binary name. For example: + // + // qt v0.1.2. + // + // This setting disables this default output, so we can manually output _just_ the actual version + // number, so that agents and scripts don't have to parse out the `qt...` prefix. + disable_version_flag = true, + arg_required_else_help = true +)] #[command( about = "A full-featured local-native toolchain for running and analyzing AI evals at scale" )] pub struct Cli { + /// Print the qt version. + #[arg(long, exclusive = true)] + pub version: bool, #[command(subcommand)] - pub command: Command, + pub command: Option, } #[derive(Debug, Subcommand)] diff --git a/cli/src/main.rs b/cli/src/main.rs index 176c68b..e542ba9 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -21,7 +21,12 @@ fn main() -> Result<()> { async fn async_main(process_start: Instant) -> Result<()> { let cli = cli::Cli::parse(); - match cli.command { + if cli.version { + println!("{}", cli::VERSION); + return Ok(()); + } + + match cli.command.expect("clap requires a subcommand") { cli::Command::Init => commands::init().await, cli::Command::List { json } => commands::list(json).await, cli::Command::Compare { run_a, run_b, json } => commands::compare(run_a, run_b, json).await, diff --git a/cli/tests/version.rs b/cli/tests/version.rs new file mode 100644 index 0000000..c4a7b6b --- /dev/null +++ b/cli/tests/version.rs @@ -0,0 +1,13 @@ +use assert_cmd::Command; +use predicates::prelude::*; + +#[test] +fn version_flag_prints_cargo_package_version_without_a_prefix() { + let expected = predicate::eq(format!("{}\n", env!("CARGO_PKG_VERSION"))); + + Command::new(assert_cmd::cargo::cargo_bin!("qt")) + .arg("--version") + .assert() + .success() + .stdout(expected); +}