tui: use configured ticket root for overlay
This commit is contained in:
parent
b1e3a2ad33
commit
40f2114541
|
|
@ -6,8 +6,8 @@ use std::time::Instant;
|
||||||
|
|
||||||
use protocol::WorkerStatus;
|
use protocol::WorkerStatus;
|
||||||
use ticket::config::{
|
use ticket::config::{
|
||||||
DEFAULT_TICKET_BACKEND_RELATIVE_PATH, TICKET_CONFIG_RELATIVE_PATH, TicketConfig,
|
TICKET_CONFIG_RELATIVE_PATH, TicketConfig, TicketOrchestrationConfig,
|
||||||
TicketOrchestrationConfig, WORKSPACE_SETTINGS_RELATIVE_PATH,
|
WORKSPACE_SETTINGS_RELATIVE_PATH,
|
||||||
};
|
};
|
||||||
use ticket::{
|
use ticket::{
|
||||||
LocalTicketBackend, TicketBackend, TicketError, TicketEvent, TicketFilter, TicketIdOrSlug,
|
LocalTicketBackend, TicketBackend, TicketError, TicketEvent, TicketFilter, TicketIdOrSlug,
|
||||||
|
|
@ -641,12 +641,13 @@ fn load_orchestration_ticket_overlay(
|
||||||
}
|
}
|
||||||
match validate_orchestration_overlay_source(workspace_root, &layout) {
|
match validate_orchestration_overlay_source(workspace_root, &layout) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
load_orchestration_ticket_overlay_states(&layout.path, config.ticket_record_language())
|
load_orchestration_ticket_overlay_states(&layout.path).unwrap_or_else(|message| {
|
||||||
.unwrap_or_else(|message| OrchestrationTicketOverlay {
|
OrchestrationTicketOverlay {
|
||||||
states: BTreeMap::new(),
|
states: BTreeMap::new(),
|
||||||
diagnostics: vec![bounded_panel_diagnostic(format!(
|
diagnostics: vec![bounded_panel_diagnostic(format!(
|
||||||
"Orchestration Ticket overlay unavailable: {message}"
|
"Orchestration Ticket overlay unavailable: {message}"
|
||||||
))],
|
))],
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(message) => OrchestrationTicketOverlay {
|
Err(message) => OrchestrationTicketOverlay {
|
||||||
|
|
@ -672,19 +673,25 @@ fn orchestration_worktree_layout(
|
||||||
|
|
||||||
fn load_orchestration_ticket_overlay_states(
|
fn load_orchestration_ticket_overlay_states(
|
||||||
worktree_root: &Path,
|
worktree_root: &Path,
|
||||||
record_language: Option<&str>,
|
|
||||||
) -> Result<OrchestrationTicketOverlay, String> {
|
) -> Result<OrchestrationTicketOverlay, String> {
|
||||||
let ticket_root = worktree_root.join(DEFAULT_TICKET_BACKEND_RELATIVE_PATH);
|
let overlay_config = TicketConfig::load_workspace(worktree_root).map_err(|error| {
|
||||||
|
format!(
|
||||||
|
"orchestration worktree {} has unusable Ticket settings: {error}",
|
||||||
|
worktree_root.display()
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
let ticket_root = overlay_config.backend_root();
|
||||||
if !ticket_root.is_dir() {
|
if !ticket_root.is_dir() {
|
||||||
return Ok(OrchestrationTicketOverlay {
|
return Ok(OrchestrationTicketOverlay {
|
||||||
states: BTreeMap::new(),
|
states: BTreeMap::new(),
|
||||||
diagnostics: vec![bounded_panel_diagnostic(format!(
|
diagnostics: vec![bounded_panel_diagnostic(format!(
|
||||||
"Orchestration worktree has no {} directory",
|
"Orchestration worktree configured Ticket backend root {} is not a directory",
|
||||||
DEFAULT_TICKET_BACKEND_RELATIVE_PATH
|
ticket_root.display()
|
||||||
))],
|
))],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let backend = LocalTicketBackend::new(ticket_root).with_record_language(record_language);
|
let backend = LocalTicketBackend::new(ticket_root.to_path_buf())
|
||||||
|
.with_record_language(overlay_config.ticket_record_language());
|
||||||
let partial = backend
|
let partial = backend
|
||||||
.list_partial(TicketFilter::all())
|
.list_partial(TicketFilter::all())
|
||||||
.map_err(|error| error.to_string())?;
|
.map_err(|error| error.to_string())?;
|
||||||
|
|
@ -1796,11 +1803,17 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_ticket_config(workspace_root: &Path) {
|
fn write_ticket_config(workspace_root: &Path) {
|
||||||
|
write_ticket_config_with_root(workspace_root, ".yoi/tickets");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_ticket_config_with_root(workspace_root: &Path, root: &str) {
|
||||||
let config_dir = workspace_root.join(".yoi");
|
let config_dir = workspace_root.join(".yoi");
|
||||||
fs::create_dir_all(&config_dir).unwrap();
|
fs::create_dir_all(&config_dir).unwrap();
|
||||||
fs::write(
|
fs::write(
|
||||||
config_dir.join("workspace.toml"),
|
config_dir.join("workspace.toml"),
|
||||||
"[ticket]\n\n[ticket.backend]\nprovider = \"builtin:yoi_local\"\nroot = \".yoi/tickets\"\n",
|
format!(
|
||||||
|
"[ticket]\n\n[ticket.backend]\nprovider = \"builtin:yoi_local\"\nroot = \"{root}\"\n"
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
@ -1848,8 +1861,12 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_ticket_to_overlay(workspace_root: &Path, orchestration_root: &Path, id: &str) {
|
fn copy_ticket_to_overlay(workspace_root: &Path, orchestration_root: &Path, id: &str) {
|
||||||
|
copy_ticket_to_overlay_root(workspace_root, &orchestration_root.join(".yoi/tickets"), id);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn copy_ticket_to_overlay_root(workspace_root: &Path, overlay_root: &Path, id: &str) {
|
||||||
let local_ticket_dir = workspace_root.join(".yoi/tickets").join(id);
|
let local_ticket_dir = workspace_root.join(".yoi/tickets").join(id);
|
||||||
let overlay_ticket_dir = orchestration_root.join(".yoi/tickets").join(id);
|
let overlay_ticket_dir = overlay_root.join(id);
|
||||||
fs::create_dir_all(overlay_ticket_dir.parent().unwrap()).unwrap();
|
fs::create_dir_all(overlay_ticket_dir.parent().unwrap()).unwrap();
|
||||||
fs::create_dir_all(&overlay_ticket_dir).unwrap();
|
fs::create_dir_all(&overlay_ticket_dir).unwrap();
|
||||||
fs::copy(
|
fs::copy(
|
||||||
|
|
@ -2020,6 +2037,40 @@ mod tests {
|
||||||
assert!(model.rows.iter().all(|row| row.title != "Overlay Only"));
|
assert!(model.rows.iter().all(|row| row.title != "Overlay Only"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn workspace_panel_orchestration_overlay_uses_configured_backend_root() {
|
||||||
|
let temp = TempDir::new().unwrap();
|
||||||
|
init_git_repo(temp.path());
|
||||||
|
write_ticket_config(temp.path());
|
||||||
|
let orchestration_root = add_orchestration_worktree(temp.path(), "orchestration");
|
||||||
|
write_ticket_config_with_root(&orchestration_root, "configured-overlay-tickets");
|
||||||
|
let backend = LocalTicketBackend::new(temp.path().join(".yoi/tickets"));
|
||||||
|
let id = create_ticket_with_id(&backend, "Overlay Custom Root", |input| {
|
||||||
|
input.workflow_state = Some(TicketWorkflowState::Queued);
|
||||||
|
});
|
||||||
|
let configured_overlay_root = orchestration_root.join("configured-overlay-tickets");
|
||||||
|
copy_ticket_to_overlay_root(temp.path(), &configured_overlay_root, &id);
|
||||||
|
let overlay_backend = LocalTicketBackend::new(&configured_overlay_root);
|
||||||
|
set_ticket_state(&overlay_backend, &id, TicketWorkflowState::InProgress);
|
||||||
|
|
||||||
|
let model = build_workspace_panel(temp.path(), &empty_pods());
|
||||||
|
|
||||||
|
assert!(model.header.diagnostics.is_empty());
|
||||||
|
let row = ticket_row_by_title(&model, "Overlay Custom Root");
|
||||||
|
assert_eq!(row.status, "q→prog");
|
||||||
|
assert_eq!(
|
||||||
|
row.ticket
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.orchestration_overlay
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.workflow_state,
|
||||||
|
TicketWorkflowState::InProgress
|
||||||
|
);
|
||||||
|
assert!(!orchestration_root.join(".yoi/tickets").exists());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn workspace_panel_displays_queued_plus_orchestration_inprogress_without_mutating_local_ticket()
|
fn workspace_panel_displays_queued_plus_orchestration_inprogress_without_mutating_local_ticket()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user