xtask: make version.rs compile here and register cargo xtask version

version.rs (ported from PhotoCraft) called crate::cargo() and a two-argument
crate::run() that don't exist in this xtask, so xtask didn't build at all.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Brandon ThomasandClaude Opus 5.5 committed 2026-10-02 16:20:47 -04:00
1 parent 92dd783b7e
commit e849fbcf1b
2 files changed
+20 -21

No files matched your search

+6
View File
@@ -15,6 +15,7 @@ type Command = fn(&[String]) -> anyhow::Result<()>;
/// Every subcommand: name, one-line summary, entry point.
const COMMANDS: &[(&str, &str, Command)] = &[
("version", "Print the workspace version, or `version set X.Y.Z[-pre]` to change it and refresh Cargo.lock", version_cmd),
("layers", "Enforce the crate dependency layering (plan/architecture.md §3)", gates::layers),
("wasm", "cargo check --target wasm32-unknown-unknown for every crate below L8", gates::wasm),
("deny", "Dependency licences, bans, sources and advisories (deny.toml; needs cargo-deny)", gates::deny),
@@ -29,6 +30,11 @@ const COMMANDS: &[(&str, &str, Command)] = &[
("demo-pdf", "Build dist/demo/printcraft-showcase.pdf (needs Google Chrome or Chromium)", demo_pdf::run),
];
fn version_cmd(args: &[String]) -> anyhow::Result<()> {
let args: Vec<&str> = args.iter().map(String::as_str).collect();
version::run(&gates::root(), &args).map_err(anyhow::Error::msg)
}
fn main() -> ExitCode {
let args: Vec<String> = std::env::args().skip(1).collect();
let Some(name) = args.first() else {
+14 -21
View File
@@ -8,10 +8,7 @@ use std::path::Path;
/// The `version = "…"` value inside `[workspace.package]`.
pub fn read(manifest: &str) -> Result<String, String> {
let (_, line) = find_line(manifest)?;
let v = line
.split_once('=')
.map(|(_, v)| v.trim().trim_matches('"').to_string())
.unwrap_or_default();
let v = line.split_once('=').map(|(_, v)| v.trim().trim_matches('"').to_string()).unwrap_or_default();
if v.is_empty() {
return Err("empty [workspace.package] version".into());
}
@@ -48,20 +45,11 @@ pub fn validate(v: &str) -> Result<(), String> {
None => (v, None),
};
let nums: Vec<&str> = core.split('.').collect();
if nums.len() != 3
|| nums.iter().any(|n| {
n.is_empty()
|| !n.bytes().all(|b| b.is_ascii_digit())
|| (n.len() > 1 && n.starts_with('0'))
})
{
if nums.len() != 3 || nums.iter().any(|n| n.is_empty() || !n.bytes().all(|b| b.is_ascii_digit()) || (n.len() > 1 && n.starts_with('0'))) {
return bad();
}
if let Some(p) = pre
&& (p.is_empty()
|| p.split('.').any(|id| {
id.is_empty() || !id.bytes().all(|b| b.is_ascii_alphanumeric() || b == b'-')
}))
&& (p.is_empty() || p.split('.').any(|id| id.is_empty() || !id.bytes().all(|b| b.is_ascii_alphanumeric() || b == b'-')))
{
return bad();
}
@@ -104,12 +92,17 @@ pub fn run(root: &Path, args: &[&str]) -> Result<(), String> {
std::fs::write(&tmp, updated).map_err(|e| format!("write {}: {e}", tmp.display()))?;
std::fs::rename(&tmp, &path).map_err(|e| format!("replace {}: {e}", path.display()))?;
// Refresh the workspace members' entries in Cargo.lock (no dependency upgrades).
let mut c = crate::cargo();
c.args(["update", "--workspace", "--offline"]);
if crate::run(c, "cargo update --workspace --offline").is_err() {
let mut c = crate::cargo();
c.args(["update", "--workspace"]);
crate::run(c, "cargo update --workspace")?;
let cargo_update = |extra: &[&str]| -> Result<(), String> {
let st = std::process::Command::new(env!("CARGO"))
.current_dir(root)
.args(["update", "--workspace"])
.args(extra)
.status()
.map_err(|e| format!("cargo update: {e}"))?;
if st.success() { Ok(()) } else { Err(format!("cargo update --workspace {} failed", extra.join(" "))) }
};
if cargo_update(&["--offline"]).is_err() {
cargo_update(&[])?;
}
println!("version: {old} -> {new}");
Ok(())