From 216b56e26f5080ec652b098849e177ec560d602f Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Sat, 24 Feb 2024 15:45:09 +0100 Subject: [PATCH] cli: Add ability to build and test only a specified program (#2823) --- CHANGELOG.md | 1 + cli/src/lib.rs | 47 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae3f3bab5c..fba3d08d95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ The minor version will be incremented upon a breaking change and the patch versi - cli: `anchor test` is able to run multiple commands ([#2799](https://github.com/coral-xyz/anchor/pull/2799)). - cli: Check `@coral-xyz/anchor` package and CLI version compatibility ([#2813](https://github.com/coral-xyz/anchor/pull/2813)). - cli: Accept package name as program name ([#2816](https://github.com/coral-xyz/anchor/pull/2816)). +- cli: Add ability to build and test only a specified program ([#2823](https://github.com/coral-xyz/anchor/pull/2823)). ### Fixes diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 7bb2d02273..4ceafd954a 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -109,6 +109,7 @@ pub enum Command { /// True if the build artifact needs to be deterministic and verifiable. #[clap(short, long)] verifiable: bool, + /// Name of the program to build #[clap(short, long)] program_name: Option, /// Version of the Solana toolchain to use. For --verifiable builds @@ -183,8 +184,11 @@ pub enum Command { skip_build: bool, }, #[clap(name = "test", alias = "t")] - /// Runs integration tests against a localnetwork. + /// Runs integration tests. Test { + /// Build and test only this program + #[clap(short, long)] + program_name: Option, /// Use this flag if you want to run tests against previously deployed /// programs. #[clap(long)] @@ -746,6 +750,7 @@ fn process_command(opts: Opts) -> Result<()> { Command::Idl { subcmd } => idl(&opts.cfg_override, subcmd), Command::Migrate => migrate(&opts.cfg_override), Command::Test { + program_name, skip_deploy, skip_local_validator, skip_build, @@ -758,6 +763,7 @@ fn process_command(opts: Opts) -> Result<()> { arch, } => test( &opts.cfg_override, + program_name, skip_deploy, skip_local_validator, skip_build, @@ -3048,6 +3054,7 @@ enum OutFile { #[allow(clippy::too_many_arguments)] fn test( cfg_override: &ConfigOverride, + program_name: Option, skip_deploy: bool, skip_local_validator: bool, skip_build: bool, @@ -3077,7 +3084,7 @@ fn test( None, false, skip_lint, - None, + program_name.clone(), None, None, BootstrapMode::None, @@ -3104,12 +3111,36 @@ fn test( deploy(cfg_override, None, None, false, vec![])?; } let mut is_first_suite = true; - if cfg.scripts.get("test").is_some() { + if let Some(test_script) = cfg.scripts.get_mut("test") { is_first_suite = false; - println!("\nFound a 'test' script in the Anchor.toml. Running it as a test suite!"); + + match program_name { + Some(program_name) => { + if let Some((from, to)) = Regex::new("\\s(tests/\\S+\\.(js|ts))") + .unwrap() + .captures_iter(&test_script.clone()) + .last() + .and_then(|c| c.get(1).and_then(|mtch| c.get(2).map(|ext| (mtch, ext)))) + .map(|(mtch, ext)| { + ( + mtch.as_str(), + format!("tests/{program_name}.{}", ext.as_str()), + ) + }) + { + println!("\nRunning tests of program `{program_name}`!"); + // Replace the last path to the program name's path + *test_script = test_script.replace(from, &to); + } + } + _ => println!( + "\nFound a 'test' script in the Anchor.toml. Running it as a test suite!" + ), + } + run_test_suite( - cfg.path(), cfg, + cfg.path(), is_localnet, skip_local_validator, skip_deploy, @@ -3135,8 +3166,8 @@ fn test( } run_test_suite( - test_suite.0, cfg, + test_suite.0, is_localnet, skip_local_validator, skip_deploy, @@ -3153,8 +3184,8 @@ fn test( #[allow(clippy::too_many_arguments)] fn run_test_suite( - test_suite_path: impl AsRef, cfg: &WithPath, + test_suite_path: impl AsRef, is_localnet: bool, skip_local_validator: bool, skip_deploy: bool, @@ -3191,7 +3222,7 @@ fn run_test_suite( let log_streams = stream_logs(cfg, &url); // Run the tests. - let test_result: Result<_> = { + let test_result = { let cmd = scripts .get("test") .expect("Not able to find script for `test`")