Jesús Pérez 41455c5b3e
Some checks failed
Build and Test / Validate Setup (push) Has been cancelled
Build and Test / Build (darwin-amd64) (push) Has been cancelled
Build and Test / Build (darwin-arm64) (push) Has been cancelled
Build and Test / Build (linux-amd64) (push) Has been cancelled
Build and Test / Build (windows-amd64) (push) Has been cancelled
Build and Test / Build (linux-arm64) (push) Has been cancelled
Build and Test / Security Audit (push) Has been cancelled
Build and Test / Package Results (push) Has been cancelled
Build and Test / Quality Gate (push) Has been cancelled
feat: Add complete Nushell full distribution system
## Major Features Added

- **Complete distribution infrastructure**: Build, package, and distribute Nushell binary alongside plugins
- **Zero-prerequisite installation**: Bootstrap installers work on fresh systems without Rust/Cargo/Nushell
- **Cross-platform support**: Linux, macOS, Windows (x86_64, ARM64)
- **Self-contained packages**: Everything needed for complete Nushell environment

## New Components

### Build System
- `scripts/build_nushell.nu` - Build nushell with all workspace plugins
- `scripts/collect_full_binaries.nu` - Collect nu binary + all plugins
- `justfiles/full_distro.just` - 40+ new recipes for distribution workflows

### Bootstrap Installers (Zero Prerequisites)
- `installers/bootstrap/install.sh` - Universal POSIX installer (900+ lines)
- `installers/bootstrap/install.ps1` - Windows PowerShell installer (800+ lines)
- Complete platform detection, PATH setup, plugin registration

### Distribution System
- `scripts/create_distribution_packages.nu` - Multi-platform package creator
- `scripts/install_full_nushell.nu` - Advanced nu-based installer
- `scripts/verify_installation.nu` - Installation verification suite
- `scripts/lib/common_lib.nu` - Shared utilities and logging

### Configuration Management
- `scripts/templates/default_config.nu` - Complete nushell configuration (500+ lines)
- `scripts/templates/default_env.nu` - Cross-platform environment setup
- `etc/distribution_config.toml` - Central distribution settings
- `scripts/templates/uninstall.sh` & `uninstall.ps1` - Clean removal

## Key Workflows

```bash
just build-full                # Build nushell + all plugins
just pack-full-all              # Create packages for all platforms
just verify-full                # Verify installation
just release-full-cross         # Complete cross-platform release
```

## Installation Experience

- One-liner: `curl -sSf https://your-url/install.sh | sh`
- Multiple modes: user, system, portable installation
- Automatic plugin registration with verification
- Professional uninstall capability

## Benefits

-  Solves bootstrap problem - no prerequisites needed
-  Production-ready distribution system
-  Complete cross-platform support
-  Professional installation experience
-  Integrates seamlessly with existing plugin workflows
-  Enterprise-grade verification and logging
2025-09-24 18:52:07 +01:00

841 lines
24 KiB
PowerShell
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Universal Nushell + Plugins Bootstrap Installer for Windows
# PowerShell script that installs Nushell and plugins without any prerequisites
#
# This script:
# - Detects Windows platform (x86_64/arm64)
# - Downloads or builds Nushell + plugins
# - Installs to user location (%USERPROFILE%\.local\bin) or system (C:\Program Files\Nushell)
# - Updates PATH in system/user environment
# - Creates initial Nushell configuration
# - Registers all plugins automatically
# - Verifies installation
param(
[switch]$System,
[switch]$User = $true,
[switch]$NoPath,
[switch]$NoConfig,
[switch]$NoPlugins,
[switch]$BuildFromSource,
[switch]$Verify,
[switch]$Uninstall,
[string]$Version = "",
[switch]$Help
)
# Configuration
$RepoUrl = "https://github.com/your-org/nushell-plugins"
$BinaryRepoUrl = "$RepoUrl/releases/download"
$InstallDirUser = "$env:USERPROFILE\.local\bin"
$InstallDirSystem = "${env:ProgramFiles}\Nushell\bin"
$ConfigDir = "$env:USERPROFILE\.config\nushell"
$TempDir = "$env:TEMP\nushell-install-$(Get-Random)"
# Colors for output
$Colors = @{
Red = "Red"
Green = "Green"
Yellow = "Yellow"
Blue = "Blue"
Magenta = "Magenta"
Cyan = "Cyan"
}
# Logging functions
function Write-LogInfo {
param([string]$Message)
Write-Host " $Message" -ForegroundColor $Colors.Blue
}
function Write-LogSuccess {
param([string]$Message)
Write-Host "$Message" -ForegroundColor $Colors.Green
}
function Write-LogWarn {
param([string]$Message)
Write-Host "⚠️ $Message" -ForegroundColor $Colors.Yellow
}
function Write-LogError {
param([string]$Message)
Write-Host "$Message" -ForegroundColor $Colors.Red
}
function Write-LogHeader {
param([string]$Message)
Write-Host ""
Write-Host "🚀 $Message" -ForegroundColor $Colors.Magenta
Write-Host ("=" * $Message.Length) -ForegroundColor $Colors.Magenta
}
# Usage information
function Show-Usage {
@"
Nushell + Plugins Bootstrap Installer for Windows
USAGE:
# Download and run:
Invoke-WebRequest -Uri "install-url/install.ps1" | Invoke-Expression
# Or download and run with parameters:
.\install.ps1 [-System] [-User] [-NoPath] [-NoConfig] [-NoPlugins] [-BuildFromSource] [-Verify] [-Uninstall] [-Version <version>] [-Help]
PARAMETERS:
-System Install to system directory (C:\Program Files\Nushell, requires admin)
-User Install to user directory (~\.local\bin) [default]
-NoPath Don't modify PATH environment variable
-NoConfig Don't create initial nushell configuration
-NoPlugins Install only nushell, skip plugins
-BuildFromSource Build from source instead of downloading binaries
-Verify Verify installation after completion
-Uninstall Remove nushell and plugins
-Version <version> Install specific version (default: latest)
-Help Show this help message
EXAMPLES:
# Default installation (user directory, with plugins)
.\install.ps1
# System installation (requires admin)
.\install.ps1 -System
# Install without plugins
.\install.ps1 -NoPlugins
# Build from source
.\install.ps1 -BuildFromSource
# Install specific version
.\install.ps1 -Version "v0.107.1"
"@
}
# Platform detection
function Get-Platform {
$arch = $env:PROCESSOR_ARCHITECTURE
switch ($arch) {
"AMD64" { return "windows-x86_64" }
"ARM64" { return "windows-aarch64" }
default {
Write-LogError "Unsupported architecture: $arch"
exit 1
}
}
}
# Check if running as administrator
function Test-Admin {
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
# Check if command exists
function Test-Command {
param([string]$Command)
try {
Get-Command $Command -ErrorAction Stop | Out-Null
return $true
} catch {
return $false
}
}
# Check dependencies for building from source
function Test-BuildDependencies {
$missing = @()
if (-not (Test-Command "git")) {
$missing += "git"
}
if (-not (Test-Command "cargo")) {
$missing += "cargo"
}
if (-not (Test-Command "rustc")) {
$missing += "rust"
}
if ($missing.Count -gt 0) {
Write-LogError "Missing build dependencies: $($missing -join ', ')"
Write-LogInfo "Please install these tools or use binary installation instead"
return $false
}
return $true
}
# Download file with progress
function Get-FileWithProgress {
param(
[string]$Url,
[string]$OutputPath,
[string]$Description = "file"
)
Write-LogInfo "Downloading $Description..."
try {
$webClient = New-Object System.Net.WebClient
$webClient.DownloadFile($Url, $OutputPath)
Write-LogSuccess "Downloaded $Description"
return $true
} catch {
Write-LogError "Failed to download $Description from $Url"
Write-LogError $_.Exception.Message
return $false
}
}
# Extract archive
function Expand-Archive {
param(
[string]$ArchivePath,
[string]$DestinationPath
)
Write-LogInfo "Extracting archive..."
try {
if ($ArchivePath -like "*.zip") {
Expand-Archive -Path $ArchivePath -DestinationPath $DestinationPath -Force
} elseif ($ArchivePath -like "*.tar.gz") {
# Use tar if available (Windows 10 build 17063 and later)
if (Test-Command "tar") {
& tar -xzf $ArchivePath -C $DestinationPath
} else {
throw "tar command not found for .tar.gz extraction"
}
} else {
throw "Unsupported archive format: $ArchivePath"
}
Write-LogSuccess "Extracted archive"
return $true
} catch {
Write-LogError "Failed to extract $ArchivePath"
Write-LogError $_.Exception.Message
return $false
}
}
# Get latest release version
function Get-LatestVersion {
try {
$response = Invoke-RestMethod -Uri "https://api.github.com/repos/your-org/nushell-plugins/releases/latest"
return $response.tag_name
} catch {
Write-LogWarn "Could not detect latest version, using v0.107.1"
return "v0.107.1"
}
}
# Download and install binaries
function Install-FromBinaries {
param(
[string]$Platform,
[string]$Version,
[string]$InstallDir,
[bool]$IncludePlugins
)
Write-LogHeader "Installing from Pre-built Binaries"
# Create temporary directory
New-Item -ItemType Directory -Path $TempDir -Force | Out-Null
Set-Location $TempDir
# Determine archive name and URL
$archiveFormat = if ($Platform -like "*windows*") { "zip" } else { "tar.gz" }
$archiveName = "nushell-plugins-$Platform-$Version.$archiveFormat"
$downloadUrl = "$BinaryRepoUrl/$Version/$archiveName"
# Download archive
if (-not (Get-FileWithProgress -Url $downloadUrl -OutputPath $archiveName -Description "Nushell distribution")) {
Write-LogWarn "Binary download failed, trying alternative..."
# Try without version prefix
$archiveName = "nushell-plugins-$Platform.$archiveFormat"
$downloadUrl = "$BinaryRepoUrl/latest/$archiveName"
if (-not (Get-FileWithProgress -Url $downloadUrl -OutputPath $archiveName -Description "Nushell distribution (latest)")) {
Write-LogError "Failed to download binaries"
return $false
}
}
# Extract archive
if (-not (Expand-Archive -ArchivePath $archiveName -DestinationPath ".")) {
return $false
}
# Find extracted directory
$extractDir = Get-ChildItem -Directory | Select-Object -First 1
if (-not $extractDir) {
Write-LogError "No extracted directory found"
return $false
}
Write-LogInfo "Installing binaries to $InstallDir..."
# Create install directory
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
# Install nushell binary
$nuBinary = "nu.exe"
$nuSourcePath = Join-Path $extractDir.FullName $nuBinary
if (Test-Path $nuSourcePath) {
Copy-Item $nuSourcePath -Destination $InstallDir
Write-LogSuccess "Installed nushell binary"
} else {
Write-LogError "Nushell binary not found in archive"
return $false
}
# Install plugins if requested
if ($IncludePlugins) {
$pluginFiles = Get-ChildItem -Path $extractDir.FullName -Name "nu_plugin_*.exe"
$pluginCount = 0
foreach ($pluginFile in $pluginFiles) {
$pluginSourcePath = Join-Path $extractDir.FullName $pluginFile
Copy-Item $pluginSourcePath -Destination $InstallDir
$pluginCount++
}
if ($pluginCount -gt 0) {
Write-LogSuccess "Installed $pluginCount plugins"
} else {
Write-LogWarn "No plugins found in archive"
}
}
# Copy configuration files if they exist
$configSourceDir = Join-Path $extractDir.FullName "config"
if (Test-Path $configSourceDir) {
New-Item -ItemType Directory -Path $ConfigDir -Force | Out-Null
Copy-Item -Path "$configSourceDir\*" -Destination $ConfigDir -Recurse -Force
Write-LogSuccess "Installed configuration files"
}
return $true
}
# Build and install from source
function Install-FromSource {
param(
[string]$InstallDir,
[bool]$IncludePlugins
)
Write-LogHeader "Building from Source"
# Check dependencies
if (-not (Test-BuildDependencies)) {
return $false
}
# Create temporary directory
New-Item -ItemType Directory -Path $TempDir -Force | Out-Null
Set-Location $TempDir
# Clone repository
Write-LogInfo "Cloning repository..."
try {
& git clone --recursive $RepoUrl nushell-plugins
Set-Location nushell-plugins
} catch {
Write-LogError "Failed to clone repository"
return $false
}
# Build nushell
Write-LogInfo "Building nushell..."
try {
if (Test-Command "just") {
& just build-nushell
} else {
# Fallback to manual build
Set-Location nushell
& cargo build --release --features "plugin,network,sqlite,trash-support,rustls-tls"
Set-Location ..
}
} catch {
Write-LogError "Failed to build nushell"
return $false
}
# Build plugins if requested
if ($IncludePlugins) {
Write-LogInfo "Building plugins..."
try {
if (Test-Command "just") {
& just build
} else {
# Build plugins manually
$pluginDirs = Get-ChildItem -Directory -Name "nu_plugin_*" | Where-Object { $_ -ne "nushell" }
foreach ($pluginDir in $pluginDirs) {
Write-LogInfo "Building $pluginDir..."
Set-Location $pluginDir
try {
& cargo build --release
Write-LogSuccess "Built $pluginDir"
} catch {
Write-LogWarn "Failed to build $pluginDir"
}
Set-Location ..
}
}
} catch {
Write-LogWarn "Failed to build some plugins"
}
}
# Install binaries
Write-LogInfo "Installing binaries to $InstallDir..."
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
# Install nushell
$nuBinary = "nushell\target\release\nu.exe"
if (Test-Path $nuBinary) {
Copy-Item $nuBinary -Destination "$InstallDir\nu.exe"
Write-LogSuccess "Installed nushell binary"
} else {
Write-LogError "Nushell binary not found"
return $false
}
# Install plugins
if ($IncludePlugins) {
$pluginCount = 0
$pluginDirs = Get-ChildItem -Directory -Name "nu_plugin_*" | Where-Object { $_ -ne "nushell" }
foreach ($pluginDir in $pluginDirs) {
$pluginBinary = "$pluginDir\target\release\$pluginDir.exe"
if (Test-Path $pluginBinary) {
Copy-Item $pluginBinary -Destination "$InstallDir\$pluginDir.exe"
$pluginCount++
}
}
if ($pluginCount -gt 0) {
Write-LogSuccess "Installed $pluginCount plugins"
} else {
Write-LogWarn "No plugins were built successfully"
}
}
return $true
}
# Register plugins with nushell
function Register-Plugins {
param(
[string]$InstallDir
)
$nuBinary = Join-Path $InstallDir "nu.exe"
if (-not (Test-Path $nuBinary)) {
Write-LogError "Nushell binary not found: $nuBinary"
return $false
}
Write-LogHeader "Registering Plugins"
# Find all plugin binaries
$pluginFiles = Get-ChildItem -Path $InstallDir -Name "nu_plugin_*.exe"
$pluginCount = 0
foreach ($pluginFile in $pluginFiles) {
$pluginPath = Join-Path $InstallDir $pluginFile
$pluginName = [System.IO.Path]::GetFileNameWithoutExtension($pluginFile)
Write-LogInfo "Registering $pluginName..."
try {
& $nuBinary -c "plugin add '$pluginPath'"
Write-LogSuccess "Registered $pluginName"
$pluginCount++
} catch {
Write-LogWarn "Failed to register $pluginName"
}
}
if ($pluginCount -gt 0) {
Write-LogSuccess "Successfully registered $pluginCount plugins"
} else {
Write-LogWarn "No plugins were registered"
}
return $true
}
# Update PATH environment variable
function Update-PathEnvironment {
param(
[string]$InstallDir,
[bool]$SystemInstall
)
Write-LogHeader "Updating PATH Environment"
# Determine scope
$scope = if ($SystemInstall) { "Machine" } else { "User" }
try {
# Get current PATH
$currentPath = [Environment]::GetEnvironmentVariable("PATH", $scope)
# Check if already in PATH
if ($currentPath -split ';' -contains $InstallDir) {
Write-LogInfo "PATH already contains $InstallDir"
return $true
}
# Add to PATH
$newPath = "$InstallDir;$currentPath"
[Environment]::SetEnvironmentVariable("PATH", $newPath, $scope)
# Update current session
$env:PATH = "$InstallDir;$env:PATH"
Write-LogSuccess "Updated PATH environment variable"
Write-LogInfo "Restart your terminal to apply changes globally"
return $true
} catch {
Write-LogError "Failed to update PATH environment variable"
Write-LogError $_.Exception.Message
return $false
}
}
# Create initial nushell configuration
function New-NushellConfig {
Write-LogHeader "Creating Nushell Configuration"
# Create config directory
New-Item -ItemType Directory -Path $ConfigDir -Force | Out-Null
# Create basic config.nu if it doesn't exist
$configFile = Join-Path $ConfigDir "config.nu"
if (-not (Test-Path $configFile)) {
@"
# Nushell Configuration
# Created by nushell-plugins installer
# Set up basic configuration
`$env.config = {
show_banner: false
edit_mode: emacs
shell_integration: true
table: {
mode: rounded
index_mode: always
show_empty: true
padding: { left: 1, right: 1 }
}
completions: {
case_sensitive: false
quick: true
partial: true
algorithm: "prefix"
}
history: {
max_size: 10000
sync_on_enter: true
file_format: "plaintext"
}
filesize: {
metric: false
format: "auto"
}
}
# Load custom commands and aliases
# Add your custom configuration below
"@ | Out-File -FilePath $configFile -Encoding utf8
Write-LogSuccess "Created config.nu"
} else {
Write-LogInfo "config.nu already exists, skipping"
}
# Create basic env.nu if it doesn't exist
$envFile = Join-Path $ConfigDir "env.nu"
if (-not (Test-Path $envFile)) {
@"
# Nushell Environment Configuration
# Created by nushell-plugins installer
# Environment variables
`$env.EDITOR = "notepad"
`$env.BROWSER = "msedge"
# Nushell specific environment
`$env.NU_LIB_DIRS = [
(`$nu.config-path | path dirname | path join "scripts")
]
`$env.NU_PLUGIN_DIRS = [
(`$nu.config-path | path dirname | path join "plugins")
]
# Add your custom environment variables below
"@ | Out-File -FilePath $envFile -Encoding utf8
Write-LogSuccess "Created env.nu"
} else {
Write-LogInfo "env.nu already exists, skipping"
}
# Create directories
$scriptsDir = Join-Path $ConfigDir "scripts"
$pluginsDir = Join-Path $ConfigDir "plugins"
New-Item -ItemType Directory -Path $scriptsDir -Force | Out-Null
New-Item -ItemType Directory -Path $pluginsDir -Force | Out-Null
return $true
}
# Verify installation
function Test-Installation {
param(
[string]$InstallDir
)
$nuBinary = Join-Path $InstallDir "nu.exe"
Write-LogHeader "Verifying Installation"
# Check if nushell binary exists
if (-not (Test-Path $nuBinary)) {
Write-LogError "Nushell binary not found: $nuBinary"
return $false
}
# Test nushell version
Write-LogInfo "Testing nushell binary..."
try {
$versionOutput = & $nuBinary --version
Write-LogSuccess "Nushell version: $versionOutput"
} catch {
Write-LogError "Failed to run nushell binary"
Write-LogError $_.Exception.Message
return $false
}
# Test basic nushell command
Write-LogInfo "Testing basic nushell functionality..."
try {
$testOutput = & $nuBinary -c "echo 'Hello from Nushell'"
if ($testOutput -eq "Hello from Nushell") {
Write-LogSuccess "Basic nushell functionality works"
} else {
Write-LogWarn "Unexpected output from basic test"
}
} catch {
Write-LogError "Basic nushell functionality failed"
return $false
}
# List registered plugins
Write-LogInfo "Checking registered plugins..."
try {
$pluginOutput = & $nuBinary -c "plugin list"
$pluginCount = ($pluginOutput | Select-String "nu_plugin_").Count
if ($pluginCount -gt 0) {
Write-LogSuccess "Found $pluginCount registered plugins"
} else {
Write-LogWarn "No plugins are registered"
}
} catch {
Write-LogWarn "Could not check plugin status"
}
# Check PATH
Write-LogInfo "Checking PATH configuration..."
try {
$nuInPath = Get-Command nu -ErrorAction SilentlyContinue
if ($nuInPath) {
Write-LogSuccess "Nushell is available in PATH"
} else {
Write-LogWarn "Nushell is not in PATH. You may need to restart your terminal."
}
} catch {
Write-LogWarn "Could not verify PATH configuration"
}
Write-LogSuccess "Installation verification complete!"
return $true
}
# Uninstall function
function Uninstall-Nushell {
Write-LogHeader "Uninstalling Nushell"
$removedFiles = 0
# Remove from user directory
if (Test-Path $InstallDirUser) {
$userBinaries = Get-ChildItem -Path $InstallDirUser -Name "nu.exe", "nu_plugin_*.exe" -ErrorAction SilentlyContinue
foreach ($binary in $userBinaries) {
$filePath = Join-Path $InstallDirUser $binary
Remove-Item $filePath -Force -ErrorAction SilentlyContinue
Write-LogSuccess "Removed $binary from $InstallDirUser"
$removedFiles++
}
}
# Remove from system directory (if accessible)
if ((Test-Admin) -and (Test-Path $InstallDirSystem)) {
$systemBinaries = Get-ChildItem -Path $InstallDirSystem -Name "nu.exe", "nu_plugin_*.exe" -ErrorAction SilentlyContinue
foreach ($binary in $systemBinaries) {
$filePath = Join-Path $InstallDirSystem $binary
Remove-Item $filePath -Force -ErrorAction SilentlyContinue
Write-LogSuccess "Removed $binary from $InstallDirSystem"
$removedFiles++
}
}
# Option to remove configuration
$response = Read-Host "Remove nushell configuration directory ($ConfigDir)? [y/N]"
if ($response -match "^[yY]") {
if (Test-Path $ConfigDir) {
Remove-Item $ConfigDir -Recurse -Force -ErrorAction SilentlyContinue
Write-LogSuccess "Removed configuration directory"
}
} else {
Write-LogInfo "Configuration directory preserved"
}
if ($removedFiles -gt 0) {
Write-LogSuccess "Uninstallation complete ($removedFiles files removed)"
Write-LogWarn "You may need to manually remove PATH entries from your environment variables"
} else {
Write-LogWarn "No nushell files found to remove"
}
}
# Main installation function
function Main {
# Handle help
if ($Help) {
Show-Usage
exit 0
}
# Handle uninstall
if ($Uninstall) {
Uninstall-Nushell
exit 0
}
# Show header
Write-LogHeader "Nushell + Plugins Installer for Windows"
Write-LogInfo "Universal bootstrap installer for Nushell and plugins"
Write-LogInfo ""
# Detect platform
$platform = Get-Platform
Write-LogInfo "Detected platform: $platform"
# Determine installation directory and check privileges
if ($System) {
$installDir = $InstallDirSystem
if (-not (Test-Admin)) {
Write-LogError "System installation requires administrator privileges"
Write-LogInfo "Run PowerShell as Administrator or use -User for user installation"
exit 1
}
} else {
$installDir = $InstallDirUser
}
Write-LogInfo "Installing to: $installDir"
# Get version if not specified
if (-not $Version) {
$Version = Get-LatestVersion
}
Write-LogInfo "Version: $Version"
# Cleanup function
$cleanup = {
if (Test-Path $TempDir) {
Remove-Item $TempDir -Recurse -Force -ErrorAction SilentlyContinue
}
}
try {
# Install based on method
if ($BuildFromSource) {
if (-not (Install-FromSource -InstallDir $installDir -IncludePlugins (-not $NoPlugins))) {
Write-LogError "Source installation failed"
exit 1
}
} else {
if (-not (Install-FromBinaries -Platform $platform -Version $Version -InstallDir $installDir -IncludePlugins (-not $NoPlugins))) {
Write-LogError "Binary installation failed"
exit 1
}
}
# Register plugins
if (-not $NoPlugins) {
Register-Plugins -InstallDir $installDir
}
# Update PATH
if (-not $NoPath) {
Update-PathEnvironment -InstallDir $installDir -SystemInstall $System
}
# Create configuration
if (-not $NoConfig) {
New-NushellConfig
}
# Verify installation
if ($Verify) {
if (-not (Test-Installation -InstallDir $installDir)) {
Write-LogError "Installation verification failed"
exit 1
}
}
# Final success message
Write-LogHeader "Installation Complete!"
Write-LogSuccess "Nushell has been successfully installed to $installDir"
if (-not $NoPlugins) {
Write-LogSuccess "Plugins have been registered with Nushell"
}
if (-not $NoPath) {
Write-LogInfo "To use Nushell, restart your terminal or start a new PowerShell session"
}
Write-LogInfo ""
Write-LogInfo "Try running: nu --version"
Write-LogInfo "Or start Nushell with: nu"
if (-not $NoPlugins) {
Write-LogInfo "Check plugins with: nu -c 'plugin list'"
}
Write-LogInfo ""
Write-LogInfo "For more information, visit: https://nushell.sh"
Write-LogInfo ""
Write-LogSuccess "Happy shell scripting! 🚀"
} finally {
& $cleanup
}
}
# Run main function
Main