@@ -11,6 +11,9 @@ import com.github.ajalt.clikt.parameters.options.flag
1111import com.github.ajalt.clikt.parameters.options.help
1212import com.github.ajalt.clikt.parameters.options.option
1313import processing.app.ui.Start
14+ import java.io.File
15+ import java.util.prefs.Preferences
16+ import kotlin.concurrent.thread
1417
1518class Processing : SuspendingCliktCommand (" processing" ){
1619 val version by option(" -v" ," --version" )
@@ -29,6 +32,11 @@ class Processing: SuspendingCliktCommand("processing"){
2932 return
3033 }
3134
35+ thread {
36+ // Update the install locations in preferences
37+ updateInstallLocations()
38+ }
39+
3240 val subcommand = currentContext.invokedSubcommand
3341 if (subcommand == null ) {
3442 Start .main(sketches.toTypedArray())
@@ -49,10 +57,13 @@ class LSP: SuspendingCliktCommand("lsp"){
4957 override fun help (context : Context ) = " Start the Processing Language Server"
5058 override suspend fun run (){
5159 try {
60+ // run in headless mode
61+ System .setProperty(" java.awt.headless" , " true" )
62+
5263 // Indirect invocation since app does not depend on java mode
5364 Class .forName(" processing.mode.java.lsp.PdeLanguageServer" )
5465 .getMethod(" main" , Array <String >::class .java)
55- .invoke(null , * arrayOf<Any >(emptyList< String >() ))
66+ .invoke(null , arrayOf<String >())
5667 } catch (e: Exception ) {
5768 throw InternalError (" Failed to invoke main method" , e)
5869 }
@@ -76,9 +87,8 @@ class LegacyCLI(val args: Array<String>): SuspendingCliktCommand( "cli"){
7687 override suspend fun run (){
7788 val cliArgs = args.filter { it != " cli" }
7889 try {
79- if (build){
80- System .setProperty(" java.awt.headless" , " true" )
81- }
90+ System .setProperty(" java.awt.headless" , " true" )
91+
8292 // Indirect invocation since app does not depend on java mode
8393 Class .forName(" processing.mode.java.Commander" )
8494 .getMethod(" main" , Array <String >::class .java)
@@ -87,4 +97,50 @@ class LegacyCLI(val args: Array<String>): SuspendingCliktCommand( "cli"){
8797 throw InternalError (" Failed to invoke main method" , e)
8898 }
8999 }
100+ }
101+
102+ fun updateInstallLocations (){
103+ val preferences = Preferences .userRoot().node(" org/processing/app" )
104+ val installLocations = preferences.get(" installLocations" , " " )
105+ .split(" ," )
106+ .dropLastWhile { it.isEmpty() }
107+ .filter { install ->
108+ try {
109+ val (path, version) = install.split(" ^" )
110+ val file = File (path)
111+ if (! file.exists() || file.isDirectory){
112+ return @filter false
113+ }
114+ // call the path to check if it is a valid install location
115+ val process = ProcessBuilder (path, " --version" )
116+ .redirectErrorStream(true )
117+ .start()
118+ val exitCode = process.waitFor()
119+ if (exitCode != 0 ){
120+ return @filter false
121+ }
122+ val output = process.inputStream.bufferedReader().readText()
123+ return @filter output.contains(version)
124+ } catch (e: Exception ){
125+ false
126+ }
127+ }
128+ .toMutableList()
129+ val command = ProcessHandle .current().info().command()
130+ if (command.isEmpty) {
131+ return
132+ }
133+ val installLocation = " ${command.get()} ^${Base .getVersionName()} "
134+
135+
136+ // Check if the installLocation is already in the list
137+ if (installLocations.contains(installLocation)) {
138+ return
139+ }
140+
141+ // Add the installLocation to the list
142+ installLocations.add(installLocation)
143+
144+ // Save the updated list back to preferences
145+ preferences.put(" installLocations" , java.lang.String .join(" ," , installLocations))
90146}
0 commit comments