From ae2d882f26d0b7fdd1220cdff8950fa3b31a0e23 Mon Sep 17 00:00:00 2001 From: Alexander Kiselev Date: Thu, 5 Feb 2026 13:19:16 -0800 Subject: [PATCH] fix: add --project/--program to BatchArgs and fix arg order in tests BatchArgs was missing --project and --program fields, so batch commands couldn't specify which project to use. Also fixed argument ordering in all test files to place --project/--program after the subcommand name, matching clap's per-subcommand argument parsing. Co-Authored-By: Claude Opus 4.6 --- src/cli.rs | 6 ++++++ src/main.rs | 2 ++ tests/batch_tests.rs | 10 +++++----- tests/comment_tests.rs | 24 ++++++++++++------------ tests/daemon_tests.rs | 20 ++++++++++---------- tests/diff_tests.rs | 8 ++++---- tests/find_tests.rs | 32 ++++++++++++++++---------------- tests/graph_tests.rs | 16 ++++++++-------- tests/program_tests.rs | 16 ++++++++-------- tests/reliability_tests.rs | 8 ++++---- tests/script_tests.rs | 16 ++++++++-------- tests/stats_tests.rs | 6 +++--- tests/symbol_tests.rs | 24 ++++++++++++------------ tests/type_tests.rs | 20 ++++++++++---------- 14 files changed, 108 insertions(+), 100 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index eaa7313..4743612 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -724,6 +724,12 @@ pub struct ScriptInlineArgs { #[derive(Args, Clone, Serialize, Deserialize, Debug)] pub struct BatchArgs { pub script_file: String, + + #[arg(long)] + pub project: Option, + + #[arg(long)] + pub program: Option, } #[derive(Subcommand, Clone, Serialize, Deserialize, Debug)] diff --git a/src/main.rs b/src/main.rs index 9067371..df03218 100644 --- a/src/main.rs +++ b/src/main.rs @@ -223,6 +223,7 @@ fn extract_project_from_command(command: &Commands) -> Option { cli::ProgramCommands::Info(args) => args.project.clone(), cli::ProgramCommands::Export(args) => args.project.clone(), }, + Commands::Batch(args) => args.project.clone(), _ => None, } } @@ -322,6 +323,7 @@ fn extract_program_from_command(command: &Commands) -> Option { cli::ProgramCommands::Info(args) => args.program.clone(), cli::ProgramCommands::Export(args) => args.program.clone(), }, + Commands::Batch(args) => args.program.clone(), _ => None, } } diff --git a/tests/batch_tests.rs b/tests/batch_tests.rs index e43af7f..cef5a75 100644 --- a/tests/batch_tests.rs +++ b/tests/batch_tests.rs @@ -39,9 +39,9 @@ query --function main Command::cargo_bin("ghidra") .unwrap() + .arg("batch") .arg("--project") .arg(TEST_PROJECT) - .arg("batch") .arg(batch_file.to_str().unwrap()) .assert() .success() @@ -72,9 +72,9 @@ fn test_batch_empty_file() { Command::cargo_bin("ghidra") .unwrap() + .arg("batch") .arg("--project") .arg(TEST_PROJECT) - .arg("batch") .arg(batch_file.to_str().unwrap()) .assert() .success() @@ -105,9 +105,9 @@ query --address 0x100000 Command::cargo_bin("ghidra") .unwrap() + .arg("batch") .arg("--project") .arg(TEST_PROJECT) - .arg("batch") .arg(batch_file.to_str().unwrap()) .assert() .success() @@ -129,9 +129,9 @@ fn test_batch_invalid_file() { Command::cargo_bin("ghidra") .unwrap() + .arg("batch") .arg("--project") .arg(TEST_PROJECT) - .arg("batch") .arg("/nonexistent/batch/file.txt") .assert() .failure() @@ -159,9 +159,9 @@ query --address 0x100000 Command::cargo_bin("ghidra") .unwrap() + .arg("batch") .arg("--project") .arg(TEST_PROJECT) - .arg("batch") .arg(batch_file.to_str().unwrap()) .assert() .success() diff --git a/tests/comment_tests.rs b/tests/comment_tests.rs index 97a0b9c..d635d00 100644 --- a/tests/comment_tests.rs +++ b/tests/comment_tests.rs @@ -24,12 +24,12 @@ fn test_comment_set_and_get() { // Note: ELF entry is 0x18910, but Ghidra loads with base 0x100000 Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("comment") .arg("set") .arg("0x00118910") .arg("test comment from integration test") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -38,11 +38,11 @@ fn test_comment_set_and_get() { // Get the comment back Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("comment") .arg("get") .arg("0x00118910") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -63,12 +63,12 @@ fn test_comment_list() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("comment") .arg("set") .arg("0x00118920") // Within executable range (Ghidra address space) .arg("another comment") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -76,10 +76,10 @@ fn test_comment_list() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("comment") .arg("list") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -100,12 +100,12 @@ fn test_comment_delete() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("comment") .arg("set") .arg("0x00118930") // Within executable range (Ghidra address space) .arg("to be deleted") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -113,11 +113,11 @@ fn test_comment_delete() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("comment") .arg("delete") .arg("0x00118930") // Within executable range (Ghidra address space) + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() diff --git a/tests/daemon_tests.rs b/tests/daemon_tests.rs index 38c72cf..848fd3e 100644 --- a/tests/daemon_tests.rs +++ b/tests/daemon_tests.rs @@ -23,9 +23,9 @@ fn test_daemon_start() { Command::cargo_bin("ghidra") .unwrap() + .arg("status") .arg("--project") .arg(TEST_PROJECT) - .arg("status") .assert() .success(); @@ -44,9 +44,9 @@ fn test_daemon_status() { Command::cargo_bin("ghidra") .unwrap() + .arg("status") .arg("--project") .arg(TEST_PROJECT) - .arg("status") .assert() .success() .stdout(predicate::str::contains("running")); @@ -66,9 +66,9 @@ fn test_daemon_ping() { Command::cargo_bin("ghidra") .unwrap() + .arg("ping") .arg("--project") .arg(TEST_PROJECT) - .arg("ping") .assert() .success(); @@ -87,26 +87,26 @@ fn test_daemon_lifecycle() { Command::cargo_bin("ghidra") .unwrap() + .arg("status") .arg("--project") .arg(TEST_PROJECT) - .arg("status") .assert() .success() .stdout(predicate::str::contains("running")); Command::cargo_bin("ghidra") .unwrap() + .arg("ping") .arg("--project") .arg(TEST_PROJECT) - .arg("ping") .assert() .success(); Command::cargo_bin("ghidra") .unwrap() + .arg("stop") .arg("--project") .arg(TEST_PROJECT) - .arg("stop") .assert() .success(); } @@ -123,17 +123,17 @@ fn test_daemon_stop() { Command::cargo_bin("ghidra") .unwrap() + .arg("stop") .arg("--project") .arg(TEST_PROJECT) - .arg("stop") .assert() .success(); Command::cargo_bin("ghidra") .unwrap() + .arg("status") .arg("--project") .arg(TEST_PROJECT) - .arg("status") .assert() .success() .stdout(predicate::str::contains("No bridge running")); @@ -153,9 +153,9 @@ fn test_daemon_restart() { Command::cargo_bin("ghidra") .unwrap() + .arg("restart") .arg("--project") .arg(TEST_PROJECT) - .arg("restart") .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -163,9 +163,9 @@ fn test_daemon_restart() { Command::cargo_bin("ghidra") .unwrap() + .arg("stop") .arg("--project") .arg(TEST_PROJECT) - .arg("stop") .assert() .success(); diff --git a/tests/diff_tests.rs b/tests/diff_tests.rs index a3d8b5a..45be4f0 100644 --- a/tests/diff_tests.rs +++ b/tests/diff_tests.rs @@ -23,12 +23,12 @@ fn test_diff_programs() { // diff programs compares two programs by name (no --program flag needed) Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("diff") .arg("programs") .arg(TEST_PROGRAM) .arg(TEST_PROGRAM) + .arg("--project") + .arg(TEST_PROJECT) .assert() .success(); @@ -48,12 +48,12 @@ fn test_diff_functions() { // Using _start (entry point) for both since we just want to verify command works Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("diff") .arg("functions") .arg("_start") .arg("_start") + .arg("--project") + .arg(TEST_PROJECT) .assert() .success(); diff --git a/tests/find_tests.rs b/tests/find_tests.rs index 3584eba..5ffd184 100644 --- a/tests/find_tests.rs +++ b/tests/find_tests.rs @@ -22,11 +22,11 @@ fn test_find_string() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("find") .arg("string") .arg("test") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -47,11 +47,11 @@ fn test_find_bytes() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("find") .arg("bytes") .arg("4883ec08") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -72,11 +72,11 @@ fn test_find_function() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("find") .arg("function") .arg("main") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -97,11 +97,11 @@ fn test_find_function_glob() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("find") .arg("function") .arg("m*") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -122,11 +122,11 @@ fn test_find_calls() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("find") .arg("calls") .arg("printf") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -146,10 +146,10 @@ fn test_find_crypto() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("find") .arg("crypto") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -170,10 +170,10 @@ fn test_find_interesting() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("find") .arg("interesting") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -194,11 +194,11 @@ fn test_find_string_no_matches() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("find") .arg("string") .arg("nonexistent_string_xyz123") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() diff --git a/tests/graph_tests.rs b/tests/graph_tests.rs index a878809..ea75555 100644 --- a/tests/graph_tests.rs +++ b/tests/graph_tests.rs @@ -22,10 +22,10 @@ fn test_graph_calls() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("graph") .arg("calls") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -47,11 +47,11 @@ fn test_graph_callers() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("graph") .arg("callers") .arg("main") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -72,11 +72,11 @@ fn test_graph_callees() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("graph") .arg("callees") .arg("main") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -97,11 +97,11 @@ fn test_graph_export_dot() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("graph") .arg("export") .arg("dot") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() diff --git a/tests/program_tests.rs b/tests/program_tests.rs index e19708a..0cde93a 100644 --- a/tests/program_tests.rs +++ b/tests/program_tests.rs @@ -22,10 +22,10 @@ fn test_program_info() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("program") .arg("info") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -47,11 +47,11 @@ fn test_program_export_json() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("program") .arg("export") .arg("json") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -72,10 +72,10 @@ fn test_program_close() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("program") .arg("close") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -95,10 +95,10 @@ fn test_program_info_no_program() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("program") .arg("info") + .arg("--project") + .arg(TEST_PROJECT) .assert() .failure(); diff --git a/tests/reliability_tests.rs b/tests/reliability_tests.rs index f58a115..bcc4b0d 100644 --- a/tests/reliability_tests.rs +++ b/tests/reliability_tests.rs @@ -28,9 +28,9 @@ fn test_stale_files_cleaned_on_restart() { // Verify bridge is working assert_cmd::Command::cargo_bin("ghidra") .unwrap() + .arg("ping") .arg("--project") .arg(TEST_PROJECT) - .arg("ping") .timeout(Duration::from_secs(30)) .assert() .success(); @@ -49,9 +49,9 @@ fn test_stale_files_cleaned_on_restart() { // Verify bridge is working assert_cmd::Command::cargo_bin("ghidra") .unwrap() + .arg("ping") .arg("--project") .arg(TEST_PROJECT) - .arg("ping") .timeout(Duration::from_secs(30)) .assert() .success(); @@ -76,9 +76,9 @@ fn test_recovery_after_crash() { // Verify it's working assert_cmd::Command::cargo_bin("ghidra") .unwrap() + .arg("ping") .arg("--project") .arg(TEST_PROJECT) - .arg("ping") .timeout(Duration::from_secs(30)) .assert() .success(); @@ -97,9 +97,9 @@ fn test_recovery_after_crash() { // Verify new bridge is working assert_cmd::Command::cargo_bin("ghidra") .unwrap() + .arg("ping") .arg("--project") .arg(TEST_PROJECT) - .arg("ping") .timeout(Duration::from_secs(30)) .assert() .success(); diff --git a/tests/script_tests.rs b/tests/script_tests.rs index 54e3e28..9b90073 100644 --- a/tests/script_tests.rs +++ b/tests/script_tests.rs @@ -47,10 +47,10 @@ fn test_script_list() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("script") .arg("list") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -73,11 +73,11 @@ fn test_script_run() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("script") .arg("run") .arg(script_path.to_str().unwrap()) + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -100,11 +100,11 @@ fn test_script_python_inline() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("script") .arg("python") .arg("output = 'Hello from Python'") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -125,11 +125,11 @@ fn test_script_run_nonexistent() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("script") .arg("run") .arg("/nonexistent/script.py") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() diff --git a/tests/stats_tests.rs b/tests/stats_tests.rs index 875347c..f99091d 100644 --- a/tests/stats_tests.rs +++ b/tests/stats_tests.rs @@ -22,9 +22,9 @@ fn test_stats_normal() { Command::cargo_bin("ghidra") .unwrap() + .arg("stats") .arg("--project") .arg(TEST_PROJECT) - .arg("stats") .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -47,9 +47,9 @@ fn test_stats_has_all_fields() { Command::cargo_bin("ghidra") .unwrap() + .arg("stats") .arg("--project") .arg(TEST_PROJECT) - .arg("stats") .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -77,9 +77,9 @@ fn test_stats_json_format() { let output = Command::cargo_bin("ghidra") .unwrap() + .arg("stats") .arg("--project") .arg(TEST_PROJECT) - .arg("stats") .arg("--program") .arg(TEST_PROGRAM) .assert() diff --git a/tests/symbol_tests.rs b/tests/symbol_tests.rs index ffc6249..b9619a1 100644 --- a/tests/symbol_tests.rs +++ b/tests/symbol_tests.rs @@ -22,10 +22,10 @@ fn test_symbol_list() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("symbol") .arg("list") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -46,12 +46,12 @@ fn test_symbol_create_and_get() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("symbol") .arg("create") .arg("0x1000") .arg("test_symbol") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -59,11 +59,11 @@ fn test_symbol_create_and_get() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("symbol") .arg("get") .arg("test_symbol") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -84,12 +84,12 @@ fn test_symbol_rename() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("symbol") .arg("create") .arg("0x2000") .arg("old_symbol") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -97,12 +97,12 @@ fn test_symbol_rename() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("symbol") .arg("rename") .arg("old_symbol") .arg("new_symbol") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -122,11 +122,11 @@ fn test_symbol_get_nonexistent() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("symbol") .arg("get") .arg("nonexistent_symbol_12345") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() diff --git a/tests/type_tests.rs b/tests/type_tests.rs index ccfd73b..fcf24b9 100644 --- a/tests/type_tests.rs +++ b/tests/type_tests.rs @@ -22,10 +22,10 @@ fn test_type_list() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("type") .arg("list") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -46,11 +46,11 @@ fn test_type_get_primitive() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("type") .arg("get") .arg("int") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -71,11 +71,11 @@ fn test_type_create() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("type") .arg("create") .arg("MyTestStruct") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -95,12 +95,12 @@ fn test_type_apply() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("type") .arg("apply") .arg("0x1000") .arg("int") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert() @@ -120,11 +120,11 @@ fn test_type_get_nonexistent() { Command::cargo_bin("ghidra") .unwrap() - .arg("--project") - .arg(TEST_PROJECT) .arg("type") .arg("get") .arg("NonexistentType12345") + .arg("--project") + .arg(TEST_PROJECT) .arg("--program") .arg(TEST_PROGRAM) .assert()