@hsusulist/luc 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -2
- package/install.ps1 +54 -41
- package/package.json +1 -1
- package/scripts/postpack.js +1 -1
- package/scripts/prepack.js +1 -1
package/README.md
CHANGED
|
@@ -23,9 +23,14 @@ luc --install -c window,ai -d "D:\Tools\LUC" -y
|
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
Available components: `window`, `ai`, `discord`, `lcode`, `vscode`, `source`.
|
|
26
|
-
LCode is optional and is not selected by default.
|
|
27
|
-
|
|
26
|
+
LCode is optional and is not selected by default. Selecting it installs
|
|
27
|
+
`lcode.exe` alongside the interpreter. To install only the editor without the
|
|
28
|
+
LUC command, use `npm install -g @hsusulist/lcode`.
|
|
28
29
|
|
|
29
30
|
The npm package is a small launcher; the runtime is downloaded from the signed
|
|
30
31
|
GitHub release and verified with SHA-256 and Ed25519 (minisign format) before it
|
|
31
32
|
is installed.
|
|
33
|
+
|
|
34
|
+
The editor-only npm package uses the separate, signed `lcode-portable.zip`
|
|
35
|
+
release asset. Generate it with `tools/make_portable.ps1` and attach the ZIP,
|
|
36
|
+
`.sha256`, and `.sha256.minisig` files to each GitHub release.
|
package/install.ps1
CHANGED
|
@@ -10,6 +10,7 @@ param(
|
|
|
10
10
|
[switch]$NoEnvironmentChanges,
|
|
11
11
|
[switch]$Force,
|
|
12
12
|
[switch]$Quiet,
|
|
13
|
+
[switch]$LCodeOnly,
|
|
13
14
|
[switch]$AllowUnsigned,
|
|
14
15
|
[switch]$NoColor
|
|
15
16
|
)
|
|
@@ -20,7 +21,7 @@ Add-Type -AssemblyName System.IO.Compression.FileSystem
|
|
|
20
21
|
|
|
21
22
|
$repo = 'hsusulist/luc'
|
|
22
23
|
$minisignPublicKey = 'RWRPLJnLdrwqwkmhtMPAEfihwSnAC9TmbPc4ghGntXYOSLqKlKGUUx40'
|
|
23
|
-
$defaultInstallPath = Join-Path $env:LOCALAPPDATA 'Programs\LUC'
|
|
24
|
+
$defaultInstallPath = Join-Path $env:LOCALAPPDATA $(if ($LCodeOnly) { 'Programs\LCode' } else { 'Programs\LUC' })
|
|
24
25
|
$optionalComponents = @('window', 'ai', 'discord', 'lcode', 'vscode', 'source')
|
|
25
26
|
$componentInfo = [ordered]@{
|
|
26
27
|
window = @{ Label = 'Window support'; Desc = 'SDL2 graphics, sound and the Pong demo' }
|
|
@@ -464,16 +465,19 @@ function Get-ArchivePlan {
|
|
|
464
465
|
[IO.Compression.ZipArchive]$Zip,
|
|
465
466
|
[string[]]$SelectedComponents,
|
|
466
467
|
[string]$Target,
|
|
467
|
-
[string]$VsCodeTarget
|
|
468
|
+
[string]$VsCodeTarget,
|
|
469
|
+
[switch]$LCodeOnly
|
|
468
470
|
)
|
|
469
471
|
|
|
470
472
|
if ($Zip.Entries.Count -gt $maxEntries) {
|
|
471
473
|
throw "Archive contains too many entries ($($Zip.Entries.Count) > $maxEntries)."
|
|
472
474
|
}
|
|
473
475
|
|
|
474
|
-
$prefixes = @(
|
|
476
|
+
$prefixes = @()
|
|
477
|
+
if ($LCodeOnly) { $prefixes += 'lcode' }
|
|
478
|
+
else { $prefixes += @('core', 'common') }
|
|
475
479
|
foreach ($name in $SelectedComponents) {
|
|
476
|
-
if ($name -ne 'core') { $prefixes += $name }
|
|
480
|
+
if ($name -ne 'core' -and $prefixes -notcontains $name) { $prefixes += $name }
|
|
477
481
|
}
|
|
478
482
|
|
|
479
483
|
$plan = New-Object System.Collections.Generic.List[object]
|
|
@@ -913,7 +917,7 @@ function Add-UserPath {
|
|
|
913
917
|
}
|
|
914
918
|
|
|
915
919
|
function Write-InstallState {
|
|
916
|
-
param([string]$Version, [string]$Path, [string[]]$Selected, [string]$SourceName)
|
|
920
|
+
param([string]$Version, [string]$Path, [string[]]$Selected, [string]$SourceName, [switch]$LCodeOnly)
|
|
917
921
|
$stateDir = Join-Path $env:LOCALAPPDATA 'LUC'
|
|
918
922
|
if (-not (Test-Path -LiteralPath $stateDir -PathType Container)) {
|
|
919
923
|
New-Item -ItemType Directory -Force -Path $stateDir | Out-Null
|
|
@@ -921,22 +925,24 @@ function Write-InstallState {
|
|
|
921
925
|
$state = [ordered]@{
|
|
922
926
|
version = $Version
|
|
923
927
|
installPath = $Path
|
|
924
|
-
components = @('core') + $Selected
|
|
928
|
+
components = if ($LCodeOnly) { @('lcode') } else { @('core') + $Selected }
|
|
925
929
|
source = $SourceName
|
|
926
930
|
installedAt = (Get-Date).ToString('o')
|
|
927
931
|
}
|
|
928
|
-
$
|
|
932
|
+
$stateFile = if ($LCodeOnly) { 'lcode-state.json' } else { 'state.json' }
|
|
933
|
+
$state | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath (Join-Path $stateDir $stateFile) -Encoding UTF8
|
|
929
934
|
}
|
|
930
935
|
|
|
931
936
|
function Write-InstallManifest {
|
|
932
|
-
param([string]$Version, [string]$Path, [string[]]$Selected)
|
|
937
|
+
param([string]$Version, [string]$Path, [string[]]$Selected, [switch]$LCodeOnly)
|
|
933
938
|
$manifest = [ordered]@{
|
|
934
939
|
version = $Version
|
|
935
|
-
components = @('core') + $Selected
|
|
940
|
+
components = if ($LCodeOnly) { @('lcode') } else { @('core') + $Selected }
|
|
936
941
|
installedAt = (Get-Date).ToString('o')
|
|
937
942
|
}
|
|
938
943
|
try {
|
|
939
|
-
$
|
|
944
|
+
$manifestFile = if ($LCodeOnly) { '.lcode-manifest.json' } else { '.luc-manifest.json' }
|
|
945
|
+
$manifest | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath (Join-Path $Path $manifestFile) -Encoding UTF8
|
|
940
946
|
} catch {
|
|
941
947
|
Write-Note "Could not write the install manifest: $($_.Exception.Message)" 'warn'
|
|
942
948
|
}
|
|
@@ -977,7 +983,8 @@ try {
|
|
|
977
983
|
if ($Source -eq 'local' -and -not $ArchivePath) {
|
|
978
984
|
if (-not $script:Interactive) { throw 'A local install needs -ArchivePath pointing at luc-portable.zip.' }
|
|
979
985
|
Enter-AltScreen
|
|
980
|
-
$
|
|
986
|
+
$archiveName = if ($LCodeOnly) { 'lcode-portable.zip' } else { 'luc-portable.zip' }
|
|
987
|
+
$ArchivePath = Show-PathPage -Title 'Portable archive (.zip)' -Default (Join-Path $env:USERPROFILE "Downloads\$archiveName") -ExistingFile
|
|
981
988
|
Exit-AltScreen
|
|
982
989
|
if (-not $ArchivePath) { Write-Note 'Installation cancelled.' 'warn'; exit 2 }
|
|
983
990
|
}
|
|
@@ -1011,11 +1018,12 @@ try {
|
|
|
1011
1018
|
$script:Version = $release.tag_name -replace '^v', ''
|
|
1012
1019
|
|
|
1013
1020
|
$assets = @($release.assets)
|
|
1014
|
-
$
|
|
1015
|
-
$
|
|
1016
|
-
$
|
|
1021
|
+
$archiveName = if ($LCodeOnly) { 'lcode-portable.zip' } else { 'luc-portable.zip' }
|
|
1022
|
+
$zipAsset = $assets | Where-Object { $_.name -eq $archiveName } | Select-Object -First 1
|
|
1023
|
+
$hashAsset = $assets | Where-Object { $_.name -eq "$archiveName.sha256" } | Select-Object -First 1
|
|
1024
|
+
$sigAsset = $assets | Where-Object { $_.name -eq "$archiveName.sha256.minisig" } | Select-Object -First 1
|
|
1017
1025
|
if (-not $zipAsset -or -not $hashAsset) {
|
|
1018
|
-
throw "Release $($release.tag_name) must include
|
|
1026
|
+
throw "Release $($release.tag_name) must include $archiveName and $archiveName.sha256."
|
|
1019
1027
|
}
|
|
1020
1028
|
Assert-ReleaseUrl $zipAsset.browser_download_url $zipAsset.name
|
|
1021
1029
|
Assert-ReleaseUrl $hashAsset.browser_download_url $hashAsset.name
|
|
@@ -1023,7 +1031,7 @@ try {
|
|
|
1023
1031
|
|
|
1024
1032
|
$downloadTemp = Join-Path ([IO.Path]::GetTempPath()) ('luc-install-' + [guid]::NewGuid().ToString('N'))
|
|
1025
1033
|
New-Item -ItemType Directory -Force -Path $downloadTemp | Out-Null
|
|
1026
|
-
$archiveFile = Join-Path $downloadTemp
|
|
1034
|
+
$archiveFile = Join-Path $downloadTemp $archiveName
|
|
1027
1035
|
$checksumFile = "$archiveFile.sha256"
|
|
1028
1036
|
$signatureFile = "$checksumFile.minisig"
|
|
1029
1037
|
Invoke-Download $zipAsset.browser_download_url $archiveFile 'portable archive'
|
|
@@ -1068,13 +1076,13 @@ try {
|
|
|
1068
1076
|
throw 'The downloaded archive version does not match its GitHub release tag.'
|
|
1069
1077
|
}
|
|
1070
1078
|
$script:Version = $archiveVersion
|
|
1071
|
-
if (-not $Quiet) { Write-Note "LUC $($script:Version) verified" 'ok' }
|
|
1079
|
+
if (-not $Quiet) { Write-Note "$(if ($LCodeOnly) { 'LCode' } else { 'LUC' }) $($script:Version) verified" 'ok' }
|
|
1072
1080
|
|
|
1073
1081
|
$licenseText = Read-ZipEntryText $zip 'LICENCE'
|
|
1074
1082
|
if (-not $licenseText) { $licenseText = 'LUC is free software released under the Apache License 2.0.' }
|
|
1075
1083
|
|
|
1076
|
-
$selected = @()
|
|
1077
|
-
if ($Components) {
|
|
1084
|
+
$selected = if ($LCodeOnly) { @('lcode') } else { @() }
|
|
1085
|
+
if (-not $LCodeOnly -and $Components) {
|
|
1078
1086
|
foreach ($item in $Components) {
|
|
1079
1087
|
foreach ($name in ($item -split '[,\s]+')) {
|
|
1080
1088
|
if ([string]::IsNullOrWhiteSpace($name)) { continue }
|
|
@@ -1086,7 +1094,7 @@ try {
|
|
|
1086
1094
|
}
|
|
1087
1095
|
}
|
|
1088
1096
|
|
|
1089
|
-
if ($script:Interactive -and -not $Components) {
|
|
1097
|
+
if (-not $LCodeOnly -and $script:Interactive -and -not $Components) {
|
|
1090
1098
|
Enter-AltScreen
|
|
1091
1099
|
$picked = Show-ComponentPage -Preselected $selected -LicenseText $licenseText
|
|
1092
1100
|
Exit-AltScreen
|
|
@@ -1108,9 +1116,10 @@ try {
|
|
|
1108
1116
|
}
|
|
1109
1117
|
|
|
1110
1118
|
$vsCodeTarget = Join-Path $env:USERPROFILE '.vscode\extensions\hsusulist.luc'
|
|
1111
|
-
$
|
|
1119
|
+
$binaryName = if ($LCodeOnly) { 'lcode.exe' } else { 'luc.exe' }
|
|
1120
|
+
$upgrade = Test-Path -LiteralPath (Join-Path $InstallPath $binaryName) -PathType Leaf
|
|
1112
1121
|
if ($upgrade -and -not $Force -and -not $Yes -and -not $script:Interactive) {
|
|
1113
|
-
throw "
|
|
1122
|
+
throw "$binaryName is already installed in '$InstallPath'. Pass -Force to replace it."
|
|
1114
1123
|
}
|
|
1115
1124
|
|
|
1116
1125
|
if ($script:Interactive) {
|
|
@@ -1135,9 +1144,9 @@ try {
|
|
|
1135
1144
|
}
|
|
1136
1145
|
|
|
1137
1146
|
$script:StagingRoot = Join-Path (Split-Path -Parent $InstallPath) ('.luc-staging-' + [guid]::NewGuid().ToString('N'))
|
|
1138
|
-
$archivePlan = Get-ArchivePlan -Zip $zip -SelectedComponents $selected -Target $InstallPath -VsCodeTarget $vsCodeTarget
|
|
1139
|
-
if (-not ($archivePlan.Items | Where-Object { $_.Relative -eq
|
|
1140
|
-
throw
|
|
1147
|
+
$archivePlan = Get-ArchivePlan -Zip $zip -SelectedComponents $selected -Target $InstallPath -VsCodeTarget $vsCodeTarget -LCodeOnly:$LCodeOnly
|
|
1148
|
+
if (-not ($archivePlan.Items | Where-Object { $_.Relative -eq $binaryName -and $_.Destination -eq (Join-Path $InstallPath $binaryName) })) {
|
|
1149
|
+
throw "Installation archive did not produce $binaryName."
|
|
1141
1150
|
}
|
|
1142
1151
|
|
|
1143
1152
|
$roots = @($InstallPath)
|
|
@@ -1159,31 +1168,33 @@ try {
|
|
|
1159
1168
|
Install-ArchivePlan $archivePlan.Items
|
|
1160
1169
|
Write-StepDone 'Files installed'
|
|
1161
1170
|
|
|
1162
|
-
if (-not (Test-Path -LiteralPath (Join-Path $InstallPath
|
|
1163
|
-
throw
|
|
1171
|
+
if (-not (Test-Path -LiteralPath (Join-Path $InstallPath $binaryName) -PathType Leaf)) {
|
|
1172
|
+
throw "Installation finished without $binaryName. The previous version was restored."
|
|
1164
1173
|
}
|
|
1165
1174
|
|
|
1166
|
-
Write-InstallManifest $script:Version $InstallPath $selected
|
|
1167
|
-
Write-InstallState $script:Version $InstallPath $selected $Source
|
|
1175
|
+
Write-InstallManifest $script:Version $InstallPath $selected -LCodeOnly:$LCodeOnly
|
|
1176
|
+
Write-InstallState $script:Version $InstallPath $selected $Source -LCodeOnly:$LCodeOnly
|
|
1168
1177
|
|
|
1169
1178
|
# Keep a copy of this script next to luc.exe so that "luc --install" works
|
|
1170
1179
|
# even when the archive was built before install.ps1 was bundled in it.
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1180
|
+
if (-not $LCodeOnly) {
|
|
1181
|
+
try {
|
|
1182
|
+
$selfScript = $PSCommandPath
|
|
1183
|
+
if (-not $selfScript) { $selfScript = $MyInvocation.MyCommand.Path }
|
|
1184
|
+
$targetScript = Join-Path $InstallPath 'install.ps1'
|
|
1185
|
+
if ($selfScript -and (Test-Path -LiteralPath $selfScript -PathType Leaf) -and
|
|
1186
|
+
-not [string]::Equals($selfScript, $targetScript, [StringComparison]::OrdinalIgnoreCase)) {
|
|
1187
|
+
Copy-Item -LiteralPath $selfScript -Destination $targetScript -Force
|
|
1188
|
+
}
|
|
1189
|
+
} catch {
|
|
1190
|
+
Write-Note "Could not copy install.ps1 next to luc.exe: $($_.Exception.Message)" 'warn'
|
|
1178
1191
|
}
|
|
1179
|
-
} catch {
|
|
1180
|
-
Write-Note "Could not copy install.ps1 next to luc.exe: $($_.Exception.Message)" 'warn'
|
|
1181
1192
|
}
|
|
1182
1193
|
|
|
1183
1194
|
Remove-StaleBackups $InstallPath
|
|
1184
1195
|
if ($selected -contains 'vscode') { Remove-StaleBackups $vsCodeTarget }
|
|
1185
1196
|
|
|
1186
|
-
if (-not $NoEnvironmentChanges) {
|
|
1197
|
+
if (-not $NoEnvironmentChanges -and -not $LCodeOnly) {
|
|
1187
1198
|
[Environment]::SetEnvironmentVariable('LUC_PATH', (Join-Path $InstallPath 'luc_modules'), 'User')
|
|
1188
1199
|
if (-not $NoPath) {
|
|
1189
1200
|
$addPath = $true
|
|
@@ -1197,8 +1208,10 @@ try {
|
|
|
1197
1208
|
}
|
|
1198
1209
|
|
|
1199
1210
|
Write-Host ''
|
|
1200
|
-
|
|
1201
|
-
Write-Host
|
|
1211
|
+
$productName = if ($LCodeOnly) { 'LCode' } else { 'LUC' }
|
|
1212
|
+
Write-Host "$productName $($script:Version) installed to $InstallPath" -ForegroundColor Green
|
|
1213
|
+
if ($LCodeOnly) { Write-Host 'Open a new terminal, then run: lcode .' }
|
|
1214
|
+
else { Write-Host 'Open a new terminal, then run: luc --help' }
|
|
1202
1215
|
exit 0
|
|
1203
1216
|
} catch {
|
|
1204
1217
|
if ($script:InAltScreen) { Exit-AltScreen }
|
package/package.json
CHANGED
package/scripts/postpack.js
CHANGED
package/scripts/prepack.js
CHANGED