Ctrl K
ComunidadGuías…

install.ps1

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Rove native-first Windows installer
$ErrorActionPreference = "Stop"

Write-Host "===================================================================" -ForegroundColor Cyan
Write-Host "Installing Rove native toolchain..." -ForegroundColor Cyan
Write-Host "===================================================================" -ForegroundColor Cyan

$InstallDir = if ($env:ROVE_INSTALL_DIR) {
    [System.IO.Path]::GetFullPath($env:ROVE_INSTALL_DIR)
} elseif ($env:NYX_INSTALL_DIR) {
    [System.IO.Path]::GetFullPath($env:NYX_INSTALL_DIR)
} else {
    Join-Path $HOME ".rove"
}
$BinDir = Join-Path $InstallDir "bin"
$SrcDir = Join-Path $InstallDir "src"
$CompilerDir = Join-Path $InstallDir "compiler"
$ExtensionDir = Join-Path $InstallDir "vscode-extension"
$NativeExe = Join-Path $BinDir "rovec.exe"
$Repository = "justsomeone-e/RoveLang"
$ReleaseTag = if ($env:ROVE_RELEASE_TAG) { $env:ROVE_RELEASE_TAG } else { $env:NYX_RELEASE_TAG }
$NativeCompilerPath = if ($env:ROVE_NATIVE_COMPILER_PATH) { $env:ROVE_NATIVE_COMPILER_PATH } else { $env:NYX_NATIVE_COMPILER_PATH }
$SkipPathUpdate = if ($env:ROVE_SKIP_PATH_UPDATE) { $env:ROVE_SKIP_PATH_UPDATE } else { $env:NYX_SKIP_PATH_UPDATE }
$SkipEditorInstall = if ($env:ROVE_SKIP_EDITOR_INSTALL) { $env:ROVE_SKIP_EDITOR_INSTALL } else { $env:NYX_SKIP_EDITOR_INSTALL }
$ExpectedVersion = $null
if ($PSScriptRoot -and (Test-Path -LiteralPath (Join-Path $PSScriptRoot "VERSION") -PathType Leaf)) {
    $ExpectedVersion = (Get-Content -LiteralPath (Join-Path $PSScriptRoot "VERSION") -Raw).Trim()
}

function Find-RovePython {
    foreach ($name in @("python", "python3")) {
        $command = Get-Command $name -ErrorAction SilentlyContinue
        if ($command) {
            $commandPath = @($command.Path, $command.Definition, $command.Source) |
                Where-Object { $_ -and (Test-Path -LiteralPath $_ -PathType Leaf) } |
                Select-Object -First 1
            if (-not $commandPath) { continue }
            try {
                & $commandPath -c "import sys; raise SystemExit(0 if sys.version_info >= (3, 10) else 1)" *> $null
                if ($LASTEXITCODE -eq 0) { return $commandPath }
            } catch {
                continue
            }
        }
    }
    return $null
}

function Test-RoveNativeCompiler([string]$Path) {
    if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) { return $false }
    try {
        $versionOutput = (& $Path --version 2>&1 | Out-String).Trim()
        if ($LASTEXITCODE -ne 0 -or (-not $versionOutput.StartsWith("rovec ") -and -not $versionOutput.StartsWith("nyxc "))) { return $false }
        if ($ExpectedVersion) {
            return $versionOutput.StartsWith("rovec $ExpectedVersion ") -or $versionOutput.StartsWith("nyxc $ExpectedVersion ")
        }
        return $true
    } catch {
        return $false
    }
}

function Get-RoveRelease {
    try {
        $headers = @{
            Accept = "application/vnd.github+json"
            "X-GitHub-Api-Version" = "2022-11-28"
        }
        if ($ReleaseTag) {
            $tag = [uri]::EscapeDataString($ReleaseTag)
            return Invoke-RestMethod -Uri "https://api.github.com/repos/$Repository/releases/tags/$tag" -Headers $headers
        }
        return $null
    } catch {
        Write-Host "[!] Release metadata unavailable; source bootstrap remains available." -ForegroundColor Yellow
        return $null
    }
}

New-Item -ItemType Directory -Path $BinDir, $SrcDir, $CompilerDir -Force | Out-Null

$CurrentRoot = $PSScriptRoot
$HasLocalSource = $CurrentRoot -and (Test-Path -LiteralPath (Join-Path $CurrentRoot "src") -PathType Container)
$Release = if ($HasLocalSource -or -not $ReleaseTag) { $null } else { Get-RoveRelease }
$SourceRoot = if ($HasLocalSource) { $CurrentRoot } else { $null }
$TempRoot = $null

try {
    if (-not $SourceRoot) {
        $TempRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("rove_install_" + [guid]::NewGuid().ToString("N"))
        $TempArchive = Join-Path $TempRoot "rove-source.zip"
        $TempExtract = Join-Path $TempRoot "source"
        New-Item -ItemType Directory -Path $TempExtract -Force | Out-Null
        $SourceUrl = if ($Release -and $Release.zipball_url) {
            [string]$Release.zipball_url
        } else {
            "https://github.com/$Repository/archive/refs/heads/main.zip"
        }
        try {
            Write-Host "[*] Downloading Rove sources..." -ForegroundColor Cyan
            Invoke-WebRequest -Uri $SourceUrl -OutFile $TempArchive -UseBasicParsing
            Expand-Archive -LiteralPath $TempArchive -DestinationPath $TempExtract -Force
            $SourceRoot = Get-ChildItem -LiteralPath $TempExtract -Directory |
                Where-Object { Test-Path -LiteralPath (Join-Path $_.FullName "src") -PathType Container } |
                Select-Object -First 1 -ExpandProperty FullName
            if (-not $SourceRoot) {
                throw "Downloaded archive did not contain a Rove source root with src/."
            }
        } catch {
            Write-Host "[!] Source download or extraction failed: $($_.Exception.Message)" -ForegroundColor Yellow
            Write-Host "[!] Native core installation can still continue from a release binary." -ForegroundColor Yellow
        }
    }

    if ($SourceRoot) {
        $sourceVersionPath = Join-Path $SourceRoot "VERSION"
        if (Test-Path -LiteralPath $sourceVersionPath -PathType Leaf) {
            $ExpectedVersion = (Get-Content -LiteralPath $sourceVersionPath -Raw).Trim()
        }
        Write-Host "[*] Installing source and compiler support files..." -ForegroundColor Cyan
        Copy-Item -Path (Join-Path $SourceRoot "src\*") -Destination $SrcDir -Recurse -Force
        foreach ($legalFileName in @("VERSION", "LICENSE")) {
            $legalFile = Join-Path $SourceRoot $legalFileName
            if (Test-Path -LiteralPath $legalFile -PathType Leaf) {
                Copy-Item -LiteralPath $legalFile -Destination (Join-Path $InstallDir $legalFileName) -Force
            }
        }
        if (Test-Path -LiteralPath (Join-Path $SourceRoot "compiler") -PathType Container) {
            Copy-Item -Path (Join-Path $SourceRoot "compiler\*") -Destination $CompilerDir -Recurse -Force
        }
        if (Test-Path -LiteralPath (Join-Path $SourceRoot "vscode-extension") -PathType Container) {
            New-Item -ItemType Directory -Path $ExtensionDir -Force | Out-Null
            $ExtensionSource = Join-Path $SourceRoot "vscode-extension"
            foreach ($fileName in @(
                "package.json", "package-lock.json", "extension.js", "server_options.js",
                "rove_commands.js", "language-configuration.json", "language-surface.json",
                "README.md", "CHANGELOG.md", "LICENSE"
            )) {
                $sourceFile = Join-Path $ExtensionSource $fileName
                if (Test-Path -LiteralPath $sourceFile -PathType Leaf) {
                    Copy-Item -LiteralPath $sourceFile -Destination (Join-Path $ExtensionDir $fileName) -Force
                }
            }
            foreach ($directoryName in @("images", "snippets", "syntaxes")) {
                $sourceDirectory = Join-Path $ExtensionSource $directoryName
                if (Test-Path -LiteralPath $sourceDirectory -PathType Container) {
                    $destinationDirectory = Join-Path $ExtensionDir $directoryName
                    New-Item -ItemType Directory -Path $destinationDirectory -Force | Out-Null
                    Copy-Item -Path (Join-Path $sourceDirectory "*") -Destination $destinationDirectory -Recurse -Force
                }
            }
        }
    }

    $NativeInstalled = $false
    if ($NativeCompilerPath) {
        $OverridePath = [System.IO.Path]::GetFullPath($NativeCompilerPath)
        if (-not (Test-RoveNativeCompiler $OverridePath)) {
            throw "ROVE_NATIVE_COMPILER_PATH does not point to a working rovec executable: $OverridePath"
        }
        Copy-Item -LiteralPath $OverridePath -Destination $NativeExe -Force
        $NativeInstalled = $true
        Write-Host "[OK] Installed native compiler from ROVE_NATIVE_COMPILER_PATH." -ForegroundColor Green
    }

    if (-not $NativeInstalled -and $HasLocalSource) {
        foreach ($candidate in @(
            (Join-Path $CurrentRoot "build\self_host\rovec.exe"),
            (Join-Path $CurrentRoot "build\self_host\nyxc.exe"),
            (Join-Path $CurrentRoot "bin\rovec.exe"),
            (Join-Path $CurrentRoot "bin\nyxc.exe")
        )) {
            if (Test-RoveNativeCompiler $candidate) {
                Copy-Item -LiteralPath $candidate -Destination $NativeExe -Force
                $NativeInstalled = $true
                Write-Host "[OK] Installed existing local native compiler." -ForegroundColor Green
                break
            }
        }
    }

    if (-not $NativeInstalled -and $Release) {
        $runtimeArchitecture = [string][System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
        if (-not $runtimeArchitecture) {
            $runtimeArchitecture = [string]$env:PROCESSOR_ARCHITECTURE
        }
        $architecture = $runtimeArchitecture.ToLowerInvariant()
        $assetArchitecture = switch ($architecture) {
            { $_ -in @("x64", "amd64") } { "x86_64"; break }
            "arm64" { "arm64" }
            default { $null }
        }
        if ($assetArchitecture) {
            $assetNames = @(
                "rovec-windows-$assetArchitecture.exe",
                "nyxc-windows-$assetArchitecture.exe"
            )
            $asset = $Release.assets | Where-Object { $_.name -in $assetNames } |
                Sort-Object { [Array]::IndexOf($assetNames, $_.name) } | Select-Object -First 1
            if ($asset) {
                $assetName = [string]$asset.name
                $TempNative = Join-Path $TempRoot $assetName
                Write-Host "[*] Downloading native compiler $assetName..." -ForegroundColor Cyan
                Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $TempNative -UseBasicParsing
                if ($asset.digest -and ([string]$asset.digest).StartsWith("sha256:")) {
                    $expected = ([string]$asset.digest).Substring(7).ToLowerInvariant()
                    $actual = (Get-FileHash -LiteralPath $TempNative -Algorithm SHA256).Hash.ToLowerInvariant()
                    if ($actual -ne $expected) { throw "Native compiler SHA-256 verification failed." }
                }
                Copy-Item -LiteralPath $TempNative -Destination $NativeExe -Force
                $NativeInstalled = Test-RoveNativeCompiler $NativeExe
                if ($NativeInstalled) {
                    Write-Host "[OK] Installed verified native release compiler." -ForegroundColor Green
                }
            }
        }
    }

    $PythonExe = Find-RovePython
    $SrcCli = Join-Path $SrcDir "cli.py"
    if (-not $NativeInstalled -and (Test-RoveNativeCompiler $NativeExe)) {
        $NativeInstalled = $true
        Write-Host "[OK] Reusing installed native compiler." -ForegroundColor Green
    }
    if (-not $NativeInstalled) {
        if (-not $PythonExe -or -not (Test-Path -LiteralPath $SrcCli -PathType Leaf)) {
            throw "No prebuilt rovec is available for this platform. Python 3.10+ and a C++20 compiler are required for the source-bootstrap fallback."
        }
        Write-Host "[*] No matching prebuilt binary; bootstrapping native rovec from source..." -ForegroundColor Cyan
        Push-Location $InstallDir
        try {
            & $PythonExe $SrcCli self-host build -o $NativeExe
            if ($LASTEXITCODE -ne 0) { throw "Native compiler source bootstrap failed." }
        } finally {
            Pop-Location
        }
        $NativeInstalled = Test-RoveNativeCompiler $NativeExe
        if (-not $NativeInstalled) { throw "Bootstrapped native compiler failed validation." }
        Write-Host "[OK] Native rovec bootstrap completed." -ForegroundColor Green
    }

    $NativeLiteral = $NativeExe.Replace("'", "''")
    $CliLiteral = $SrcCli.Replace("'", "''")
    $PythonLiteral = if ($PythonExe) { $PythonExe.Replace("'", "''") } else { "" }
    $Ps1Content = @'
$native = '__ROVE_NATIVE__'
$pythonCli = '__ROVE_CLI__'
$preferredPython = '__ROVE_PYTHON__'
$nativeCommands = @('check', 'compile', 'emit-cpp', 'version', '--version', '-v')
if ($args.Count -gt 0 -and $nativeCommands -contains $args[0]) {
    & $native @args
    exit $LASTEXITCODE
}
if ($preferredPython -and (Test-Path -LiteralPath $preferredPython -PathType Leaf) -and (Test-Path -LiteralPath $pythonCli -PathType Leaf)) {
    & $preferredPython $pythonCli @args
    exit $LASTEXITCODE
}
$python = Get-Command python, python3 -ErrorAction SilentlyContinue | Select-Object -First 1
if ($python -and (Test-Path -LiteralPath $pythonCli -PathType Leaf)) {
    & $python.Source $pythonCli @args
    exit $LASTEXITCODE
}
if ($args.Count -eq 0) {
    & $native --help
    exit $LASTEXITCODE
}
Write-Error "This command still uses the optional Python orchestration layer. Install Python 3.10+, or use rovec check/compile/emit-cpp."
exit 2
'@
    $Ps1Content = $Ps1Content.Replace("__ROVE_NATIVE__", $NativeLiteral).Replace("__ROVE_CLI__", $CliLiteral).Replace("__ROVE_PYTHON__", $PythonLiteral)
    foreach ($name in @("rove.ps1", "nyx.ps1")) {
        Set-Content -LiteralPath (Join-Path $BinDir $name) -Value $Ps1Content -Encoding UTF8
    }

    $BatchNative = $NativeExe.Replace("%", "%%")
    $BatchCli = $SrcCli.Replace("%", "%%")
    $BatchPython = if ($PythonExe) { $PythonExe.Replace("%", "%%") } else { "" }
    $BatContent = @"
@echo off
setlocal
set "ROVE_NATIVE=$BatchNative"
set "ROVE_PYCLI=$BatchCli"
set "ROVE_PYTHON=$BatchPython"
if "%~1"=="check" goto rove_native
if "%~1"=="compile" goto rove_native
if "%~1"=="emit-cpp" goto rove_native
if "%~1"=="version" goto rove_native
if "%~1"=="--version" goto rove_native
if "%~1"=="-v" goto rove_native
if exist "%ROVE_PYTHON%" (
    "%ROVE_PYTHON%" "%ROVE_PYCLI%" %*
    exit /b %errorlevel%
)
where python >nul 2>nul
if not errorlevel 1 (
    python "%ROVE_PYCLI%" %*
    exit /b %errorlevel%
)
where python3 >nul 2>nul
if not errorlevel 1 (
    python3 "%ROVE_PYCLI%" %*
    exit /b %errorlevel%
)
if "%~1"=="" (
    "%ROVE_NATIVE%" --help
    exit /b %errorlevel%
)
echo This command still uses the optional Python orchestration layer. Install Python 3.10+, or use rovec check/compile/emit-cpp. 1>&2
exit /b 2
:rove_native
"%ROVE_NATIVE%" %*
exit /b %errorlevel%
"@
    foreach ($name in @("rove.bat", "rove.cmd", "nyx.bat", "nyx.cmd")) {
        Set-Content -LiteralPath (Join-Path $BinDir $name) -Value $BatContent -Encoding ASCII
    }

    $ShContent = @'
#!/usr/bin/env bash
set -euo pipefail
wrapper_dir="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
install_dir="$(dirname -- "$wrapper_dir")"
native="$wrapper_dir/rovec.exe"
python_cli="$install_dir/src/cli.py"
case "${1:-}" in
    check|compile|emit-cpp|version|--version|-v) exec "$native" "$@" ;;
esac
if command -v python3 >/dev/null 2>&1 && [ -f "$python_cli" ]; then
    exec python3 "$python_cli" "$@"
fi
if command -v python >/dev/null 2>&1 && [ -f "$python_cli" ]; then
    exec python "$python_cli" "$@"
fi
if [ "$#" -eq 0 ]; then
    exec "$native" --help
fi
echo "This command still uses the optional Python orchestration layer. Install Python 3.10+, or use rovec check/compile/emit-cpp." >&2
exit 2
'@
    Set-Content -LiteralPath (Join-Path $BinDir "rove") -Value $ShContent -Encoding ASCII
    Set-Content -LiteralPath (Join-Path $BinDir "nyx") -Value $ShContent -Encoding ASCII

    if ($SkipPathUpdate -ne "1") {
        $UserPath = [Environment]::GetEnvironmentVariable("Path", "User")
        if (-not $UserPath) { $UserPath = "" }
        $PathEntries = @($UserPath -split ";" | Where-Object {
            $_ -and -not $_.Equals($BinDir, [System.StringComparison]::OrdinalIgnoreCase)
        })
        $UpdatedPath = (@($BinDir) + $PathEntries) -join ";"
        if ($UpdatedPath -ne $UserPath) {
            [Environment]::SetEnvironmentVariable("Path", $UpdatedPath, "User")
            Write-Host "[OK] Prioritized $BinDir in User PATH." -ForegroundColor Green
        }
        $ProcessPathEntries = @($env:Path -split ";" | Where-Object {
            $_ -and -not $_.Equals($BinDir, [System.StringComparison]::OrdinalIgnoreCase)
        })
        $env:Path = (@($BinDir) + $ProcessPathEntries) -join ";"
    } else {
        Write-Host "[*] PATH update skipped (ROVE_SKIP_PATH_UPDATE=1)." -ForegroundColor Yellow
    }

    $VsCodeExtDir = Join-Path $HOME ".vscode\extensions\rove-lang-support"
    if ($SkipEditorInstall -ne "1" -and (Test-Path -LiteralPath $ExtensionDir -PathType Container)) {
        # Prefer npm.cmd or npm.exe over npm.ps1 to avoid PowerShell script execution policy restrictions
        $NpmCandidate = Get-Command "npm.cmd", "npm.exe" -ErrorAction SilentlyContinue | Select-Object -First 1
        if (-not $NpmCandidate) {
            $NpmCandidate = Get-Command "npm" -ErrorAction SilentlyContinue
        }
        $NpmPath = if ($NpmCandidate) {
            @($NpmCandidate.Path, $NpmCandidate.Source, $NpmCandidate.Definition) |
                Where-Object { $_ -and (Test-Path -LiteralPath $_ -PathType Leaf) } |
                Select-Object -First 1
        } else {
            $null
        }
        if ($NpmPath) {
            Push-Location $ExtensionDir
            try {
                if ([System.IO.Path]::GetExtension($NpmPath) -ieq ".ps1") {
                    cmd.exe /c npm ci --omit=dev --ignore-scripts | Out-Null
                } else {
                    & $NpmPath ci --omit=dev --ignore-scripts | Out-Null
                }
                if ($LASTEXITCODE -eq 0) {
                    New-Item -ItemType Directory -Path $VsCodeExtDir -Force | Out-Null
                    Copy-Item -Path (Join-Path $ExtensionDir "*") -Destination $VsCodeExtDir -Recurse -Force
                    Write-Host "[OK] Synced Rove VS Code extension to $VsCodeExtDir" -ForegroundColor Green
                } else {
                    Write-Host "[!] npm ci failed; VS Code extension installation skipped." -ForegroundColor Yellow
                }
            } catch {
                Write-Host "[!] VS Code extension installation skipped ($($_.Exception.Message))." -ForegroundColor Yellow
            } finally {
                Pop-Location
            }
        } else {
            Write-Host "[!] npm not found; VS Code extension installation skipped." -ForegroundColor Yellow
        }
    }

    if (-not (Test-RoveNativeCompiler $NativeExe)) { throw "Installed native compiler failed final validation." }
    Copy-Item -LiteralPath $NativeExe -Destination (Join-Path $BinDir "nyxc.exe") -Force
    Write-Host "[OK] Native compiler validation passed." -ForegroundColor Green
} finally {
    if ($TempRoot -and (Test-Path -LiteralPath $TempRoot)) {
        $ResolvedTemp = [System.IO.Path]::GetFullPath($TempRoot)
        $TempBase = [System.IO.Path]::GetFullPath([System.IO.Path]::GetTempPath())
        if ($ResolvedTemp.StartsWith($TempBase, [System.StringComparison]::OrdinalIgnoreCase)) {
            Remove-Item -LiteralPath $ResolvedTemp -Recurse -Force -ErrorAction SilentlyContinue
        }
    }
}

Write-Host "===================================================================" -ForegroundColor Cyan
Write-Host "[OK] Rove installed successfully at $InstallDir" -ForegroundColor Green
Write-Host "     Native core: rovec --help (legacy alias: nyxc)" -ForegroundColor Green
Write-Host "     Unified CLI: rove --help (legacy alias: nyx)" -ForegroundColor Green
Write-Host "===================================================================" -ForegroundColor Cyan