Skip to content

Commit b2c1ad5

Browse files
committed
fix(hook): use per-alias content hashing for fine-grained change detection
- add compute_short_hash() to trust.rs (7-char blake3 prefix) - change _AM_PROJECT_ALIASES format from "b,t" to "b|hash,t|hash" - rewrite hook change detection to diff at individual alias level: removed = unload, added = load, changed = unload+reload, unchanged = skip - show incremental message ("1 added, 2 updated") on alias changes instead of full load message (which is kept for fresh cd-into-project) - backward compat: old format entries (no |) trigger a full reload - add regression test for overwriting an alias value (the original bug) - update snapshot tests for new env var format
1 parent 1aca41d commit b2c1ad5

8 files changed

Lines changed: 468 additions & 78 deletions

crates/am/src/env_vars.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
/// Value: comma-separated list, e.g. `"gs,ll"`.
33
pub const AM_ALIASES: &str = "_AM_ALIASES";
44

5-
/// Tracks project-level alias names loaded by the cd hook.
6-
/// Value: comma-separated list, e.g. `"b,t"`.
5+
/// Tracks project-level aliases loaded by the cd hook.
6+
/// Value: comma-separated entries of `name|short_hash`, e.g. `"b|a132b21,t|1241ab1"`.
7+
/// The short hash is the first 7 hex chars of the BLAKE3 hash of the alias value,
8+
/// enabling per-alias change detection on reload.
79
pub const AM_PROJECT_ALIASES: &str = "_AM_PROJECT_ALIASES";
810

911
/// Path of the `.aliases` file currently in scope, used to suppress

crates/am/src/hook.rs

Lines changed: 424 additions & 69 deletions
Large diffs are not rendered by default.

crates/am/src/trust.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ pub fn compute_hash(content: &[u8]) -> String {
4747
blake3::hash(content).to_hex().to_string()
4848
}
4949

50+
/// Compute a 7-character short BLAKE3 hash of byte content.
51+
///
52+
/// Returns the first 7 hex characters of the BLAKE3 hash — analogous to
53+
/// git's short SHA. 28 bits gives collision probability <0.2 % for 1 000 items.
54+
pub fn compute_short_hash(content: &[u8]) -> String {
55+
blake3::hash(content).to_hex()[..7].to_string()
56+
}
57+
5058
/// Render the "loaded" info message shown on cd into a trusted directory.
5159
///
5260
/// Alias names are right-padded so `->` and commands align in columns.
@@ -118,6 +126,27 @@ mod tests {
118126
assert_eq!(hash1, hash2);
119127
}
120128

129+
#[test]
130+
fn compute_short_hash_returns_7_chars() {
131+
let hash = compute_short_hash(b"make build");
132+
assert_eq!(hash.len(), 7);
133+
assert!(hash.chars().all(|c| c.is_ascii_hexdigit()));
134+
}
135+
136+
#[test]
137+
fn compute_short_hash_deterministic() {
138+
let h1 = compute_short_hash(b"make build");
139+
let h2 = compute_short_hash(b"make build");
140+
assert_eq!(h1, h2);
141+
}
142+
143+
#[test]
144+
fn compute_short_hash_different_content() {
145+
let h1 = compute_short_hash(b"make build");
146+
let h2 = compute_short_hash(b"cargo build");
147+
assert_ne!(h1, h2);
148+
}
149+
121150
#[test]
122151
fn compute_hash_different_content_different_hash() {
123152
let hash1 = compute_hash(b"[aliases]\nb = \"make build\"\n");
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
---
22
source: crates/am/tests/snapshots.rs
3+
assertion_line: 584
34
expression: output
45
---
56
printf '%s\n' 'am: loaded .aliases'
67
printf '%s\n' ' b → cargo build'
78
printf '%s\n' ' t → cargo test'
89
alias b="cargo build"
910
alias t="cargo test"
10-
export _AM_PROJECT_ALIASES="b,t"
11+
export _AM_PROJECT_ALIASES="b|b58de66,t|ab61de4"
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
---
22
source: crates/am/tests/snapshots.rs
3+
assertion_line: 613
34
expression: output
45
---
56
functions -e old_a
67
functions -e old_b
7-
echo 'am: loaded .aliases'
8-
echo ' t → make test'
8+
echo 'am: .aliases changed (1 added, 2 removed)'
99
alias t "make test"
10-
set -gx _AM_PROJECT_ALIASES "t"
10+
set -gx _AM_PROJECT_ALIASES "t|7f7c42c"
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
---
22
source: crates/am/tests/snapshots.rs
3+
assertion_line: 497
34
expression: output
45
---
56
echo 'am: loaded .aliases'
67
echo ' b → cargo build'
78
echo ' t → cargo test'
89
alias b "cargo build"
910
alias t "cargo test"
10-
set -gx _AM_PROJECT_ALIASES "b,t"
11+
set -gx _AM_PROJECT_ALIASES "b|b58de66,t|ab61de4"
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
---
22
source: crates/am/tests/snapshots.rs
3+
assertion_line: 555
34
expression: output
45
---
56
Write-Host 'am: loaded .aliases'
67
Write-Host ' b → cargo build'
78
Write-Host ' t → cargo test'
89
function global:b { cargo build @args }
910
function global:t { cargo test @args }
10-
$env:_AM_PROJECT_ALIASES = "b,t"
11+
$env:_AM_PROJECT_ALIASES = "b|b58de66,t|ab61de4"
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
---
22
source: crates/am/tests/snapshots.rs
3+
assertion_line: 526
34
expression: output
45
---
56
printf '%s\n' 'am: loaded .aliases'
67
printf '%s\n' ' b → cargo build'
78
printf '%s\n' ' t → cargo test'
89
alias b="cargo build"
910
alias t="cargo test"
10-
export _AM_PROJECT_ALIASES="b,t"
11+
export _AM_PROJECT_ALIASES="b|b58de66,t|ab61de4"

0 commit comments

Comments
 (0)