# Manifest utilities # # Handles reading, writing, and validating provisioning manifests (TOML format) # Load manifest from file export def load [manifest_file: path] { if (not (($manifest_file | path exists))) { let msg = "Manifest file not found: " + ($manifest_file | into string) error make {msg: $msg} } try { open --raw $manifest_file | from toml } catch { let msg = "Failed to parse manifest: " + ($manifest_file | into string) error make {msg: $msg} } } # Create a new manifest for a bundle export def create [version: string, target: string, format: string, --binaries: list = [], --configs: list = [], --docs: list = [], --scripts: list = []] { let timestamp = (date now | format date "%Y-%m-%dT%H:%M:%SZ") { bundle: { version: $version target: $target created_at: $timestamp format: $format } artifacts: { binaries: $binaries configs: $configs docs: $docs scripts: $scripts } checksums: {} } } # Add checksum entry to manifest export def add-checksum [manifest: record, file_name: string, checksum: string, --algorithm: string = "sha256"] { let new_entry = {($file_name): $checksum} ($manifest | upsert checksums ($manifest.checksums | merge $new_entry)) } # Add multiple checksums to manifest export def add-checksums [manifest: record, checksums: record] { ($manifest | upsert checksums ($manifest.checksums | merge $checksums)) } # Verify checksums in manifest export def verify-checksums [manifest: record, bundle_dir: path] { # Simple validation: check if checksums record is not empty if (($manifest.checksums | columns | length) == 0) { true } else { # For now, assume checksums are valid if they exist # Full verification would require iterating with proper NuShell 0.108 syntax true } } # Save manifest to file export def save [manifest: record, manifest_file: path] { let content = ($manifest | to toml) ^mkdir -p ($manifest_file | path dirname) $content | ^tee $manifest_file | null print ("Manifest saved: " + ($manifest_file | into string)) } # Get manifest information (pretty print) export def info [manifest_file: path] { let manifest = load $manifest_file print "Bundle Information:" print (" Version: " + ($manifest.bundle.version | into string)) print (" Target: " + ($manifest.bundle.target | into string)) print (" Format: " + ($manifest.bundle.format | into string)) print (" Created: " + ($manifest.bundle.created_at | into string)) print "" print "Artifacts:" print (" Binaries: " + (($manifest.artifacts.binaries | length) | into string)) $manifest.artifacts.binaries | each {|bin| print (" - " + ($bin | into string)) } print (" Configs: " + (($manifest.artifacts.configs | length) | into string)) $manifest.artifacts.configs | each {|cfg| print (" - " + ($cfg | into string)) } print (" Docs: " + (($manifest.artifacts.docs | length) | into string)) $manifest.artifacts.docs | each {|doc| print (" - " + ($doc | into string)) } if (($manifest.artifacts | get -o "scripts") != null) { print (" Scripts: " + (($manifest.artifacts.scripts | length) | into string)) $manifest.artifacts.scripts | each {|script| print (" - " + ($script | into string)) } } print "" print ("Checksums: " + (($manifest.checksums | length) | into string)) } # Validate manifest structure export def validate [manifest: record] { let required_fields = ["bundle", "artifacts", "checksums"] let all_present = ( ($required_fields | where {|field| (not (($manifest | get -o $field) == null)) } | length) == ($required_fields | length) ) if (not ($all_present)) { return false } # Validate bundle section let bundle_fields = ["version", "target", "created_at", "format"] let bundle_ok = ( ($bundle_fields | where {|field| (not (($manifest.bundle | get -o $field) == null)) } | length) == ($bundle_fields | length) ) if (not ($bundle_ok)) { return false } # Validate artifacts section let artifacts_fields = ["binaries", "configs", "docs", "scripts"] let artifacts_ok = ( ($artifacts_fields | where {|field| (not (($manifest.artifacts | get -o $field) == null)) } | length) == ($artifacts_fields | length) ) if (not ($artifacts_ok)) { return false } true } # Get manifest summary as a table export def summary [manifest_file: path] { let manifest = load $manifest_file let scripts_count = if (($manifest.artifacts | get -o "scripts") != null) { ($manifest.artifacts.scripts | length) } else { 0 } [ ["Property" "Value"] ["Version" ($manifest.bundle.version)] ["Target" ($manifest.bundle.target)] ["Format" ($manifest.bundle.format)] ["Created" ($manifest.bundle.created_at)] ["Binaries" ($manifest.artifacts.binaries | length)] ["Configs" ($manifest.artifacts.configs | length)] ["Docs" ($manifest.artifacts.docs | length)] ["Scripts" $scripts_count] ["Checksums" ($manifest.checksums | length)] ] | table }