use std::collections::HashSet;
use std::path::{Path, PathBuf};
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);
}
}
pub(super) fn relock_lockfiles_beside_changed_manifests(changed_paths: &HashSet<PathBuf>) {
for path in changed_paths {
if path.file_name().and_then(|name| name.to_str()) != Some("Cargo.toml") {
continue;
}
let Some(dir) = path.parent() else {
continue;
};
let lock_path = dir.join("Cargo.lock");
if !lock_path.exists() {
continue;
}
info!("Relocking {} after its generated manifest changed", 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(),
"cargo update --offline -w failed for this lockfile; it may still be stale against \
its manifest. Re-run `cargo update` in that directory with network access if a \
later `cargo check --locked` rejects it"
);
}
Err(error) => {
warn!(
lock = %lock_path.display(),
%error,
"could not run cargo update for this lockfile; it may still be stale against its manifest"
);
}
}
}