aboutsummaryrefslogtreecommitdiff
path: root/src/detect/manifest_update.rs
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-06-10 19:23:13 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-06-10 19:23:13 +0300
commit82468a0e03360219898ebf3735bdf559182009f8 (patch)
tree0ee5213fe041a539f23e846f9148493528249512 /src/detect/manifest_update.rs
parent36a1b7f86444871f0c38ff36510a6e3c2eec48c6 (diff)
feat: add manifest-based detection engine
Diffstat (limited to 'src/detect/manifest_update.rs')
-rw-r--r--src/detect/manifest_update.rs24
1 files changed, 14 insertions, 10 deletions
diff --git a/src/detect/manifest_update.rs b/src/detect/manifest_update.rs
index 6534b885..f82b4864 100644
--- a/src/detect/manifest_update.rs
+++ b/src/detect/manifest_update.rs
@@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
use super::{agent_label, parse_agent_label, Agent};
-pub(crate) const MANIFEST_ENGINE_VERSION: u32 = 1;
+pub(crate) const MANIFEST_ENGINE_VERSION: u32 = 2;
const DEFAULT_CATALOG_URL: &str = "https://herdr.dev/agent-detection/index.toml";
const CATALOG_URL_ENV: &str = "HERDR_AGENT_DETECTION_MANIFEST_CATALOG_URL";
const MAX_FETCH_BYTES: usize = 256 * 1024;
@@ -446,9 +446,13 @@ fn sync_parent_dir(parent: &Path) -> Result<(), String> {
}
fn directory_sync_unsupported(err: &std::io::Error) -> bool {
+ // PermissionDenied: Windows cannot open directories via `File::open`
+ // (os error 5), so directory sync is effectively unsupported there.
matches!(
err.kind(),
- std::io::ErrorKind::Unsupported | std::io::ErrorKind::InvalidInput
+ std::io::ErrorKind::Unsupported
+ | std::io::ErrorKind::InvalidInput
+ | std::io::ErrorKind::PermissionDenied
)
}
@@ -610,7 +614,7 @@ contains = ["{contains}"]
#[test]
fn process_agent_manifest_commits_newer_manifest_atomically() {
with_state_dir("commit-newer", || {
- let content = remote_manifest("2026.06.10.1", "ready");
+ let content = remote_manifest("2026.06.10.3", "ready");
let commit = process_agent_manifest(Agent::Codex, &content, 1)
.unwrap()
.unwrap();
@@ -618,7 +622,7 @@ contains = ["{contains}"]
assert_eq!(commit.agent, Agent::Codex);
assert_eq!(
commit.version,
- ManifestVersion::parse("2026.06.10.1").unwrap()
+ ManifestVersion::parse("2026.06.10.3").unwrap()
);
assert_eq!(
fs::read_to_string(remote_manifest_path(Agent::Codex)).unwrap(),
@@ -648,7 +652,7 @@ path = "codex.toml"
.unwrap();
fs::write(
web_dir.join("codex.toml"),
- remote_manifest("2026.06.10.1", "auto-update-ready"),
+ remote_manifest("2026.06.10.3", "auto-update-ready"),
)
.unwrap();
std::env::set_var(
@@ -689,10 +693,10 @@ path = "codex.toml"
#[test]
fn process_agent_manifest_rejects_downgrade_and_keeps_cached_manifest() {
with_state_dir("reject-downgrade", || {
- let current = remote_manifest("2026.06.10.2", "current");
+ let current = remote_manifest("2026.06.10.4", "current");
process_agent_manifest(Agent::Codex, &current, 1).unwrap();
- let older = remote_manifest("2026.06.10.1", "older");
+ let older = remote_manifest("2026.06.10.3", "older");
assert!(process_agent_manifest(Agent::Codex, &older, 2).is_err());
assert_eq!(
fs::read_to_string(remote_manifest_path(Agent::Codex)).unwrap(),
@@ -704,10 +708,10 @@ path = "codex.toml"
#[test]
fn process_agent_manifest_rejects_equal_version_content_change() {
with_state_dir("reject-equal-change", || {
- let current = remote_manifest("2026.06.10.1", "current");
+ let current = remote_manifest("2026.06.10.3", "current");
process_agent_manifest(Agent::Codex, &current, 1).unwrap();
- let changed = remote_manifest("2026.06.10.1", "changed");
+ let changed = remote_manifest("2026.06.10.3", "changed");
assert!(process_agent_manifest(Agent::Codex, &changed, 2).is_err());
assert_eq!(
fs::read_to_string(remote_manifest_path(Agent::Codex)).unwrap(),
@@ -719,7 +723,7 @@ path = "codex.toml"
#[test]
fn process_agent_manifest_skips_same_version_same_content() {
with_state_dir("skip-same", || {
- let current = remote_manifest("2026.06.10.1", "current");
+ let current = remote_manifest("2026.06.10.3", "current");
process_agent_manifest(Agent::Codex, &current, 1).unwrap();
let result = process_agent_manifest(Agent::Codex, &current, 2).unwrap();