use dag-executor.nu [load-dag] use ../workspace/state.nu [state-read, state-node-get] use ../lib_provisioning/config/accessor.nu * use ../lib_provisioning/utils/settings.nu [find_get_settings, settings_with_env] def state-icon [s: string]: nothing -> string { match $s { "completed" => $"(_ansi green)✅(_ansi reset)", "running" => $"(_ansi yellow)🔄(_ansi reset)", "failed" => $"(_ansi red)❌(_ansi reset)", "blocked" => $"(_ansi red_dimmed)⊘(_ansi reset)", _ => $"(_ansi default_dimmed)⏳(_ansi reset)", } } def state-col [s: string]: nothing -> string { match $s { "completed" => (_ansi green), "running" => (_ansi yellow), "failed" => (_ansi red), "blocked" => (_ansi red_dimmed), _ => (_ansi default_dimmed), } } def fmt-ts [ts: string]: nothing -> string { if ($ts | is-empty) { "—" } else { $ts | str replace "T" " " | str replace "Z" "" } } # Show DAG formula execution progress — which taskservs completed, pending, failed export def "main status" [ --infra (-i): string = "" --settings (-s): string = "" --server: string = "" ] { let curr_settings = (settings_with_env (find_get_settings --infra $infra --settings $settings)) let workspace_path = ($curr_settings.src_path? | default $env.PWD) let dag = (load-dag $curr_settings) if not $dag.has_dag { _print "No DAG found — no formula state to show." return } let st = (state-read $workspace_path) for formula in $dag.formulas { if ($server | is-not-empty) and $formula.server != $server { continue } let all_done = ($formula.nodes | all {|n| let ns = (state-node-get $workspace_path $formula.server $n.taskserv.name) $ns.state == "completed" }) let tag = if $all_done { $"(_ansi green)[complete](_ansi reset)" } else { $"(_ansi yellow)[in progress](_ansi reset)" } _print $"▶ (_ansi green_bold)($formula.id)(_ansi reset) on (_ansi cyan_bold)($formula.server)(_ansi reset) ($tag)" for node in $formula.nodes { let ns = (state-node-get $workspace_path $formula.server $node.taskserv.name) let icon = (state-icon $ns.state) let col = (state-col $ns.state) let name_pad = ($node.taskserv.name | fill -a l -w 20) let st_pad = ($ns.state | fill -a l -w 10) let ts = if $ns.state == "completed" { fmt-ts $ns.ended_at } else { "" } let extra = if ($ns.blocker? | default "" | is-not-empty) { $" ← blocked by (_ansi red)($ns.blocker)(_ansi reset)" } else { "" } _print $" ($icon) ($col)($name_pad)(_ansi reset) ($col)($st_pad)(_ansi reset) ($ts)($extra)" } _print "" } } # List all taskservs in the DAG with their state export def "main list" [ --infra (-i): string = "" --settings (-s): string = "" --server: string = "" --out: string = "" ] { let curr_settings = (settings_with_env (find_get_settings --infra $infra --settings $settings)) let workspace_path = ($curr_settings.src_path? | default $env.PWD) let dag = (load-dag $curr_settings) if not $dag.has_dag { _print "No DAG found." return } let rows = ($dag.formulas | each {|formula| if ($server | is-not-empty) and $formula.server != $server { [] } else { $formula.nodes | each {|node| let ns = (state-node-get $workspace_path $formula.server $node.taskserv.name) { taskserv: $node.taskserv.name, server: $formula.server, state: $ns.state, profile: ($node.taskserv.profile? | default "default"), depends_on: ($node.depends_on? | default [] | each {|d| $d.node_id } | str join ","), ended: (fmt-ts $ns.ended_at), actor: ($ns.actor?.identity? | default ""), } } } } | flatten) if $out == "json" { $rows | to json; return } if $out == "yaml" { $rows | to yaml; return } _print $"(_ansi default_dimmed)TASKSERV SERVER STATE PROFILE DEPENDS-ON ENDED(_ansi reset)" for row in $rows { let col = (state-col $row.state) let icon = (state-icon $row.state) _print ( $"($icon) ($col)($row.taskserv | fill -a l -w 20)(_ansi reset)" + $" (_ansi cyan)($row.server | fill -a l -w 17)(_ansi reset)" + $" ($col)($row.state | fill -a l -w 10)(_ansi reset)" + $" ($row.profile | fill -a l -w 10)" + $" ($row.depends_on | fill -a l -w 20)" + $" ($row.ended)" ) } }