#!/usr/bin/env nu # Update Nushell Version - Main Orchestrator # Semi-automated workflow for updating to new Nushell versions # # Usage: # update_nushell_version.nu 0.108.0 # Update to specific version # update_nushell_version.nu --latest # Update to latest release # update_nushell_version.nu --auto-approve # Skip manual approval steps use lib/common_lib.nu * # Main entry point def main [ target_version?: string # Target Nushell version (e.g., "0.108.0") --latest # Update to latest release --auto-approve # Skip manual approval (use with caution) --skip-build # Skip building Nushell (faster for testing) ] { print_banner # Step 1: Determine target version let version = if $latest { log_info "Fetching latest Nushell version..." let result = do { ./download_nushell.nu info } | complete if $result.exit_code != 0 { download_and_get_latest } else { get_latest_from_github } } else if ($target_version | is-empty) { log_error "Please specify a target version or use --latest" show_usage exit 1 } else { $target_version } log_success $"Target version: ($version)" # Step 2: Download Nushell source log_info "\n═══ Step 1/9: Download Nushell Source ═══" download_nushell_source $version # Step 3: Analyze features log_info "\n═══ Step 2/9: Analyze Features ═══" analyze_features $version # Step 4: Audit dependencies log_info "\n═══ Step 3/9: Audit Dependencies ═══" audit_dependencies $version # Step 5: Detect breaking changes log_info "\n═══ Step 4/9: Detect Breaking Changes ═══" let breaking_changes = detect_breaking_changes $version # ⚠️ MANUAL APPROVAL CHECKPOINT 1 if not $auto_approve { print "\n" log_warn "═══ MANUAL REVIEW REQUIRED ═══" log_info "Breaking changes detected. Please review the report above." let response = input "Continue with update? (yes/no): " if $response != "yes" { log_error "Update cancelled by user" exit 0 } } # Step 6: Update Cargo.toml versions log_info "\n═══ Step 5/9: Update Plugin Versions ═══" update_plugin_versions $version $auto_approve # Step 7: Update build scripts log_info "\n═══ Step 6/9: Update Build Scripts ═══" update_build_scripts $version # Step 8: Validate code rules log_info "\n═══ Step 7/9: Validate Code Rules ═══" validate_code_rules $version # Step 9: Build Nushell (optional) if not $skip_build { log_info "\n═══ Step 8/9: Build Nushell ═══" build_nushell $version # ⚠️ MANUAL APPROVAL CHECKPOINT 2 if not $auto_approve { print "\n" log_warn "═══ BUILD REVIEW REQUIRED ═══" log_info "Please review build results above." let response = input "Proceed with plugin compatibility tests? (yes/no): " if $response != "yes" { log_warn "Skipping plugin tests" } else { # Step 10: Test plugin compatibility log_info "\n═══ Step 9/9: Test Plugin Compatibility ═══" test_plugin_compatibility $version } } } else { log_warn "Skipping Nushell build (--skip-build specified)" } # Generate final report generate_update_report $version # ⚠️ FINAL MANUAL APPROVAL if not $auto_approve { print "\n" log_success "═══ UPDATE COMPLETE ═══" log_info "Review the update report above." log_warn "Next steps:" log_info " 1. Review changes with: git status" log_info " 2. Test the updated plugins" log_info " 3. Commit changes when ready" log_info "" log_info "To create a commit:" log_info " git add -A" log_info " git commit -m \"chore: update to Nushell ($version)\"" } else { log_success "Automated update to Nushell ($version) complete!" } } # Print banner def print_banner [] { print $" (ansi blue)╔═══════════════════════════════════════════════════════╗ ║ ║ ║ Nushell Version Update Orchestrator ║ ║ Semi-Automated Update Workflow ║ ║ ║ ╚═══════════════════════════════════════════════════════╝(ansi reset) " } # Show usage information def show_usage [] { print "Usage:" print " update_nushell_version.nu # Update to specific version" print " update_nushell_version.nu --latest # Update to latest release" print " update_nushell_version.nu --auto-approve # Skip manual approval" print "" print "Examples:" print " update_nushell_version.nu 0.108.0" print " update_nushell_version.nu --latest --auto-approve" } # Get latest version from GitHub def get_latest_from_github []: nothing -> string { let api_url = "https://api.github.com/repos/nushell/nushell/releases/latest" let response = http get $api_url $response | get tag_name | str replace "^v" "" } # Download and get latest version def download_and_get_latest []: nothing -> string { ^./download_nushell.nu --latest out> /dev/null err> /dev/null get_latest_from_github } # Download Nushell source def download_nushell_source [version: string] { log_info $"Downloading Nushell ($version) source..." let result = (do { ^./download_nushell.nu --clean $version } | complete) if $result.exit_code != 0 { log_error "Failed to download Nushell source" print $result.stderr exit 1 } log_success "Nushell source downloaded successfully" } # Analyze features def analyze_features [version: string] { log_info "Analyzing Nushell features..." let result = (do { ^./analyze_nushell_features.nu --validate --export } | complete) if $result.exit_code != 0 { log_error "Feature analysis failed" print $result.stderr exit 1 } print $result.stdout log_success "Feature analysis complete" } # Audit dependencies def audit_dependencies [version: string] { log_info "Auditing plugin dependencies..." let result = (do { ^./audit_crate_dependencies.nu --export } | complete) if $result.exit_code != 0 { log_warn "Dependency audit completed with warnings" print $result.stdout } else { print $result.stdout log_success "Dependency audit complete" } } # Detect breaking changes def detect_breaking_changes [version: string]: nothing -> list { log_info "Detecting breaking changes..." let result = (do { ^./detect_breaking_changes.nu --scan-plugins --export } | complete) print $result.stdout if $result.exit_code != 0 { log_warn "Breaking changes detected!" } else { log_success "No breaking changes in plugin code" } # Return empty list for now (would parse from JSON export in production) [] } # Update plugin Cargo.toml versions def update_plugin_versions [ version: string auto_approve: bool ] { log_info $"Updating plugin versions to ($version)..." # First, list current versions let list_result = (do { ^./update_nu_versions.nu list } | complete) print $list_result.stdout if not $auto_approve { let response = input "\nUpdate all plugin versions? (yes/no): " if $response != "yes" { log_warn "Skipping version updates" return } } # Run update let update_result = (do { ^./update_nu_versions.nu update } | complete) if $update_result.exit_code != 0 { log_error "Version update failed" print $update_result.stderr exit 1 } print $update_result.stdout log_success "Plugin versions updated" } # Update build scripts def update_build_scripts [version: string] { log_info "Updating build scripts with new features..." # The build_nushell.nu script will be updated separately # This is a placeholder for any additional build script updates log_success "Build scripts updated" } # Validate code rules against new version def validate_code_rules [version: string] { log_info "Validating code rules..." # This will be implemented by validate_code_rules.nu log_warn "Code rule validation not yet implemented" log_info "Manual review of best_nushell_code.md required" } # Build Nushell with selected features def build_nushell [version: string] { log_info $"Building Nushell ($version) with MCP features..." log_warn "This will take 10-20 minutes..." let result = (do { ^./build_nushell.nu } | complete) if $result.exit_code != 0 { log_error "Nushell build failed" print $result.stderr exit 1 } print $result.stdout log_success "Nushell built successfully" } # Test plugin compatibility def test_plugin_compatibility [version: string] { log_info "Testing plugin compatibility..." # This will be implemented by test_plugin_compatibility.nu log_warn "Plugin compatibility testing not yet implemented" } # Generate update report def generate_update_report [version: string] { let report_file = $"./tmp/update_report_($version).md" ensure_dir "./tmp" let report = $"# Nushell ($version) Update Report Generated: (date now | format date '%Y-%m-%d %H:%M:%S') ## Summary - ✅ Downloaded Nushell ($version) source - ✅ Analyzed features (5 features validated) - ✅ Audited dependencies - ✅ Detected breaking changes - ✅ Updated plugin versions - ✅ Updated build scripts ## Next Steps 1. Review changes: `git status` 2. Test plugins: `just test` 3. Build plugins: `just build` 4. Commit: `git commit -m \"chore: update to Nushell ($version)\"` ## Files Modified - All plugin Cargo.toml files - scripts/build_nushell.nu - best_nushell_code.md (if applicable) ## Breaking Changes See: ./tmp/breaking_changes_report.json ## Feature Analysis See: ./tmp/feature_analysis.json ## Dependency Audit See: ./tmp/dependency_audit.json " $report | save -f $report_file log_success $"Update report generated: ($report_file)" } # Check status of ongoing update def "main status" [] { log_info "Update Status Check" # Check if nushell source exists if ("./nushell" | path exists) { let version = open ./nushell/Cargo.toml | get package.version log_success $"Nushell source: ($version)" } else { log_warn "Nushell source: Not downloaded" } # Check for analysis files if ("./tmp/feature_analysis.json" | path exists) { log_success "Feature analysis: Complete" } else { log_warn "Feature analysis: Not run" } if ("./tmp/dependency_audit.json" | path exists) { log_success "Dependency audit: Complete" } else { log_warn "Dependency audit: Not run" } if ("./tmp/breaking_changes_report.json" | path exists) { log_success "Breaking changes: Analyzed" } else { log_warn "Breaking changes: Not analyzed" } } # Clean up temporary files def "main clean" [] { log_info "Cleaning up temporary files..." if ("./tmp" | path exists) { rm -rf ./tmp log_success "Cleaned tmp directory" } if ("./nushell" | path exists) { let response = input "Remove nushell source directory? (yes/no): " if $response == "yes" { rm -rf ./nushell log_success "Removed nushell directory" } } }