Newer
Older
Sunfish / build.ps1
@Ivan Dominguez Ivan Dominguez 21 hours ago 8 KB 3.0
# Sunfish - autocompilacion para Windows (PowerShell 5.1 o superior).
#
#   irm https://raw.githubusercontent.com/XWolfOverride/Sunfish/main/build.ps1 | iex
#
# Que hace:
#   1. Comprueba que estan instaladas las herramientas necesarias (NO instala nada).
#   2. Descarga (o actualiza) la ultima version del codigo con git.
#   3. Compila Sunfish.exe (ventana, un solo .exe) y sunfish-cli.exe (consola, NativeAOT).
#   4. Deja los dos en la raiz del proyecto y te explica como instalar sunfish-cli.
#
# Variables opcionales:
#   $env:SUNFISH_REPO_URL     URL del repositorio (util para forks)
#   $env:SUNFISH_LIGHT = '1'  Sunfish.exe ligero: necesita el .NET Desktop Runtime 10 instalado
#
# Nota: todo va dentro de una funcion y se sale con `return`, para que al ejecutarlo con
# `| iex` un fallo no cierre tu ventana de PowerShell.

function Invoke-SunfishBuild {
    $ErrorActionPreference = 'Stop'

    $repoUrl = if ($env:SUNFISH_REPO_URL) { $env:SUNFISH_REPO_URL } else { 'https://github.com/XWolfOverride/Sunfish' }
    $dirName = 'Sunfish'
    $light = $env:SUNFISH_LIGHT -eq '1'

    function Ok($m)   { Write-Host "[OK] " -ForegroundColor Green -NoNewline; Write-Host $m }
    function Bad($m)  { Write-Host "[X]  " -ForegroundColor Red -NoNewline; Write-Host $m }
    function Info($m) { Write-Host ">>   " -ForegroundColor Cyan -NoNewline; Write-Host $m }

    Write-Host ""
    Write-Host "Sunfish: autocompilacion" -ForegroundColor White
    Write-Host ""

    # ---------------------------------------------------------- arquitectura
    $arch = $env:PROCESSOR_ARCHITEW6432
    if (-not $arch) { $arch = $env:PROCESSOR_ARCHITECTURE }
    switch ($arch) {
        'AMD64' { $rid = 'win-x64' }
        'ARM64' { $rid = 'win-arm64' }
        default { Write-Host "Arquitectura no soportada por el script: $arch" -ForegroundColor Red; return }
    }
    Info "Sistema detectado: $rid"
    Write-Host ""

    # ---------------------------------------------------------- prerrequisitos
    $missing = @()
    $hints = @()

    if (Get-Command git -ErrorAction SilentlyContinue) {
        Ok ("git (" + ((git --version) -replace 'git version ', '') + ")")
    } else {
        Bad 'git'; $missing += 'git'; $hints += 'winget install Git.Git'
    }

    $dotnetOk = $false
    if (Get-Command dotnet -ErrorAction SilentlyContinue) {
        $ver = (& dotnet --version 2>$null)
        $major = 0
        if ($ver -and [int]::TryParse(($ver -split '\.')[0], [ref]$major) -and $major -ge 10) {
            Ok "SDK de .NET ($ver)"; $dotnetOk = $true
        } else {
            Bad "SDK de .NET: version $ver, se necesita 10 o superior"
        }
    } else {
        Bad 'SDK de .NET 10'
    }
    if (-not $dotnetOk) { $missing += 'SDK de .NET 10'; $hints += 'winget install Microsoft.DotNet.SDK.10' }

    # Compilador nativo para sunfish-cli (NativeAOT): Build Tools / Visual Studio con C++.
    $vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe'
    $hasCpp = $false
    if (Test-Path $vswhere) {
        $vsPath = & $vswhere -latest -products '*' -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath 2>$null
        if ($vsPath) { $hasCpp = $true }
    }
    if ($hasCpp) {
        Ok 'Compilador de C++ (Visual Studio Build Tools)'
        # ILCompiler invoca "vswhere.exe" por nombre: nos aseguramos de que este en el PATH de este proceso.
        $vsDir = Split-Path $vswhere
        if (($env:PATH -split ';') -notcontains $vsDir) { $env:PATH = "$env:PATH;$vsDir" }
    } else {
        Bad 'Compilador de C++ (Visual Studio Build Tools con "Desktop development with C++")'
        $missing += 'Compilador de C++'
        $hints += 'winget install Microsoft.VisualStudio.2022.BuildTools --override "--passive --wait --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended"'
    }

    if ($missing.Count -gt 0) {
        Write-Host ""
        Write-Host ("Faltan herramientas necesarias: " + ($missing -join ', ')) -ForegroundColor Yellow
        Write-Host ""
        Write-Host "Instalalas con (este script no instala nada por ti):"
        Write-Host ""
        foreach ($h in $hints) { Write-Host "    $h" }
        Write-Host ""
        Write-Host "Cierra y vuelve a abrir PowerShell tras instalarlas y repite este comando."
        Write-Host "Detalles en el README del proyecto."
        return
    }

    # ---------------------------------------------------------- codigo fuente
    Write-Host ""
    $here = (Get-Location).Path

    function Update-Repo($path) {
        # Sin remoto (copia local aun sin publicar) no hay nada que actualizar.
        if (-not (git -C $path remote)) {
            Info "El repositorio no tiene remoto configurado: se compila el codigo tal como esta."
            return $true
        }
        git -C $path pull --ff-only
        if ($LASTEXITCODE -ne 0) {
            Write-Host "No se pudo actualizar (hay cambios locales?). Resuelvelo y repite." -ForegroundColor Red
            return $false
        }
        return $true
    }

    if ((Test-Path (Join-Path $here 'Sunfish.slnx')) -and (Test-Path (Join-Path $here '.git'))) {
        $root = $here
        Info "Usando el repositorio actual: $root"
        if (-not (Update-Repo $root)) { return }
    } elseif (Test-Path (Join-Path $here "$dirName\.git")) {
        $root = Join-Path $here $dirName
        Info "Actualizando $root"
        if (-not (Update-Repo $root)) { return }
    } else {
        $root = Join-Path $here $dirName
        Info "Descargando $repoUrl"
        git clone --depth 1 $repoUrl $root
        if ($LASTEXITCODE -ne 0) { Write-Host "No se pudo clonar el repositorio." -ForegroundColor Red; return }
    }

    # ---------------------------------------------------------- compilacion
    $env:DOTNET_NOLOGO = '1'
    $pub = Join-Path $root 'publish'
    if (Test-Path $pub) { Remove-Item $pub -Recurse -Force }

    # Sunfish.exe: un solo .exe (WinForms no admite NativeAOT).
    $gui = Join-Path $pub 'gui'
    if ($light) {
        Info "Compilando Sunfish.exe ligero ($rid, necesita el .NET Desktop Runtime 10)..."
        dotnet publish (Join-Path $root 'src\Sunfish.WinForms\Sunfish.WinForms.csproj') -c Release -r $rid -o $gui -p:SelfContained=false -nologo -v q
    } else {
        Info "Compilando Sunfish.exe autocontenido ($rid)..."
        dotnet publish (Join-Path $root 'src\Sunfish.WinForms\Sunfish.WinForms.csproj') -c Release -r $rid -o $gui -nologo -v q
    }
    if ($LASTEXITCODE -ne 0) { Write-Host "Fallo la compilacion de Sunfish.exe." -ForegroundColor Red; return }
    Copy-Item (Join-Path $gui 'Sunfish.exe') (Join-Path $root 'Sunfish.exe') -Force
    Ok "Sunfish.exe -> $(Join-Path $root 'Sunfish.exe')"

    # sunfish-cli.exe: NativeAOT.
    $cli = Join-Path $pub 'cli'
    Info "Compilando sunfish-cli.exe (NativeAOT, $rid)... puede tardar un par de minutos"
    dotnet publish (Join-Path $root 'src\Sunfish.Cli\Sunfish.Cli.csproj') -c Release -r $rid -o $cli -nologo -v q
    if ($LASTEXITCODE -ne 0) { Write-Host "Fallo la compilacion de sunfish-cli.exe." -ForegroundColor Red; return }
    Copy-Item (Join-Path $cli 'sunfish-cli.exe') (Join-Path $root 'sunfish-cli.exe') -Force
    Ok "sunfish-cli.exe -> $(Join-Path $root 'sunfish-cli.exe')"

    Remove-Item $pub -Recurse -Force

    # ---------------------------------------------------------- final
    Write-Host ""
    Write-Host "Listo." -ForegroundColor Green
    foreach ($name in 'Sunfish.exe', 'sunfish-cli.exe') {
        $f = Get-Item (Join-Path $root $name)
        Write-Host ("    {0,8:N1} MB  {1}" -f ($f.Length / 1MB), $f.FullName)
    }
    Write-Host ""
    Write-Host "Sunfish.exe se abre con doble clic. Arrastra una carpeta sobre el para compartirla al momento." -ForegroundColor White
    Write-Host ""
    Write-Host "Para usar sunfish-cli desde cualquier terminal (sin administrador), ejecuta:" -ForegroundColor White
    Write-Host ""
    Write-Host "    cd `"$root`""
    Write-Host '    mkdir $HOME\bin -Force | Out-Null'
    Write-Host '    copy sunfish-cli.exe $HOME\bin'
    Write-Host '    $p = [Environment]::GetEnvironmentVariable("Path", "User")'
    Write-Host '    [Environment]::SetEnvironmentVariable("Path", "$p;$HOME\bin", "User")'
    Write-Host ""
    Write-Host "Cierra y vuelve a abrir la terminal y pruebalo con:  sunfish-cli --help"
    Write-Host "Para actualizar a una nueva version, vuelve a ejecutar este script."
    Write-Host ""
}

Invoke-SunfishBuild