provisioning-core/nulib/domain/version/registry.nu

237 lines
7.8 KiB
Text
Raw Permalink Normal View History

#!/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"
}
}