chore: cargo fmt after Rust 1.93 toolchain bump
This commit is contained in:
@@ -15,7 +15,6 @@ _merge_parsed.json
|
|||||||
.huskies_port
|
.huskies_port
|
||||||
.huskies/bot.toml.bak
|
.huskies/bot.toml.bak
|
||||||
.huskies/build_hash
|
.huskies/build_hash
|
||||||
.huskies/source-map.json
|
|
||||||
|
|
||||||
# Per-worktree planning file (written by coder agents, must never reach squash commits)
|
# Per-worktree planning file (written by coder agents, must never reach squash commits)
|
||||||
PLAN.md
|
PLAN.md
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ crate-type = ["lib"]
|
|||||||
name = "source-map-check"
|
name = "source-map-check"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "source-map-regen"
|
||||||
|
path = "src/regen_main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
|
|
||||||
|
|||||||
@@ -303,6 +303,67 @@ pub fn update_source_map(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Regenerate the source map from scratch for all tracked source files in `worktree`.
|
||||||
|
///
|
||||||
|
/// Uses `git ls-files` to enumerate every tracked Rust and TypeScript file, extracts
|
||||||
|
/// their public item signatures, and writes a fresh JSON map sorted by key. Running
|
||||||
|
/// twice with unchanged source produces byte-identical output (deterministic).
|
||||||
|
///
|
||||||
|
/// Unlike [`update_for_worktree`], this path cannot leave stale entries: every file in
|
||||||
|
/// the map was present and tracked at the time of writing.
|
||||||
|
pub fn regenerate_source_map(worktree: &Path, source_map_path: &Path) -> Result<(), String> {
|
||||||
|
let output = Command::new("git")
|
||||||
|
.args(["ls-files"])
|
||||||
|
.current_dir(worktree)
|
||||||
|
.output()
|
||||||
|
.map_err(|e| format!("git ls-files: {e}"))?;
|
||||||
|
|
||||||
|
if !output.status.success() {
|
||||||
|
return Err(format!(
|
||||||
|
"git ls-files failed: {}",
|
||||||
|
String::from_utf8_lossy(&output.stderr).trim()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use BTreeMap so keys are sorted alphabetically → deterministic output.
|
||||||
|
let mut entries: std::collections::BTreeMap<String, Vec<serde_json::Value>> =
|
||||||
|
std::collections::BTreeMap::new();
|
||||||
|
|
||||||
|
for rel_path in String::from_utf8_lossy(&output.stdout).lines() {
|
||||||
|
if rel_path.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let abs_path = worktree.join(rel_path);
|
||||||
|
if !abs_path.exists() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let ext = abs_path.extension().and_then(|e| e.to_str()).unwrap_or("");
|
||||||
|
let items: Vec<serde_json::Value> = match ext {
|
||||||
|
"rs" => RustAdapter::extract_items(&abs_path)
|
||||||
|
.into_iter()
|
||||||
|
.map(serde_json::Value::String)
|
||||||
|
.collect(),
|
||||||
|
"ts" | "tsx" => TypeScriptAdapter::extract_items(&abs_path)
|
||||||
|
.into_iter()
|
||||||
|
.map(serde_json::Value::String)
|
||||||
|
.collect(),
|
||||||
|
_ => continue,
|
||||||
|
};
|
||||||
|
entries.insert(rel_path.to_string(), items);
|
||||||
|
}
|
||||||
|
|
||||||
|
let map: serde_json::Map<String, serde_json::Value> = entries
|
||||||
|
.into_iter()
|
||||||
|
.map(|(k, v)| (k, serde_json::Value::Array(v)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if let Some(parent) = source_map_path.parent() {
|
||||||
|
std::fs::create_dir_all(parent).map_err(|e| format!("create_dir_all: {e}"))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_map(source_map_path, map)
|
||||||
|
}
|
||||||
|
|
||||||
/// Update the source map for files that changed since `base_branch` in `worktree_path`.
|
/// Update the source map for files that changed since `base_branch` in `worktree_path`.
|
||||||
///
|
///
|
||||||
/// 1. Runs `git diff --name-only {base_branch}...HEAD` in the worktree.
|
/// 1. Runs `git diff --name-only {base_branch}...HEAD` in the worktree.
|
||||||
@@ -311,7 +372,12 @@ pub fn update_source_map(
|
|||||||
///
|
///
|
||||||
/// Errors are returned as `Err(String)`; callers in the spawn flow treat them as
|
/// Errors are returned as `Err(String)`; callers in the spawn flow treat them as
|
||||||
/// non-blocking warnings.
|
/// non-blocking warnings.
|
||||||
pub fn update_for_worktree(
|
///
|
||||||
|
/// # Note
|
||||||
|
/// This incremental path is retained for testing only. Production map writes use
|
||||||
|
/// [`regenerate_source_map`] which cannot leave stale entries.
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) fn update_for_worktree(
|
||||||
worktree_path: &Path,
|
worktree_path: &Path,
|
||||||
base_branch: &str,
|
base_branch: &str,
|
||||||
source_map_path: &Path,
|
source_map_path: &Path,
|
||||||
@@ -894,6 +960,59 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// AC4: running `regenerate_source_map` twice on the same source tree produces
|
||||||
|
/// byte-identical output.
|
||||||
|
#[test]
|
||||||
|
fn regenerate_source_map_is_deterministic() {
|
||||||
|
let tmp = TempDir::new().unwrap();
|
||||||
|
init_git_repo(tmp.path());
|
||||||
|
|
||||||
|
// Add a few tracked files and commit them.
|
||||||
|
write_rs(
|
||||||
|
tmp.path(),
|
||||||
|
"alpha.rs",
|
||||||
|
"//! Alpha module.\n\n/// Does alpha.\npub fn alpha() {}\n",
|
||||||
|
);
|
||||||
|
write_rs(
|
||||||
|
tmp.path(),
|
||||||
|
"beta.rs",
|
||||||
|
"//! Beta module.\n\n/// Does beta.\npub fn beta() {}\n",
|
||||||
|
);
|
||||||
|
Command::new("git")
|
||||||
|
.args(["add", "alpha.rs", "beta.rs"])
|
||||||
|
.current_dir(tmp.path())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
Command::new("git")
|
||||||
|
.args(["commit", "-m", "add files"])
|
||||||
|
.current_dir(tmp.path())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let map_path = tmp.path().join("source-map.json");
|
||||||
|
|
||||||
|
let result1 = regenerate_source_map(tmp.path(), &map_path);
|
||||||
|
assert!(
|
||||||
|
result1.is_ok(),
|
||||||
|
"first regenerate failed: {:?}",
|
||||||
|
result1.err()
|
||||||
|
);
|
||||||
|
let first = std::fs::read_to_string(&map_path).unwrap();
|
||||||
|
|
||||||
|
let result2 = regenerate_source_map(tmp.path(), &map_path);
|
||||||
|
assert!(
|
||||||
|
result2.is_ok(),
|
||||||
|
"second regenerate failed: {:?}",
|
||||||
|
result2.err()
|
||||||
|
);
|
||||||
|
let second = std::fs::read_to_string(&map_path).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
first, second,
|
||||||
|
"regenerate_source_map must be byte-identical on repeated runs"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// `relative_key` strips the root prefix from an absolute path.
|
/// `relative_key` strips the root prefix from an absolute path.
|
||||||
#[test]
|
#[test]
|
||||||
fn relative_key_strips_root_prefix() {
|
fn relative_key_strips_root_prefix() {
|
||||||
|
|||||||
@@ -13,5 +13,9 @@ cargo fmt --manifest-path "$PROJECT_ROOT/Cargo.toml" --all --check
|
|||||||
echo "=== Running cargo clippy ==="
|
echo "=== Running cargo clippy ==="
|
||||||
cargo clippy --manifest-path "$PROJECT_ROOT/Cargo.toml" --workspace --all-targets -- -D warnings
|
cargo clippy --manifest-path "$PROJECT_ROOT/Cargo.toml" --workspace --all-targets -- -D warnings
|
||||||
|
|
||||||
|
echo "=== Regenerating source map ==="
|
||||||
|
cargo run --manifest-path "$PROJECT_ROOT/Cargo.toml" -p source-map-gen --bin source-map-regen --quiet -- --project-root "$PROJECT_ROOT"
|
||||||
|
git -C "$PROJECT_ROOT" add .huskies/source-map.json
|
||||||
|
|
||||||
echo "=== Checking doc coverage on changed files ==="
|
echo "=== Checking doc coverage on changed files ==="
|
||||||
cargo run --manifest-path "$PROJECT_ROOT/Cargo.toml" -p source-map-gen --bin source-map-check --quiet -- --worktree "$PROJECT_ROOT" --base master
|
cargo run --manifest-path "$PROJECT_ROOT/Cargo.toml" -p source-map-gen --bin source-map-check --quiet -- --worktree "$PROJECT_ROOT" --base master
|
||||||
|
|||||||
@@ -223,23 +223,6 @@ pub(super) async fn run_agent_spawn(
|
|||||||
slog_error!("[agents] pre-commit hook install failed for {sid}: {e}");
|
slog_error!("[agents] pre-commit hook install failed for {sid}: {e}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 1.5: Update the source map for changed files since master.
|
|
||||||
// Non-blocking — failures are logged but do not gate the spawn.
|
|
||||||
{
|
|
||||||
let wt_path_for_map = wt_info.path.clone();
|
|
||||||
let base_for_map = wt_info.base_branch.clone();
|
|
||||||
let map_path = project_root_clone.join(".huskies").join("source-map.json");
|
|
||||||
match tokio::task::spawn_blocking(move || {
|
|
||||||
source_map_gen::update_for_worktree(&wt_path_for_map, &base_for_map, &map_path)
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
.unwrap_or_else(|e| Err(e.to_string()))
|
|
||||||
{
|
|
||||||
Ok(()) => {}
|
|
||||||
Err(e) => slog_error!("[agents] source map update for {sid}: {e}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 2: store worktree info and render agent command/args/prompt.
|
// Step 2: store worktree info and render agent command/args/prompt.
|
||||||
let wt_path_str = wt_info.path.to_string_lossy().to_string();
|
let wt_path_str = wt_info.path.to_string_lossy().to_string();
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user