From 864a7bd6acc42efb156442286d56941a85868320 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Fri, 10 Jul 2026 16:43:11 +0300 Subject: [PATCH 1/3] Add standalone Codename One Settings editor --- .../workflows/release-on-maven-central.yml | 35 + .../com/codename1/maven/OpenSettingsMojo.java | 336 ++- .../codename1/maven/OpenSettingsMojoTest.java | 168 ++ maven/update-version.sh | 16 +- scripts/settings/.gitignore | 3 + .../common/codenameone_settings.properties | 15 + scripts/settings/common/icon.png | Bin 0 -> 123269 bytes scripts/settings/common/pom.xml | 139 ++ .../settings/common/src/main/css/theme.css | 622 +++++ .../settings/CodenameOneSettings.java | 2011 +++++++++++++++++ .../extensions/ExtensionCatalogMerger.java | 42 + .../extensions/ExtensionDescriptor.java | 122 + .../extensions/MavenCentralSearch.java | 114 + .../settings/extensions/MavenDependency.java | 43 + .../settings/extensions/PomEditor.java | 137 ++ .../settings/hints/BuildHintCatalog.java | 218 ++ .../settings/hints/BuildHintMetadata.java | 42 + .../settings/hints/BuildHintType.java | 14 + .../settings/project/ProjectBinding.java | 63 + .../codename1/settings/project/ProjectIO.java | 46 + .../settings/project/SettingsProperties.java | 258 +++ .../codename1/settings/extensions/CN1Libs.xml | 933 ++++++++ .../settings/BuildHintCatalogTest.java | 54 + .../settings/ExtensionCatalogMergerTest.java | 49 + .../com/codename1/settings/PomEditorTest.java | 63 + .../codename1/settings/SettingsThemeTest.java | 180 ++ scripts/settings/javase/pom.xml | 194 ++ .../settings/CodenameOneSettingsLauncher.java | 10 + .../settings/CodenameOneSettingsStub.java | 318 +++ .../src/desktop/resources/NativeTheme.res | Bin 0 -> 300158 bytes .../settings/SettingsDesktopIdentityTest.java | 85 + scripts/settings/pom.xml | 192 ++ .../scripts/capture-html-reference.mjs | 222 ++ 33 files changed, 6720 insertions(+), 24 deletions(-) create mode 100644 maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/OpenSettingsMojoTest.java create mode 100644 scripts/settings/.gitignore create mode 100644 scripts/settings/common/codenameone_settings.properties create mode 100644 scripts/settings/common/icon.png create mode 100644 scripts/settings/common/pom.xml create mode 100644 scripts/settings/common/src/main/css/theme.css create mode 100644 scripts/settings/common/src/main/java/com/codename1/settings/CodenameOneSettings.java create mode 100644 scripts/settings/common/src/main/java/com/codename1/settings/extensions/ExtensionCatalogMerger.java create mode 100644 scripts/settings/common/src/main/java/com/codename1/settings/extensions/ExtensionDescriptor.java create mode 100644 scripts/settings/common/src/main/java/com/codename1/settings/extensions/MavenCentralSearch.java create mode 100644 scripts/settings/common/src/main/java/com/codename1/settings/extensions/MavenDependency.java create mode 100644 scripts/settings/common/src/main/java/com/codename1/settings/extensions/PomEditor.java create mode 100644 scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintCatalog.java create mode 100644 scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintMetadata.java create mode 100644 scripts/settings/common/src/main/java/com/codename1/settings/hints/BuildHintType.java create mode 100644 scripts/settings/common/src/main/java/com/codename1/settings/project/ProjectBinding.java create mode 100644 scripts/settings/common/src/main/java/com/codename1/settings/project/ProjectIO.java create mode 100644 scripts/settings/common/src/main/java/com/codename1/settings/project/SettingsProperties.java create mode 100644 scripts/settings/common/src/main/resources/com/codename1/settings/extensions/CN1Libs.xml create mode 100644 scripts/settings/common/src/test/java/com/codename1/settings/BuildHintCatalogTest.java create mode 100644 scripts/settings/common/src/test/java/com/codename1/settings/ExtensionCatalogMergerTest.java create mode 100644 scripts/settings/common/src/test/java/com/codename1/settings/PomEditorTest.java create mode 100644 scripts/settings/common/src/test/java/com/codename1/settings/SettingsThemeTest.java create mode 100644 scripts/settings/javase/pom.xml create mode 100644 scripts/settings/javase/src/desktop/java/com/codename1/settings/CodenameOneSettingsLauncher.java create mode 100644 scripts/settings/javase/src/desktop/java/com/codename1/settings/CodenameOneSettingsStub.java create mode 100644 scripts/settings/javase/src/desktop/resources/NativeTheme.res create mode 100644 scripts/settings/javase/src/test/java/com/codename1/settings/SettingsDesktopIdentityTest.java create mode 100644 scripts/settings/pom.xml create mode 100644 scripts/settings/scripts/capture-html-reference.mjs diff --git a/.github/workflows/release-on-maven-central.yml b/.github/workflows/release-on-maven-central.yml index 9020193ab0e..2259751af64 100644 --- a/.github/workflows/release-on-maven-central.yml +++ b/.github/workflows/release-on-maven-central.yml @@ -201,3 +201,38 @@ jobs: sleep 20 done echo "codenameone-certificatewizard ${GITHUB_REF_NAME} not visible on repo1 yet; it may still be propagating from Sonatype Central." + + # --- Settings editor ---------------------------------------------------- + # The cn1:settings goal resolves the standalone Java-17 Settings editor + # and its runtime dependencies from Maven Central. + - name: Deploy Settings editor to Maven Central + if: steps.deploy.outcome == 'success' || steps.confirm.outcome == 'success' + run: | + export GPG_TTY=$(tty) + cd scripts/settings + xvfb-run -a mvn -Pexecutable-jar -Psettings-central deploy \ + -Dcodename1.platform=javase \ + -Dgpg.passphrase=$MAVEN_GPG_PASSPHRASE \ + -Dcn1.version=$GITHUB_REF_NAME -Dcn1.plugin.version=$GITHUB_REF_NAME \ + -Dmaven.test.skip=true + env: + MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} + + - name: Confirm Settings editor on Maven Central + if: steps.deploy.outcome == 'success' || steps.confirm.outcome == 'success' + continue-on-error: true + run: | + set +e + url="https://repo1.maven.org/maven2/com/codenameone/codenameone-settings/${GITHUB_REF_NAME}/codenameone-settings-${GITHUB_REF_NAME}.jar" + for i in $(seq 1 15); do + code=$(curl -s -o /dev/null -w "%{http_code}" "$url") + if [ "$code" = "200" ]; then + echo "Confirmed codenameone-settings ${GITHUB_REF_NAME} on Maven Central" + exit 0 + fi + echo "[$i/15] Waiting on Maven Central for codenameone-settings (code=$code)" + sleep 20 + done + echo "codenameone-settings ${GITHUB_REF_NAME} not visible on repo1 yet; it may still be propagating from Sonatype Central." diff --git a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/OpenSettingsMojo.java b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/OpenSettingsMojo.java index 3185f599c16..8d867d638d7 100644 --- a/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/OpenSettingsMojo.java +++ b/maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/OpenSettingsMojo.java @@ -1,48 +1,338 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. */ package com.codename1.maven; -import java.io.File; +import org.apache.commons.io.FileUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; +import org.apache.maven.artifact.resolver.ArtifactResolutionResult; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; import org.apache.tools.ant.taskdefs.Java; -import org.apache.tools.ant.types.Commandline.Argument; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; /** - * Opens Codename One Settings. - * @author shannah + * Opens the standalone Codename One Settings tool. + * + *
mvn cn1:settings*/ @Mojo(name = "settings") public class OpenSettingsMojo extends AbstractCN1Mojo { + private static final String LAUNCHED_PROPERTY = + "com.codename1.maven.OpenSettingsMojo.launched"; + + @Parameter(property = "settings.spawn", required = false, defaultValue = "true") + private boolean spawn; @Override protected void executeImpl() throws MojoExecutionException, MojoFailureException { + if (Boolean.getBoolean(LAUNCHED_PROPERTY)) { + getLog().debug("Skipping settings: already launched in this Maven invocation"); + return; + } if (!isCN1ProjectDir()) { + getLog().debug("Skipping settings: not a CN1 project dir"); + return; + } + System.setProperty(LAUNCHED_PROPERTY, "true"); + + File projectDir = getCN1ProjectDir(); + File runtimeDir = new File(System.getProperty("user.home"), ".codenameoneSettings"); + runtimeDir.mkdirs(); + File inputFile = new File(runtimeDir, "settings-" + UUID.randomUUID() + ".input"); + writeBinding(inputFile, projectDir); + + ToolClasspath toolClasspath = getSettingsClasspath(); + getLog().info("Launching Codename One Settings bound to " + projectDir); + if (shouldSpawn()) { + launchDetached(toolClasspath, runtimeDir, inputFile, projectDir); return; } - updateCodenameOne(false, getGuiBuilderJar()); + Java java = createJava(); java.setFork(true); - java.setSpawn(true); - java.setJar(getGuiBuilderJar()); - Argument arg = java.createArg(); - arg.setValue("-settings"); - arg = java.createArg(); - arg.setFile(new File(getCN1ProjectDir(), "codenameone_settings.properties")); + java.setJvm(namedJavaLauncher(runtimeDir).getAbsolutePath()); + java.setClassname("com.codename1.settings.CodenameOneSettingsLauncher"); + java.createClasspath().setPath(joinClasspath(toolClasspath.files)); + configureDesktopIdentity(java, toolClasspath.primaryJar, runtimeDir); + java.createJvmarg().setValue("-Dsettings.input=" + inputFile.getAbsolutePath()); java.executeJava(); - } - - private File getGuiBuilderJar() { - File home = new File(System.getProperty("user.home")); - File codenameone = new File(home, ".codenameone"); - File settingsJar = new File(codenameone, "guibuilder.jar"); - - return settingsJar; + + @Override + protected boolean isCN1ProjectDir() { + File cn1ProjectDir = getCN1ProjectDir(); + if (cn1ProjectDir == null || project == null || project.getBasedir() == null) { + return false; + } + try { + File current = project.getBasedir().getCanonicalFile(); + File cn1 = cn1ProjectDir.getCanonicalFile(); + if (cn1.equals(current)) { + return true; + } + File rootCommon = new File(current, "common").getCanonicalFile(); + return cn1.equals(rootCommon); + } catch (IOException ex) { + getLog().error("Failed to get canonical paths for project dir", ex); + return false; + } + } + + private boolean shouldSpawn() { + String legacySpawn = System.getProperty("spawn"); + if (legacySpawn != null) { + return Boolean.parseBoolean(legacySpawn); + } + return spawn; + } + + private void launchDetached(ToolClasspath toolClasspath, File runtimeDir, File inputFile, File projectDir) + throws MojoExecutionException { + File log = new File(runtimeDir, "settings.log"); + List
g@MUJI%y7Y%nv>yane7)=nUW(=; JfKRJz(Nv$L8-CPgztKw_lKHY
z!IMXY4Gl>j$^FX80ND>JV5u6R{-O;rl18<%XcYm%j&WRL
Rl?^`We0ZUz@k@
z!c})rvd7}UQwFun?s-&b@U>v%j*H93EmxD*?oYK+&5yr52@-T9S{5a6W-sk@N*;>C
zGvkEcZW@Kf3Etsk`RBTUFAdT7@K>uYC@w}CCdpB8^n$Vn3iT3=?7WiccVf-24_*iP
zUi)HX|J{_nJtSgzK`$w`EhNx^fW)W!j+#J`KyTt?bq+FkPND>&Mhew)p$J+@z8z@)
zrDnbw>^=x{K+uUBE;^APrf97zAoksTVa}o-Po3~)c%v;RHI+O~o>B%oP8x{z4J8-6
zIF@p9FM;z7=u;UR`~{?I2hKAfkwh&cub`AMRHDJeN32Nv8d-gwIlDQx_8KYy-S}VD
z5DcE6wgS~_)dlJz+5=~@WfB=3Rci+kR?Nb_3zMccCVVd$p<`09Kp(^nGb~k;rcD6m
zl&Y1wBwgVP8lO!9(<0{^PezLFEOmW(y)|KfXVTvX#Ig~qY0UFwB42OUs! Me3$Ruq`1TVb;5r~k9`w;^Whg-dxZ(>A
zJ+B0g>