fix(automation): retain batch results with identical filenames (#877)

* fix(automation): retain batch results with identical filenames

* Format

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
Nigel Ihza FirdausyandBrandon Thomas authored and GitHub committed 2026-10-10 15:29:47 -04:00
1 parent f54aa1db1e
commit fc08d56e97
2 files changed
+41 -1

No files matched your search

+11 -1
View File
@@ -3,7 +3,7 @@
use pdfcraft_engine::a11y::{Category, Options, Report, Rule, Status};
use serde_json::{Value, json};
use crate::{Args, Automation, Result, ToolError, child, failed, write_atomic};
use crate::{Args, Automation, Result, ToolError, child, failed, unused, write_atomic};
fn status_id(s: Status) -> &'static str {
match s {
@@ -347,6 +347,16 @@ impl Automation {
out.push(match result {
Ok(r) => {
let target = child(&folder, &name);
let target = if target.exists() {
let stem =
std::path::Path::new(&name).file_stem().map(|s| s.to_string_lossy().into_owned()).unwrap_or_else(|| "document".into());
unused(&folder, &stem)
} else {
target
};
if target.exists() {
return Err(failed(format!("{}: no unused output name available", target.display())));
}
write_atomic(&target, &r.bytes)?;
json!({ "path": p, "output": target.to_string_lossy(), "log": r.log })
}
+30
View File
@@ -3026,6 +3026,36 @@ fn actions_through_tools() {
assert!(a.call("action_run", &json!({ "steps": [{ "step": "fly" }], "paths": ["a.pdf"], "folder": "x" })).is_err());
}
#[test]
fn action_run_keeps_outputs_with_duplicate_input_basenames() {
let dir = workdir("action-duplicate-basenames");
std::fs::create_dir_all(dir.join("left")).unwrap();
std::fs::create_dir_all(dir.join("right")).unwrap();
std::fs::write(dir.join("left/report.pdf"), fixture(1)).unwrap();
std::fs::write(dir.join("right/report.pdf"), fixture(2)).unwrap();
let mut a = auto(&dir);
let args = json!({
"steps": [{ "step": "set_title", "arg": "Processed" }],
"paths": ["left/report.pdf", "right/report.pdf"],
"folder": "results"
});
let result = ok(&mut a, "action_run", args.clone());
let files = result["files"].as_array().unwrap();
assert_eq!(files.len(), 2);
let first_path = files[0]["output"].as_str().unwrap();
let second_path = files[1]["output"].as_str().unwrap();
assert!(first_path.ends_with("report.pdf"), "{first_path}");
assert!(second_path.ends_with("report (2).pdf"), "{second_path}");
let first_bytes = std::fs::read(first_path).unwrap();
assert_eq!(ok(&mut a, "doc_open", json!({ "path": first_path }))["pages"], 1);
assert_eq!(ok(&mut a, "doc_open", json!({ "path": second_path }))["pages"], 2);
let repeated = ok(&mut a, "action_run", args);
assert!(repeated["files"][0]["output"].as_str().unwrap().ends_with("report (3).pdf"));
assert!(repeated["files"][1]["output"].as_str().unwrap().ends_with("report (4).pdf"));
assert_eq!(std::fs::read(first_path).unwrap(), first_bytes, "an earlier output must not be replaced");
}
#[test]
fn pdfa_through_tools() {
let dir = workdir("pdfa");