@@ -10,7 +10,12 @@ import com.github.ajalt.clikt.parameters.arguments.multiple
1010import com.github.ajalt.clikt.parameters.options.flag
1111import com.github.ajalt.clikt.parameters.options.help
1212import com.github.ajalt.clikt.parameters.options.option
13+ import processing.app.api.Contributions
14+ import processing.app.api.Sketchbook
1315import processing.app.ui.Start
16+ import java.io.File
17+ import java.util.prefs.Preferences
18+ import kotlin.concurrent.thread
1419
1520class Processing : SuspendingCliktCommand (" processing" ){
1621 val version by option(" -v" ," --version" )
@@ -29,6 +34,11 @@ class Processing: SuspendingCliktCommand("processing"){
2934 return
3035 }
3136
37+ thread {
38+ // Update the install locations in preferences
39+ updateInstallLocations()
40+ }
41+
3242 val subcommand = currentContext.invokedSubcommand
3343 if (subcommand == null ) {
3444 Start .main(sketches.toTypedArray())
@@ -40,7 +50,9 @@ suspend fun main(args: Array<String>){
4050 Processing ()
4151 .subcommands(
4252 LSP (),
43- LegacyCLI (args)
53+ LegacyCLI (args),
54+ Contributions (),
55+ Sketchbook ()
4456 )
4557 .main(args)
4658}
@@ -49,6 +61,9 @@ class LSP: SuspendingCliktCommand("lsp"){
4961 override fun help (context : Context ) = " Start the Processing Language Server"
5062 override suspend fun run (){
5163 try {
64+ // run in headless mode
65+ System .setProperty(" java.awt.headless" , " true" )
66+
5267 // Indirect invocation since app does not depend on java mode
5368 Class .forName(" processing.mode.java.lsp.PdeLanguageServer" )
5469 .getMethod(" main" , Array <String >::class .java)
@@ -68,10 +83,9 @@ class LegacyCLI(val args: Array<String>): SuspendingCliktCommand("cli") {
6883
6984 override suspend fun run () {
7085 try {
71- if (arguments.contains(" --build" )) {
72- System .setProperty(" java.awt.headless" , " true" )
73- }
86+ System .setProperty(" java.awt.headless" , " true" )
7487
88+ // Indirect invocation since app does not depend on java mode
7589 Class .forName(" processing.mode.java.Commander" )
7690 .getMethod(" main" , Array <String >::class .java)
7791 .invoke(null , arguments.toTypedArray())
@@ -80,3 +94,49 @@ class LegacyCLI(val args: Array<String>): SuspendingCliktCommand("cli") {
8094 }
8195 }
8296}
97+
98+ fun updateInstallLocations (){
99+ val preferences = Preferences .userRoot().node(" org/processing/app" )
100+ val installLocations = preferences.get(" installLocations" , " " )
101+ .split(" ," )
102+ .dropLastWhile { it.isEmpty() }
103+ .filter { install ->
104+ try {
105+ val (path, version) = install.split(" ^" )
106+ val file = File (path)
107+ if (! file.exists() || file.isDirectory){
108+ return @filter false
109+ }
110+ // call the path to check if it is a valid install location
111+ val process = ProcessBuilder (path, " --version" )
112+ .redirectErrorStream(true )
113+ .start()
114+ val exitCode = process.waitFor()
115+ if (exitCode != 0 ){
116+ return @filter false
117+ }
118+ val output = process.inputStream.bufferedReader().readText()
119+ return @filter output.contains(version)
120+ } catch (e: Exception ){
121+ false
122+ }
123+ }
124+ .toMutableList()
125+ val command = ProcessHandle .current().info().command()
126+ if (command.isEmpty) {
127+ return
128+ }
129+ val installLocation = " ${command.get()} ^${Base .getVersionName()} "
130+
131+
132+ // Check if the installLocation is already in the list
133+ if (installLocations.contains(installLocation)) {
134+ return
135+ }
136+
137+ // Add the installLocation to the list
138+ installLocations.add(installLocation)
139+
140+ // Save the updated list back to preferences
141+ preferences.put(" installLocations" , java.lang.String .join(" ," , installLocations))
142+ }
0 commit comments