docs: Update README and documentation for lxs multi-tool across Linux and Windows platforms.
This commit is contained in:
+502
@@ -0,0 +1,502 @@
|
||||
<#
|
||||
LXS - Windows multi-tool
|
||||
Description: Centralized workstation management and deployment toolkit
|
||||
Repo: https://git.hyko.cx/hykocx/lxs
|
||||
License: MIT
|
||||
|
||||
Mirrors linux/lxs.sh: same verbs, same menu, same update flow.
|
||||
Compatible with Windows PowerShell 5.1 and PowerShell 7+.
|
||||
#>
|
||||
|
||||
# Raw $args pass-through: sub-scripts get their own flags verbatim
|
||||
# (e.g. `lxs tool harden -Yes`) without this script trying to bind them.
|
||||
$LxsArgs = @($args)
|
||||
$LxsCommand = if ($LxsArgs.Count -gt 0) { [string]$LxsArgs[0] } else { '' }
|
||||
$LxsRest = if ($LxsArgs.Count -gt 1) { $LxsArgs[1..($LxsArgs.Count - 1)] } else { @() }
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# Configuration
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
$LxsScriptDir = $PSScriptRoot
|
||||
if (-not $LxsScriptDir) { $LxsScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path }
|
||||
|
||||
$LxsVersion = 'dev'
|
||||
if ($LxsScriptDir) {
|
||||
$versionFile = Join-Path $LxsScriptDir '..\VERSION'
|
||||
if (Test-Path $versionFile) {
|
||||
$raw = (Get-Content $versionFile -TotalCount 1 -ErrorAction SilentlyContinue)
|
||||
if ($raw) { $LxsVersion = $raw.Trim() }
|
||||
}
|
||||
}
|
||||
|
||||
$LxsRepoUrl = 'https://git.hyko.cx/hykocx/lxs'
|
||||
$LxsBranch = if ($env:LXS_BRANCH) { $env:LXS_BRANCH } else { 'main' }
|
||||
$LxsRawBase = if ($env:LXS_RAW_BASE) { $env:LXS_RAW_BASE } else { "$LxsRepoUrl/raw/branch/$LxsBranch" }
|
||||
|
||||
# Platform sub-tree: every apps\ and tools\ path resolves under it.
|
||||
$LxsPlatformDir = 'windows'
|
||||
$env:LXS_RAW_BASE = $LxsRawBase
|
||||
$env:LXS_RAW_PLATFORM_BASE = "$LxsRawBase/$LxsPlatformDir"
|
||||
|
||||
$LxsZipUrl = if ($env:LXS_ZIP_URL) { $env:LXS_ZIP_URL } else { "$LxsRepoUrl/archive/$LxsBranch.zip" }
|
||||
# LOCALAPPDATA is normally set; fall back so a service/SYSTEM context that
|
||||
# lacks it still resolves to a writable directory instead of erroring out.
|
||||
$LxsLocalAppData = $env:LOCALAPPDATA
|
||||
if (-not $LxsLocalAppData) {
|
||||
$LxsLocalAppData = if ($env:USERPROFILE) { Join-Path $env:USERPROFILE 'AppData\Local' } else { [IO.Path]::GetTempPath() }
|
||||
}
|
||||
$LxsInstallDir = if ($env:LXS_INSTALL_DIR) { $env:LXS_INSTALL_DIR } else { Join-Path $LxsLocalAppData 'lxs' }
|
||||
$LxsBinDir = Join-Path $LxsInstallDir 'bin'
|
||||
$LxsShimPath = Join-Path $LxsBinDir 'lxs.cmd'
|
||||
$LxsCacheDir = Join-Path $LxsInstallDir 'cache'
|
||||
$LxsVersionCache = Join-Path $LxsCacheDir 'remote_version'
|
||||
$LxsVersionTtl = 86400
|
||||
|
||||
$script:LxsUpdateAvailable = $false
|
||||
$script:LxsRemoteVersion = ''
|
||||
$script:LxsPublicIpCache = $null
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# Load common library
|
||||
# Prefers a sibling lib\common.ps1 (installed or repo checkout); falls back to
|
||||
# fetching it from the remote when run via `irm ... | iex`.
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
$libPath = if ($LxsScriptDir) { Join-Path $LxsScriptDir 'lib\common.ps1' } else { $null }
|
||||
if ($libPath -and (Test-Path $libPath)) {
|
||||
. $libPath
|
||||
} else {
|
||||
try {
|
||||
$libSource = Invoke-RestMethod -Uri "$env:LXS_RAW_PLATFORM_BASE/lib/common.ps1" -UseBasicParsing -ErrorAction Stop
|
||||
} catch {
|
||||
Write-Error 'Failed to fetch lib/common.ps1'
|
||||
exit 1
|
||||
}
|
||||
. ([scriptblock]::Create($libSource))
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# Core helpers
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
function Get-LxsCachedPublicIP {
|
||||
if ($null -eq $script:LxsPublicIpCache) {
|
||||
$script:LxsPublicIpCache = Get-LxsPublicIP
|
||||
}
|
||||
return $script:LxsPublicIpCache
|
||||
}
|
||||
|
||||
# Compare two dotted versions. Returns $true when $Candidate is newer.
|
||||
function Test-LxsNewerVersion {
|
||||
param([string]$Current, [string]$Candidate)
|
||||
try {
|
||||
return ([version]$Candidate -gt [version]$Current)
|
||||
} catch {
|
||||
return ($Candidate -ne $Current)
|
||||
}
|
||||
}
|
||||
|
||||
function Test-LxsRemoteVersion {
|
||||
$script:LxsUpdateAvailable = $false
|
||||
$script:LxsRemoteVersion = ''
|
||||
|
||||
try {
|
||||
if (-not (Test-Path $LxsCacheDir)) { New-Item -ItemType Directory -Path $LxsCacheDir -Force | Out-Null }
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
||||
$age = [double]::MaxValue
|
||||
if (Test-Path $LxsVersionCache) {
|
||||
$age = ((Get-Date) - (Get-Item $LxsVersionCache).LastWriteTime).TotalSeconds
|
||||
}
|
||||
|
||||
if ($age -ge $LxsVersionTtl) {
|
||||
# Refresh inline but on a short leash — a slow repo must not stall the menu.
|
||||
try {
|
||||
$remote = Invoke-RestMethod -Uri "$LxsRawBase/VERSION" -TimeoutSec 3 `
|
||||
-Headers @{ 'Cache-Control' = 'no-cache' } -UseBasicParsing -ErrorAction Stop
|
||||
("$remote").Trim() | Set-Content -Path $LxsVersionCache -Encoding ASCII
|
||||
} catch {
|
||||
# Offline or unreachable: fall through to whatever is cached.
|
||||
}
|
||||
}
|
||||
|
||||
if (-not (Test-Path $LxsVersionCache)) { return }
|
||||
$cached = (Get-Content $LxsVersionCache -TotalCount 1 -ErrorAction SilentlyContinue)
|
||||
if (-not $cached) { return }
|
||||
$cached = $cached.Trim()
|
||||
|
||||
if (Test-LxsNewerVersion -Current $LxsVersion -Candidate $cached) {
|
||||
$script:LxsUpdateAvailable = $true
|
||||
$script:LxsRemoteVersion = $cached
|
||||
}
|
||||
}
|
||||
|
||||
function Show-LxsLogo {
|
||||
Show-LxsBoxTop -Title "LXS // v$LxsVersion" -Right 'WINDOWS'
|
||||
}
|
||||
|
||||
function Show-LxsHeader {
|
||||
Clear-Host
|
||||
Show-LxsLogo
|
||||
|
||||
if ($script:LxsUpdateAvailable) {
|
||||
Write-Host ''
|
||||
Write-Host " $($script:Cyan)[!!] UPDATE_AVAILABLE$($script:NC) $($script:White)v$($script:LxsRemoteVersion)$($script:NC) $($script:Gray)// run ``lxs update``$($script:NC)"
|
||||
}
|
||||
|
||||
$hostname = $env:COMPUTERNAME
|
||||
$osName = 'Windows'
|
||||
$build = ''
|
||||
$uptime = 'unknown'
|
||||
$totalMem = 0.0
|
||||
$usedMem = 0.0
|
||||
try {
|
||||
$os = Get-CimInstance Win32_OperatingSystem -ErrorAction Stop
|
||||
$osName = ($os.Caption -replace '^Microsoft ', '').Trim()
|
||||
$build = "$($os.Version) ($($os.BuildNumber))"
|
||||
$span = (Get-Date) - $os.LastBootUpTime
|
||||
$uptime = "{0}d {1}h {2}m" -f $span.Days, $span.Hours, $span.Minutes
|
||||
$totalMem = [math]::Round($os.TotalVisibleMemorySize / 1MB, 1)
|
||||
$usedMem = [math]::Round(($os.TotalVisibleMemorySize - $os.FreePhysicalMemory) / 1MB, 1)
|
||||
} catch {
|
||||
# CIM unavailable — the header degrades but the menu still works.
|
||||
}
|
||||
|
||||
$cores = $env:NUMBER_OF_PROCESSORS
|
||||
$ip = Get-LxsCachedPublicIP
|
||||
|
||||
$disk = 'unknown'
|
||||
try {
|
||||
$sys = New-Object System.IO.DriveInfo "$env:SystemDrive\"
|
||||
$totalGB = [math]::Round($sys.TotalSize / 1GB, 1)
|
||||
$usedGB = [math]::Round(($sys.TotalSize - $sys.AvailableFreeSpace) / 1GB, 1)
|
||||
$pct = if ($sys.TotalSize -gt 0) { [math]::Round(100 * ($sys.TotalSize - $sys.AvailableFreeSpace) / $sys.TotalSize) } else { 0 }
|
||||
$disk = "${usedGB}G/${totalGB}G (${pct}%)"
|
||||
} catch {
|
||||
# No access to the system drive info.
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host (" $($script:Cyan)NODE$($script:NC) $($script:White){0,-26}$($script:NC) $($script:Cyan)BUILD$($script:NC) $($script:White){1}$($script:NC)" -f $hostname, $build)
|
||||
Write-Host (" $($script:Cyan)ADDR$($script:NC) $($script:White){0,-26}$($script:NC) $($script:Cyan)UP$($script:NC) $($script:White){1}$($script:NC)" -f $ip, $uptime)
|
||||
Write-Host (" $($script:Cyan)OS$($script:NC) $($script:White){0,-26}$($script:NC) $($script:Cyan)CPU$($script:NC) $($script:White){1} cores$($script:NC)" -f $osName, $cores)
|
||||
Write-Host (" $($script:Cyan)DISK$($script:NC) $($script:White){0,-26}$($script:NC) $($script:Cyan)MEM$($script:NC) $($script:White){1} / {2} GB$($script:NC)" -f $disk, $usedMem, $totalMem)
|
||||
Write-Host ''
|
||||
}
|
||||
|
||||
# Run a sub-script (tools\... or apps\...). Prefers the installed copy;
|
||||
# falls back to fetching it. Mirrors download_and_run() in linux/lxs.sh.
|
||||
function Invoke-LxsScript {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$RelativePath,
|
||||
[string[]]$Arguments = @()
|
||||
)
|
||||
$name = Split-Path $RelativePath -Leaf
|
||||
$localPath = $null
|
||||
if ($LxsScriptDir) { $localPath = Join-Path $LxsScriptDir $RelativePath }
|
||||
|
||||
$target = $null
|
||||
$temp = $null
|
||||
if ($localPath -and (Test-Path $localPath)) {
|
||||
$target = $localPath
|
||||
} else {
|
||||
$url = "$env:LXS_RAW_PLATFORM_BASE/$($RelativePath -replace '\\', '/')"
|
||||
$temp = Join-Path (Get-LxsTempDir) ("lxs.{0}.{1}.ps1" -f [IO.Path]::GetFileNameWithoutExtension($name), [guid]::NewGuid().ToString('N').Substring(0, 8))
|
||||
Write-Host ''
|
||||
Write-LxsInfo "Fetching $($script:Bold)$name$($script:NC)..."
|
||||
try {
|
||||
Invoke-WebRequest -Uri $url -OutFile $temp -UseBasicParsing `
|
||||
-Headers @{ 'Cache-Control' = 'no-cache' } -ErrorAction Stop
|
||||
} catch {
|
||||
Write-LxsErr "Failed to download $RelativePath"
|
||||
Write-Host "$($script:Gray) URL: $url$($script:NC)"
|
||||
return 1
|
||||
}
|
||||
Write-LxsOk 'Payload acquired'
|
||||
$target = $temp
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Show-LxsSeparator
|
||||
Write-Host ''
|
||||
|
||||
$global:LASTEXITCODE = 0
|
||||
try {
|
||||
& $target @Arguments
|
||||
$code = $LASTEXITCODE
|
||||
} finally {
|
||||
if ($temp) { Remove-Item $temp -Force -ErrorAction SilentlyContinue }
|
||||
}
|
||||
if ($null -eq $code) { $code = 0 }
|
||||
|
||||
Write-Host ''
|
||||
Show-LxsSeparator
|
||||
if ($code -eq 0 -or $code -eq 75) {
|
||||
Write-LxsOk 'Script completed successfully'
|
||||
} else {
|
||||
Write-LxsWarn "Script exited with code: $code"
|
||||
}
|
||||
return $code
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# CLI commands
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
function Invoke-LxsCmdVersion { Write-Host "lxs $LxsVersion" }
|
||||
|
||||
function Invoke-LxsCmdHelp {
|
||||
Write-Host @"
|
||||
LXS - Windows multi-tool (v$LxsVersion)
|
||||
|
||||
Usage:
|
||||
lxs Interactive menu (browse apps and tools)
|
||||
lxs setup Install lxs to $LxsInstallDir and add it to PATH
|
||||
lxs update Update all installed files to latest
|
||||
lxs install <app> Install an application bundle
|
||||
lxs tool <name> [args] Run a system tool
|
||||
lxs info Show system info
|
||||
lxs version Show version
|
||||
lxs help Show this help
|
||||
|
||||
Applications:
|
||||
dev Git, VS Code, Node.js, Python, PowerShell 7, Windows Terminal
|
||||
utilities 7-Zip, Notepad++, PowerToys, Sysinternals, Everything, ShareX
|
||||
browsers Firefox, LibreWolf, Chrome, Brave, VLC, OBS Studio
|
||||
containers WSL2, Hyper-V, Docker Desktop, VirtualBox
|
||||
claude-code Claude Code CLI (+ Git for Windows)
|
||||
|
||||
Tools:
|
||||
system System information and diagnostics
|
||||
network Network diagnostics and repair
|
||||
cleanup Free disk space (temp, update cache, recycle bin, WinSxS)
|
||||
repair SFC / DISM / chkdsk integrity repair
|
||||
restore-point Create, list or roll back to a System Restore point
|
||||
update Windows Update + winget upgrade
|
||||
harden Baseline security hardening
|
||||
remote-access Remote Desktop and OpenSSH server
|
||||
debloat Remove preinstalled apps and disable telemetry
|
||||
|
||||
Source: $LxsRepoUrl
|
||||
"@
|
||||
}
|
||||
|
||||
function Invoke-LxsCmdInstall {
|
||||
param([string]$App, [string[]]$Arguments = @())
|
||||
switch ($App) {
|
||||
'dev' { return (Invoke-LxsScript 'apps\dev-pack.ps1' $Arguments) }
|
||||
'utilities' { return (Invoke-LxsScript 'apps\utilities.ps1' $Arguments) }
|
||||
'browsers' { return (Invoke-LxsScript 'apps\browsers-media.ps1' $Arguments) }
|
||||
'containers' { return (Invoke-LxsScript 'apps\containers.ps1' $Arguments) }
|
||||
'claude-code' { return (Invoke-LxsScript 'apps\claude-code.ps1' $Arguments) }
|
||||
'' { Write-LxsErr 'Missing app name. Try: lxs help'; return 1 }
|
||||
default { Write-LxsErr "Unknown app: $App. Try: lxs help"; return 1 }
|
||||
}
|
||||
}
|
||||
|
||||
function Invoke-LxsCmdTool {
|
||||
param([string]$Tool, [string[]]$Arguments = @())
|
||||
switch ($Tool) {
|
||||
'system' { return (Invoke-LxsScript 'tools\system-info.ps1' $Arguments) }
|
||||
'network' { return (Invoke-LxsScript 'tools\net-diag.ps1' $Arguments) }
|
||||
'cleanup' { return (Invoke-LxsScript 'tools\cleanup.ps1' $Arguments) }
|
||||
'repair' { return (Invoke-LxsScript 'tools\repair.ps1' $Arguments) }
|
||||
'restore-point' { return (Invoke-LxsScript 'tools\restore-point.ps1' $Arguments) }
|
||||
'update' { return (Invoke-LxsScript 'tools\update-windows.ps1' $Arguments) }
|
||||
'harden' { return (Invoke-LxsScript 'tools\harden.ps1' $Arguments) }
|
||||
'remote-access' { return (Invoke-LxsScript 'tools\remote-access.ps1' $Arguments) }
|
||||
'debloat' { return (Invoke-LxsScript 'tools\debloat.ps1' $Arguments) }
|
||||
'' { Write-LxsErr 'Missing tool name. Try: lxs help'; return 1 }
|
||||
default { Write-LxsErr "Unknown tool: $Tool. Try: lxs help"; return 1 }
|
||||
}
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# setup / update — download the repo zip and mirror it into $LxsInstallDir.
|
||||
# Everything lands under %LOCALAPPDATA%, so no elevation is needed here;
|
||||
# individual tools elevate themselves when they touch the machine.
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
function Invoke-LxsSync {
|
||||
param([ValidateSet('setup', 'update')][string]$Action = 'update')
|
||||
|
||||
$work = Join-Path (Get-LxsTempDir) ("lxs.install.{0}" -f [guid]::NewGuid().ToString('N').Substring(0, 8))
|
||||
try {
|
||||
New-Item -ItemType Directory -Path $work -Force | Out-Null
|
||||
} catch {
|
||||
Write-LxsErr 'Failed to create temp dir'
|
||||
return 1
|
||||
}
|
||||
|
||||
try {
|
||||
$zip = Join-Path $work 'lxs.zip'
|
||||
Write-LxsInfo "Fetching $LxsZipUrl..."
|
||||
try {
|
||||
$progressBackup = $ProgressPreference
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
Invoke-WebRequest -Uri $LxsZipUrl -OutFile $zip -UseBasicParsing `
|
||||
-Headers @{ 'Cache-Control' = 'no-cache' } -ErrorAction Stop
|
||||
$ProgressPreference = $progressBackup
|
||||
} catch {
|
||||
Write-LxsErr "Download failed: $($_.Exception.Message)"
|
||||
return 1
|
||||
}
|
||||
|
||||
$extracted = Join-Path $work 'extracted'
|
||||
try {
|
||||
Expand-Archive -Path $zip -DestinationPath $extracted -Force -ErrorAction Stop
|
||||
} catch {
|
||||
Write-LxsErr "Extraction failed: $($_.Exception.Message)"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Gitea wraps the tree in a single <repo>/ directory: strip it.
|
||||
$root = $extracted
|
||||
$entries = @(Get-ChildItem -Path $extracted -Force)
|
||||
if ($entries.Count -eq 1 -and $entries[0].PSIsContainer) { $root = $entries[0].FullName }
|
||||
|
||||
if (-not (Test-Path (Join-Path $root "$LxsPlatformDir\lxs.ps1")) -or
|
||||
-not (Test-Path (Join-Path $root 'VERSION'))) {
|
||||
Write-LxsErr "Archive is missing $LxsPlatformDir\lxs.ps1 or VERSION"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Replace the payload directories wholesale (so files deleted upstream
|
||||
# really disappear) but keep bin\ and cache\, so the shim on PATH and
|
||||
# the version cache survive an update. The old tree is moved aside
|
||||
# rather than deleted, and put back if the copy fails.
|
||||
if (-not (Test-Path $LxsInstallDir)) { New-Item -ItemType Directory -Path $LxsInstallDir -Force | Out-Null }
|
||||
$backup = Join-Path $work 'previous'
|
||||
New-Item -ItemType Directory -Path $backup -Force | Out-Null
|
||||
foreach ($dir in @('linux', 'windows')) {
|
||||
$dest = Join-Path $LxsInstallDir $dir
|
||||
if (Test-Path $dest) { Move-Item -Path $dest -Destination (Join-Path $backup $dir) -Force -ErrorAction SilentlyContinue }
|
||||
}
|
||||
try {
|
||||
Copy-Item -Path (Join-Path $root '*') -Destination $LxsInstallDir -Recurse -Force -ErrorAction Stop
|
||||
} catch {
|
||||
Write-LxsErr "Copy failed: $($_.Exception.Message)"
|
||||
Write-LxsInfo 'Restoring the previous install...'
|
||||
foreach ($dir in @('linux', 'windows')) {
|
||||
$saved = Join-Path $backup $dir
|
||||
if (Test-Path $saved) {
|
||||
$dest = Join-Path $LxsInstallDir $dir
|
||||
if (Test-Path $dest) { Remove-Item $dest -Recurse -Force -ErrorAction SilentlyContinue }
|
||||
Move-Item -Path $saved -Destination $dest -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
# Command shim on PATH. -ExecutionPolicy Bypass so a restricted policy
|
||||
# (the default on desktop SKUs) does not block the installed scripts.
|
||||
if (-not (Test-Path $LxsBinDir)) { New-Item -ItemType Directory -Path $LxsBinDir -Force | Out-Null }
|
||||
$shim = @"
|
||||
@echo off
|
||||
powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0..\$LxsPlatformDir\lxs.ps1" %*
|
||||
exit /b %ERRORLEVEL%
|
||||
"@
|
||||
Set-Content -Path $LxsShimPath -Value $shim -Encoding ASCII -Force
|
||||
|
||||
try {
|
||||
if (Add-LxsUserPath -Directory $LxsBinDir) {
|
||||
Write-LxsOk "Added $LxsBinDir to your user PATH (open a new terminal to use ``lxs``)"
|
||||
}
|
||||
} catch {
|
||||
# A blocked registry write must not fail an otherwise good install.
|
||||
Write-LxsWarn "Could not update your user PATH: $($_.Exception.Message)"
|
||||
Write-Host "$($script:Gray) Run lxs directly: $LxsShimPath$($script:NC)"
|
||||
}
|
||||
|
||||
Remove-Item $LxsVersionCache -Force -ErrorAction SilentlyContinue
|
||||
|
||||
$newVersion = (Get-Content (Join-Path $LxsInstallDir 'VERSION') -TotalCount 1 -ErrorAction SilentlyContinue)
|
||||
if ($newVersion) { $newVersion = $newVersion.Trim() }
|
||||
Write-LxsOk "lxs $newVersion installed in $LxsInstallDir"
|
||||
Write-LxsOk "Command: $LxsShimPath"
|
||||
return 0
|
||||
} finally {
|
||||
Remove-Item $work -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# Interactive menu
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
function Invoke-LxsMainMenu {
|
||||
if (-not (Assert-LxsWindows)) { exit 1 }
|
||||
Test-LxsRemoteVersion
|
||||
|
||||
while ($true) {
|
||||
Show-LxsHeader
|
||||
Show-LxsBoxMid 'SELECT'
|
||||
Write-Host ''
|
||||
Show-LxsMenuItem '01' 'APPLICATIONS' 'deploy stacks'
|
||||
Show-LxsMenuItem '02' 'TOOLS' 'windows toolbox'
|
||||
Show-LxsMenuItem 'UU' 'FETCH_UPDATE' 'sync remote'
|
||||
Show-LxsMenuItem '00' 'JACK_OUT' 'exit shell' -Exit
|
||||
Write-Host ''
|
||||
Show-LxsBoxBottom
|
||||
Write-Host ''
|
||||
$choice = Read-LxsChoice
|
||||
|
||||
switch -Regex ($choice) {
|
||||
'^0?1$' { Invoke-LxsScript 'apps\index.ps1' | Out-Null; continue }
|
||||
'^0?2$' { Invoke-LxsScript 'tools\index.ps1' | Out-Null; continue }
|
||||
'^[uU]{1,2}$' {
|
||||
if ((Invoke-LxsSync -Action update) -eq 0) {
|
||||
$reinstalled = Join-Path $LxsInstallDir "$LxsPlatformDir\lxs.ps1"
|
||||
if (Test-Path $reinstalled) {
|
||||
Read-LxsEnter 'Press Enter to reload with the new version...'
|
||||
& $reinstalled
|
||||
exit 0
|
||||
}
|
||||
}
|
||||
Read-LxsEnter
|
||||
continue
|
||||
}
|
||||
'^0?0$' {
|
||||
Clear-Host
|
||||
Show-LxsLogo
|
||||
Write-Host "$($script:Cyan)JACK_OUT$($script:NC) $($script:Gray)// session terminated$($script:NC)"
|
||||
Write-Host ''
|
||||
exit 0
|
||||
}
|
||||
default {
|
||||
Write-LxsErr 'Invalid protocol.'
|
||||
Start-Sleep -Seconds 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# Entrypoint
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
$exitCode = 0
|
||||
switch ($LxsCommand) {
|
||||
'install' { $exitCode = Invoke-LxsCmdInstall -App ([string]($LxsRest | Select-Object -First 1)) -Arguments @($LxsRest | Select-Object -Skip 1) }
|
||||
'tool' { $exitCode = Invoke-LxsCmdTool -Tool ([string]($LxsRest | Select-Object -First 1)) -Arguments @($LxsRest | Select-Object -Skip 1) }
|
||||
'info' { Show-LxsHeader }
|
||||
'update' { $exitCode = Invoke-LxsSync -Action update }
|
||||
'setup' { $exitCode = Invoke-LxsSync -Action setup }
|
||||
'install-self' { $exitCode = Invoke-LxsSync -Action setup }
|
||||
'version' { Invoke-LxsCmdVersion }
|
||||
'-v' { Invoke-LxsCmdVersion }
|
||||
'--version' { Invoke-LxsCmdVersion }
|
||||
'help' { Invoke-LxsCmdHelp }
|
||||
'-h' { Invoke-LxsCmdHelp }
|
||||
'--help' { Invoke-LxsCmdHelp }
|
||||
'' { Invoke-LxsMainMenu }
|
||||
default {
|
||||
Write-LxsErr "Unknown command: $LxsCommand"
|
||||
Invoke-LxsCmdHelp
|
||||
$exitCode = 1
|
||||
}
|
||||
}
|
||||
exit $exitCode
|
||||
Reference in New Issue
Block a user