@@ -34,6 +34,7 @@ import processing.app.ui.EditorToolbar
3434import processing.app.ui.theme.ProcessingTheme
3535import java.io.BufferedReader
3636import java.io.File
37+ import java.io.IOException
3738import java.io.InputStreamReader
3839import java.net.URL
3940import javax.swing.JMenu
@@ -42,6 +43,7 @@ import javax.swing.JMenu
4243class p5jsEditor (base : Base , path : String? , state : EditorState ? , mode : Mode ? ): Editor(base, path, state, mode) {
4344
4445 val scope = CoroutineScope (Dispatchers .Default )
46+
4547 init {
4648 scope.launch {
4749 val folder = sketch.folder
@@ -71,18 +73,33 @@ class p5jsEditor(base: Base, path: String?, state: EditorState?, mode: Mode?): E
7173
7274 <body>
7375 <script src="renderer.js"></script>
74- <script src="./node_modules/p5/lib/p5.min. js"></script>
75- <script src="./node_modules/p5.sound/dist/p5.sound.min. js"></script>
76+ <script src="./node_modules/p5/lib/p5.js"></script>
77+ <script src="./node_modules/p5.sound/dist/p5.sound.js"></script>
7678 <script src="$name .js"></script>
7779 </body>
7880 </html>
7981 """ .trimIndent()
8082 File (" $folder /index.html" ).writeText(indexHtml)
8183
82- // TODO: Install `pnpm` automatically, stand-alone, and use as Node manager
83- runNpmActions(folder, TYPE .npm, listOf (" install" , " -g" , " pnpm" ))
84+ // TODO: refactor into functions
85+ // Check whether `pnpm` is already installed; horrible code—my apologies!
86+ // TODO: Make more robust, cross-platform, etc. Only job for now is to get a PDEX file out that works on MacOS
87+ statusNotice(" Looking for pnpm…" )
88+ try {
89+ // TODO: Only an interactive shell allows me access to pnpm
90+ runCommand(" /bin/bash" , listOf (" -ci" , " pnpm -v" ))
91+ }
92+ catch (e: Exception ) {
93+ statusNotice(" pnpm not found. Installing pnpm…" )
94+ runCommand(" /bin/bash" , listOf (" -ci" , " ${mode?.folder} /install.sh" ))
95+
96+ statusNotice(" Installing Node via pnpm…" )
97+ runCommand(" /bin/bash" , listOf (" -ci" , " pnpm env use --global lts" ))
98+ }
99+
100+ statusNotice(" " )
84101 // --dangerously-allow-all-builds allows electron in particular to install properly
85- runNpmActions(folder, TYPE .pnpm, listOf (" install " , " --dangerously-allow-all-builds" ))
102+ runCommand( " /bin/bash " , listOf (" -ci " , " pnpm install --dangerously-allow-all-builds" ))
86103 }
87104 }
88105
@@ -126,9 +143,9 @@ class p5jsEditor(base: Base, path: String?, state: EditorState?, mode: Mode?): E
126143 processes.forEach { it.destroy() }
127144 }
128145
129-
130146 override fun deactivateRun () {
131147 processes.forEach { it.destroy() }
148+ toolbar.deactivateRun()
132149 }
133150
134151 override fun createFooter (): EditorFooter {
@@ -170,7 +187,7 @@ class p5jsEditor(base: Base, path: String?, state: EditorState?, mode: Mode?): E
170187 Button (onClick = {
171188 if (packageToInstall.isNotBlank()) {
172189 // TODO Better error handling
173- runNpmActions(sketch.folder, TYPE . pnpm, listOf (" add" , packageToInstall, " --dangerously-allow-all-builds" ))
190+ runCommand( " pnpm" , listOf (" add" , packageToInstall, " --dangerously-allow-all-builds" ))
174191 packageToInstall = " "
175192 }
176193 }) {
@@ -192,25 +209,22 @@ class p5jsEditor(base: Base, path: String?, state: EditorState?, mode: Mode?): E
192209 return footer
193210 }
194211
195- enum class TYPE {
196- npm, pnpm, npx
197- }
198-
199212 private fun filenameToCodeIndex (filename : String ) {
200213
201214 }
202215
216+ // TODO: state is maintained => turn into class
203217 val processes = mutableListOf<Process >()
204- fun runNpmActions ( directory : File , type : TYPE , actions : List <String >, onFinished : () -> Unit = {}) {
218+ fun runCommand ( type : String , actions : List <String >, directory : File = sketch.folder , onFinished : () -> Unit = {}) {
205219 // Wait for previous processes to finish
206220 processes.forEach { it.waitFor() }
207221
208222 val processBuilder = ProcessBuilder ()
209223 // Set the command based on the operating system
210224 val command = if (System .getProperty(" os.name" ).lowercase().contains(" windows" )) {
211- listOf (" cmd" , " /c" , type.name , * actions.toTypedArray())
225+ listOf (" cmd" , " /c" , type, * actions.toTypedArray())
212226 } else {
213- listOf (type.name , * actions.toTypedArray())
227+ listOf (type, * actions.toTypedArray())
214228 }
215229
216230 processBuilder.command(command)
@@ -227,7 +241,7 @@ class p5jsEditor(base: Base, path: String?, state: EditorState?, mode: Mode?): E
227241 while (reader.readLine().also { line = it } != null ) {
228242 // TODO: so much refactoring!
229243 // Only check for errors when running the sketch
230- if (type == TYPE . npx && line.startsWith(" error" )) {
244+ if (actions[ 1 ].startsWith( " npx" ) && line.startsWith(" error" )) {
231245 // TODO: more robust data exchange, double-check with @Stef
232246 // TODO: `statusError` does not do anything with column of a SketchException
233247 val ( msgType, msgText, msgFile, msgLine, msgCol ) = line.split(" |" )
0 commit comments