278 lines
9.2 KiB
Text
278 lines
9.2 KiB
Text
|
|
#!/usr/bin/env nu
|
||
|
|
# Taskserv version extraction and management utilities
|
||
|
|
# Handles Nickel taskserv files and version configuration
|
||
|
|
|
||
|
|
# Selective imports (ADR-025 Phase 3 Layer 2).
|
||
|
|
# version/core.nu and version/loader.nu star-imports were dead — dropped.
|
||
|
|
use primitives/io/interface.nu [_print]
|
||
|
|
use platform/config/accessor/functions.nu [get-taskservs-path]
|
||
|
|
|
||
|
|
# Extract version field from Nickel taskserv files
|
||
|
|
export def extract-nickel-version [
|
||
|
|
file_path: string
|
||
|
|
] {
|
||
|
|
if not ($file_path | path exists) { return "" }
|
||
|
|
|
||
|
|
let content = (open $file_path --raw)
|
||
|
|
|
||
|
|
# Look for version assignment in taskserv configuration files
|
||
|
|
let version_matches = ($content | lines | each { |line|
|
||
|
|
let trimmed_line = ($line | str trim)
|
||
|
|
# Match "version = " pattern (but not major_version, cni_version, etc.)
|
||
|
|
if ($trimmed_line | str starts-with "version") and ($trimmed_line | str contains "=") {
|
||
|
|
# Split on equals and take the right side
|
||
|
|
let parts = ($trimmed_line | split row "=")
|
||
|
|
if ($parts | length) >= 2 {
|
||
|
|
let version_value = ($parts | get 1 | str trim)
|
||
|
|
if ($version_value | str starts-with '"') {
|
||
|
|
# Remove quotes and get the value
|
||
|
|
($version_value | parse -r '"([^"]*)"' | get 0? | default {} | get capture0? | default "")
|
||
|
|
} else if ($version_value | str starts-with "'") {
|
||
|
|
# Handle single quotes
|
||
|
|
($version_value | parse -r "'([^']*)'" | get 0? | default {} | get capture0? | default "")
|
||
|
|
} else {
|
||
|
|
# Handle unquoted values (remove any trailing comments)
|
||
|
|
($version_value | str replace "\\s*#.*$" "" | str trim)
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
""
|
||
|
|
}
|
||
|
|
} else if ($trimmed_line | str starts-with "version:") and not ($trimmed_line | str contains "str") {
|
||
|
|
# Handle schema-style "version: value" (not type declarations)
|
||
|
|
let version_part = ($trimmed_line | str replace "version:\\s*" "")
|
||
|
|
if ($version_part | str starts-with '"') {
|
||
|
|
($version_part | parse -r '"([^"]*)"' | get 0? | default {} | get capture0? | default "")
|
||
|
|
} else if ($version_part | str starts-with "'") {
|
||
|
|
($version_part | parse -r "'([^']*)'" | get 0? | default {} | get capture0? | default "")
|
||
|
|
} else {
|
||
|
|
($version_part | str replace "\\s*#.*$" "" | str trim)
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
""
|
||
|
|
}
|
||
|
|
} | where { |v| $v != "" })
|
||
|
|
|
||
|
|
if ($version_matches | length) > 0 {
|
||
|
|
$version_matches | get 0
|
||
|
|
} else {
|
||
|
|
""
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Discover all taskserv Nickel files and their versions
|
||
|
|
export def discover-taskserv-configurations [
|
||
|
|
--base-path: string = ""
|
||
|
|
] {
|
||
|
|
let taskservs_path = if ($base_path | is-not-empty) {
|
||
|
|
$base_path
|
||
|
|
} else {
|
||
|
|
(get-taskservs-path)
|
||
|
|
}
|
||
|
|
|
||
|
|
if not ($taskservs_path | path exists) {
|
||
|
|
_print $"⚠️ Taskservs path not found: ($taskservs_path)"
|
||
|
|
return []
|
||
|
|
}
|
||
|
|
|
||
|
|
# Find all .ncl files recursively in the taskservs directory
|
||
|
|
let all_k_files = (glob $"($taskservs_path)/**/*.ncl")
|
||
|
|
|
||
|
|
let nickel_configs = ($all_k_files | each { |decl_file|
|
||
|
|
let version = (extract-nickel-version $decl_file)
|
||
|
|
if ($version | is-not-empty) {
|
||
|
|
let relative_path = ($decl_file | str replace $"($taskservs_path)/" "")
|
||
|
|
let path_parts = ($relative_path | split row "/" | where { |p| $p != "" })
|
||
|
|
|
||
|
|
# Determine ID from the path structure
|
||
|
|
let id = if ($path_parts | length) >= 2 {
|
||
|
|
# If it's a server-specific file like "wuji-strg-1/kubernetes.ncl"
|
||
|
|
let filename = ($decl_file | path basename | str replace ".ncl" "")
|
||
|
|
$"($path_parts.0)::($filename)"
|
||
|
|
} else {
|
||
|
|
# If it's a general file like "proxy.ncl"
|
||
|
|
($decl_file | path basename | str replace ".ncl" "")
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
|
id: $id
|
||
|
|
type: "taskserv"
|
||
|
|
nickel_file: $decl_file
|
||
|
|
version: $version
|
||
|
|
metadata: {
|
||
|
|
source_file: $decl_file
|
||
|
|
category: "taskserv"
|
||
|
|
path_structure: $path_parts
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
null
|
||
|
|
}
|
||
|
|
} | where { |item| $item != null })
|
||
|
|
|
||
|
|
$nickel_configs
|
||
|
|
}
|
||
|
|
|
||
|
|
# Update version in Nickel file
|
||
|
|
export def update-nickel-version [
|
||
|
|
file_path: string
|
||
|
|
new_version: string
|
||
|
|
] {
|
||
|
|
if not ($file_path | path exists) {
|
||
|
|
_print $"❌ File not found: ($file_path)"
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
let content = (open $file_path --raw)
|
||
|
|
|
||
|
|
# Replace version field while preserving formatting
|
||
|
|
let updated_content = ($content | lines | each { |line|
|
||
|
|
if ($line | str trim | str starts-with "version:") {
|
||
|
|
# Preserve indentation and update version
|
||
|
|
let indent = ($line | str replace "^(\\s*).*" '$1')
|
||
|
|
let line_trimmed = ($line | str trim)
|
||
|
|
if ($line_trimmed | str contains '"') {
|
||
|
|
$"($indent)version: \"($new_version)\""
|
||
|
|
} else if ($line_trimmed | str contains "'") {
|
||
|
|
$"($indent)version: '($new_version)'"
|
||
|
|
} else {
|
||
|
|
$"($indent)version: str = \"($new_version)\""
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
$line
|
||
|
|
}
|
||
|
|
} | str join "\n")
|
||
|
|
|
||
|
|
$updated_content | save -f $file_path
|
||
|
|
_print $"✅ Updated version in ($file_path) to ($new_version)"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Check taskserv versions against available versions
|
||
|
|
export def check-taskserv-versions [
|
||
|
|
--fetch-latest = false
|
||
|
|
] {
|
||
|
|
let configs = (discover-taskserv-configurations)
|
||
|
|
|
||
|
|
if ($configs | is-empty) {
|
||
|
|
_print "No taskserv configurations found"
|
||
|
|
return []
|
||
|
|
}
|
||
|
|
|
||
|
|
$configs | each { |config|
|
||
|
|
# For now, return basic info - can be extended with version checking logic
|
||
|
|
{
|
||
|
|
id: $config.id
|
||
|
|
type: $config.type
|
||
|
|
configured: $config.version
|
||
|
|
nickel_file: $config.nickel_file
|
||
|
|
status: "configured"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Update taskserv version in Nickel file
|
||
|
|
export def update-taskserv-version [
|
||
|
|
taskserv_id: string
|
||
|
|
new_version: string
|
||
|
|
--dry-run = false
|
||
|
|
] {
|
||
|
|
let configs = (discover-taskserv-configurations)
|
||
|
|
let config = ($configs | where id == $taskserv_id | first | default null)
|
||
|
|
|
||
|
|
if ($config | is-empty) {
|
||
|
|
_print $"❌ Taskserv '($taskserv_id)' not found"
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
if $dry_run {
|
||
|
|
_print $"🔍 Would update ($taskserv_id) from ($config.version) to ($new_version) in ($config.nickel_file)"
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
update-nickel-version $config.nickel_file $new_version
|
||
|
|
}
|
||
|
|
|
||
|
|
# Bulk update multiple taskservs
|
||
|
|
export def bulk-update-taskservs [
|
||
|
|
updates: list # List of {id: string, version: string}
|
||
|
|
--dry-run = false
|
||
|
|
] {
|
||
|
|
if ($updates | is-empty) {
|
||
|
|
_print "No updates provided"
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
_print $"Updating ($updates | length) taskservs..."
|
||
|
|
|
||
|
|
for update in $updates {
|
||
|
|
let taskserv_id = ($update | get id? | default "")
|
||
|
|
let new_version = ($update | get version? | default "")
|
||
|
|
|
||
|
|
if ($taskserv_id | is-empty) or ($new_version | is-empty) {
|
||
|
|
_print $"⚠️ Invalid update entry: ($update)"
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
|
||
|
|
update-taskserv-version $taskserv_id $new_version --dry-run=$dry_run
|
||
|
|
}
|
||
|
|
|
||
|
|
if not $dry_run {
|
||
|
|
_print "✅ Bulk update completed"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Sync taskserv versions with registry
|
||
|
|
export def taskserv-sync-versions [
|
||
|
|
--taskservs-path: string = ""
|
||
|
|
--component: string = "" # Specific component to sync
|
||
|
|
--dry-run = false
|
||
|
|
] {
|
||
|
|
let registry = (load-version-registry)
|
||
|
|
let comparisons = (compare-registry-with-taskservs --taskservs-path=$taskservs_path)
|
||
|
|
|
||
|
|
if ($comparisons | is-empty) {
|
||
|
|
_print "❌ No taskserv configurations found"
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
# Filter to out-of-sync components
|
||
|
|
mut out_of_sync = ($comparisons | where status == "out_of_sync")
|
||
|
|
|
||
|
|
if ($component | is-not-empty) {
|
||
|
|
let filtered = ($out_of_sync | where component == $component)
|
||
|
|
if ($filtered | is-empty) {
|
||
|
|
_print $"✅ Component '($component)' is already in sync or not found"
|
||
|
|
return
|
||
|
|
}
|
||
|
|
$out_of_sync = $filtered
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($out_of_sync | is-empty) {
|
||
|
|
_print "✅ All taskservs are in sync with registry"
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
_print $"Found ($out_of_sync | length) components with version mismatches:"
|
||
|
|
|
||
|
|
for comp in $out_of_sync {
|
||
|
|
_print $"\n🔧 ($comp.component) [Registry: ($comp.registry_version)]"
|
||
|
|
|
||
|
|
# Find taskservs that need updating
|
||
|
|
let outdated_taskservs = ($comp.taskserv_configs | where not matches_registry)
|
||
|
|
|
||
|
|
for taskserv in $outdated_taskservs {
|
||
|
|
if $dry_run {
|
||
|
|
_print $"🔍 Would update ($taskserv.id): ($taskserv.version) -> ($comp.registry_version)"
|
||
|
|
} else {
|
||
|
|
_print $"🔄 Updating ($taskserv.id): ($taskserv.version) -> ($comp.registry_version)"
|
||
|
|
update-nickel-version $taskserv.file $comp.registry_version
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if $dry_run {
|
||
|
|
_print "\n🔍 Dry run completed - no changes made"
|
||
|
|
} else {
|
||
|
|
_print "\n✅ Sync completed"
|
||
|
|
}
|
||
|
|
}
|