mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-09 04:22:20 +00:00
This commit is contained in:
1 parent
ea292f6be1
commit
448a7cab67
5 files changed
+21
-16
No files matched your search
@@ -6,7 +6,7 @@ use serde_json::{Value, json};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use crate::{Args, Automation, Result, ToolError, child, failed, unused, write_atomic};
|
||||
use crate::{Args, Automation, Result, ToolError, child, failed, write_atomic};
|
||||
|
||||
mod documents;
|
||||
mod form_tools;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::{Args, Automation, Result, ToolError, Value, child, failed, json, unused, write_atomic};
|
||||
use super::{Args, Automation, Result, ToolError, Value, child, failed, json, write_atomic};
|
||||
|
||||
impl Automation {
|
||||
pub(crate) fn doc_export_office(&self, a: &Args) -> Result<Value> {
|
||||
@@ -148,18 +148,7 @@ impl Automation {
|
||||
.and_then(|bytes| run_on(&action, &name, std::sync::Arc::new(bytes), |_, _| {}));
|
||||
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)?;
|
||||
let target = crate::batch::publish(&child(&folder, &name), &r.bytes)?;
|
||||
json!({ "path": p, "output": target.to_string_lossy(), "log": r.log })
|
||||
}
|
||||
Err(e) => json!({ "path": p, "error": e }),
|
||||
|
||||
@@ -281,7 +281,7 @@ impl Automation {
|
||||
}
|
||||
|
||||
/// Publish atomically without replacing any existing name, even if another writer wins a race.
|
||||
fn publish(target: &Path, bytes: &[u8]) -> Result<PathBuf> {
|
||||
pub(crate) fn publish(target: &Path, bytes: &[u8]) -> Result<PathBuf> {
|
||||
let dir = target.parent().ok_or_else(|| failed("output has no parent"))?;
|
||||
std::fs::create_dir_all(dir).map_err(failed)?;
|
||||
let mut temp = tempfile::NamedTempFile::new_in(dir).map_err(failed)?;
|
||||
|
||||
@@ -70,7 +70,7 @@ use pages::{DEFAULT_DPI, MAX_DPI, encode_png, rendered_content};
|
||||
use pages::{FIND_FIRST_BATCH, FIND_MAX_WARNING_BYTES, FIND_MAX_WARNINGS, extract_parallel};
|
||||
#[cfg(test)]
|
||||
pub(crate) use paths::MAX_INPUT;
|
||||
use paths::{child, lexical, unused, write_atomic};
|
||||
use paths::{child, lexical, write_atomic};
|
||||
pub(crate) use paths::{read_input, read_input_bytes};
|
||||
#[cfg(test)]
|
||||
use paths::{write_atomic_synced, write_atomic_with};
|
||||
|
||||
@@ -8368,6 +8368,22 @@ fn action_run_keeps_outputs_with_duplicate_input_basenames() {
|
||||
assert_eq!(std::fs::read(first_path).unwrap(), first_bytes, "an earlier output must not be replaced");
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn action_run_never_replaces_an_entry_that_exists_check_misses() {
|
||||
let dir = workdir("action-noclobber");
|
||||
std::fs::create_dir_all(dir.join("results")).unwrap();
|
||||
std::fs::write(dir.join("report.pdf"), fixture(1)).unwrap();
|
||||
// A dangling link is invisible to `exists()` but is still an occupied name.
|
||||
std::os::unix::fs::symlink(dir.join("nowhere.pdf"), dir.join("results/report.pdf")).unwrap();
|
||||
let mut a = auto(&dir);
|
||||
let args = json!({ "steps": [{ "step": "set_title", "arg": "Processed" }], "paths": ["report.pdf"], "folder": "results" });
|
||||
let result = ok(&mut a, "action_run", args);
|
||||
let output = result["files"][0]["output"].as_str().unwrap();
|
||||
assert!(output.ends_with("report (2).pdf"), "{output}");
|
||||
assert!(dir.join("results/report.pdf").symlink_metadata().unwrap().file_type().is_symlink(), "the existing entry must stay");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pdfa_through_tools() {
|
||||
let dir = workdir("pdfa");
|
||||
|
||||
Reference in new issue
Block a user