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:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Java 17
|
- name: Install Java 21
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
java-version: '17'
|
java-version: '21'
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
- name: Install Rust toolchain
|
||||||
uses: dtolnay/rust-toolchain@stable
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
|||||||
@@ -359,10 +359,6 @@ impl BridgeClient {
|
|||||||
self.send_command("script_list", None)
|
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> {
|
pub fn program_close(&self) -> Result<serde_json::Value> {
|
||||||
self.send_command("close_program", None)
|
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::Disasm(args) => client.disasm(&args.address, args.num_instructions),
|
||||||
Commands::Batch(args) => {
|
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)
|
let content = std::fs::read_to_string(&args.script_file)
|
||||||
.map_err(|e| anyhow::anyhow!("Failed to read batch file: {}", e))?;
|
.map_err(|e| anyhow::anyhow!("Failed to read batch file: {}", e))?;
|
||||||
let commands: Vec<serde_json::Value> = content
|
let lines: Vec<&str> = content
|
||||||
.lines()
|
.lines()
|
||||||
.filter(|l| !l.trim().is_empty() && !l.trim().starts_with('#'))
|
.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();
|
.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(),
|
Commands::Stats(_) => client.stats(),
|
||||||
_ => anyhow::bail!("Command not supported"),
|
_ => anyhow::bail!("Command not supported"),
|
||||||
|
|||||||
Reference in New Issue
Block a user