Skip to content

Commit 69c8634

Browse files
committed
Prepare pdex for Windows
1 parent 23b6807 commit 69c8634

File tree

3 files changed

+164
-15
lines changed

3 files changed

+164
-15
lines changed

p5js/library/install.ps1

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#!/usr/bin/env pwsh
2+
3+
# Stop executing script on any error
4+
$ErrorActionPreference = 'Stop'
5+
# Do not show download progress
6+
$ProgressPreference = 'SilentlyContinue'
7+
8+
# Taken from https://stackoverflow.com/a/34559554/6537420
9+
function New-TemporaryDirectory {
10+
$parent = [System.IO.Path]::GetTempPath()
11+
[string] $name = [System.Guid]::NewGuid()
12+
New-Item -ItemType Directory -Path (Join-Path $parent $name)
13+
}
14+
15+
$platform = $null
16+
$architecture = $null
17+
$pnpmName = $null
18+
19+
# PowerShell versions before 6.* were only for Windows OS
20+
if ($PSVersionTable.PSVersion.Major -eq 5) {
21+
$platform = 'win'
22+
}
23+
24+
if ($PSVersionTable.PSVersion.Major -ge 6) {
25+
if ($PSVersionTable.Platform -eq 'Unix') {
26+
switch -Wildcard ($PSVersionTable.OS) {
27+
'Darwin*' {
28+
$platform = 'macos'
29+
}
30+
'Linux*' {
31+
$platform = 'linux'
32+
}
33+
'Ubuntu*' {
34+
$platform = 'linux'
35+
}
36+
}
37+
38+
# PowerShell does not seem to have normal cmdlets for retrieving system information, so we use UNAME(1) for this.
39+
$arch = uname -m
40+
switch -Wildcard ($arch) {
41+
'x86_64' { $architecture = 'x64'; Break }
42+
'amd64' { $architecture = 'x64'; Break }
43+
'armv*' { $architecture = 'arm'; Break }
44+
'arm64' { $architecture = 'arm64'; Break }
45+
'aarch64' { $architecture = 'arm64'; Break }
46+
}
47+
48+
# 'uname -m' in some cases mis-reports 32-bit OS as 64-bit, so double check
49+
if ([System.Environment]::Is64BitOperatingSystem -eq $false) {
50+
if ($architecture -eq 'x64') {
51+
$architecture = 'i686'
52+
}
53+
54+
if ($architecture -eq 'arm64') {
55+
$architecture = 'arm'
56+
}
57+
}
58+
59+
$pnpmName = "pnpm"
60+
}
61+
62+
if ($PSVersionTable.Platform -eq 'Win32NT') {
63+
$platform = 'win'
64+
}
65+
}
66+
67+
if ($platform -eq 'win') {
68+
if ([System.Environment]::Is64BitOperatingSystem -eq $true) {
69+
$architecture = 'x64'
70+
}
71+
72+
if ([System.Environment]::Is64BitOperatingSystem -eq $false) {
73+
$architecture = 'i686'
74+
}
75+
76+
$pnpmName = "pnpm.exe"
77+
}
78+
79+
if ($null -eq $platform) {
80+
Write-Error "Platform could not be determined! Only Windows, Linux and MacOS are supported."
81+
}
82+
83+
switch ($architecture) {
84+
'x64' { ; Break }
85+
'arm64' { ; Break }
86+
Default {
87+
Write-Error "Sorry! pnpm currently only provides pre-built binaries for x86_64/arm64 architectures."
88+
}
89+
}
90+
91+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
92+
93+
$pkgInfo = Invoke-WebRequest "https://registry.npmjs.org/@pnpm/exe" -UseBasicParsing
94+
$versionJson = $pkgInfo.Content | ConvertFrom-Json
95+
$versions = Get-Member -InputObject $versionJson.versions -Type NoteProperty | Select-Object -ExpandProperty Name
96+
$distTags = Get-Member -InputObject $versionJson.'dist-tags' -Type NoteProperty | Select-Object -ExpandProperty Name
97+
98+
$version = $null
99+
$preferredVersion = "latest"
100+
101+
if ($null -ne $env:PNPM_VERSION -and $env:PNPM_VERSION -ne "") {
102+
$preferredVersion = $env:PNPM_VERSION
103+
}
104+
105+
if ($null -eq $version -and $preferredVersion -in $distTags) {
106+
$version = $versionJson.'dist-tags' | Select-Object -ExpandProperty $preferredVersion
107+
}
108+
109+
if ($null -eq $version -and $preferredVersion -in $versions) {
110+
$version = $preferredVersion
111+
}
112+
113+
if ($null -eq $version) {
114+
Write-Host "Current tags:" -ForegroundColor Yellow -NoNewline
115+
$versionJson.'dist-tags' | Format-List
116+
117+
Write-Host "Versions:" -ForegroundColor Yellow -NoNewline
118+
$versionJson.versions | Get-Member -Type NoteProperty | Format-Wide -Property Name -AutoSize
119+
120+
Write-Error "Sorry! pnpm '$preferredVersion' version could not be found. Use one of the tags or published versions from the provided list"
121+
}
122+
123+
Write-Host "Downloading pnpm from GitHub...`n" -ForegroundColor Green
124+
125+
$tempFileFolder = New-TemporaryDirectory
126+
$tempFile = (Join-Path $tempFileFolder.FullName $pnpmName)
127+
$archiveUrl="https://github.com/pnpm/pnpm/releases/download/v$version/pnpm-$platform-$architecture"
128+
if ($platform -eq 'win') {
129+
$archiveUrl="$archiveUrl.exe"
130+
}
131+
Invoke-WebRequest $archiveUrl -OutFile $tempFile -UseBasicParsing
132+
133+
Write-Host "Running setup...`n" -ForegroundColor Green
134+
135+
if ($platform -ne 'win') {
136+
chmod +x $tempFile
137+
}
138+
139+
Start-Process -FilePath $tempFile -ArgumentList "setup" -NoNewWindow -Wait -ErrorAction Continue
140+
141+
Remove-Item $tempFile
142+
Remove-Item $tempFileFolder -Recurse

p5js/src/main/kotlin/p5jsEditor.kt

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ import javax.swing.JMenu
4343
class p5jsEditor(base: Base, path: String?, state: EditorState?, mode: Mode?): Editor(base, path, state, mode) {
4444

4545
val scope = CoroutineScope(Dispatchers.Default)
46-
val SHELL = System.getenv("SHELL")
46+
val isWindows = System.getProperty("os.name").lowercase().contains("windows")
47+
val shell = System.getenv("SHELL")
4748

4849
init {
4950
scope.launch {
@@ -88,21 +89,26 @@ class p5jsEditor(base: Base, path: String?, state: EditorState?, mode: Mode?): E
8889
statusNotice("Looking for pnpm…")
8990
try {
9091
// TODO: Only an interactive shell allows me access to pnpm
91-
runCommand(SHELL, listOf("-ci", "pnpm -v"))
92+
runCommand("pnpm -v")
9293
}
9394
catch (e: Exception) {
9495
statusNotice("pnpm not found. Installing pnpm…")
95-
runCommand("chmod", listOf("u+x", "${mode?.folder}/install.sh"))
96-
runCommand(SHELL, listOf("-ci", "${mode?.folder}/install.sh"))
96+
if (isWindows) {
97+
runCommand("powershell -command \"Invoke-WebRequest https://get.pnpm.io/install.ps1 -UseBasicParsing | Invoke-Expression\"")
98+
}
99+
else {
100+
runCommand("chmod u+x ${mode?.folder}/install.sh")
101+
runCommand("${mode?.folder}/install.sh")
102+
}
97103

98104
statusNotice("Installing Node via pnpm…")
99-
runCommand(SHELL, listOf("-ci", "pnpm env use --global lts"), onFinished = {
105+
runCommand("pnpm env use --global lts", onFinished = {
100106
statusNotice("Installing Node dependencies…")
101107
})
102108
}
103109

104110
// --dangerously-allow-all-builds allows electron in particular to install properly
105-
runCommand(SHELL, listOf("-ci", "pnpm install --dangerously-allow-all-builds"), onFinished = {
111+
runCommand("pnpm install --dangerously-allow-all-builds", onFinished = {
106112
statusNotice("All done! Enjoy p5.js mode.")
107113
})
108114
}
@@ -192,7 +198,7 @@ class p5jsEditor(base: Base, path: String?, state: EditorState?, mode: Mode?): E
192198
Button(onClick = {
193199
if (packageToInstall.isNotBlank()) {
194200
// TODO Better error handling
195-
runCommand(SHELL, listOf("-ci", "pnpm add $packageToInstall --dangerously-allow-all-builds"))
201+
runCommand("pnpm add $packageToInstall --dangerously-allow-all-builds")
196202
packageToInstall = ""
197203
}
198204
}) {
@@ -220,16 +226,17 @@ class p5jsEditor(base: Base, path: String?, state: EditorState?, mode: Mode?): E
220226

221227
// TODO: state is maintained => turn into class
222228
val processes = mutableListOf<Process>()
223-
fun runCommand(type: String, actions: List<String>, directory: File = sketch.folder, onFinished: () -> Unit = {}) {
229+
fun runCommand(action: String, directory: File = sketch.folder, onFinished: () -> Unit = {}) {
224230
// Wait for previous processes to finish
225231
processes.forEach { it.waitFor() }
226232

227233
val processBuilder = ProcessBuilder()
234+
228235
// Set the command based on the operating system
229-
val command = if (System.getProperty("os.name").lowercase().contains("windows")) {
230-
listOf("cmd", "/c", type, *actions.toTypedArray())
236+
val command = if (isWindows) {
237+
listOf("cmd", "/c", action)
231238
} else {
232-
listOf(type, *actions.toTypedArray())
239+
listOf(shell, "-ci", action)
233240
}
234241

235242
processBuilder.command(command)
@@ -246,7 +253,7 @@ class p5jsEditor(base: Base, path: String?, state: EditorState?, mode: Mode?): E
246253
while (reader.readLine().also { line = it } != null) {
247254
// TODO: so much refactoring!
248255
// Only check for errors when running the sketch
249-
if (actions[1].startsWith("npx") && line.startsWith("error")) {
256+
if (action.startsWith("npx") && line.startsWith("error")) {
250257
// TODO: more robust data exchange, double-check with @Stef
251258
// TODO: `statusError` does not do anything with column of a SketchException
252259
val ( msgType, msgText, msgFile, msgLine, msgCol ) = line.split("|")
@@ -262,10 +269,10 @@ class p5jsEditor(base: Base, path: String?, state: EditorState?, mode: Mode?): E
262269
processes.remove(process)
263270
onFinished()
264271
if (exitCode != 0) {
265-
throw RuntimeException("$type ${actions.joinToString(" ")} failed with exit code $exitCode.")
272+
throw RuntimeException("$action failed with exit code $exitCode.")
266273
}
267274
} catch (e: Exception) {
268-
throw RuntimeException("Failed to run $type ${actions.joinToString(" ")}.", e)
275+
throw RuntimeException("Failed to run $action.", e)
269276
}
270277
}
271278
}

p5js/src/main/kotlin/p5jsEditorToolbar.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class p5jsEditorToolbar(editor: p5jsEditor?) : EditorToolbar(editor) {
1414

1515
runButton.setSelected(true)
1616
editor.statusNotice("Starting up sketch…")
17-
editor.runCommand(editor.SHELL, listOf("-ci", "npx electron .")) {
17+
editor.runCommand("npx electron .") {
1818
runButton.setSelected(false)
1919
}
2020
}

0 commit comments

Comments
 (0)