mirror of
https://github.com/encounter/ghidra-cli.git
synced 2026-07-10 03:18:56 -07:00
fix: handle batch commands locally and require Java 21 in CI
Batch was broken because it sent a single "batch" command to the Java bridge, which rejected it. Now the Rust CLI parses each line of the batch file as a sub-command and dispatches them individually through execute_via_bridge, collecting results into a JSON response. Also updated CI to install Java 21 (required by Ghidra 12.0.1). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
ae2d882f26
commit
57dbf62fd4
@@ -20,11 +20,11 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Java 17
|
||||
- name: Install Java 21
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
java-version: '21'
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
@@ -359,10 +359,6 @@ impl BridgeClient {
|
||||
self.send_command("script_list", None)
|
||||
}
|
||||
|
||||
pub fn batch(&self, commands: &[serde_json::Value]) -> Result<serde_json::Value> {
|
||||
self.send_command("batch", Some(json!({"commands": commands})))
|
||||
}
|
||||
|
||||
pub fn program_close(&self) -> Result<serde_json::Value> {
|
||||
self.send_command("close_program", None)
|
||||
}
|
||||
|
||||
+24
-4
@@ -803,15 +803,35 @@ fn execute_via_bridge(
|
||||
}
|
||||
Commands::Disasm(args) => client.disasm(&args.address, args.num_instructions),
|
||||
Commands::Batch(args) => {
|
||||
// Read batch file and send commands
|
||||
// Read batch file and execute each command locally
|
||||
let content = std::fs::read_to_string(&args.script_file)
|
||||
.map_err(|e| anyhow::anyhow!("Failed to read batch file: {}", e))?;
|
||||
let commands: Vec<serde_json::Value> = content
|
||||
let lines: Vec<&str> = content
|
||||
.lines()
|
||||
.filter(|l| !l.trim().is_empty() && !l.trim().starts_with('#'))
|
||||
.map(|l| serde_json::from_str(l).unwrap_or_else(|_| json!({"command": l.trim()})))
|
||||
.collect();
|
||||
client.batch(&commands)
|
||||
|
||||
let mut results = Vec::new();
|
||||
for line in &lines {
|
||||
let words: Vec<&str> = std::iter::once("ghidra")
|
||||
.chain(line.split_whitespace())
|
||||
.collect();
|
||||
let sub_result = match Cli::try_parse_from(&words) {
|
||||
Ok(sub_cli) => {
|
||||
execute_via_bridge(client, &sub_cli.command, true, default_limit)
|
||||
}
|
||||
Err(e) => Err(anyhow::anyhow!("{}", e)),
|
||||
};
|
||||
match sub_result {
|
||||
Ok(val) => results.push(json!({"command": line.trim(), "result": val})),
|
||||
Err(e) => results.push(json!({"command": line.trim(), "error": e.to_string()})),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(json!({
|
||||
"commands_parsed": lines.len(),
|
||||
"results": results
|
||||
}))
|
||||
}
|
||||
Commands::Stats(_) => client.stats(),
|
||||
_ => anyhow::bail!("Command not supported"),
|
||||
|
||||
Reference in New Issue
Block a user