use std::path::Path;
use tracing::{debug, info, warn};
use crate::cli::commands::version_manifests::discover_cargo_locks;
use crate::cli::git::tracked_paths_under;
pub(super) fn relock_cargo_lockfiles(canonical: &str) {
let workspace_root = std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from("."));
let tracked = tracked_paths_under(&workspace_root);
if tracked.is_none() {
warn!(
"version-sync: cannot determine which files are git-tracked (not a git work tree, or `git` is \
unavailable) — lockfile relock falls back to an unfiltered disk walk and may touch build-staging \
copies"
);
}
for lock in discover_cargo_locks(&workspace_root, canonical, tracked.as_ref()) {
if lock.blocked_on_publish.is_some() {
debug!(lock = %lock.path.display(), "version-sync: skipping relock — blocked on publish");
continue;
}
let Some(dir) = lock.path.parent() else {
continue;
};
info!("Relocking {} after version sync", lock.path.display());
relock_one(dir, &lock.path);
}
}
fn relock_one(dir: &Path, lock_path: &Path) {
match std::process::Command::new("cargo")
.args(["update", "--offline", "-w"])
.current_dir(dir)
.status()
{
Ok(status) if status.success() => {}
Ok(status) => {
warn!(
lock = %lock_path.display(),
code = ?status.code(),
"version-sync: cargo update --offline -w failed for this lockfile"
);
}
Err(error) => {
warn!(
lock = %lock_path.display(),
%error,
"version-sync: could not run cargo update for this lockfile"
);
}
}
}