mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-10 01:50:22 -06:00
107 lines
4.2 KiB
Rust
107 lines
4.2 KiB
Rust
//! Verify that PDF reading and writing use one immutable shared crate and patched backends.
|
|
|
|
use std::path::Path;
|
|
use std::process::Command;
|
|
|
|
use serde_json::Value;
|
|
|
|
const REV: &str = "92d392cff132eaf53e13afff77f38b5c11b73aa0";
|
|
/// The writer's revision: craft-libs#417, CMYK, gray and spot colors with their exact inks.
|
|
const KRILLA_REV: &str = "fb08be5fa19eee8d37e624397fcdc96df6035e92";
|
|
const PACKAGES: &[(&str, &str, &str)] = &[
|
|
("craft-pdf", "0.1.0", REV),
|
|
("krilla", "0.8.2", KRILLA_REV),
|
|
("hayro-syntax", "0.7.2", REV),
|
|
("hayro-interpret", "0.7.0", REV),
|
|
("hayro-jbig2", "0.3.0", REV),
|
|
("hayro-cmap", "0.1.0", REV),
|
|
("hayro-postscript", "0.1.0", REV),
|
|
];
|
|
|
|
/// The resolved source of a craft-libs package at `rev`.
|
|
fn source(rev: &str) -> String {
|
|
format!("git+https://github.com/storytold/craft-libs?rev={rev}#{rev}")
|
|
}
|
|
|
|
pub fn run(root: &Path) -> Result<(), String> {
|
|
let output = Command::new(std::env::var_os("CARGO").unwrap_or_else(|| "cargo".into()))
|
|
.current_dir(root)
|
|
.args(["metadata", "--locked", "--format-version", "1"])
|
|
.output()
|
|
.map_err(|e| format!("cargo metadata: {e}"))?;
|
|
if !output.status.success() {
|
|
return Err(format!("cargo metadata: {}", String::from_utf8_lossy(&output.stderr)));
|
|
}
|
|
let metadata: Value = serde_json::from_slice(&output.stdout).map_err(|e| format!("cargo metadata: {e}"))?;
|
|
validate(&metadata)?;
|
|
println!("PDF: shared crate and patched backends resolve once to {REV} (krilla to {KRILLA_REV})");
|
|
Ok(())
|
|
}
|
|
|
|
fn validate(metadata: &Value) -> Result<(), String> {
|
|
let packages = metadata.get("packages").and_then(Value::as_array).ok_or("cargo metadata has no packages")?;
|
|
for &(name, version, rev) in PACKAGES {
|
|
let source = source(rev);
|
|
let mut found = packages.iter().filter(|p| p.get("name").and_then(Value::as_str) == Some(name));
|
|
let package = found.next().ok_or_else(|| format!("{name}: missing resolved package"))?;
|
|
if found.next().is_some() {
|
|
return Err(format!("{name}: expected one resolved package"));
|
|
}
|
|
if package.get("version").and_then(Value::as_str) != Some(version) || package.get("source").and_then(Value::as_str) != Some(source.as_str()) {
|
|
return Err(format!("{name}: expected {version} from {source}; got {package}"));
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use serde_json::json;
|
|
|
|
fn metadata() -> Value {
|
|
let packages: Vec<_> = PACKAGES.iter().map(|(name, version, rev)| json!({"name":name, "version":version, "source":source(rev)})).collect();
|
|
json!({"packages": packages})
|
|
}
|
|
|
|
#[test]
|
|
fn accepts_pinned_pdf_packages_without_changing_printer_transport() {
|
|
let mut m = metadata();
|
|
m["packages"]
|
|
.as_array_mut()
|
|
.unwrap()
|
|
.push(json!({"name":"craft-print", "version":"0.1.0", "source":"git+https://github.com/storytold/craft-libs?rev=d991bf6792f8ade99c51358bf3c1d902c8cd96b5#d991bf6792f8ade99c51358bf3c1d902c8cd96b5"}));
|
|
assert!(validate(&m).is_ok());
|
|
}
|
|
|
|
#[test]
|
|
fn rejects_missing_or_duplicate_pdf_packages() {
|
|
for index in 0..PACKAGES.len() {
|
|
let mut m = metadata();
|
|
m["packages"].as_array_mut().unwrap().remove(index);
|
|
assert!(validate(&m).is_err());
|
|
let mut m = metadata();
|
|
let duplicate = m["packages"][index].clone();
|
|
m["packages"].as_array_mut().unwrap().push(duplicate);
|
|
assert!(validate(&m).is_err());
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn rejects_registry_local_version_and_revision_drift() {
|
|
for index in 0..PACKAGES.len() {
|
|
for (field, value) in [
|
|
("source", Value::Null),
|
|
("source", json!("registry+https://github.com/rust-lang/crates.io-index")),
|
|
("source", json!("git+https://github.com/storytold/craft-libs?branch=main#other")),
|
|
("source", json!(source(if PACKAGES[index].2 == REV { KRILLA_REV } else { REV }))),
|
|
("version", json!("0.99.0")),
|
|
] {
|
|
let mut m = metadata();
|
|
m["packages"][index][field] = value;
|
|
assert!(validate(&m).is_err());
|
|
}
|
|
}
|
|
}
|
|
}
|