Files
c3c/install/install.ps1
Arnaud Moura 9c42919e5a Install scripts (#2393)
* Add scripts to install c3
* Install script support debian binaries
---------

Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
2025-09-19 22:24:05 +02:00

190 lines
5.9 KiB
PowerShell

<#
.SYNOPSIS
C3 install script.
.DESCRIPTION
This script installs C3 on Windows from the command line.
.PARAMETER C3Version
Specifies the version of C3 to install.
Default is 'latest'. Can also be set via environment variable 'C3_VERSION'.
.PARAMETER C3Home
Specifies C3's installation directory.
Default is '$Env:USERPROFILE\.c3'. Can also be set via environment variable 'C3_HOME'.
.PARAMETER NoPathUpdate
If specified, the script will not modify the PATH environment variable.
.PARAMETER C3Repourl
Specifies the repository URL of C3.
Default is 'https://github.com/c3lang/c3c'. Can also be set via environment variable 'C3_REPOURL'.
.LINK
https://c3-lang.org/
.LINK
https://github.com/c3lang/c3c
#>
# Script parameters with defaults
param (
[string] $C3Version = 'latest',
[string] $C3Home = "$Env:USERPROFILE\.c3",
[switch] $NoPathUpdate,
[string] $C3Repourl = 'https://github.com/c3lang/c3c'
)
# Enable strict mode for better error handling
Set-StrictMode -Version Latest
# Function to broadcast environment variable changes to Windows system
function Publish-Env {
# Add P/Invoke type if it does not exist
if (-not ("Win32.NativeMethods" -as [Type])) {
Add-Type -Namespace Win32 -Name NativeMethods -MemberDefinition @"
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr SendMessageTimeout(
IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam,
uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);
"@
}
# Constants for broadcasting environment changes
$HWND_BROADCAST = [IntPtr] 0xffff
$WM_SETTINGCHANGE = 0x1a
$result = [UIntPtr]::Zero
# Broadcast the message to all windows
[Win32.Nativemethods]::SendMessageTimeout($HWND_BROADCAST,
$WM_SETTINGCHANGE,
[UIntPtr]::Zero,
"Environment",
2,
5000,
[ref] $result
) | Out-Null
}
# Function to write or update an environment variable in the registry
function Write-Env {
param(
[String] $name,
[String] $val,
[Switch] $global
)
# Determine the registry key based on scope (user or system)
$RegisterKey = if ($global) {
Get-Item -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager'
} else {
Get-Item -Path 'HKCU:'
}
$EnvRegisterKey = $RegisterKey.OpenSubKey('Environment', $true)
# If value is null, delete the variable
if ($null -eq $val) {
$EnvRegisterKey.DeleteValue($name)
} else {
# Determine the correct registry value type
$RegistryValueKind = if ($val.Contains('%')) {
[Microsoft.Win32.RegistryValueKind]::ExpandString
} elseif ($EnvRegisterKey.GetValue($name)) {
$EnvRegisterKey.GetValueKind($name)
} else {
[Microsoft.Win32.RegistryValueKind]::String
}
$EnvRegisterKey.SetValue($name, $val, $RegistryValueKind)
}
# Broadcast the change to the system
Publish-Env
}
# Function to get an environment variable from the registry
function Get-Env {
param(
[String] $name,
[Switch] $global
)
# Determine registry key based on scope
$RegisterKey = if ($global) {
Get-Item -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager'
} else {
Get-Item -Path 'HKCU:'
}
$EnvRegisterKey = $RegisterKey.OpenSubKey('Environment')
$RegistryValueOption = [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames
# Retrieve the value without expanding environment variables
$EnvRegisterKey.GetValue($name, $null, $RegistryValueOption)
}
# Override defaults if environment variables exist
if ($Env:C3_VERSION) { $C3Version = $Env:C3_VERSION }
if ($Env:C3_HOME) { $C3Home = $Env:C3_HOME }
if ($Env:C3_NO_PATH_UPDATE) { $NoPathUpdate = $true }
if ($Env:C3_REPOURL) { $C3Repourl = $Env:C3_REPOURL -replace '/$', '' }
# Set binary name
$BINARY = "c3-windows"
# Determine the download URL based on version
if ($C3Version -eq 'latest') {
$DOWNLOAD_URL = "$C3Repourl/releases/latest/download/$BINARY.zip"
} else {
# Ensure version starts with 'v'
$C3Version = "v" + ($C3Version -replace '^v', '')
$DOWNLOAD_URL = "$C3Repourl/releases/download/$C3Version/$BINARY.zip"
}
$BinDir = $C3Home
Write-Host "This script will automatically download and install C3 ($C3Version) for you."
Write-Host "Getting it from this url: $DOWNLOAD_URL"
Write-Host "The binary will be installed into '$BinDir'"
# Create temporary file for download
$TEMP_FILE = [System.IO.Path]::GetTempFileName()
try {
# Download the binary
Invoke-WebRequest -Uri $DOWNLOAD_URL -OutFile $TEMP_FILE
# Remove previous installation if it exists
if (Test-Path -Path $BinDir) {
Remove-Item -Path $BinDir -Recurse -Force | Out-Null
}
# Rename temp file to .zip
$ZIP_FILE = $TEMP_FILE + ".zip"
Rename-Item -Path $TEMP_FILE -NewName $ZIP_FILE
# Extract downloaded zip
Expand-Archive -Path $ZIP_FILE -DestinationPath $Env:USERPROFILE -Force
# Rename extracted folder to target installation directory
Rename-Item -Path "$Env:USERPROFILE/c3-windows-Release" -NewName $BinDir
} catch {
Write-Host "Error: '$DOWNLOAD_URL' is not available or failed to download"
exit 1
} finally {
# Cleanup temporary zip file
Remove-Item -Path $ZIP_FILE
}
# Update PATH environment variable if requested
if (!$NoPathUpdate) {
$PATH = Get-Env 'PATH'
if ($PATH -notlike "*$BinDir*") {
Write-Output "Adding $BinDir to PATH"
# Persist PATH for future sessions
Write-Env -name 'PATH' -val "$BinDir;$PATH"
# Update PATH for current session
$Env:PATH = "$BinDir;$PATH"
Write-Output "You may need to restart your shell"
} else {
Write-Output "$BinDir is already in PATH"
}
} else {
Write-Output "You may need to update your PATH manually to use c3"
}