236 lines
7.8 KiB
Text
236 lines
7.8 KiB
Text
#!/usr/bin/env nu
|
|
# Version registry management for taskservs
|
|
# Handles the central version registry and integrates with taskserv configurations
|
|
|
|
# Selective imports (ADR-025 Phase 3 Layer 2).
|
|
use domain/version/core.nu [fetch-versions]
|
|
use domain/version/taskserv.nu [discover-taskserv-configurations]
|
|
use primitives/io/interface.nu [_print]
|
|
|
|
# Load the version registry
|
|
export def load-version-registry [
|
|
--registry-file: string = ""
|
|
] {
|
|
let registry_path = if ($registry_file | is-not-empty) {
|
|
$registry_file
|
|
} else {
|
|
($env.PROVISIONING | path join "core" | path join "taskservs-versions.yaml")
|
|
}
|
|
|
|
if not ($registry_path | path exists) {
|
|
_print $"⚠️ Version registry not found: ($registry_path)"
|
|
return {}
|
|
}
|
|
|
|
open $registry_path
|
|
}
|
|
|
|
# Update registry with latest version information
|
|
export def update-registry-versions [
|
|
--components: list = [] # Specific components to update, empty for all
|
|
--dry-run = false
|
|
] {
|
|
let registry = (load-version-registry)
|
|
|
|
if ($registry | is-empty) {
|
|
_print "❌ Could not load version registry"
|
|
return
|
|
}
|
|
|
|
let components_to_update = if ($components | is-empty) {
|
|
$registry | transpose key value | get key
|
|
} else {
|
|
$components
|
|
}
|
|
|
|
_print $"Updating versions for ($components_to_update | length) components..."
|
|
|
|
for component in $components_to_update {
|
|
let component_config = if ($component in ($registry | columns)) { $registry | get $component } else { null }
|
|
|
|
if ($component_config | is-empty) {
|
|
_print $"⚠️ Component '($component)' not found in registry"
|
|
continue
|
|
}
|
|
|
|
if ($component_config.fixed | default false) {
|
|
_print $"🔒 Skipping pinned component: ($component)"
|
|
continue
|
|
}
|
|
|
|
if ($component_config.source | is-empty) {
|
|
_print $"⚠️ No source configured for: ($component)"
|
|
continue
|
|
}
|
|
|
|
_print $"🔍 Checking latest version for: ($component)"
|
|
|
|
let latest_versions = (fetch-versions $component_config.source --limit=5)
|
|
if ($latest_versions | is-empty) {
|
|
_print $"❌ Could not fetch versions for: ($component)"
|
|
continue
|
|
}
|
|
|
|
let latest = ($latest_versions | get 0)
|
|
let current = ($component_config.current_version | default "")
|
|
|
|
if $latest != $current {
|
|
_print $"📦 ($component): ($current) -> ($latest)"
|
|
if not $dry_run {
|
|
# Update registry with new version
|
|
update-registry-component $component "current_version" $latest
|
|
update-registry-component $component "latest_check" (date now | format date "%Y-%m-%d %H:%M:%S")
|
|
}
|
|
} else {
|
|
_print $"✅ ($component): up to date at ($current)"
|
|
}
|
|
}
|
|
|
|
if not $dry_run {
|
|
_print "✅ Registry update completed"
|
|
} else {
|
|
_print "🔍 Dry run completed - no changes made"
|
|
}
|
|
}
|
|
|
|
# Update a specific component field in the registry
|
|
export def update-registry-component [
|
|
component_id: string
|
|
field: string
|
|
value: string
|
|
] {
|
|
let registry_path = ($env.PROVISIONING | path join "core" | path join "taskservs-versions.yaml")
|
|
|
|
if not ($registry_path | path exists) {
|
|
_print $"❌ Registry file not found: ($registry_path)"
|
|
return
|
|
}
|
|
|
|
let registry = (open $registry_path)
|
|
let component_config = if ($component_id in ($registry | columns)) { $registry | get $component_id } else { null }
|
|
|
|
if ($component_config | is-empty) {
|
|
_print $"❌ Component '($component_id)' not found in registry"
|
|
return
|
|
}
|
|
|
|
let updated_component = ($component_config | upsert $field $value)
|
|
let updated_registry = ($registry | upsert $component_id $updated_component)
|
|
|
|
$updated_registry | save -f $registry_path
|
|
}
|
|
|
|
# Compare registry versions with taskserv configurations
|
|
export def compare-registry-with-taskservs [
|
|
--taskservs-path: string = ""
|
|
] {
|
|
let registry = (load-version-registry)
|
|
let taskserv_configs = (discover-taskserv-configurations --base-path=$taskservs_path)
|
|
|
|
if ($registry | is-empty) or ($taskserv_configs | is-empty) {
|
|
_print "❌ Could not load registry or taskserv configurations"
|
|
return []
|
|
}
|
|
|
|
# Group taskservs by component type
|
|
let taskserv_by_component = ($taskserv_configs | group-by { |config|
|
|
# Extract component name from ID (handle both "component" and "server::component" formats)
|
|
if ($config.id | str contains "::") {
|
|
($config.id | split row "::" | get 1)
|
|
} else {
|
|
$config.id
|
|
}
|
|
})
|
|
|
|
let comparisons = ($registry | transpose component registry_config | each { |registry_item|
|
|
let component = $registry_item.component
|
|
let registry_version = ($registry_item.registry_config.current_version | default "")
|
|
let taskservs = if ($component in ($taskserv_by_component | columns)) { $taskserv_by_component | get $component } else { [] }
|
|
|
|
if ($taskservs | is-empty) {
|
|
{
|
|
component: $component
|
|
registry_version: $registry_version
|
|
taskserv_configs: []
|
|
status: "unused"
|
|
summary: "Not used in any taskservs"
|
|
}
|
|
} else {
|
|
let taskserv_versions = ($taskservs | each { |ts| {
|
|
id: $ts.id
|
|
version: $ts.version
|
|
file: $ts.nickel_file
|
|
matches_registry: ($ts.version == $registry_version)
|
|
}})
|
|
|
|
let all_match = ($taskserv_versions | all { |ts| $ts.matches_registry })
|
|
let any_outdated = ($taskserv_versions | any { |ts| not $ts.matches_registry })
|
|
|
|
let status = if $all_match {
|
|
"in_sync"
|
|
} else if $any_outdated {
|
|
"out_of_sync"
|
|
} else {
|
|
"mixed"
|
|
}
|
|
|
|
{
|
|
component: $component
|
|
registry_version: $registry_version
|
|
taskserv_configs: $taskserv_versions
|
|
status: $status
|
|
summary: $"($taskserv_versions | length) taskservs, ($taskserv_versions | where matches_registry | length) in sync"
|
|
}
|
|
}
|
|
})
|
|
|
|
$comparisons
|
|
}
|
|
|
|
# Show version status summary
|
|
export def show-version-status [
|
|
--taskservs-path: string = ""
|
|
--format: string = "table" # table, detail, json
|
|
] {
|
|
let comparisons = (compare-registry-with-taskservs --taskservs-path=$taskservs_path)
|
|
|
|
match $format {
|
|
"table" => {
|
|
_print "Taskserv Version Status:"
|
|
_print ($comparisons | select component registry_version status summary | table)
|
|
}
|
|
"detail" => {
|
|
for comparison in $comparisons {
|
|
_print $"\n🔧 ($comparison.component) \\(Registry: ($comparison.registry_version)\\)"
|
|
_print $" Status: ($comparison.status) - ($comparison.summary)"
|
|
|
|
if ($comparison.taskserv_configs | length) > 0 {
|
|
for config in $comparison.taskserv_configs {
|
|
let status_icon = if $config.matches_registry { "✅" } else { "❌" }
|
|
_print $" ($status_icon) ($config.id): ($config.version)"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
"json" => {
|
|
print ($comparisons | to json -i 2)
|
|
}
|
|
_ => {
|
|
_print $"❌ Unknown format: ($format). Use 'table', 'detail', or 'json'"
|
|
}
|
|
}
|
|
}
|
|
|
|
# Pin/unpin component in registry
|
|
export def set-registry-fixed [
|
|
component_id: string
|
|
fixed: bool
|
|
] {
|
|
update-registry-component $component_id "fixed" ($fixed | into string)
|
|
|
|
if $fixed {
|
|
_print $"🔒 Pinned ($component_id) in registry"
|
|
} else {
|
|
_print $"🔓 Unpinned ($component_id) in registry"
|
|
}
|
|
}
|