From 51c9734d2ae28fa4f86f4638db39ba701d079cea Mon Sep 17 00:00:00 2001 From: Stef Tervelde Date: Sat, 19 Apr 2025 09:34:06 +0200 Subject: [PATCH] Refined Command Line Structure --- app/build.gradle.kts | 2 +- app/src/processing/app/Processing.kt | 45 +++++++++------- .../app/tools/InstallCommander.java | 53 +++++++++++-------- gradle/libs.versions.toml | 1 + 4 files changed, 60 insertions(+), 41 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f02a511cc..f3da7263f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -123,7 +123,7 @@ dependencies { testImplementation(libs.junitJupiter) testImplementation(libs.junitJupiterParams) - implementation("com.github.ajalt.clikt:clikt:5.0.2") + implementation(libs.clikt) } tasks.test { diff --git a/app/src/processing/app/Processing.kt b/app/src/processing/app/Processing.kt index 82f89572d..498d63b21 100644 --- a/app/src/processing/app/Processing.kt +++ b/app/src/processing/app/Processing.kt @@ -4,45 +4,49 @@ import com.github.ajalt.clikt.command.SuspendingCliktCommand import com.github.ajalt.clikt.command.main import com.github.ajalt.clikt.core.Context import com.github.ajalt.clikt.core.subcommands +import com.github.ajalt.clikt.parameters.arguments.argument +import com.github.ajalt.clikt.parameters.arguments.multiple import com.github.ajalt.clikt.parameters.options.flag import com.github.ajalt.clikt.parameters.options.option import processing.app.ui.Start -// TODO: Allow Start to run on no args -// TODO: Modify InstallCommander to use the new structure -// TODO: Move dependency to gradle toml -// TODO: Add the options/arguments for Base arguments -class Processing(val args: Array): SuspendingCliktCommand(name = "Processing"){ +class Processing: SuspendingCliktCommand("processing"){ + val sketches by argument().multiple(default = emptyList()) + + override fun help(context: Context) = "Start the Processing IDE" + override val invokeWithoutSubcommand = true override suspend fun run() { - if(currentContext.invokedSubcommand == null){ - Start.main(args) + val subcommand = currentContext.invokedSubcommand + if (subcommand == null) { + Start.main(sketches.toTypedArray()) } } } -suspend fun main(args: Array) = Processing(args) - .subcommands( - LSP(args), - LegacyCLI(args) - ) - .main(args) +suspend fun main(args: Array){ + Processing() + .subcommands( + LSP(), + LegacyCLI(args) + ) + .main(args) +} - -class LSP(val args: Array): SuspendingCliktCommand("lsp"){ +class LSP: SuspendingCliktCommand("lsp"){ override fun help(context: Context) = "Start the Processing Language Server" override suspend fun run(){ try { // Indirect invocation since app does not depend on java mode Class.forName("processing.mode.java.lsp.PdeLanguageServer") .getMethod("main", Array::class.java) - .invoke(null, *arrayOf(args)) + .invoke(null, *arrayOf(emptyList())) } catch (e: Exception) { throw InternalError("Failed to invoke main method", e) } } } -class LegacyCLI(val args: Array): SuspendingCliktCommand(name = "cli"){ +class LegacyCLI(val args: Array): SuspendingCliktCommand( "cli"){ override fun help(context: Context) = "Legacy processing-java command line interface" val help by option("--help").flag() @@ -57,12 +61,15 @@ class LegacyCLI(val args: Array): SuspendingCliktCommand(name = "cli"){ val variant: String? by option("--variant") override suspend fun run(){ - val cliArgs = args.filter { it != "cli" }.toTypedArray() + val cliArgs = args.filter { it != "cli" } try { + if(build){ + System.setProperty("java.awt.headless", "true") + } // Indirect invocation since app does not depend on java mode Class.forName("processing.mode.java.Commander") .getMethod("main", Array::class.java) - .invoke(null, *arrayOf(cliArgs)) + .invoke(null, *arrayOf(cliArgs.toTypedArray())) } catch (e: Exception) { throw InternalError("Failed to invoke main method", e) } diff --git a/app/src/processing/app/tools/InstallCommander.java b/app/src/processing/app/tools/InstallCommander.java index cd136c362..33eabc6f6 100644 --- a/app/src/processing/app/tools/InstallCommander.java +++ b/app/src/processing/app/tools/InstallCommander.java @@ -86,30 +86,41 @@ public class InstallCommander implements Tool { PrintWriter writer = PApplet.createWriter(file); writer.print("#!/bin/sh\n\n"); - writer.print("# Prevents processing-java from stealing focus, see:\n" + - "# https://github.com/processing/processing/issues/3996.\n" + - "OPTION_FOR_HEADLESS_RUN=\"\"\n" + - "for ARG in \"$@\"\n" + - "do\n" + - " if [ \"$ARG\" = \"--build\" ]; then\n" + - " OPTION_FOR_HEADLESS_RUN=\"-Djava.awt.headless=true\"\n" + - " fi\n" + - "done\n\n"); + var resourcesDir = System.getProperty("compose.application.resources.dir"); + if(resourcesDir != null) { + // Gradle based distributable + var appBinary = (resourcesDir + .split("\\.app")[0] + ".app/Contents/MacOS/Processing") + .replaceAll(" ", "\\\\ "); + writer.print(appBinary + " cli $@"); - String javaRoot = Platform.getContentFile(".").getCanonicalPath(); + } else { + // Ant based distributable + writer.print("# Prevents processing-java from stealing focus, see:\n" + + "# https://github.com/processing/processing/issues/3996.\n" + + "OPTION_FOR_HEADLESS_RUN=\"\"\n" + + "for ARG in \"$@\"\n" + + "do\n" + + " if [ \"$ARG\" = \"--build\" ]; then\n" + + " OPTION_FOR_HEADLESS_RUN=\"-Djava.awt.headless=true\"\n" + + " fi\n" + + "done\n\n"); - StringList jarList = new StringList(); - addJarList(jarList, new File(javaRoot)); - addJarList(jarList, new File(javaRoot, "core/library")); - addJarList(jarList, new File(javaRoot, "modes/java/mode")); - String classPath = jarList.join(":").replaceAll(javaRoot + "\\/?", ""); + String javaRoot = Platform.getContentFile(".").getCanonicalPath(); - writer.println("cd \"" + javaRoot + "\" && " + - Platform.getJavaPath().replaceAll(" ", "\\\\ ") + - " -Djna.nosys=true" + - " $OPTION_FOR_HEADLESS_RUN" + - " -cp \"" + classPath + "\"" + - " processing.mode.java.Commander \"$@\""); + StringList jarList = new StringList(); + addJarList(jarList, new File(javaRoot)); + addJarList(jarList, new File(javaRoot, "core/library")); + addJarList(jarList, new File(javaRoot, "modes/java/mode")); + String classPath = jarList.join(":").replaceAll(javaRoot + "\\/?", ""); + + writer.println("cd \"" + javaRoot + "\" && " + + Platform.getJavaPath().replaceAll(" ", "\\\\ ") + + " -Djna.nosys=true" + + " $OPTION_FOR_HEADLESS_RUN" + + " -cp \"" + classPath + "\"" + + " processing.mode.java.Commander \"$@\""); + } writer.flush(); writer.close(); file.setExecutable(true); diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a9fe0b6e5..70f93aaff 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -27,6 +27,7 @@ lsp4j = { module = "org.eclipse.lsp4j:org.eclipse.lsp4j", version = "0.22.0" } jsoup = { module = "org.jsoup:jsoup", version = "1.17.2" } markdown = { module = "com.mikepenz:multiplatform-markdown-renderer-m2", version = "0.31.0" } markdownJVM = { module = "com.mikepenz:multiplatform-markdown-renderer-jvm", version = "0.31.0" } +clikt = { module = "com.github.ajalt.clikt:clikt", version = "5.0.2" } [plugins] jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-plugin" }