@hsusulist/luc 0.2.5 → 0.3.1
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 +34 -14
- package/bin/luc.js +295 -5
- package/install.ps1 +222 -9
- package/package.json +4 -5
- package/scripts/build-linux.js +34 -0
- package/scripts/postinstall.js +8 -2
- package/scripts/postpack.js +14 -0
- package/scripts/prepack.js +27 -0
- package/src/lcode-linux/lcode.c +582 -0
- package/src/luc.h +303 -0
- package/src/luc_core.c +5527 -0
- package/src/luc_libs.c +5760 -0
- package/src/luc_nums.c +1747 -0
- package/src/luc_trans.c +1735 -0
package/install.ps1
CHANGED
|
@@ -43,6 +43,10 @@ $script:UseAnsi = $false
|
|
|
43
43
|
$script:InAltScreen = $false
|
|
44
44
|
$script:Interactive = $false
|
|
45
45
|
$script:Version = ''
|
|
46
|
+
$script:MaintenanceAction = 'install'
|
|
47
|
+
$script:ExistingComponents = @()
|
|
48
|
+
$script:ExistingInstall = $null
|
|
49
|
+
$script:ScriptDirectory = if ($PSCommandPath) { Split-Path -Parent $PSCommandPath } else { $null }
|
|
46
50
|
|
|
47
51
|
# ---------------------------------------------------------------------------
|
|
48
52
|
# Console helpers
|
|
@@ -253,6 +257,153 @@ function Show-SourcePage {
|
|
|
253
257
|
}
|
|
254
258
|
}
|
|
255
259
|
|
|
260
|
+
function Get-InstalledDetails {
|
|
261
|
+
param([string]$RequestedPath)
|
|
262
|
+
|
|
263
|
+
$state = $null
|
|
264
|
+
$stateFile = Join-Path (Join-Path $env:LOCALAPPDATA 'LUC') 'state.json'
|
|
265
|
+
if (Test-Path -LiteralPath $stateFile -PathType Leaf) {
|
|
266
|
+
try {
|
|
267
|
+
$state = Get-Content -LiteralPath $stateFile -Raw | ConvertFrom-Json -ErrorAction Stop
|
|
268
|
+
} catch {
|
|
269
|
+
Write-Note "Could not read the install state: $($_.Exception.Message)" 'warn'
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
$path = $RequestedPath
|
|
274
|
+
if (-not $path -and $script:ScriptDirectory -and
|
|
275
|
+
(Test-Path -LiteralPath (Join-Path $script:ScriptDirectory 'luc.exe') -PathType Leaf)) {
|
|
276
|
+
$path = $script:ScriptDirectory
|
|
277
|
+
}
|
|
278
|
+
if (-not $path -and $state -and $state.installPath) { $path = [string]$state.installPath }
|
|
279
|
+
if (-not $path) { $path = $defaultInstallPath }
|
|
280
|
+
$path = Resolve-InstallPathValue $path
|
|
281
|
+
if (-not (Test-Path -LiteralPath (Join-Path $path 'luc.exe') -PathType Leaf)) { return $null }
|
|
282
|
+
|
|
283
|
+
if ($state -and $state.installPath) {
|
|
284
|
+
try {
|
|
285
|
+
$statePath = Resolve-InstallPathValue ([string]$state.installPath)
|
|
286
|
+
if (-not [string]::Equals($statePath, $path, [StringComparison]::OrdinalIgnoreCase)) {
|
|
287
|
+
$state = $null
|
|
288
|
+
}
|
|
289
|
+
} catch {
|
|
290
|
+
Write-Note "Could not resolve the install state path: $($_.Exception.Message)" 'warn'
|
|
291
|
+
$state = $null
|
|
292
|
+
}
|
|
293
|
+
} elseif ($RequestedPath) {
|
|
294
|
+
$state = $null
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
$uninstallKey = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\Luc_is1'
|
|
298
|
+
$registeredPath = $null
|
|
299
|
+
$registeredVersion = $null
|
|
300
|
+
try {
|
|
301
|
+
$registration = Get-ItemProperty -LiteralPath $uninstallKey -ErrorAction Stop
|
|
302
|
+
$registeredPath = [string]$registration.InstallLocation
|
|
303
|
+
$registeredVersion = [string]$registration.DisplayVersion
|
|
304
|
+
} catch { }
|
|
305
|
+
$registeredMatches = $false
|
|
306
|
+
if ($registeredPath) {
|
|
307
|
+
try {
|
|
308
|
+
$registeredMatches = [string]::Equals(
|
|
309
|
+
(Resolve-InstallPathValue $registeredPath), $path, [StringComparison]::OrdinalIgnoreCase)
|
|
310
|
+
if (-not $registeredMatches) { $registeredVersion = $null }
|
|
311
|
+
} catch {
|
|
312
|
+
Write-Note "Could not resolve the Windows installer path: $($_.Exception.Message)" 'warn'
|
|
313
|
+
$registeredPath = $null
|
|
314
|
+
$registeredVersion = $null
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
$innoStateMatches = $state -and $state.source -eq 'inno' -and $state.installPath
|
|
318
|
+
|
|
319
|
+
$rawComponents = @()
|
|
320
|
+
if ($state -and $state.components) {
|
|
321
|
+
$rawComponents = @($state.components)
|
|
322
|
+
} else {
|
|
323
|
+
$manifestFile = Join-Path $path '.luc-manifest.json'
|
|
324
|
+
if (Test-Path -LiteralPath $manifestFile -PathType Leaf) {
|
|
325
|
+
try {
|
|
326
|
+
$manifest = Get-Content -LiteralPath $manifestFile -Raw | ConvertFrom-Json -ErrorAction Stop
|
|
327
|
+
if ($manifest.components) { $rawComponents = @($manifest.components) }
|
|
328
|
+
} catch {
|
|
329
|
+
Write-Note "Could not read the install manifest: $($_.Exception.Message)" 'warn'
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if ($rawComponents.Count -eq 0) {
|
|
334
|
+
if ($registeredMatches -or ($innoStateMatches -and -not $registeredPath)) {
|
|
335
|
+
try {
|
|
336
|
+
$saved = (Get-ItemProperty -LiteralPath 'HKCU:\Software\LUC' -Name Components -ErrorAction Stop).Components
|
|
337
|
+
if ($saved) { $rawComponents = @([string]$saved -split '[,\s]+') }
|
|
338
|
+
} catch { }
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
$components = @()
|
|
343
|
+
foreach ($name in $rawComponents) {
|
|
344
|
+
$name = ([string]$name).ToLowerInvariant()
|
|
345
|
+
if ($name -eq 'ailib') { $name = 'ai' }
|
|
346
|
+
if ($optionalComponents -contains $name -and $components -notcontains $name) {
|
|
347
|
+
$components += $name
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
$uninstaller = $null
|
|
352
|
+
if ($innoStateMatches -or $registeredMatches) {
|
|
353
|
+
$uninstaller = Get-ChildItem -LiteralPath $path -Filter 'unins*.exe' -File -ErrorAction SilentlyContinue |
|
|
354
|
+
Select-Object -First 1
|
|
355
|
+
}
|
|
356
|
+
return [pscustomobject]@{
|
|
357
|
+
Path = $path
|
|
358
|
+
Version = if ($state -and $state.version) { [string]$state.version } elseif ($registeredVersion) { $registeredVersion } else { 'unknown' }
|
|
359
|
+
Components = $components
|
|
360
|
+
Uninstaller = $uninstaller
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function Show-MaintenancePage {
|
|
365
|
+
param($Install)
|
|
366
|
+
|
|
367
|
+
$items = @(
|
|
368
|
+
@{ Action = 'libraries'; Label = 'Install libraries'; Desc = 'Add or remove optional components' },
|
|
369
|
+
@{ Action = 'repair'; Label = 'Fix / reinstall'; Desc = 'Reinstall the current components' }
|
|
370
|
+
)
|
|
371
|
+
if ($Install.Uninstaller) {
|
|
372
|
+
$items += @{ Action = 'uninstall'; Label = 'Uninstall'; Desc = 'Remove LUC from this computer' }
|
|
373
|
+
}
|
|
374
|
+
$items += @{ Action = 'cancel'; Label = 'Cancel'; Desc = 'Exit without making changes' }
|
|
375
|
+
$index = 0
|
|
376
|
+
while ($true) {
|
|
377
|
+
Clear-Tui
|
|
378
|
+
Write-TuiHeader 'LUC is installed' 'Choose an action'
|
|
379
|
+
Write-Tui (" Version {0}" -f $Install.Version)
|
|
380
|
+
Write-Tui (" Folder {0}" -f $Install.Path) '90'
|
|
381
|
+
Write-Tui ''
|
|
382
|
+
for ($i = 0; $i -lt $items.Count; $i++) {
|
|
383
|
+
$marker = if ($i -eq $index) { '>' } else { ' ' }
|
|
384
|
+
$code = if ($i -eq $index) { '1;36' } else { '' }
|
|
385
|
+
Write-Tui (" $marker " + $items[$i].Label) $code
|
|
386
|
+
Write-Tui (" " + $items[$i].Desc) '90'
|
|
387
|
+
Write-Tui ''
|
|
388
|
+
}
|
|
389
|
+
Write-TuiFooter 'Up/Down move Enter select q quit'
|
|
390
|
+
$key = [Console]::ReadKey($true)
|
|
391
|
+
switch ($key.Key) {
|
|
392
|
+
'UpArrow' { $index = ($index - 1 + $items.Count) % $items.Count }
|
|
393
|
+
'DownArrow' { $index = ($index + 1) % $items.Count }
|
|
394
|
+
'Enter' { return $items[$index].Action }
|
|
395
|
+
'Escape' { return 'cancel' }
|
|
396
|
+
'Q' { return 'cancel' }
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
function Start-InnoUninstaller {
|
|
402
|
+
param($Install)
|
|
403
|
+
if (-not $Install.Uninstaller) { throw 'The Windows installer uninstaller was not found.' }
|
|
404
|
+
Start-Process -FilePath $Install.Uninstaller.FullName -ArgumentList '/NORESTART' | Out-Null
|
|
405
|
+
}
|
|
406
|
+
|
|
256
407
|
function Show-LicenseEntry {
|
|
257
408
|
param([string]$LicenseText)
|
|
258
409
|
Show-LicensePage $LicenseText
|
|
@@ -846,7 +997,7 @@ public static extern bool MoveFileEx(string existingFileName, string newFileName
|
|
|
846
997
|
}
|
|
847
998
|
|
|
848
999
|
function Install-ArchivePlan {
|
|
849
|
-
param([object[]]$Items)
|
|
1000
|
+
param([object[]]$Items, [string[]]$RemovePaths = @())
|
|
850
1001
|
$journal = New-Object System.Collections.ArrayList
|
|
851
1002
|
try {
|
|
852
1003
|
foreach ($item in $Items) {
|
|
@@ -865,6 +1016,13 @@ function Install-ArchivePlan {
|
|
|
865
1016
|
try { Move-Item -LiteralPath $item.Staging -Destination $destination -Force }
|
|
866
1017
|
catch { throw "Cannot write '$destination': $($_.Exception.Message)" }
|
|
867
1018
|
}
|
|
1019
|
+
foreach ($destination in $RemovePaths) {
|
|
1020
|
+
if (-not (Test-Path -LiteralPath $destination -PathType Leaf)) { continue }
|
|
1021
|
+
$old = "$destination.luc-old-$([guid]::NewGuid().ToString('N').Substring(0, 8))"
|
|
1022
|
+
try { Move-Item -LiteralPath $destination -Destination $old -Force }
|
|
1023
|
+
catch { throw "Cannot remove '$destination'. Close the program using it and try again." }
|
|
1024
|
+
[void]$journal.Add([pscustomobject]@{ Destination = $destination; Old = $old })
|
|
1025
|
+
}
|
|
868
1026
|
} catch {
|
|
869
1027
|
$failure = $_
|
|
870
1028
|
for ($i = $journal.Count - 1; $i -ge 0; $i--) {
|
|
@@ -966,6 +1124,26 @@ $downloadTemp = $null
|
|
|
966
1124
|
$tempChecksumFile = $null
|
|
967
1125
|
$zip = $null
|
|
968
1126
|
try {
|
|
1127
|
+
if ($script:Interactive -and -not $LCodeOnly -and -not $Components) {
|
|
1128
|
+
$script:ExistingInstall = Get-InstalledDetails -RequestedPath $InstallPath
|
|
1129
|
+
if ($script:ExistingInstall) {
|
|
1130
|
+
Enter-AltScreen
|
|
1131
|
+
$script:MaintenanceAction = Show-MaintenancePage $script:ExistingInstall
|
|
1132
|
+
Exit-AltScreen
|
|
1133
|
+
if ($script:MaintenanceAction -eq 'cancel') {
|
|
1134
|
+
Write-Note 'Installation cancelled.' 'warn'
|
|
1135
|
+
exit 2
|
|
1136
|
+
}
|
|
1137
|
+
if ($script:MaintenanceAction -eq 'uninstall') {
|
|
1138
|
+
Start-InnoUninstaller $script:ExistingInstall
|
|
1139
|
+
Write-Note 'LUC uninstaller started.' 'ok'
|
|
1140
|
+
exit 0
|
|
1141
|
+
}
|
|
1142
|
+
$InstallPath = $script:ExistingInstall.Path
|
|
1143
|
+
$script:ExistingComponents = @($script:ExistingInstall.Components)
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
|
|
969
1147
|
$sourceSpecified = $PSBoundParameters.ContainsKey('Source')
|
|
970
1148
|
if (-not $Source) {
|
|
971
1149
|
if ($ArchivePath) { $Source = 'local' } else { $Source = 'github' }
|
|
@@ -1081,7 +1259,13 @@ try {
|
|
|
1081
1259
|
$licenseText = Read-ZipEntryText $zip 'LICENCE'
|
|
1082
1260
|
if (-not $licenseText) { $licenseText = 'LUC is free software released under the Apache License 2.0.' }
|
|
1083
1261
|
|
|
1084
|
-
|
|
1262
|
+
if ($LCodeOnly) {
|
|
1263
|
+
$selected = @('lcode')
|
|
1264
|
+
} elseif ($script:MaintenanceAction -ne 'install') {
|
|
1265
|
+
$selected = @($script:ExistingComponents)
|
|
1266
|
+
} else {
|
|
1267
|
+
$selected = @()
|
|
1268
|
+
}
|
|
1085
1269
|
if (-not $LCodeOnly -and $Components) {
|
|
1086
1270
|
foreach ($item in $Components) {
|
|
1087
1271
|
foreach ($name in ($item -split '[,\s]+')) {
|
|
@@ -1094,7 +1278,8 @@ try {
|
|
|
1094
1278
|
}
|
|
1095
1279
|
}
|
|
1096
1280
|
|
|
1097
|
-
if (-not $LCodeOnly -and $script:Interactive -and -not $Components
|
|
1281
|
+
if (-not $LCodeOnly -and $script:Interactive -and -not $Components -and
|
|
1282
|
+
$script:MaintenanceAction -ne 'repair') {
|
|
1098
1283
|
Enter-AltScreen
|
|
1099
1284
|
$picked = Show-ComponentPage -Preselected $selected -LicenseText $licenseText
|
|
1100
1285
|
Exit-AltScreen
|
|
@@ -1115,6 +1300,14 @@ try {
|
|
|
1115
1300
|
$InstallPath = Resolve-InstallPathValue $InstallPath
|
|
1116
1301
|
}
|
|
1117
1302
|
|
|
1303
|
+
if (-not $script:ExistingInstall -or
|
|
1304
|
+
-not [string]::Equals($script:ExistingInstall.Path, $InstallPath, [StringComparison]::OrdinalIgnoreCase)) {
|
|
1305
|
+
$script:ExistingInstall = Get-InstalledDetails -RequestedPath $InstallPath
|
|
1306
|
+
}
|
|
1307
|
+
if ($script:ExistingInstall) {
|
|
1308
|
+
$script:ExistingComponents = @($script:ExistingInstall.Components)
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1118
1311
|
$vsCodeTarget = Join-Path $env:USERPROFILE '.vscode\extensions\hsusulist.luc'
|
|
1119
1312
|
$binaryName = if ($LCodeOnly) { 'lcode.exe' } else { 'luc.exe' }
|
|
1120
1313
|
$upgrade = Test-Path -LiteralPath (Join-Path $InstallPath $binaryName) -PathType Leaf
|
|
@@ -1140,6 +1333,10 @@ try {
|
|
|
1140
1333
|
Exit-AltScreen
|
|
1141
1334
|
if ($null -eq $picked -or -not $InstallPath) { Write-Note 'Installation cancelled.' 'warn'; exit 2 }
|
|
1142
1335
|
$selected = @($picked)
|
|
1336
|
+
$InstallPath = Resolve-InstallPathValue $InstallPath
|
|
1337
|
+
$script:ExistingInstall = Get-InstalledDetails -RequestedPath $InstallPath
|
|
1338
|
+
$script:ExistingComponents = if ($script:ExistingInstall) { @($script:ExistingInstall.Components) } else { @() }
|
|
1339
|
+
$upgrade = Test-Path -LiteralPath (Join-Path $InstallPath $binaryName) -PathType Leaf
|
|
1143
1340
|
}
|
|
1144
1341
|
}
|
|
1145
1342
|
|
|
@@ -1149,10 +1346,24 @@ try {
|
|
|
1149
1346
|
throw "Installation archive did not produce $binaryName."
|
|
1150
1347
|
}
|
|
1151
1348
|
|
|
1349
|
+
$removePaths = @()
|
|
1350
|
+
if ($upgrade -and -not $LCodeOnly -and $script:ExistingComponents.Count -gt 0) {
|
|
1351
|
+
$previousPlan = Get-ArchivePlan -Zip $zip -SelectedComponents $script:ExistingComponents -Target $InstallPath -VsCodeTarget $vsCodeTarget
|
|
1352
|
+
$newDestinations = @{}
|
|
1353
|
+
foreach ($item in $archivePlan.Items) { $newDestinations[$item.Destination.ToLowerInvariant()] = $true }
|
|
1354
|
+
foreach ($item in $previousPlan.Items) {
|
|
1355
|
+
if (-not $newDestinations.ContainsKey($item.Destination.ToLowerInvariant()) -and
|
|
1356
|
+
(Test-Path -LiteralPath $item.Destination -PathType Leaf)) {
|
|
1357
|
+
$removePaths += $item.Destination
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1152
1362
|
$roots = @($InstallPath)
|
|
1153
|
-
if ($selected -contains 'vscode') { $roots += $vsCodeTarget }
|
|
1363
|
+
if (($selected -contains 'vscode') -or ($script:ExistingComponents -contains 'vscode')) { $roots += $vsCodeTarget }
|
|
1364
|
+
$lockItems = @($archivePlan.Items) + @($removePaths | ForEach-Object { @{ Destination = $_ } })
|
|
1154
1365
|
Write-Step 'Checking for running programs and locked files'
|
|
1155
|
-
Test-InstallLocks -Items $
|
|
1366
|
+
Test-InstallLocks -Items $lockItems -Roots $roots
|
|
1156
1367
|
Write-StepDone 'No running LUC process blocks the install'
|
|
1157
1368
|
|
|
1158
1369
|
Test-DiskSpace $InstallPath $archivePlan.TotalBytes
|
|
@@ -1165,17 +1376,19 @@ try {
|
|
|
1165
1376
|
Write-StepDone "Extracted $($archivePlan.Items.Count) files"
|
|
1166
1377
|
|
|
1167
1378
|
Write-Step 'Installing files'
|
|
1168
|
-
Install-ArchivePlan $archivePlan.Items
|
|
1169
|
-
Write-StepDone
|
|
1379
|
+
Install-ArchivePlan -Items $archivePlan.Items -RemovePaths $removePaths
|
|
1380
|
+
if ($removePaths.Count) { Write-StepDone "Files installed; removed $($removePaths.Count) deselected files" }
|
|
1381
|
+
else { Write-StepDone 'Files installed' }
|
|
1170
1382
|
|
|
1171
1383
|
if (-not (Test-Path -LiteralPath (Join-Path $InstallPath $binaryName) -PathType Leaf)) {
|
|
1172
1384
|
throw "Installation finished without $binaryName. The previous version was restored."
|
|
1173
1385
|
}
|
|
1174
1386
|
|
|
1175
1387
|
Write-InstallManifest $script:Version $InstallPath $selected -LCodeOnly:$LCodeOnly
|
|
1176
|
-
|
|
1388
|
+
$stateSource = if ($script:ExistingInstall -and $script:ExistingInstall.Uninstaller) { 'inno' } else { $Source }
|
|
1389
|
+
Write-InstallState $script:Version $InstallPath $selected $stateSource -LCodeOnly:$LCodeOnly
|
|
1177
1390
|
|
|
1178
|
-
# Keep a copy of this script next to luc.exe so that "luc
|
|
1391
|
+
# Keep a copy of this script next to luc.exe so that "luc install" works
|
|
1179
1392
|
# even when the archive was built before install.ps1 was bundled in it.
|
|
1180
1393
|
if (-not $LCodeOnly) {
|
|
1181
1394
|
try {
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hsusulist/luc",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "LUC language installer and launcher
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "LUC language installer and launcher",
|
|
5
5
|
"bin": {
|
|
6
6
|
"luc": "bin/luc.js"
|
|
7
7
|
},
|
|
8
8
|
"files": [
|
|
9
9
|
"bin",
|
|
10
10
|
"scripts",
|
|
11
|
+
"src",
|
|
11
12
|
"install.ps1",
|
|
12
13
|
"LICENCE",
|
|
13
14
|
"README.md"
|
|
@@ -17,9 +18,7 @@
|
|
|
17
18
|
"postpack": "node scripts/postpack.js",
|
|
18
19
|
"postinstall": "node scripts/postinstall.js"
|
|
19
20
|
},
|
|
20
|
-
"os": [
|
|
21
|
-
"win32"
|
|
22
|
-
],
|
|
21
|
+
"os": ["win32", "linux"],
|
|
23
22
|
"engines": {
|
|
24
23
|
"node": ">=16"
|
|
25
24
|
},
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { spawnSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
function buildLinux(packageDir, name) {
|
|
8
|
+
const sourceDir = path.join(packageDir, 'src');
|
|
9
|
+
const files = ['luc_core.c', 'luc_libs.c', 'luc_trans.c'].map((file) =>
|
|
10
|
+
path.join(sourceDir, file)
|
|
11
|
+
);
|
|
12
|
+
for (const file of files) {
|
|
13
|
+
if (!fs.existsSync(file)) {
|
|
14
|
+
throw new Error('Linux source is missing from this npm package: ' + file);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const outputDir = path.join(packageDir, 'native');
|
|
19
|
+
const output = path.join(outputDir, name);
|
|
20
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
21
|
+
|
|
22
|
+
const compiler = process.env.CC || 'cc';
|
|
23
|
+
const args = ['-O2', '-std=gnu99', '-o', output].concat(files, ['-lm', '-ldl']);
|
|
24
|
+
const result = spawnSync(compiler, args, { stdio: 'inherit' });
|
|
25
|
+
if (result.error) {
|
|
26
|
+
throw new Error('could not start ' + compiler + ' to build LUC: ' + result.error.message);
|
|
27
|
+
}
|
|
28
|
+
if (result.status !== 0) {
|
|
29
|
+
throw new Error(compiler + ' failed to build LUC (exit code ' + result.status + ').');
|
|
30
|
+
}
|
|
31
|
+
return output;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = { buildLinux };
|
package/scripts/postinstall.js
CHANGED
|
@@ -5,6 +5,12 @@ const os = require('os');
|
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const { spawnSync } = require('child_process');
|
|
7
7
|
|
|
8
|
+
if (process.platform === 'linux') {
|
|
9
|
+
const { buildLinux } = require('./build-linux');
|
|
10
|
+
buildLinux(path.join(__dirname, '..'), 'luc');
|
|
11
|
+
process.exit(0);
|
|
12
|
+
}
|
|
13
|
+
|
|
8
14
|
function findBinary() {
|
|
9
15
|
const candidates = [];
|
|
10
16
|
const local = process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local');
|
|
@@ -35,7 +41,7 @@ if (process.platform !== 'win32' || findBinary()) {
|
|
|
35
41
|
|
|
36
42
|
const script = path.join(__dirname, '..', 'install.ps1');
|
|
37
43
|
if (!fs.existsSync(script)) {
|
|
38
|
-
console.warn('luc: install.ps1 is missing; run "luc
|
|
44
|
+
console.warn('luc: install.ps1 is missing; run "luc install" after installing.');
|
|
39
45
|
process.exit(0);
|
|
40
46
|
}
|
|
41
47
|
|
|
@@ -47,6 +53,6 @@ const result = spawnSync(
|
|
|
47
53
|
);
|
|
48
54
|
|
|
49
55
|
if (result.error || result.status !== 0) {
|
|
50
|
-
console.warn('luc: automatic install did not finish. Run "luc
|
|
56
|
+
console.warn('luc: automatic install did not finish. Run "luc install" to open the installer.');
|
|
51
57
|
}
|
|
52
58
|
process.exit(0);
|
package/scripts/postpack.js
CHANGED
|
@@ -9,3 +9,17 @@ for (const name of ['install.ps1', 'LICENCE']) {
|
|
|
9
9
|
} catch (_) {
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
+
|
|
13
|
+
const source = path.join(process.cwd(), 'src');
|
|
14
|
+
const marker = path.join(process.cwd(), '.npm-source-bundle-generated');
|
|
15
|
+
if (fs.existsSync(marker)) {
|
|
16
|
+
fs.rmSync(source, { recursive: true, force: true });
|
|
17
|
+
fs.unlinkSync(marker);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const helper = path.join(process.cwd(), 'scripts', 'build-linux.js');
|
|
21
|
+
const helperMarker = path.join(process.cwd(), '.npm-build-linux-generated');
|
|
22
|
+
if (fs.existsSync(helperMarker)) {
|
|
23
|
+
fs.unlinkSync(helper);
|
|
24
|
+
fs.unlinkSync(helperMarker);
|
|
25
|
+
}
|
package/scripts/prepack.js
CHANGED
|
@@ -17,3 +17,30 @@ function copy(name) {
|
|
|
17
17
|
|
|
18
18
|
copy('install.ps1');
|
|
19
19
|
copy('LICENCE');
|
|
20
|
+
|
|
21
|
+
const source = path.join(root, 'src');
|
|
22
|
+
const target = path.join(here, 'src');
|
|
23
|
+
if (fs.existsSync(target)) {
|
|
24
|
+
throw new Error('refusing to overwrite existing npm/src directory');
|
|
25
|
+
}
|
|
26
|
+
fs.mkdirSync(target);
|
|
27
|
+
for (const name of ['luc_core.c', 'luc_libs.c', 'luc_nums.c', 'luc_trans.c', 'luc.h']) {
|
|
28
|
+
const from = path.join(source, name);
|
|
29
|
+
if (!fs.existsSync(from)) throw new Error('missing release source: ' + from);
|
|
30
|
+
fs.copyFileSync(from, path.join(target, name));
|
|
31
|
+
}
|
|
32
|
+
const linuxEditor = path.join(source, 'lcode-linux', 'lcode.c');
|
|
33
|
+
if (!fs.existsSync(linuxEditor)) throw new Error('missing Linux editor source: ' + linuxEditor);
|
|
34
|
+
fs.mkdirSync(path.join(target, 'lcode-linux'));
|
|
35
|
+
fs.copyFileSync(linuxEditor, path.join(target, 'lcode-linux', 'lcode.c'));
|
|
36
|
+
fs.writeFileSync(path.join(here, '.npm-source-bundle-generated'), 'generated by prepack\n');
|
|
37
|
+
|
|
38
|
+
const helper = path.join(__dirname, 'build-linux.js');
|
|
39
|
+
const packagedHelper = path.join(here, 'scripts', 'build-linux.js');
|
|
40
|
+
if (helper !== packagedHelper) {
|
|
41
|
+
if (fs.existsSync(packagedHelper)) {
|
|
42
|
+
throw new Error('refusing to overwrite existing scripts/build-linux.js');
|
|
43
|
+
}
|
|
44
|
+
fs.copyFileSync(helper, packagedHelper);
|
|
45
|
+
fs.writeFileSync(path.join(here, '.npm-build-linux-generated'), 'generated by prepack\n');
|
|
46
|
+
}
|