Build: drop the unused egui patches and fail CI on [[patch.unused]] (#3404)

Removes the unused egui_demo_lib, egui_inspection and egui_system_font_provider patches and adds cargo xtask lock-patches to cargo xtask ci. Fixes #3403.
This commit is contained in:
nnaannoo
2026-11-10 15:13:16 +05:30
committed by GitHub
parent f31463abfe
commit 87000339ed
5 changed files with 81 additions and 22 deletions
Generated
-15
View File
@@ -8037,18 +8037,3 @@ dependencies = [
"syn 3.0.6",
"winnow",
]
[[patch.unused]]
name = "egui_demo_lib"
version = "0.37.0"
source = "git+https://github.com/storytold/egui.git?rev=6d518fc799681571963842f95b55a6b68431b15a#6d518fc799681571963842f95b55a6b68431b15a"
[[patch.unused]]
name = "egui_inspection"
version = "0.37.0"
source = "git+https://github.com/storytold/egui.git?rev=6d518fc799681571963842f95b55a6b68431b15a#6d518fc799681571963842f95b55a6b68431b15a"
[[patch.unused]]
name = "egui_system_font_provider"
version = "0.37.0"
source = "git+https://github.com/storytold/egui.git?rev=6d518fc799681571963842f95b55a6b68431b15a#6d518fc799681571963842f95b55a6b68431b15a"
+2 -3
View File
@@ -254,8 +254,7 @@ egui-wgpu = { git = "https://github.com/storytold/egui.git", rev = "6d518fc79968
egui_glow = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
egui_extras = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
egui_kittest = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
egui_system_font_provider = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
eframe = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
egui_demo_lib = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
egui_inspection = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" }
# Patch a crate only together with the dependency that needs it: an unused patch makes the Nix
# build, which uses vendored sources, fail (`cargo xtask lock-patches`).
winit = { git = "https://github.com/storytold/winit.git", rev = "a517b3846ee8457d84ee4975110bfda6797c44dc" }
+1 -1
View File
@@ -2,7 +2,7 @@
```sh
cargo test --workspace # everything
cargo xtask ci # fmt, clippy -D warnings, tests, pdf-deps, layers, assets, wasm
cargo xtask ci # fmt, clippy -D warnings, tests, pdf-deps, lock-patches, layers, assets, wasm
```
The After Effects test projects of `crates/aep` are not in the repository; without them the
+71
View File
@@ -0,0 +1,71 @@
//! Fail when `Cargo.lock` records a `[patch]` entry nothing uses.
//!
//! An unused patch only makes cargo warn, but the Nix package builds offline from vendored
//! sources, which hold only the packages the build uses: it cannot find the patched package and
//! refuses to build (#3403). Patch a crate together with the dependency that needs it.
use std::path::Path;
pub fn run(root: &Path) -> Result<(), String> {
let lock = std::fs::read_to_string(root.join("Cargo.lock")).map_err(|e| format!("Cargo.lock: {e}"))?;
let unused = unused_patches(&lock);
if unused.is_empty() {
println!("Cargo.lock: every [patch] entry is used");
return Ok(());
}
Err(format!(
"Cargo.lock has [[patch.unused]] entries: {}. Remove them from [patch] in Cargo.toml (add a patch together with the dependency that needs it); the Nix build, which uses vendored sources, fails on them (#3403)",
unused.join(", ")
))
}
/// The package names of the `[[patch.unused]]` entries in the text of a `Cargo.lock`.
fn unused_patches(lock: &str) -> Vec<String> {
let mut names = Vec::new();
let mut in_unused = false;
for line in lock.lines() {
let line = line.trim();
if line.starts_with('[') {
in_unused = line == "[[patch.unused]]";
} else if let Some(name) = line.strip_prefix("name = ").filter(|_| in_unused) {
names.push(name.trim_matches('"').to_string());
}
}
names
}
#[cfg(test)]
mod tests {
use super::*;
const LOCK: &str = r#"
[[package]]
name = "egui"
version = "0.37.0"
[[patch.unused]]
name = "egui_demo_lib"
version = "0.37.0"
source = "git+https://github.com/storytold/egui.git?rev=6d518fc#6d518fc"
[[patch.unused]]
name = "egui_inspection"
version = "0.37.0"
"#;
#[test]
fn lists_the_unused_patches_and_only_those() {
assert_eq!(unused_patches(LOCK), ["egui_demo_lib", "egui_inspection"]);
}
#[test]
fn a_lock_without_unused_patches_is_accepted() {
assert!(unused_patches("[[package]]\nname = \"egui\"\nversion = \"0.37.0\"\n").is_empty());
}
#[test]
fn the_repository_lock_has_no_unused_patches() {
let root = Path::new(env!("CARGO_MANIFEST_DIR")).join("..");
assert!(run(&root).is_ok(), "{:?}", run(&root));
}
}
+7 -3
View File
@@ -1,4 +1,4 @@
//! Workspace automation: `cargo xtask <layers|assets|pdf-deps|aep-corpus|wasm|web|ico|ci>`.
//! Workspace automation: `cargo xtask <layers|assets|pdf-deps|lock-patches|aep-corpus|wasm|web|ico|ci>`.
//!
//! - `layers`: enforces the dependency layering of `docs/architecture.md` §1 (downward-only edges,
//! listed same-layer edges, no UI/OS crates below L5).
@@ -6,6 +6,7 @@
//! and the web app.
//! - `web [--dev] [--serve PORT]`: build the web app (`apps/effectcraft-web`) into
//! `<target>/web/dist` with `wasm-bindgen` (docs/web.md); `--serve` serves it on localhost.
//! - `lock-patches`: `Cargo.lock` records no unused `[patch]` entry (the Nix build cannot vendor one).
//! - `assets`: every asset file (image, icon, font, LUT, audio, video…) has a complete
//! `<file>.attribution` sidecar and an entry in `ATTRIBUTION.md` (AGENTS.md §1).
//! - `aep-corpus [--dir DIR]`: fetch the After Effects test corpus at the commit pinned in
@@ -19,6 +20,7 @@
mod aep_corpus;
mod bench;
mod ico;
mod lock_patches;
mod pdf_deps;
mod version;
@@ -534,12 +536,13 @@ type Stage = fn() -> Result<(), String>;
/// Every stage runs even when an earlier one fails, so one run reports all the problems.
fn ci() -> Result<(), String> {
let stages: [(&str, Stage); 8] = [
let stages: [(&str, Stage); 9] = [
("audio backend", audio_backend),
("fmt", || run(Command::new(env!("CARGO")).args(["fmt", "--check"]))),
("clippy", || run(Command::new(env!("CARGO")).args(["clippy", "--workspace", "--all-targets", "--", "-D", "warnings"]))),
("tests", tests),
("pdf-deps", || pdf_deps::run(&root())),
("lock-patches", || lock_patches::run(&root())),
("layers", layers),
("assets", assets),
("wasm", wasm),
@@ -555,6 +558,7 @@ fn main() -> ExitCode {
"wasm" => wasm(),
"assets" => assets(),
"pdf-deps" => pdf_deps::run(&root()),
"lock-patches" => lock_patches::run(&root()),
"aep-corpus" => aep_corpus::run(&root(), &std::env::args().skip(2).collect::<Vec<_>>()),
"ci" => ci(),
"audio-backend" => audio_backend(),
@@ -568,7 +572,7 @@ fn main() -> ExitCode {
let rest: Vec<String> = std::env::args().skip(2).collect();
version::run(&root(), &rest.iter().map(String::as_str).collect::<Vec<_>>())
}
_ => Err("usage: cargo xtask <layers|assets|pdf-deps|aep-corpus [--dir DIR]|wasm|web [--dev] [--serve PORT]|ico OUT.ico IN.png…|version [set X.Y.Z]|ci|audio-backend|bench [--bin CLI] [--quick] [--project F --comp C] [--compare OLD.jsonl] (--help)>".into()),
_ => Err("usage: cargo xtask <layers|assets|pdf-deps|lock-patches|aep-corpus [--dir DIR]|wasm|web [--dev] [--serve PORT]|ico OUT.ico IN.png…|version [set X.Y.Z]|ci|audio-backend|bench [--bin CLI] [--quick] [--project F --comp C] [--compare OLD.jsonl] (--help)>".into()),
};
match r {
Ok(()) => ExitCode::SUCCESS,