#!/usr/bin/env nu # Unified Checksums Generation Script # Creates unified checksums.txt for BOTH nushell-full and plugins-only distributions # This ensures both package types are included in a single checksums file use lib/common_lib.nu [ log_info, log_error, log_success, log_warn, log_debug, validate_nushell_version ] # Format file size for display def format_size [bytes: int] { if $bytes < 1024 { $"($bytes)B" } else if $bytes < (1024 * 1024) { let kb = ($bytes / 1024) $"($kb)KB" } else if $bytes < (1024 * 1024 * 1024) { let mb = ($bytes / (1024 * 1024) | round -p 1) $"($mb)MB" } else { let gb = ($bytes / (1024 * 1024 * 1024) | round -p 1) $"($gb)GB" } } def main [ --output (-o): string = "./bin_archives" # Output directory containing packages --platforms: string = "" # Comma-separated list of platforms (optional, auto-detect if empty) --force (-f) # Overwrite existing checksums.txt ] { log_info "🔐 Unified Checksums Generation for bin_archives" log_info "==================================================" log_debug $"force flag value: ($force)" # Validate environment validate_nushell_version if not ($output | path exists) { log_error $"Output directory does not exist: ($output)" exit 1 } log_info $"📂 Scanning directory: ($output)" # Find all distribution packages (both nushell-full and plugins-only) let all_archives = ( (glob $"($output)/nushell-full-*.tar.gz") | append (glob $"($output)/nushell-full-*.zip") | append (glob $"($output)/plugins-only-*.tar.gz") | append (glob $"($output)/plugins-only-*.zip") ) if ($all_archives | length) == 0 { log_warn "No distribution packages found in ($output)" log_warn "Expected patterns:" log_warn " - nushell-full-*.tar.gz" log_warn " - nushell-full-*.zip" log_warn " - plugins-only-*.tar.gz" log_warn " - plugins-only-*.zip" exit 1 } let archive_count = ($all_archives | length) log_success $"Found ($archive_count) distribution packages:" $all_archives | each {|archive| let filename = ($archive | path basename) try { let stat_info = (stat $archive) let size_bytes = ($stat_info | get size) let size = (format_size $size_bytes) log_info $" ✓ ($filename) ($size)" } catch { log_info $" ✓ ($filename)" } } # Check if checksums.txt already exists let checksums_file = $"($output)/checksums.txt" if ($checksums_file | path exists) { log_debug $"Existing checksums file found, will be overwritten: ($checksums_file)" } log_info "" log_info "📊 Generating checksums..." # Generate SHA256 checksums for all packages let checksum_data = $all_archives | each {|archive| let filename = $archive | path basename log_debug $"Computing SHA256 for: ($filename)" try { let hash = (open $archive --raw | hash sha256) { filename: $filename, hash: $hash } } catch {|err| log_error $"Failed to compute checksum for ($filename): ($err.msg)" null } } | compact if ($checksum_data | length) == 0 { log_error "Failed to generate checksums for any packages" exit 1 } # Format checksums in standard sha256sum format let checksums_content = ($checksum_data | each {|item| $"($item.hash) ($item.filename)" } | str join "\n") + "\n" # Ensure trailing newline # Write checksums file try { $checksums_content | save -f $checksums_file let pkg_count = ($checksum_data | length) log_success $"✅ Unified checksums.txt created" log_success $"📄 File: ($checksums_file)" log_success $"📦 Packages included: ($pkg_count)" log_info "" log_info "Checksums content:" log_info "====================" $checksums_content | print log_info "====================" } catch {|err| log_error $"Failed to write checksums file: ($err.msg)" exit 1 } # Verification: Read back and validate log_info "" log_info "✓ Verification:" try { let read_checksums = open $checksums_file let line_count = ($read_checksums | lines | length) log_success $"✅ Checksums file verified ($line_count) entries" # Extract package names and verify they match let packages_in_checksums = $read_checksums | lines | where {|line| ($line | str length) > 0 } | each {|line| let parts = ($line | split row " ") if ($parts | length) >= 2 { $parts | get 1 } } log_success $"Packages in checksums:" $packages_in_checksums | each {|pkg| log_info $" • ($pkg)" } } catch {|err| log_error $"Verification failed: ($err.msg)" exit 1 } log_success "🎉 Unified checksums generation complete!" } # Call main (arguments are passed from the command line) main