huskies: merge 872
This commit is contained in:
@@ -53,7 +53,7 @@ pub use types::{
|
||||
};
|
||||
pub use write::{
|
||||
bump_retry_count, migrate_names_from_slugs, migrate_story_ids_to_numeric, name_from_story_id,
|
||||
set_agent, set_qa_mode, set_retry_count, write_item,
|
||||
set_agent, set_depends_on, set_qa_mode, set_retry_count, write_item,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -186,6 +186,32 @@ pub fn migrate_names_from_slugs() {
|
||||
slog!("[crdt] Migrated names for {count} items from story ID slugs");
|
||||
}
|
||||
|
||||
/// Set the typed `depends_on` CRDT register for a pipeline item.
|
||||
///
|
||||
/// Encodes `deps` as a compact JSON array string (e.g. `"[837]"`) and writes it
|
||||
/// to the item's `depends_on` register. An empty slice clears the register to an
|
||||
/// empty string, which means "no dependencies".
|
||||
///
|
||||
/// Returns `true` if the item was found and the op was applied, `false` otherwise.
|
||||
pub fn set_depends_on(story_id: &str, deps: &[u32]) -> bool {
|
||||
let Some(state_mutex) = get_crdt() else {
|
||||
return false;
|
||||
};
|
||||
let Ok(mut state) = state_mutex.lock() else {
|
||||
return false;
|
||||
};
|
||||
let Some(&idx) = state.index.get(story_id) else {
|
||||
return false;
|
||||
};
|
||||
let value = if deps.is_empty() {
|
||||
String::new()
|
||||
} else {
|
||||
serde_json::to_string(deps).unwrap_or_default()
|
||||
};
|
||||
apply_and_persist(&mut state, |s| s.crdt.doc.items[idx].depends_on.set(value));
|
||||
true
|
||||
}
|
||||
|
||||
/// Set the `agent` field for a pipeline item by its story ID.
|
||||
///
|
||||
/// `Some(name)` writes the agent name into the CRDT register.
|
||||
@@ -715,6 +741,63 @@ mod tests {
|
||||
migrate_names_from_slugs();
|
||||
}
|
||||
|
||||
// ── set_depends_on regression tests ──────────────────────────────────────
|
||||
|
||||
#[test]
|
||||
fn set_depends_on_round_trip_and_clear() {
|
||||
use super::super::read::{check_unmet_deps_crdt, read_item};
|
||||
init_for_test();
|
||||
|
||||
write_item(
|
||||
"872_test_target",
|
||||
"1_backlog",
|
||||
Some("Target"),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
);
|
||||
|
||||
// Set depends_on to [837] and verify CRDT register holds the list.
|
||||
let ok = set_depends_on("872_test_target", &[837]);
|
||||
assert!(ok, "set_depends_on should return true for known item");
|
||||
let view = read_item("872_test_target").unwrap();
|
||||
assert_eq!(
|
||||
view.depends_on,
|
||||
Some(vec![837]),
|
||||
"CRDT register should hold [837]"
|
||||
);
|
||||
|
||||
// Clear by passing an empty slice.
|
||||
let ok = set_depends_on("872_test_target", &[]);
|
||||
assert!(ok, "set_depends_on([]) should return true");
|
||||
let view = read_item("872_test_target").unwrap();
|
||||
assert_eq!(
|
||||
view.depends_on, None,
|
||||
"clearing should leave register unset"
|
||||
);
|
||||
|
||||
// Auto-assigner sees no unmet dependency after clearing.
|
||||
let unmet = check_unmet_deps_crdt("872_test_target");
|
||||
assert!(
|
||||
unmet.is_empty(),
|
||||
"after clearing deps, auto-assigner should see no unmet dependencies"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_depends_on_returns_false_for_unknown_story() {
|
||||
init_for_test();
|
||||
let ok = set_depends_on("nonexistent_story_872", &[1, 2, 3]);
|
||||
assert!(
|
||||
!ok,
|
||||
"set_depends_on should return false for unknown story_id"
|
||||
);
|
||||
}
|
||||
|
||||
// ── set_agent tests ──────────────────────────────────────────────────────
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user