Skip to main content

cmx_core/
artifact_status.rs

1use crate::types::LockEntry;
2
3/// Returns `true` if an installed artifact is considered outdated relative to
4/// the source.  Pure function — no I/O.
5///
6/// The three rules:
7/// - No lock entry → outdated (artifact is untracked)
8/// - `source_checksum` differs from lock's `source_checksum` → outdated (content changed in source)
9/// - Version newly present in source (source has a version, lock entry has none) → outdated
10pub fn source_outdated(
11    lock_entry: Option<&LockEntry>,
12    source_checksum: &str,
13    source_version: Option<&str>,
14) -> bool {
15    match lock_entry {
16        Some(entry) => {
17            // Checksum changed
18            if entry.source_checksum != source_checksum {
19                return true;
20            }
21            // Installed without a version but source now has one
22            if entry.version.is_none() && source_version.is_some() {
23                return true;
24            }
25            false
26        }
27        // No lock entry — untracked
28        None => true,
29    }
30}
31
32// ---------------------------------------------------------------------------
33// Unit tests
34// ---------------------------------------------------------------------------
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39    use crate::test_support::make_lock_entry_with_checksum;
40    use crate::types::ArtifactKind;
41
42    fn make_lock_entry(source_checksum: &str, version: Option<&str>) -> LockEntry {
43        make_lock_entry_with_checksum(
44            ArtifactKind::Agent,
45            version,
46            "guidelines",
47            "agents/my-agent.md",
48            source_checksum,
49        )
50    }
51
52    #[test]
53    fn source_outdated_matching_checksum_not_outdated() {
54        let entry = make_lock_entry("sha256:abc", Some("1.0.0"));
55        assert!(!source_outdated(Some(&entry), "sha256:abc", Some("1.0.0")));
56    }
57
58    #[test]
59    fn source_outdated_changed_checksum_is_outdated() {
60        let entry = make_lock_entry("sha256:abc", Some("1.0.0"));
61        assert!(source_outdated(Some(&entry), "sha256:xyz", Some("1.0.0")));
62    }
63
64    #[test]
65    fn source_outdated_no_lock_entry_is_outdated() {
66        assert!(source_outdated(None, "sha256:abc", Some("1.0.0")));
67    }
68
69    #[test]
70    fn source_outdated_version_appeared_in_source_is_outdated() {
71        // Installed without a version; source now carries one
72        let entry = make_lock_entry("sha256:abc", None);
73        assert!(source_outdated(Some(&entry), "sha256:abc", Some("1.0.0")));
74    }
75
76    #[test]
77    fn source_outdated_both_unversioned_same_checksum_not_outdated() {
78        let entry = make_lock_entry("sha256:abc", None);
79        assert!(!source_outdated(Some(&entry), "sha256:abc", None));
80    }
81}