# 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