Jesús Pérez 9cef9b8d57 refactor: consolidate configuration directories
Merge _configs/ into config/ for single configuration directory.
Update all path references.

Changes:
- Move _configs/* to config/
- Update .gitignore for new patterns
- No code references to _configs/ found

Impact: -1 root directory (layout_conventions.md compliance)
2025-12-26 18:36:23 +00:00

241 lines
7.5 KiB
Plaintext

#!/usr/bin/env nu
# Unpack - Extract and validate distribution bundles
#
# Usage:
# nu scripts/provisioning/unpack.nu bundle.tar.gz
# nu scripts/provisioning/unpack.nu --bundle bundle.tar.gz --dest ./extracted
#
use common/validate.nu *
def show-help [] {
let help_text = "
syntaxis Unpack - Extract and validate distribution bundles
USAGE:
nu scripts/provisioning/unpack.nu [OPTIONS] [BUNDLE]
ARGUMENTS:
BUNDLE Bundle file to extract (.tar.gz or .zip)
OPTIONS:
--bundle <FILE> Bundle file path (alternative to positional argument)
--dest <DIR> Extraction destination directory
Default: current directory
--verify Verify checksums after extraction
--list-contents Show bundle contents without extracting
--help Show this help message
EXAMPLES:
# Extract bundle to current directory
nu scripts/provisioning/unpack.nu bundle.tar.gz
# Extract to specific directory
nu scripts/provisioning/unpack.nu --bundle bundle.tar.gz --dest ./extracted
# List bundle contents
nu scripts/provisioning/unpack.nu --list-contents bundle.tar.gz
# Extract and verify checksums
nu scripts/provisioning/unpack.nu bundle.tar.gz --verify
"
print $help_text
}
def detect-bundle-format [bundle_file: path] {
let ext = ($bundle_file | path parse | get extension)
match $ext {
"gz" => { "tar.gz" }
"zip" => { "zip" }
_ => { let msg = "Unknown bundle format: " + $ext
error make {msg: $msg} }
}
}
def extract-bundle [bundle_file: path, dest_dir: path, format: string] {
print ("📦 Extracting " + $format + " bundle...")
^mkdir -p $dest_dir
match $format {
"tar.gz" => {
^tar -xzf $bundle_file -C $dest_dir
print "✅ Extraction complete"
}
"zip" => {
^unzip -q $bundle_file -d $dest_dir
print "✅ Extraction complete"
}
_ => {
let msg = "Unsupported format: " + $format
error make {msg: $msg}
}
}
}
def find-manifest [dest_dir: path] {
let manifest_file = ($dest_dir | path join "*" "manifest.toml")
let matching_files = (glob $manifest_file)
if (($matching_files | length) == 0) {
error make {msg: "No manifest found in bundle"}
}
$matching_files.0
}
def show-bundle-info [manifest_file: path] {
let manifest = try {
open --raw $manifest_file | from toml
} catch {
let msg = "Failed to read manifest: " + ($manifest_file | into string)
error make {msg: $msg}
}
print ""
print "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
print "📦 Bundle Information"
print "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
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))
}
print ""
print ("Checksums: " + (($manifest.checksums | length) | into string))
print ""
}
def verify-bundle [dest_dir: path, manifest_file: path] {
print "🔍 Verifying bundle checksums..."
let bundle_root = ($manifest_file | path dirname)
let checksums_file = ($bundle_root | path join ".." "*.checksums.toml")
let matching_checksums = (glob $checksums_file)
if (($matching_checksums | length) == 0) {
print "⚠️ No checksums file found - skipping verification"
return
}
let checksums_path = $matching_checksums.0
let verify_result = (verify-checksums $checksums_path $bundle_root)
if ($verify_result.failed == 0) {
print ("✅ All " + ($verify_result.verified | into string) + " checksums verified")
} else {
print ("❌ " + ($verify_result.failed | into string) + " checksum mismatches found")
print "Failed files:"
$verify_result.errors | each { |err|
print (" - " + $err.file + ": expected " + ($err.expected | str substring 0..8) + "... got " + ($err.actual | str substring 0..8) + "...")
}
}
}
def list-bundle-contents [bundle_file: path, format: string] {
print ("📋 Contents of " + ($bundle_file | path basename) + ":")
print ""
match $format {
"tar.gz" => {
^tar -tzf $bundle_file | each { |line|
print (" " + $line)
}
}
"zip" => {
^unzip -l $bundle_file | lines | skip 3 | drop 2 | each { |line|
let trimmed = ($line | str trim)
if (($trimmed | str length) > 0) {
print (" " + $line)
}
}
}
_ => {
let msg = "Unsupported format: " + $format
error make {msg: $msg}
}
}
print ""
}
# Main entry point
def main [bundle: string = "", --bundle: path = "", --dest: path = ".", --verify = false, --list-contents = false, --help = false] {
if $help {
show-help
return
}
# Determine bundle file
let bundle_file = if ($bundle != "") {
$bundle
} else if ($bundle != "") {
$bundle
} else {
error make {msg: "Bundle file must be specified"}
}
if (not (($bundle_file | path exists))) {
let msg = "Bundle file not found: " + ($bundle_file | into string)
error make {msg: $msg}
}
# Validate bundle
print "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
print "🔍 syntaxis Unpack"
print "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
print ("Bundle: " + ($bundle_file | path basename))
print ("Size: " + (((ls $bundle_file | get size.0) | into int) / (1024 * 1024) | math round --precision 2 | into string) + " MB")
print ""
let format = (detect-bundle-format $bundle_file)
# Validate bundle structure
let validation = (validate-bundle-structure $bundle_file)
if (not ($validation.valid)) {
print "❌ Bundle validation failed:"
$validation.errors | each { |err|
print (" - " + $err)
}
error make {msg: "Invalid bundle"}
}
print ("✅ Bundle format valid: " + $format)
print ""
# List contents if requested
if $list_contents {
list-bundle-contents $bundle_file $format
return
}
# Extract bundle
extract-bundle $bundle_file $dest $format
# Find and display manifest
let manifest_file = (find-manifest $dest)
show-bundle-info $manifest_file
# Verify if requested
if $verify {
verify-bundle $dest $manifest_file
}
print "📂 Extracted to: " + ($dest | into string)
print ""
}