#!/usr/bin/env nu # Fix try-catch blocks for Nushell 0.107.1 compatibility # # Converts old try-catch pattern to complete-based error handling # See .claude/best_nushell_code.md lines 642-697 def main [ --dry-run # Show what would be changed without modifying files --verbose # Show detailed progress ] { print "🔍 Searching for files with try-catch blocks..." let files = ( find provisioning -name "*.nu" -type f | lines | where $it != "" | each { |file| if ($file | path exists) { let content = (open $file) let has_try = ($content | str contains "try {") if $has_try { $file } else { null } } else { null } } | compact ) let total = ($files | length) print $"📝 Found ($total) files with try-catch blocks" if $total == 0 { print "✅ No files need fixing" return } print "" print "⚙️ Pattern to apply:" print "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" print "OLD (Nushell 0.106):" print " try {" print " operation" print " } catch { |err|" print " handle_error" print " }" print "" print "NEW (Nushell 0.107.1):" print " let result = (do {" print " operation" print " } | complete)" print " " print " if $result.exit_code == 0 {" print " $result.stdout" print " } else {" print " handle_error" print " }" print "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" print "" if $dry_run { print "🔍 DRY RUN MODE - No files will be modified" print "" print "Files that would be processed:" $files | each { |file| print $" • ($file)" } print "" print $"Run without --dry-run to apply changes to ($total) files" return } print "⚠️ WARNING: This will modify ($total) files" print "Make sure you have committed your changes or have a backup!" print "" let confirm = (input "Type 'yes' to continue: ") if $confirm != "yes" { print "❌ Aborted by user" return } print "" print "🚀 Processing files..." print "" mut fixed_count = 0 mut error_count = 0 for file in $files { if $verbose { print $"📄 Processing: ($file)" } let result = (do { fix-file $file } | complete) if $result.exit_code == 0 { $fixed_count = ($fixed_count + 1) if $verbose { print $" ✅ Fixed" } else { print -n "." } } else { $error_count = ($error_count + 1) print $" ❌ Error: ($result.stderr)" } } if not $verbose { print "" } print "" print "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" print $"✅ Fixed: ($fixed_count) files" print $"❌ Errors: ($error_count) files" print $"📊 Total: ($total) files" print "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" if $error_count > 0 { print "" print "⚠️ Some files had errors. Review them manually:" print " git diff provisioning/" } } # Fix try-catch in a single file def fix-file [file: path] -> nothing { let content = (open $file) # Pattern 1: Simple try-catch without error parameter # try { code } catch { error } let pattern1_fixed = ( $content | str replace --all --regex 'try \{\s*([^}]+)\s*\} catch \{\s*([^}]+)\s*\}' ( 'let result = (do { $1 } | complete); if $result.exit_code == 0 { $result.stdout } else { $2 }' ) ) # Pattern 2: Try-catch with error parameter (more complex) # This requires manual review for now # Just add a comment let pattern2_fixed = ( $pattern1_fixed | str replace --all --regex 'try \{' '# TODO: Convert to complete pattern\ntry {' ) $pattern2_fixed | save --force $file null } # Show statistics about try-catch usage def stats [] { print "📊 Try-Catch Usage Statistics" print "" let files = ( find provisioning -name "*.nu" -type f | lines | where $it != "" | each { |file| if ($file | path exists) { let content = (open $file) let count = ( $content | split row "try {" | length | $in - 1 ) if $count > 0 { { file: $file, count: $count } } else { null } } else { null } } | compact ) let total_files = ($files | length) let total_blocks = ($files | get count | math sum) print $"Files with try-catch: ($total_files)" print $"Total try-catch blocks: ($total_blocks)" print "" print "Top 10 files by usage:" $files | sort-by count --reverse | first 10 | each { |row| print $" ($row.count)x - ($row.file)" } }