This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch CAMEL-24727-jbang-export-request in repository https://gitbox.apache.org/repos/asf/camel.git
commit 6ee1668c696b0d9cf16f667be7c4349d4fd4b6bf Author: Claus Ibsen <[email protected]> AuthorDate: Fri Oct 30 18:59:04 2026 +0100 CAMEL-24727: camel-jbang-export - an exporter holds the export request instead of extending it, and the exporters are internal Co-Authored-By: Claude Opus 5.5 <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../dsl/jbang/core/commands/ExportBaseCommand.java | 13 +- .../apache/camel/dsl/jbang/core/commands/Run.java | 13 +- .../camel/dsl/jbang/export/CamelMainExporter.java | 86 +++--- .../apache/camel/dsl/jbang/export/Exporter.java | 307 ++++++--------------- .../camel/dsl/jbang/export/ProjectExporter.java | 2 +- .../camel/dsl/jbang/export/QuarkusExporter.java | 94 +++---- .../camel/dsl/jbang/export/SpringBootExporter.java | 115 ++++---- .../dsl/jbang/export/common/ExportHelper.java | 148 ++++++++++ .../core/commands/kubernetes/KubernetesExport.java | 7 +- 9 files changed, 397 insertions(+), 388 deletions(-) diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java index 58fa300b7443..6d07a81d6347 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java @@ -35,8 +35,8 @@ import org.apache.camel.dsl.jbang.core.common.RuntimeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.RuntimeTypeConverter; import org.apache.camel.dsl.jbang.export.ExportContext; import org.apache.camel.dsl.jbang.export.ExportRequest; -import org.apache.camel.dsl.jbang.export.Exporter; import org.apache.camel.dsl.jbang.export.ProjectExporter; +import org.apache.camel.dsl.jbang.export.common.ExportHelper; import org.apache.camel.dsl.jbang.export.common.HawtioVersion; import org.apache.camel.dsl.jbang.export.common.MavenResolver; import org.apache.camel.dsl.jbang.export.common.Printer; @@ -373,7 +373,7 @@ public abstract class ExportBaseCommand extends CamelCommand { * --clean-dir. */ static boolean isCurrentDirOrParent(String dir) { - return Exporter.isCurrentDirOrParent(dir); + return ExportHelper.isCurrentDirOrParent(dir); } /** @@ -384,12 +384,7 @@ public abstract class ExportBaseCommand extends CamelCommand { ExportRequest request = toRequest(); request.exportBaseDir = exportBaseDir; applySystemProperties(request); - Exporter exporter = new ProjectExporter(exportContext()).createExporter(request); - if (exporter == null) { - printer().printErr("Unknown runtime: " + runtime); - return 1; - } - return exporter.export(); + return new ProjectExporter(exportContext()).export(exportBaseDir, request); } /** @@ -415,7 +410,7 @@ public abstract class ExportBaseCommand extends CamelCommand { } public Comparator<MavenGav> mavenGavComparator() { - return Exporter.mavenGavComparator(); + return ExportHelper.mavenGavComparator(); } /** diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java index f479e65ce187..b124b4292f94 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java @@ -63,10 +63,8 @@ import org.apache.camel.dsl.jbang.core.common.ProfileCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.RunRuntimeCompletionCandidates; import org.apache.camel.dsl.jbang.core.common.RunRuntimeTypeConverter; import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper; -import org.apache.camel.dsl.jbang.export.CamelMainExporter; import org.apache.camel.dsl.jbang.export.ExportRequest; -import org.apache.camel.dsl.jbang.export.QuarkusExporter; -import org.apache.camel.dsl.jbang.export.SpringBootExporter; +import org.apache.camel.dsl.jbang.export.ProjectExporter; import org.apache.camel.dsl.jbang.export.common.ExportHelper; import org.apache.camel.dsl.jbang.export.common.Printer; import org.apache.camel.dsl.jbang.export.common.RuntimeType; @@ -1026,7 +1024,8 @@ public class Run extends CamelCommand { // run export ExportBaseCommand.applySystemProperties(eq); - int exit = new QuarkusExporter(eq, CliExportContext.create(getMain(), getMain().getOut(), eq.yes)).export(); + int exit = new ProjectExporter(CliExportContext.create(getMain(), getMain().getOut(), eq.yes)) + .export(eq.exportBaseDir, eq); if (exit != 0) { return exit; } @@ -1188,7 +1187,8 @@ public class Run extends CamelCommand { // run export ExportBaseCommand.applySystemProperties(eq); - int exit = new CamelMainExporter(eq, CliExportContext.create(getMain(), getMain().getOut(), eq.yes)).export(); + int exit = new ProjectExporter(CliExportContext.create(getMain(), getMain().getOut(), eq.yes)) + .export(eq.exportBaseDir, eq); if (exit != 0) { return exit; } @@ -1824,7 +1824,8 @@ public class Run extends CamelCommand { // run export ExportBaseCommand.applySystemProperties(eq); - int exit = new SpringBootExporter(eq, CliExportContext.create(getMain(), getMain().getOut(), eq.yes)).export(); + int exit = new ProjectExporter(CliExportContext.create(getMain(), getMain().getOut(), eq.yes)) + .export(eq.exportBaseDir, eq); if (exit != 0) { return exit; } diff --git a/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/CamelMainExporter.java b/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/CamelMainExporter.java index e2c964c235c8..345d50293c6e 100644 --- a/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/CamelMainExporter.java +++ b/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/CamelMainExporter.java @@ -46,39 +46,39 @@ import static org.apache.camel.dsl.jbang.export.common.ExportHelper.exportPackag /** * Exports to a Camel Main Maven project. */ -public class CamelMainExporter extends Exporter { +class CamelMainExporter extends Exporter { - public CamelMainExporter(ExportRequest request, ExportContext context) { + CamelMainExporter(ExportRequest request, ExportContext context) { super(request, context); - if (pomTemplateName == null) { - pomTemplateName = "main-pom.ftl"; + if (this.request.pomTemplateName == null) { + this.request.pomTemplateName = "main-pom.ftl"; } } @Override public Integer export() throws Exception { try { - MavenGav.parseStrictGav(gav); + MavenGav.parseStrictGav(request.gav); } catch (IllegalArgumentException e) { printer().printErr("--gav must be in syntax: groupId:artifactId:version"); return 1; } - if (parentPom != null) { + if (request.parentPom != null) { try { - MavenGav.parseStrictGav(parentPom); + MavenGav.parseStrictGav(request.parentPom); } catch (IllegalArgumentException e) { printer().printErr("--parent-pom must be in syntax: groupId:artifactId:version"); return 1; } } - String[] ids = gav.split(":"); + String[] ids = request.gav.split(":"); // the settings file has information what to export Path settings = runSettingsFile(); - if (mavenResolver.fresh() || !files.isEmpty() || !Files.exists(settings)) { + if (request.mavenResolver.fresh() || !request.files.isEmpty() || !Files.exists(settings)) { // allow to automatic build printer().println("Generating fresh run data"); - int silent = runSilently(ignoreLoadingError, lazyBean, verbose); + int silent = runSilently(request.ignoreLoadingError, request.lazyBean, request.verbose); if (silent != 0) { return silent; } @@ -86,10 +86,10 @@ public class CamelMainExporter extends Exporter { printer().println("Reusing existing run data"); } - printer().println("Exporting as Camel Main project to: " + exportDir); + printer().println("Exporting as Camel Main project to: " + request.exportDir); - exportBaseDir = exportBaseDir != null ? exportBaseDir : Path.of("."); - Path profile = exportBaseDir.resolve("application.properties"); + request.exportBaseDir = request.exportBaseDir != null ? request.exportBaseDir : Path.of("."); + Path profile = request.exportBaseDir.resolve("application.properties"); // use a temporary work dir Path buildDir = buildDir(); @@ -101,7 +101,7 @@ public class CamelMainExporter extends Exporter { // compute source folders Path srcJavaDirRoot = buildDir.resolve("src/main/java"); - String srcPackageName = exportPackageName(ids[0], ids[1], packageName); + String srcPackageName = exportPackageName(ids[0], ids[1], request.packageName); Path srcJavaDir; if (srcPackageName == null) { srcJavaDir = srcJavaDirRoot; @@ -124,7 +124,7 @@ public class CamelMainExporter extends Exporter { Map<String, String> devProfile = new LinkedHashMap<>(); copySettingsAndProfile(settings, profile, srcResourcesDir, prop -> { - if (groovyPrecompiled && !prop.containsKey("camel.main.groovyPreloadCompiled")) { + if (request.groovyPrecompiled && !prop.containsKey("camel.main.groovyPreloadCompiled")) { prop.put("camel.main.groovyPreloadCompiled", "true"); } if (!prop.containsKey("camel.main.basePackageScan") @@ -147,7 +147,7 @@ public class CamelMainExporter extends Exporter { prop.put("camel.server.port", port); } if (!prop.containsKey("camel.server.health-check-enabled")) { - if (VersionHelper.isGE(camelVersion, "4.14.0")) { + if (VersionHelper.isGE(request.camelVersion, "4.14.0")) { prop.put("camel.management.enabled", "true"); prop.put("camel.management.health-check-enabled", "true"); } else { @@ -156,7 +156,7 @@ public class CamelMainExporter extends Exporter { } } } - port = httpManagementPort(settings); + port = ExportHelper.httpManagementPort(settings); if (port != -1) { prop.put("camel.management.enabled", "true"); prop.put("camel.management.port", port); @@ -176,11 +176,11 @@ public class CamelMainExporter extends Exporter { }); writeDevProfileProperties(srcResourcesDir, devProfile); // create main class - createMainClassSource(srcJavaDir, srcPackageName, mainClassname); + createMainClassSource(srcJavaDir, srcPackageName, request.mainClassname); // copy local lib JARs copyLocalLibDependencies(deps); // copy local lib JARs - if (groovyPrecompiled) { + if (request.groovyPrecompiled) { copyGroovyPrecompiled(srcResourcesDir); } // copy agent JARs and remove as dependency @@ -188,62 +188,62 @@ public class CamelMainExporter extends Exporter { deps.removeIf(d -> d.startsWith("agent:")); createMavenPom(settings, profile, buildDir.resolve("pom.xml"), deps, srcPackageName); - if (mavenWrapper) { + if (request.mavenWrapper) { copyMavenWrapper(); } - if (camelWrapper) { + if (request.camelWrapper) { copyCamelWrapper(); } - if (docker) { + if (request.docker) { copyDockerFiles(buildDir.toString()); } String appJar = Paths.get("target", ids[1] + "-" + ids[2] + ".jar").toString(); copyReadme(buildDir.toString(), appJar); - if (cleanExportDir || !isCurrentDirOrParent(exportDir)) { + if (request.cleanExportDir || !ExportHelper.isCurrentDirOrParent(request.exportDir)) { // cleaning current dir can be a bit dangerous so only clean if explicit enabled // otherwise always clean export-dir to avoid stale data - if (cleanExportDir) { - String absPath = Path.of(exportDir).toAbsolutePath().toString(); - if (!yes && !exportContext.confirm("Are you sure you want to delete " + absPath + "?")) { + if (request.cleanExportDir) { + String absPath = Path.of(request.exportDir).toAbsolutePath().toString(); + if (!request.yes && !exportContext.confirm("Are you sure you want to delete " + absPath + "?")) { return 1; } } - ExportHelper.cleanExportDir(exportDir); + ExportHelper.cleanExportDir(request.exportDir); } // copy to export dir and remove work dir - PathUtils.copyDirectory(buildDir, Path.of(exportDir)); - createDeferredSymlinks(buildDir, Path.of(exportDir)); + PathUtils.copyDirectory(buildDir, Path.of(request.exportDir)); + createDeferredSymlinks(buildDir, Path.of(request.exportDir)); PathUtils.deleteDirectory(buildDir); return 0; } private void createMavenPom(Path settings, Path profile, Path pom, Set<String> deps, String packageName) throws Exception { - String[] ids = gav.split(":"); + String[] ids = request.gav.split(":"); CamelCatalog catalog = new DefaultCamelCatalog(); - if (ObjectHelper.isEmpty(camelVersion)) { - camelVersion = catalog.getLoadedVersion(); + if (ObjectHelper.isEmpty(request.camelVersion)) { + request.camelVersion = catalog.getLoadedVersion(); } - if (ObjectHelper.isEmpty(camelVersion)) { - camelVersion = VersionHelper.extractCamelVersion(); + if (ObjectHelper.isEmpty(request.camelVersion)) { + request.camelVersion = VersionHelper.extractCamelVersion(); } Properties prop = new CamelCaseOrderedProperties(); RuntimeUtil.loadProperties(prop, settings); - String repos = getMavenRepositories(settings, prop, camelVersion); + String repos = getMavenRepositories(settings, prop, request.camelVersion); // build the template data model Map<String, Object> model = new HashMap<>(); model.put("GroupId", ids[0]); model.put("ArtifactId", ids[1]); model.put("Version", ids[2]); - model.put("JavaVersion", javaVersion); - model.put("CamelVersion", camelVersion); + model.put("JavaVersion", request.javaVersion); + model.put("CamelVersion", request.camelVersion); if (packageName != null) { - model.put("MainClassname", packageName + "." + mainClassname); + model.put("MainClassname", packageName + "." + request.mainClassname); } else { - model.put("MainClassname", mainClassname); + model.put("MainClassname", request.mainClassname); } model.put("ProjectBuildOutputTimestamp", this.getBuildMavenProjectDate()); model.put("BuildProperties", formatBuildProperties()); @@ -255,7 +255,7 @@ public class CamelMainExporter extends Exporter { // kubernetes/docker properties enrichKubernetesModel(model, settings, profile); - String context = TemplateHelper.processTemplate(pomTemplateName, model); + String context = TemplateHelper.processTemplate(request.pomTemplateName, model); Files.writeString(pom, context); } @@ -282,7 +282,7 @@ public class CamelMainExporter extends Exporter { } } if (fromImage == null) { - fromImage = "mirror.gcr.io/library/eclipse-temurin:" + javaVersion + "-jre"; + fromImage = "mirror.gcr.io/library/eclipse-temurin:" + request.javaVersion + "-jre"; kubernetesProperties.add(Map.of("key", "jib.from.image", "value", fromImage)); } } @@ -302,7 +302,7 @@ public class CamelMainExporter extends Exporter { model.put("Port", String.valueOf(port)); } if (jkube) { - model.put("JkubeMavenPluginVersion", jkubeMavenPluginVersion(settings, prop)); + model.put("JkubeMavenPluginVersion", ExportHelper.jkubeMavenPluginVersion(settings, prop)); } } @@ -390,7 +390,7 @@ public class CamelMainExporter extends Exporter { protected void copyGroovyPrecompiled(Path srcResourcesDir) throws Exception { // are there any pre-compiled groovy code // the silent run compiles the groovy code into the work directory - File gc = workDir.resolve("compile/groovy").toFile(); + File gc = request.workDir.resolve("compile/groovy").toFile(); if (gc.exists() && gc.isDirectory()) { File[] files = gc.listFiles(); if (files != null) { diff --git a/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/Exporter.java b/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/Exporter.java index e3facfaa0965..966bc515422a 100644 --- a/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/Exporter.java +++ b/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/Exporter.java @@ -30,10 +30,8 @@ import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -72,10 +70,10 @@ import org.apache.camel.util.StringHelper; import static org.apache.camel.dsl.jbang.export.common.CamelJBangConstants.*; /** - * Exports Camel files to a Maven project of a runtime. The exporter is configured from a copy of the - * {@link ExportRequest}, and uses the {@link ExportContext} of its caller. + * Exports Camel files to a Maven project of a runtime. The exporter holds a copy of the {@link ExportRequest}, and uses + * the {@link ExportContext} of its caller. */ -public abstract class Exporter extends ExportRequest { +abstract class Exporter { protected static final String[] SETTINGS_PROP_SOURCE_KEYS = new String[] { "camel.main.routesIncludePattern", @@ -99,10 +97,11 @@ public abstract class Exporter extends ExportRequest { // Map to store deferred symbolic links: target path in the build dir → original source path private Map<Path, Path> deferredSymlinks = new HashMap<>(); + protected final ExportRequest request; protected final ExportContext exportContext; protected Exporter(ExportRequest request, ExportContext context) { - super(request); + this.request = new ExportRequest(request); this.exportContext = context; } @@ -110,14 +109,14 @@ public abstract class Exporter extends ExportRequest { * The directory in the work directory where the project is built, before it is copied to the export directory. */ protected Path buildDir() { - return workDir.resolve("work"); + return request.workDir.resolve("work"); } /** * The run settings in the work directory, which the dependency resolver writes. */ protected Path runSettingsFile() { - return workDir.resolve(ExportHelper.RUN_SETTINGS_FILE); + return request.workDir.resolve(ExportHelper.RUN_SETTINGS_FILE); } /** @@ -162,7 +161,7 @@ public abstract class Exporter extends ExportRequest { } // sort artifacts - gavs.sort(mavenGavComparator()); + gavs.sort(ExportHelper.mavenGavComparator()); List<Map<String, Object>> result = new ArrayList<>(); for (MavenGav gav : gavs) { @@ -178,78 +177,12 @@ public abstract class Exporter extends ExportRequest { return result; } - public static Comparator<MavenGav> mavenGavComparator() { - return new Comparator<MavenGav>() { - @Override - public int compare(MavenGav o1, MavenGav o2) { - int r1 = rankGroupId(o1); - int r2 = rankGroupId(o2); - - if (r1 > r2) { - return -1; - } else if (r2 > r1) { - return 1; - } else { - return o1.toString().compareTo(o2.toString()); - } - } - - int rankGroupId(MavenGav o1) { - String g1 = o1.getGroupId(); - if (g1 == null) { - return 0; - } - - switch (g1) { - case "org.springframework.boot" -> { - return 30; - } - case "io.quarkus" -> { - return 30; - } - case "org.apache.camel.quarkus" -> { - String a1 = o1.getArtifactId(); - // main/core/engine first - if ("camel-quarkus-core".equals(a1)) { - return 21; - } - return 20; - } - case "org.apache.camel.springboot" -> { - String a1 = o1.getArtifactId(); - // main/core/engine first - if ("camel-spring-boot-starter".equals(a1)) { - return 21; - } else if ("camel-spring-boot-engine-starter".equals(a1)) { - return 22; - } - return 20; - } - case "org.apache.camel" -> { - String a1 = o1.getArtifactId(); - // main/core/engine first - if ("camel-main".equals(a1)) { - return 11; - } - return 10; - } - case "org.apache.camel.kamelets" -> { - return 5; - } - default -> { - return 0; - } - } - } - }; - } - /** * Formats build properties as XML property lines for inclusion in POM templates. */ protected void enrichParentPom(Map<String, Object> model) { - if (parentPom != null) { - MavenGav gav = MavenGav.parseStrictGav(parentPom); + if (request.parentPom != null) { + MavenGav gav = MavenGav.parseStrictGav(request.parentPom); model.put("ParentGroupId", gav.getGroupId()); model.put("ParentArtifactId", gav.getArtifactId()); model.put("ParentVersion", gav.getVersion()); @@ -259,7 +192,7 @@ public abstract class Exporter extends ExportRequest { protected String formatBuildProperties() { Properties properties = mapBuildProperties(); - if (!skipPlugins) { + if (!request.skipPlugins) { Set<PluginExporter> exporters = pluginExporters(); for (PluginExporter exporter : exporters) { @@ -279,30 +212,20 @@ public abstract class Exporter extends ExportRequest { */ public abstract Integer export() throws Exception; - /** - * Whether the directory is the current directory, or one that contains it, such as <tt>./</tt>, <tt>$PWD</tt> or - * <tt>..</tt>: cleaning it before the export deletes the files of the project, so it is only cleaned with - * --clean-dir. - */ - public static boolean isCurrentDirOrParent(String dir) { - Path path = Path.of(dir).toAbsolutePath().normalize(); - return Path.of("").toAbsolutePath().normalize().startsWith(path); - } - protected Integer runSilently(boolean ignoreLoadingError, boolean lazyBean, boolean verbose) throws Exception { - if (kameletsVersion == null) { - kameletsVersion = VersionHelper.extractKameletsVersion(); - } - ExportRequest request = new ExportRequest(this); - request.ignoreLoadingError = ignoreLoadingError; - request.lazyBean = lazyBean; - request.verbose = verbose; - return exportContext.getDependencyResolver().resolve(request, exportContext); + if (request.kameletsVersion == null) { + request.kameletsVersion = VersionHelper.extractKameletsVersion(); + } + ExportRequest silent = new ExportRequest(request); + silent.ignoreLoadingError = ignoreLoadingError; + silent.lazyBean = lazyBean; + silent.verbose = verbose; + return exportContext.getDependencyResolver().resolve(silent, exportContext); } protected void addDependencies(String... deps) { var depsArray = Optional.ofNullable(deps).orElse(new String[0]); - dependencies.addAll(Arrays.asList(depsArray)); + request.dependencies.addAll(Arrays.asList(depsArray)); } /** @@ -333,19 +256,20 @@ public abstract class Exporter extends ExportRequest { return o1.compareTo(o2); }); - if (kameletsVersion == null) { - kameletsVersion = VersionHelper.extractKameletsVersion(); + if (request.kameletsVersion == null) { + request.kameletsVersion = VersionHelper.extractKameletsVersion(); } // custom dependencies - for (String d : dependencies) { + for (String d : request.dependencies) { answer.add(normalizeDependency(d)); } List<String> lines = RuntimeUtil.loadPropertiesLines(settings); // check if we use custom and/or official ASF kamelets - List<String> officialKamelets = KameletCatalogHelper.findKameletNames(kameletsVersion, mavenResolver.repos()); + List<String> officialKamelets + = KameletCatalogHelper.findKameletNames(request.kameletsVersion, request.mavenResolver.repos()); boolean kamelets = false; boolean asfKamelets = false; for (String line : lines) { @@ -381,9 +305,9 @@ public abstract class Exporter extends ExportRequest { answer.add("camel:yaml-dsl"); if (asfKamelets) { // include JARs for official ASF kamelets - answer.add("org.apache.camel.kamelets:camel-kamelets:" + kameletsVersion); - if (VersionHelper.compare(camelVersion, "4.10.0") < 0) { - answer.add("org.apache.camel.kamelets:camel-kamelets-utils:" + kameletsVersion); + answer.add("org.apache.camel.kamelets:camel-kamelets:" + request.kameletsVersion); + if (VersionHelper.compare(request.camelVersion, "4.10.0") < 0) { + answer.add("org.apache.camel.kamelets:camel-kamelets-utils:" + request.kameletsVersion); } } } @@ -398,19 +322,19 @@ public abstract class Exporter extends ExportRequest { answer.add("camel:yaml-dsl"); if (asfKamelets) { // include JARs for official ASF kamelets - answer.add("org.apache.camel.kamelets:camel-kamelets:" + kameletsVersion); - if (VersionHelper.compare(camelVersion, "4.10.0") < 0) { - answer.add("org.apache.camel.kamelets:camel-kamelets-utils:" + kameletsVersion); + answer.add("org.apache.camel.kamelets:camel-kamelets:" + request.kameletsVersion); + if (VersionHelper.compare(request.camelVersion, "4.10.0") < 0) { + answer.add("org.apache.camel.kamelets:camel-kamelets-utils:" + request.kameletsVersion); } } } } } - } else if (line.startsWith(DEPENDENCIES_MAIN + "=") && runtime == RuntimeType.main) { + } else if (line.startsWith(DEPENDENCIES_MAIN + "=") && request.runtime == RuntimeType.main) { addRuntimeSpecificDependencies(StringHelper.after(line, DEPENDENCIES_MAIN + "="), answer); - } else if (line.startsWith(DEPENDENCIES_SPRING_BOOT + "=") && runtime == RuntimeType.springBoot) { + } else if (line.startsWith(DEPENDENCIES_SPRING_BOOT + "=") && request.runtime == RuntimeType.springBoot) { addRuntimeSpecificDependencies(StringHelper.after(line, DEPENDENCIES_SPRING_BOOT + "="), answer); - } else if (line.startsWith(DEPENDENCIES_QUARKUS + "=") && runtime == RuntimeType.quarkus) { + } else if (line.startsWith(DEPENDENCIES_QUARKUS + "=") && request.runtime == RuntimeType.quarkus) { addRuntimeSpecificDependencies(StringHelper.after(line, DEPENDENCIES_QUARKUS + "="), answer); } else if (line.startsWith(CLASSPATH_FILES + "=")) { String deps = StringHelper.after(line, CLASSPATH_FILES + "="); @@ -440,9 +364,10 @@ public abstract class Exporter extends ExportRequest { answer.add("camel:kamelet"); if (asfKamelets) { // include JARs for official ASF kamelets - answer.add("mvn:org.apache.camel.kamelets:camel-kamelets:" + kameletsVersion); - if (VersionHelper.compare(camelVersion, "4.10.0") < 0) { - answer.add("mvn:org.apache.camel.kamelets:camel-kamelets-utils:" + kameletsVersion); + answer.add("mvn:org.apache.camel.kamelets:camel-kamelets:" + request.kameletsVersion); + if (VersionHelper.compare(request.camelVersion, "4.10.0") < 0) { + answer.add("mvn:org.apache.camel.kamelets:camel-kamelets-utils:" + + request.kameletsVersion); } } } @@ -456,9 +381,9 @@ public abstract class Exporter extends ExportRequest { answer.add("camel:yaml-dsl"); if (asfKamelets) { // include JARs for official ASF kamelets - answer.add("mvn:org.apache.camel.kamelets:camel-kamelets:" + kameletsVersion); - if (VersionHelper.compare(camelVersion, "4.10.0") < 0) { - answer.add("mvn:org.apache.camel.kamelets:camel-kamelets-utils:" + kameletsVersion); + answer.add("mvn:org.apache.camel.kamelets:camel-kamelets:" + request.kameletsVersion); + if (VersionHelper.compare(request.camelVersion, "4.10.0") < 0) { + answer.add("mvn:org.apache.camel.kamelets:camel-kamelets-utils:" + request.kameletsVersion); } } } else if (line.startsWith("modeline=")) { @@ -501,11 +426,11 @@ public abstract class Exporter extends ExportRequest { } } - if (!skipPlugins) { + if (!request.skipPlugins) { Set<PluginExporter> exporters = pluginExporters(); for (PluginExporter exporter : exporters) { - answer.addAll(exporter.getDependencies(runtime)); + answer.addAll(exporter.getDependencies(request.runtime)); } } @@ -519,13 +444,13 @@ public abstract class Exporter extends ExportRequest { if (profile != null && Files.exists(profile)) { RuntimeUtil.loadProperties(exportProperties, profile); } - GenAiDependencyHelper.addAiObservabilityIfNeeded(answer, exportProperties, observe); + GenAiDependencyHelper.addAiObservabilityIfNeeded(answer, exportProperties, request.observe); // remove duplicate versions (keep first) but an explicit --dep version always wins over // an auto-detected dependency for the same groupId:artifactId (e.g. a JDBC driver whose // version is inferred from the camel-dependencies BOM) Set<String> preferred = new HashSet<>(); - for (String d : dependencies) { + for (String d : request.dependencies) { String line = normalizeDependency(d); MavenGav gav = MavenGav.parseGav(line); if (gav.getVersion() != null && !gav.getVersion().isBlank()) { @@ -737,7 +662,7 @@ public abstract class Exporter extends ExportRequest { if (!java) { if (kamelet) { ExportHelper.safeCopy(source, out, true); - if (symbolicLink) { + if (request.symbolicLink) { deferredSymlinks.put(out, source); } } else if (jkube) { @@ -747,13 +672,13 @@ public abstract class Exporter extends ExportRequest { out = srcCamelResourcesDir.getParent().getParent().resolve("jkube/" + f); Files.createDirectories(out.getParent()); ExportHelper.safeCopy(source, out, true); - if (symbolicLink) { + if (request.symbolicLink) { deferredSymlinks.put(out, source); } } else { Files.createDirectories(out.getParent()); ExportHelper.safeCopy(getClass().getClassLoader(), scheme, source, out, true); - if (symbolicLink) { + if (request.symbolicLink) { deferredSymlinks.put(out, source); } } @@ -773,7 +698,7 @@ public abstract class Exporter extends ExportRequest { throw new IOException("Cannot determine package name from source: " + source); } } else { - if (javaLiveReload) { + if (request.javaLiveReload) { out = srcJavaDirRoot.resolve(source.getFileName()); } else { if (packageName != null && !"false".equalsIgnoreCase(packageName)) { @@ -782,9 +707,9 @@ public abstract class Exporter extends ExportRequest { } } } - if (javaLiveReload) { + if (request.javaLiveReload) { ExportHelper.safeCopy(source, out, true); - if (symbolicLink) { + if (request.symbolicLink) { deferredSymlinks.put(out, source); } } else { @@ -803,7 +728,7 @@ public abstract class Exporter extends ExportRequest { copyResourceDirs(srcResourcesDir); - if (!skipPlugins) { + if (!request.skipPlugins) { Set<PluginExporter> exporters = pluginExporters(); for (PluginExporter exporter : exporters) { @@ -814,10 +739,10 @@ public abstract class Exporter extends ExportRequest { } private void copyResourceDirs(Path srcResourcesDir) throws Exception { - if (resourceDirs == null || resourceDirs.isEmpty()) { + if (request.resourceDirs == null || request.resourceDirs.isEmpty()) { return; } - for (String dir : resourceDirs) { + for (String dir : request.resourceDirs) { Path dirPath = ExportHelper.validateResourceDir(dir); // use the last component as the target directory name // so ../shared/schemas -> src/main/resources/schemas/ @@ -832,11 +757,11 @@ public abstract class Exporter extends ExportRequest { } private boolean isUnderResourceDir(String file) { - if (resourceDirs == null || resourceDirs.isEmpty()) { + if (request.resourceDirs == null || request.resourceDirs.isEmpty()) { return false; } Path filePath = Paths.get(file).normalize(); - for (String dir : resourceDirs) { + for (String dir : request.resourceDirs) { Path dirPath = Paths.get(dir).normalize(); if (filePath.startsWith(dirPath)) { return true; @@ -878,8 +803,8 @@ public abstract class Exporter extends ExportRequest { } // include camel profile if set (so exported runtimes like Spring Boot and Quarkus know the profile) - if (this.profile != null && !profileProps.containsKey("camel.main.profile")) { - profileProps.put("camel.main.profile", this.profile); + if (request.profile != null && !profileProps.containsKey("camel.main.profile")) { + profileProps.put("camel.main.profile", request.profile); } StringBuilder content = new StringBuilder(); @@ -914,7 +839,7 @@ public abstract class Exporter extends ExportRequest { // User properties Properties userProps = new CamelCaseOrderedProperties(); - userProps.putAll(propertiesMap(this.applicationProperties)); + userProps.putAll(propertiesMap(request.applicationProperties)); for (Map.Entry<Object, Object> entryUserProp : userProps.entrySet()) { String uK = entryUserProp.getKey().toString(); String uV = entryUserProp.getValue().toString(); @@ -936,49 +861,17 @@ public abstract class Exporter extends ExportRequest { } protected Map<String, String> propertiesMap(String[]... propertySources) { - return propertiesMap(printer(), propertySources); - } - - /** - * The key=value properties of the given sources, where a later source overrides an earlier one. - */ - public static Map<String, String> propertiesMap(Printer printer, String[]... propertySources) { - Map<String, String> result = new LinkedHashMap<>(); - if (propertySources != null) { - for (String[] props : Arrays.stream(propertySources).filter(Objects::nonNull).toList()) { - for (String s : props) { - String[] kv = s.split("=", 2); - if (kv.length < 2) { - printer.printWarn("property '" + s + "' has a bad format (should be 'key=value'), skipping."); - } else { - result.put(kv[0], kv[1]); - } - } - } - } - return result; + return ExportHelper.propertiesMap(printer(), propertySources); } // Returns true if it has either an openapi spec or it uses contract-first DSL protected boolean hasOpenapi(Set<String> dependencies) { - return openapi != null || dependencies.stream().anyMatch(s -> s.contains("mvn:org.apache.camel:camel-rest-openapi")); + return request.openapi != null + || dependencies.stream().anyMatch(s -> s.contains("mvn:org.apache.camel:camel-rest-openapi")); } protected Properties mapBuildProperties() { - return mapBuildProperties(buildProperties); - } - - /** - * The given Maven build properties (prop=value) as properties. - */ - public static Properties mapBuildProperties(List<String> buildProperties) { - var answer = new Properties(); - buildProperties.stream() - .filter(item -> !item.isEmpty()) - .map(item -> item.split("=", 2)) - .filter(toks -> toks.length == 2) - .forEach(toks -> answer.setProperty(toks[0], toks[1])); - return answer; + return ExportHelper.mapBuildProperties(request.buildProperties); } protected void copyMavenWrapper() throws Exception { @@ -1016,11 +909,11 @@ public abstract class Exporter extends ExportRequest { // write camel-wrapper.properties with the export's camel version String distributionUrl = "https://repo1.maven.org/maven2" + "/org/apache/camel/camel-launcher/" - + camelVersion + + request.camelVersion + "/camel-launcher-" - + camelVersion + + request.camelVersion + ".jar"; - String content = "camel.version=" + camelVersion + "\n" + String content = "camel.version=" + request.camelVersion + "\n" + "distributionUrl=" + distributionUrl + "\n"; Files.writeString(camelDir.resolve("camel-wrapper.properties"), content); @@ -1073,13 +966,13 @@ public abstract class Exporter extends ExportRequest { } } - if (mavenResolver.repos() != null) { - Collections.addAll(answer, this.mavenResolver.repos().split("\\s*,\\s*")); + if (request.mavenResolver.repos() != null) { + Collections.addAll(answer, request.mavenResolver.repos().split("\\s*,\\s*")); } // include the extra default repositories the downloads use (the camel.extra.repos system property unless the // request sets them) - String extraRepos = mavenResolver.downloader().getExtraRepos(); + String extraRepos = request.mavenResolver.downloader().getExtraRepos(); if (extraRepos != null && !extraRepos.isBlank()) { for (String r : extraRepos.split("\\s*,\\s*")) { if (!r.isBlank()) { @@ -1135,7 +1028,7 @@ public abstract class Exporter extends ExportRequest { * only has the console when running with the dev profile. */ protected boolean isConsoleInApplicationProperties() { - return consoleForRun || "dev".equals(profile); + return request.consoleForRun || "dev".equals(request.profile); } /** @@ -1195,18 +1088,6 @@ public abstract class Exporter extends ExportRequest { Files.writeString(file, content); } - public static int httpManagementPort(Path settings) { - try { - List<String> lines = RuntimeUtil.loadPropertiesLines(settings); - String port = lines.stream().filter(l -> l.startsWith("camel.management.port=")) - .map(s -> StringHelper.after(s, "=")).findFirst().orElse("-1"); - return Integer.parseInt(port); - } catch (Exception e) { - // ignore - } - return -1; - } - public static String jibMavenPluginVersion(Path settings, Properties prop) { String answer = null; if (prop != null) { @@ -1224,24 +1105,6 @@ public abstract class Exporter extends ExportRequest { return answer != null ? answer : "3.5.2"; } - public static String jkubeMavenPluginVersion(Path settings, Properties props) { - String answer = null; - if (props != null) { - answer = props.getProperty(JKUBE_MAVEN_PLUGIN_VERSION); - } - if (answer == null) { - try { - List<String> lines = RuntimeUtil.loadPropertiesLines(settings); - answer = lines.stream() - .filter(l -> l.startsWith(JKUBE_MAVEN_PLUGIN_VERSION + "=") || l.startsWith("jkube.version=")) - .map(s -> StringHelper.after(s, "=")).findFirst().orElse(null); - } catch (Exception e) { - // ignore - } - } - return answer != null ? answer : "1.20.0"; - } - // This method is kept for backward compatibility with derived classes @Deprecated protected void safeCopy(File source, File target, boolean override) throws Exception { @@ -1257,7 +1120,7 @@ public abstract class Exporter extends ExportRequest { * @throws Exception if symbolic link creation fails */ protected void createDeferredSymlinks(Path buildDir, Path exportDir) throws Exception { - if (!symbolicLink || deferredSymlinks.isEmpty()) { + if (!request.symbolicLink || deferredSymlinks.isEmpty()) { return; } @@ -1347,7 +1210,7 @@ public abstract class Exporter extends ExportRequest { } private MavenGav parseLocalJar(String dep) { - Path path = exportBaseDir.resolve(dep + ".jar"); + Path path = request.exportBaseDir.resolve(dep + ".jar"); if (!Files.isRegularFile(path) || !Files.exists(path)) { return null; } @@ -1402,7 +1265,7 @@ public abstract class Exporter extends ExportRequest { private void copyAgentLibDependencies(MavenGav gav) { try { - List<MavenArtifact> artifacts = mavenResolver.downloader().resolveArtifacts( + List<MavenArtifact> artifacts = request.mavenResolver.downloader().resolveArtifacts( List.of(gav.toString()), Set.of(), true, gav.getVersion().contains("SNAPSHOT")); for (MavenArtifact artifact : artifacts) { Path target = buildDir().resolve("agent").resolve(artifact.getFile().getName()); @@ -1419,7 +1282,7 @@ public abstract class Exporter extends ExportRequest { } protected void copyApplicationPropertiesFiles(Path srcResourcesDir) throws Exception { - try (Stream<Path> files = Files.list(exportBaseDir)) { + try (Stream<Path> files = Files.list(request.exportBaseDir)) { files.filter(p -> Files.isRegularFile(p)) .filter(p -> { String fileName = p.getFileName().toString(); @@ -1432,12 +1295,12 @@ public abstract class Exporter extends ExportRequest { // skip generic as its handled specially return false; } - if (profile == null) { + if (request.profile == null) { // accept all kind of configuration files return name.startsWith("application"); } else { // only accept the configuration file that matches the profile - return name.equals("application-" + profile); + return name.equals("application-" + request.profile); } }) .forEach(p -> { @@ -1470,7 +1333,7 @@ public abstract class Exporter extends ExportRequest { * The exporters of the active plugins. */ protected Set<PluginExporter> pluginExporters() { - return new LinkedHashSet<>(exportContext.getPluginExporters(mavenResolver.repos())); + return new LinkedHashSet<>(exportContext.getPluginExporters(request.mavenResolver.repos())); } protected Printer outPrinter() { @@ -1478,7 +1341,7 @@ public abstract class Exporter extends ExportRequest { } protected Printer printer() { - if (quiet) { + if (request.quiet) { if (quietPrinter == null) { quietPrinter = new Printer.QuietPrinter(exportContext.getPrinter()); } @@ -1488,11 +1351,11 @@ public abstract class Exporter extends ExportRequest { } protected String getProjectName() { - return ProjectExporter.projectName(name, gav, files); + return ProjectExporter.projectName(request.name, request.gav, request.files); } protected String getVersion() { - return ProjectExporter.projectVersion(gav); + return ProjectExporter.projectVersion(request.gav); } // Maven reproducible builds: https://maven.apache.org/guides/mini/guide-reproducible-builds.html @@ -1504,7 +1367,7 @@ public abstract class Exporter extends ExportRequest { protected void copyDockerFiles(String buildDir) throws Exception { Path docker = Path.of(buildDir).resolve("src/main/docker"); Files.createDirectories(docker); - String[] ids = gav.split(":"); + String[] ids = request.gav.split(":"); Map<String, Object> model = new HashMap<>(); model.put("ArtifactId", ids[1]); @@ -1517,13 +1380,13 @@ public abstract class Exporter extends ExportRequest { // Process the Dockerfile template for the Java version, e.g. Dockerfile25.ftl for Java 25. protected String processDockerfileTemplate(String templateName, Map<String, Object> model) throws IOException { - String ftlName = templateName + javaVersion + ".ftl"; + String ftlName = templateName + request.javaVersion + ".ftl"; try { return TemplateHelper.processTemplate(ftlName, model); } catch (TemplateNotFoundException e) { // fallback to JDK 21 template (other errors, e.g. a malformed template, are not hidden by the fallback) String fallback = templateName + "21.ftl"; - printer().printf("No Dockerfile template for Java %s, falling back to Java 21 template%n", javaVersion); + printer().printf("No Dockerfile template for Java %s, falling back to Java 21 template%n", request.javaVersion); return TemplateHelper.processTemplate(fallback, model); } } @@ -1534,7 +1397,7 @@ public abstract class Exporter extends ExportRequest { // Copy the readme.md into the same Maven project root directory. protected void copyReadme(String buildDir, String appJar) throws Exception { - String[] ids = gav.split(":"); + String[] ids = request.gav.split(":"); Map<String, Object> model = new HashMap<>(); model.put("ArtifactId", ids[1]); model.put("Version", ids[2]); @@ -1548,7 +1411,7 @@ public abstract class Exporter extends ExportRequest { // Copy the AGENTS.md into the same Maven project root directory to assist AI coding assistants. protected void copyAgents(String buildDir) throws Exception { - String[] ids = gav.split(":"); + String[] ids = request.gav.split(":"); Map<String, Object> model = new HashMap<>(); model.put("ArtifactId", ids[1]); diff --git a/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/ProjectExporter.java b/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/ProjectExporter.java index 19eba96174b0..aad433b178a6 100644 --- a/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/ProjectExporter.java +++ b/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/ProjectExporter.java @@ -190,7 +190,7 @@ public class ProjectExporter { /** * The exporter of the runtime of the request, or null for a runtime that cannot be exported to. */ - public Exporter createExporter(ExportRequest request) { + Exporter createExporter(ExportRequest request) { return switch (request.runtime) { case springBoot -> new SpringBootExporter(request, context); case quarkus -> new QuarkusExporter(request, context); diff --git a/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/QuarkusExporter.java b/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/QuarkusExporter.java index a295d8d51452..65f6b9ea7840 100644 --- a/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/QuarkusExporter.java +++ b/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/QuarkusExporter.java @@ -66,44 +66,44 @@ import static org.apache.camel.dsl.jbang.export.common.ExportHelper.exportPackag /** * Exports to a Camel Quarkus Maven project. */ -public class QuarkusExporter extends Exporter { +class QuarkusExporter extends Exporter { private QuarkusPlatformBom quarkusCamelBom; - public QuarkusExporter(ExportRequest request, ExportContext context) { + QuarkusExporter(ExportRequest request, ExportContext context) { super(request, context); - if (pomTemplateName == null) { - pomTemplateName = "quarkus-pom.ftl"; + if (this.request.pomTemplateName == null) { + this.request.pomTemplateName = "quarkus-pom.ftl"; } } @Override public Integer export() throws Exception { try { - MavenGav.parseStrictGav(gav); + MavenGav.parseStrictGav(request.gav); } catch (IllegalArgumentException e) { printer().printErr("--gav must be in syntax: groupId:artifactId:version"); return 1; } - if (parentPom != null) { + if (request.parentPom != null) { try { - MavenGav.parseStrictGav(parentPom); + MavenGav.parseStrictGav(request.parentPom); } catch (IllegalArgumentException e) { printer().printErr("--parent-pom must be in syntax: groupId:artifactId:version"); return 1; } } - String[] ids = gav.split(":"); + String[] ids = request.gav.split(":"); - exportBaseDir = exportBaseDir != null ? exportBaseDir : Path.of("."); - Path profile = exportBaseDir.resolve("application.properties"); + request.exportBaseDir = request.exportBaseDir != null ? request.exportBaseDir : Path.of("."); + Path profile = request.exportBaseDir.resolve("application.properties"); // the settings file has information what to export Path settings = runSettingsFile(); - if (mavenResolver.fresh() || !files.isEmpty() || !Files.exists(settings)) { + if (request.mavenResolver.fresh() || !request.files.isEmpty() || !Files.exists(settings)) { // allow to automatic build printer().println("Generating fresh run data"); - int silent = runSilently(ignoreLoadingError, lazyBean, verbose); + int silent = runSilently(request.ignoreLoadingError, request.lazyBean, request.verbose); if (silent != 0) { return silent; } @@ -111,7 +111,7 @@ public class QuarkusExporter extends Exporter { printer().println("Reusing existing run data"); } - printer().println("Exporting as Quarkus project to: " + exportDir); + printer().println("Exporting as Quarkus project to: " + request.exportDir); // use a temporary work dir Path buildDir = buildDir(); @@ -119,7 +119,7 @@ public class QuarkusExporter extends Exporter { Files.createDirectories(buildDir); Path srcJavaDirRoot = buildDir.resolve("src/main/java"); - String srcPackageName = exportPackageName(ids[0], ids[1], packageName); + String srcPackageName = exportPackageName(ids[0], ids[1], request.packageName); Path srcJavaDir; if (srcPackageName == null) { srcJavaDir = srcJavaDirRoot; @@ -152,12 +152,12 @@ public class QuarkusExporter extends Exporter { } } if (!prop.containsKey("quarkus.management.port")) { - port = httpManagementPort(settings); - if (port != -1) { - prop.put("quarkus.management.port", port); + request.port = ExportHelper.httpManagementPort(settings); + if (request.port != -1) { + prop.put("quarkus.management.port", request.port); } } - if (hawtio) { + if (request.hawtio) { prop.setProperty("quarkus.hawtio.authenticationEnabled", "false"); } // developer console (--console) is the camel-quarkus-console extension (/q/camel/dev-console), which @@ -170,11 +170,11 @@ public class QuarkusExporter extends Exporter { }); writeDevProfileProperties(srcResourcesDir, devProfile); // copy docker files - if (docker) { + if (request.docker) { copyDockerFiles(buildDir.toString()); } String appJar; - if ("fast-jar".equals(quarkusPackageType)) { + if ("fast-jar".equals(request.quarkusPackageType)) { appJar = "target" + File.separator + "quarkus-app" + File.separator + "quarkus-run.jar"; } else { appJar = "target" + File.separator + ids[1] + "-" + ids[2] + ".jar"; @@ -185,27 +185,27 @@ public class QuarkusExporter extends Exporter { // copy local lib JARs copyLocalLibDependencies(deps); createMavenPom(settings, buildDir.resolve("pom.xml"), deps); - if (mavenWrapper) { + if (request.mavenWrapper) { copyMavenWrapper(); } - if (camelWrapper) { + if (request.camelWrapper) { copyCamelWrapper(); } - if (cleanExportDir || !isCurrentDirOrParent(exportDir)) { + if (request.cleanExportDir || !ExportHelper.isCurrentDirOrParent(request.exportDir)) { // cleaning current dir can be a bit dangerous so only clean if explicit enabled // otherwise always clean export-dir to avoid stale data - if (cleanExportDir) { - String absPath = Path.of(exportDir).toAbsolutePath().toString(); - if (!yes && !exportContext.confirm("Are you sure you want to delete " + absPath + "?")) { + if (request.cleanExportDir) { + String absPath = Path.of(request.exportDir).toAbsolutePath().toString(); + if (!request.yes && !exportContext.confirm("Are you sure you want to delete " + absPath + "?")) { return 1; } } - ExportHelper.cleanExportDir(exportDir); + ExportHelper.cleanExportDir(request.exportDir); } // copy to export dir and remove work dir - PathUtils.copyDirectory(buildDir, Path.of(exportDir)); - createDeferredSymlinks(buildDir, Path.of(exportDir)); + PathUtils.copyDirectory(buildDir, Path.of(request.exportDir)); + createDeferredSymlinks(buildDir, Path.of(request.exportDir)); PathUtils.deleteDirectory(buildDir); return 0; @@ -280,11 +280,11 @@ public class QuarkusExporter extends Exporter { private QuarkusPlatformBom getQuarkusCamelBom() { if (quarkusCamelBom == null) { // resolve Quarkus platform version from registry (when download is true) - quarkusCamelBom = quarkusPlatform.resolve( - camelVersion, - mavenResolver.downloader()::resolveArtifact, - mavenResolver.download(), - mavenResolver.fresh()); + quarkusCamelBom = request.quarkusPlatform.resolve( + request.camelVersion, + request.mavenResolver.downloader()::resolveArtifact, + request.mavenResolver.download(), + request.mavenResolver.fresh()); } return quarkusCamelBom; } @@ -382,7 +382,7 @@ public class QuarkusExporter extends Exporter { @Override protected void copyDockerFiles(String buildDir) throws Exception { Path dockerSrc = Path.of(buildDir).resolve("src/main/docker"); - if ("uber-jar".equals(quarkusPackageType)) { + if ("uber-jar".equals(request.quarkusPackageType)) { super.copyDockerFiles(buildDir); } else { Files.createDirectories(dockerSrc); @@ -409,7 +409,7 @@ public class QuarkusExporter extends Exporter { @Override protected void copyReadme(String buildDir, String appJar) throws Exception { - String[] ids = gav.split(":"); + String[] ids = request.gav.split(":"); Map<String, Object> model = new HashMap<>(); model.put("ArtifactId", ids[1]); model.put("Version", ids[2]); @@ -422,7 +422,7 @@ public class QuarkusExporter extends Exporter { } private void createMavenPom(Path settings, Path pom, Set<String> deps) throws Exception { - String[] ids = gav.split(":"); + String[] ids = request.gav.split(":"); Properties prop = new CamelCaseOrderedProperties(); RuntimeUtil.loadProperties(prop, settings); @@ -432,8 +432,8 @@ public class QuarkusExporter extends Exporter { MavenGav quarkusCamelBom = plfBom.quarkusCamelBom(); String repos = getMavenRepositories(settings, prop, quarkusCamelBom.getVersion()); - if (camelVersion == null) { - camelVersion = plfBom.camelVersion(); + if (request.camelVersion == null) { + request.camelVersion = plfBom.camelVersion(); } // Build template data model @@ -447,8 +447,8 @@ public class QuarkusExporter extends Exporter { model.put("QuarkusArtifactId", quarkusCamelBom.getArtifactId()); model.put("QuarkusVersion", quarkusCamelBom.getVersion()); model.put("UseQuarkusJunit", VersionHelper.isGE(quarkusCamelBom.getVersion(), "3.31.0")); - model.put("QuarkusPackageType", quarkusPackageType); - model.put("JavaVersion", javaVersion); + model.put("QuarkusPackageType", request.quarkusPackageType); + model.put("JavaVersion", request.javaVersion); model.put("ProjectBuildOutputTimestamp", this.getBuildMavenProjectDate()); model.put("BuildProperties", formatBuildProperties()); model.put("Repositories", buildRepositoryList(repos)); @@ -456,14 +456,14 @@ public class QuarkusExporter extends Exporter { model.put("JibMavenPluginVersion", jibMavenPluginVersion(settings, prop)); enrichParentPom(model); - String context = TemplateHelper.processTemplate(pomTemplateName, model); + String context = TemplateHelper.processTemplate(request.pomTemplateName, model); Files.writeString(pom, context); } private List<Map<String, Object>> buildQuarkusDependencyList(Set<String> deps, MavenGav quarkusCamelBom) { List<MavenGav> gavs = new ArrayList<>(); - Path file = mavenResolver.downloader().resolveArtifact(quarkusCamelBom).getFile().toPath(); + Path file = request.mavenResolver.downloader().resolveArtifact(quarkusCamelBom).getFile().toPath(); DocumentBuilderFactory dbf = XmlHelper.createDocumentBuilderFactory(); try (InputStream in = Files.newInputStream(file)) { @@ -487,7 +487,7 @@ public class QuarkusExporter extends Exporter { gav.setVersion(null); } else { // Use plain camel with hard-coded version - gav.setVersion(camelVersion); + gav.setVersion(request.camelVersion); } } gavs.add(gav); @@ -504,7 +504,7 @@ public class QuarkusExporter extends Exporter { replaceQuarkusDependencies(gavs); // sort artifacts - gavs.sort(mavenGavComparator()); + gavs.sort(ExportHelper.mavenGavComparator()); List<Map<String, Object>> result = new ArrayList<>(); for (MavenGav gav : gavs) { @@ -553,9 +553,9 @@ public class QuarkusExporter extends Exporter { answer.removeIf(s -> s.contains("camel-core")); answer.removeIf(s -> s.contains("camel-microprofile-health")); - if (hawtio) { + if (request.hawtio) { answer.add("mvn:org.apache.camel:camel-management"); - answer.add("mvn:io.hawt:hawtio-quarkus:" + hawtioVersion); + answer.add("mvn:io.hawt:hawtio-quarkus:" + request.hawtioVersion); } if (settingsFlag(settings, CONSOLE)) { // developer console (--console) as the camel-quarkus-console extension diff --git a/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/SpringBootExporter.java b/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/SpringBootExporter.java index 1a354cf9209a..c1d523a8ec7b 100644 --- a/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/SpringBootExporter.java +++ b/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/SpringBootExporter.java @@ -54,42 +54,42 @@ import static org.apache.camel.dsl.jbang.export.common.ExportHelper.exportPackag /** * Exports to a Camel Spring Boot Maven project. */ -public class SpringBootExporter extends Exporter { +class SpringBootExporter extends Exporter { - public SpringBootExporter(ExportRequest request, ExportContext context) { + SpringBootExporter(ExportRequest request, ExportContext context) { super(request, context); - if (pomTemplateName == null) { - pomTemplateName = "spring-boot-pom.ftl"; + if (this.request.pomTemplateName == null) { + this.request.pomTemplateName = "spring-boot-pom.ftl"; } } @Override public Integer export() throws Exception { try { - MavenGav.parseStrictGav(gav); + MavenGav.parseStrictGav(request.gav); } catch (IllegalArgumentException e) { printer().printErr("--gav must be in syntax: groupId:artifactId:version"); return 1; } - if (parentPom != null) { + if (request.parentPom != null) { try { - MavenGav.parseStrictGav(parentPom); + MavenGav.parseStrictGav(request.parentPom); } catch (IllegalArgumentException e) { printer().printErr("--parent-pom must be in syntax: groupId:artifactId:version"); return 1; } } - String[] ids = gav.split(":"); + String[] ids = request.gav.split(":"); - exportBaseDir = exportBaseDir != null ? exportBaseDir : Path.of("."); - Path profile = exportBaseDir.resolve("application.properties"); + request.exportBaseDir = request.exportBaseDir != null ? request.exportBaseDir : Path.of("."); + Path profile = request.exportBaseDir.resolve("application.properties"); // the settings file has information what to export Path settings = runSettingsFile(); - if (mavenResolver.fresh() || !files.isEmpty() || !Files.exists(settings)) { + if (request.mavenResolver.fresh() || !request.files.isEmpty() || !Files.exists(settings)) { // allow to automatic build printer().println("Generating fresh run data"); - int silent = runSilently(ignoreLoadingError, lazyBean, verbose); + int silent = runSilently(request.ignoreLoadingError, request.lazyBean, request.verbose); if (silent != 0) { return silent; } @@ -97,7 +97,7 @@ public class SpringBootExporter extends Exporter { printer().println("Reusing existing run data"); } - printer().println("Exporting as Spring Boot project to: " + exportDir); + printer().println("Exporting as Spring Boot project to: " + request.exportDir); // use a temporary work dir Path buildDir = buildDir(); @@ -105,7 +105,7 @@ public class SpringBootExporter extends Exporter { Files.createDirectories(buildDir); Path srcJavaDirRoot = buildDir.resolve("src/main/java"); - String srcPackageName = exportPackageName(ids[0], ids[1], packageName); + String srcPackageName = exportPackageName(ids[0], ids[1], request.packageName); Path srcJavaDir; if (srcPackageName == null) { srcJavaDir = srcJavaDirRoot; @@ -126,7 +126,7 @@ public class SpringBootExporter extends Exporter { srcKameletsResourcesDir, srcPackageName); // create main class - createMainClassSource(srcJavaDir, srcPackageName, mainClassname); + createMainClassSource(srcJavaDir, srcPackageName, request.mainClassname); // gather dependencies final Set<String> deps = resolveDependencies(settings, profile); // copy local lib JARs @@ -153,12 +153,12 @@ public class SpringBootExporter extends Exporter { } } if (!prop.containsKey("management.server.port")) { - port = httpManagementPort(settings); - if (port != -1) { - prop.put("management.server.port", port); + request.port = ExportHelper.httpManagementPort(settings); + if (request.port != -1) { + prop.put("management.server.port", request.port); } } - if (hawtio) { + if (request.hawtio) { // spring boot needs these options configured to support hawtio prop.setProperty("management.endpoints.web.exposure.include", exposeActuatorEndpoints(prop.getProperty("management.endpoints.web.exposure.include"), @@ -173,7 +173,7 @@ public class SpringBootExporter extends Exporter { // value. With --observe the starter exposes health and prometheus as its default, which an explicit // list would replace, so keep them too (the console is then at /observe/camel) String exposed = prop.getProperty("management.endpoints.web.exposure.include"); - if (exposed == null && observe) { + if (exposed == null && request.observe) { exposed = "health,prometheus"; } exposed = exposeActuatorEndpoints(exposed, "camel"); @@ -187,58 +187,60 @@ public class SpringBootExporter extends Exporter { }); writeDevProfileProperties(srcResourcesDir, devProfile); createMavenPom(settings, profile, buildDir.resolve("pom.xml"), deps); - if (mavenWrapper) { + if (request.mavenWrapper) { copyMavenWrapper(); } - if (camelWrapper) { + if (request.camelWrapper) { copyCamelWrapper(); } - if (docker) { + if (request.docker) { copyDockerFiles(buildDir.toString()); } String appJar = "target" + File.separator + ids[1] + "-" + ids[2] + ".jar"; copyReadme(buildDir.toString(), appJar); - if (cleanExportDir || !isCurrentDirOrParent(exportDir)) { + if (request.cleanExportDir || !ExportHelper.isCurrentDirOrParent(request.exportDir)) { // cleaning current dir can be a bit dangerous so only clean if explicit enabled // otherwise always clean export-dir to avoid stale data - if (cleanExportDir) { - String absPath = Paths.get(exportDir).toAbsolutePath().toString(); - if (!yes && !exportContext.confirm("Are you sure you want to delete " + absPath + "?")) { + if (request.cleanExportDir) { + String absPath = Paths.get(request.exportDir).toAbsolutePath().toString(); + if (!request.yes && !exportContext.confirm("Are you sure you want to delete " + absPath + "?")) { return 1; } } - ExportHelper.cleanExportDir(exportDir); + ExportHelper.cleanExportDir(request.exportDir); } // copy to export dir and remove work dir - PathUtils.copyDirectory(buildDir, Paths.get(exportDir)); - createDeferredSymlinks(buildDir, Paths.get(exportDir)); + PathUtils.copyDirectory(buildDir, Paths.get(request.exportDir)); + createDeferredSymlinks(buildDir, Paths.get(request.exportDir)); PathUtils.deleteDirectory(buildDir); return 0; } private void createMavenPom(Path settings, Path profile, Path pom, Set<String> deps) throws Exception { - String[] ids = gav.split(":"); + String[] ids = request.gav.split(":"); Properties prop = new CamelCaseOrderedProperties(); RuntimeUtil.loadProperties(prop, settings); - String sbVersion = camelSpringBootVersion != null - ? camelSpringBootVersion : (camelVersion == null ? RuntimeType.main.version() : camelVersion); + String sbVersion = request.camelSpringBootVersion != null + ? request.camelSpringBootVersion + : (request.camelVersion == null ? RuntimeType.main.version() : request.camelVersion); String repos = getMavenRepositories(settings, prop, sbVersion); - CamelCatalog catalog = CatalogLoader.loadSpringBootCatalog(repos, sbVersion, sbVersion, null, mavenResolver.download()); - if (ObjectHelper.isEmpty(camelVersion)) { - camelVersion = catalog.getLoadedVersion(); + CamelCatalog catalog + = CatalogLoader.loadSpringBootCatalog(repos, sbVersion, sbVersion, null, request.mavenResolver.download()); + if (ObjectHelper.isEmpty(request.camelVersion)) { + request.camelVersion = catalog.getLoadedVersion(); } - if (ObjectHelper.isEmpty(camelVersion)) { - camelVersion = VersionHelper.extractCamelVersion(); + if (ObjectHelper.isEmpty(request.camelVersion)) { + request.camelVersion = VersionHelper.extractCamelVersion(); } // Check if catalog provides a custom template (backward compatibility) // Also check old .tmpl name for catalogs that haven't been updated - InputStream catalogTemplate = catalog.loadResource("camel-jbang", pomTemplateName); + InputStream catalogTemplate = catalog.loadResource("camel-jbang", request.pomTemplateName); if (catalogTemplate == null) { - catalogTemplate = catalog.loadResource("camel-jbang", pomTemplateName.replace(".ftl", ".tmpl")); + catalogTemplate = catalog.loadResource("camel-jbang", request.pomTemplateName.replace(".ftl", ".tmpl")); } if (catalogTemplate != null) { // Catalog provides a custom template - use legacy regex-based processing @@ -256,10 +258,10 @@ public class SpringBootExporter extends Exporter { model.put("GroupId", ids[0]); model.put("ArtifactId", ids[1]); model.put("Version", ids[2]); - model.put("SpringBootVersion", springBootVersion); - model.put("JavaVersion", javaVersion); + model.put("SpringBootVersion", request.springBootVersion); + model.put("JavaVersion", request.javaVersion); model.put("CamelSpringBootVersion", - Objects.requireNonNullElseGet(camelSpringBootVersion, () -> camelVersion)); + Objects.requireNonNullElseGet(request.camelSpringBootVersion, () -> request.camelVersion)); model.put("ProjectBuildOutputTimestamp", this.getBuildMavenProjectDate()); model.put("BuildProperties", formatBuildProperties()); model.put("Repositories", buildRepositoryList(repos)); @@ -267,7 +269,7 @@ public class SpringBootExporter extends Exporter { model.put("JibMavenPluginVersion", jibMavenPluginVersion(settings, prop)); enrichParentPom(model); - String context = TemplateHelper.processTemplate(pomTemplateName, model); + String context = TemplateHelper.processTemplate(request.pomTemplateName, model); IOHelper.writeText(context, Files.newOutputStream(pom)); } @@ -286,7 +288,7 @@ public class SpringBootExporter extends Exporter { gav.setArtifactId(am.getArtifactId()); gav.setVersion(null); } else { - gav.setVersion(camelVersion); + gav.setVersion(request.camelVersion); } } if ("org.springframework.boot".equals(gid)) { @@ -295,7 +297,7 @@ public class SpringBootExporter extends Exporter { gavs.add(gav); } - gavs.sort(mavenGavComparator()); + gavs.sort(ExportHelper.mavenGavComparator()); List<Map<String, Object>> result = new ArrayList<>(); for (MavenGav gav : gavs) { @@ -319,11 +321,11 @@ public class SpringBootExporter extends Exporter { context = context.replaceAll("\\{\\{ \\.GroupId }}", ids[0]); context = context.replaceAll("\\{\\{ \\.ArtifactId }}", ids[1]); context = context.replaceAll("\\{\\{ \\.Version }}", ids[2]); - context = context.replaceAll("\\{\\{ \\.SpringBootVersion }}", springBootVersion); - context = context.replaceAll("\\{\\{ \\.JavaVersion }}", javaVersion); - context = context.replaceAll("\\{\\{ \\.CamelVersion }}", camelVersion); + context = context.replaceAll("\\{\\{ \\.SpringBootVersion }}", request.springBootVersion); + context = context.replaceAll("\\{\\{ \\.JavaVersion }}", request.javaVersion); + context = context.replaceAll("\\{\\{ \\.CamelVersion }}", request.camelVersion); context = context.replaceAll("\\{\\{ \\.CamelSpringBootVersion }}", - Objects.requireNonNullElseGet(camelSpringBootVersion, () -> camelVersion)); + Objects.requireNonNullElseGet(request.camelSpringBootVersion, () -> request.camelVersion)); context = context.replaceFirst("\\{\\{ \\.ProjectBuildOutputTimestamp }}", this.getBuildMavenProjectDate()); context = replaceBuildProperties(context); @@ -346,7 +348,7 @@ public class SpringBootExporter extends Exporter { gav.setArtifactId(am.getArtifactId()); gav.setVersion(null); } else { - gav.setVersion(camelVersion); + gav.setVersion(request.camelVersion); } } if ("org.springframework.boot".equals(gid)) { @@ -354,7 +356,7 @@ public class SpringBootExporter extends Exporter { } gavs.add(gav); } - gavs.sort(mavenGavComparator()); + gavs.sort(ExportHelper.mavenGavComparator()); StringBuilder sb = new StringBuilder(); for (MavenGav gav : gavs) { @@ -443,10 +445,10 @@ public class SpringBootExporter extends Exporter { // include http server if using openapi answer.add("mvn:org.apache.camel:camel-platform-http"); } - if (hawtio) { + if (request.hawtio) { answer.add("mvn:org.apache.camel:camel-management"); - String hawtioArtifact = springBootVersion.startsWith("4.") ? "hawtio-springboot4" : "hawtio-springboot"; - answer.add("mvn:io.hawt:" + hawtioArtifact + ":" + hawtioVersion); + String hawtioArtifact = request.springBootVersion.startsWith("4.") ? "hawtio-springboot4" : "hawtio-springboot"; + answer.add("mvn:io.hawt:" + hawtioArtifact + ":" + request.hawtioVersion); } if (settingsFlag(settings, CamelJBangConstants.CONSOLE)) { // developer console (--console) as actuator endpoint (camel-console-starter) @@ -503,7 +505,8 @@ public class SpringBootExporter extends Exporter { // skip "camel.server." or "camel.management." as this is for camel-main only return null; } - boolean camel44orOlder = camelSpringBootVersion != null && VersionHelper.isGE("4.4.0", camelSpringBootVersion); + boolean camel44orOlder + = request.camelSpringBootVersion != null && VersionHelper.isGE("4.4.0", request.camelSpringBootVersion); if (camel44orOlder) { // camel.main.x should be renamed to camel.springboot.x (for camel 4.4.x or older) if (key.startsWith("camel.main.")) { diff --git a/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/common/ExportHelper.java b/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/common/ExportHelper.java index dd94eef2f959..6a9e57b6d1d8 100644 --- a/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/common/ExportHelper.java +++ b/dsl/camel-jbang/camel-jbang-export/src/main/java/org/apache/camel/dsl/jbang/export/common/ExportHelper.java @@ -23,11 +23,21 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.util.Arrays; +import java.util.Comparator; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Properties; import java.util.stream.Stream; +import org.apache.camel.tooling.maven.MavenGav; import org.apache.camel.util.FileUtil; import org.apache.camel.util.IOHelper; +import org.apache.camel.util.StringHelper; + +import static org.apache.camel.dsl.jbang.export.common.CamelJBangConstants.JKUBE_MAVEN_PLUGIN_VERSION; /** * Helper class provides export utilities for instance when copying files from temporary work folder to export directory @@ -204,4 +214,142 @@ public final class ExportHelper { return sb.toString(); } + public static Comparator<MavenGav> mavenGavComparator() { + return new Comparator<MavenGav>() { + @Override + public int compare(MavenGav o1, MavenGav o2) { + int r1 = rankGroupId(o1); + int r2 = rankGroupId(o2); + + if (r1 > r2) { + return -1; + } else if (r2 > r1) { + return 1; + } else { + return o1.toString().compareTo(o2.toString()); + } + } + + int rankGroupId(MavenGav o1) { + String g1 = o1.getGroupId(); + if (g1 == null) { + return 0; + } + + switch (g1) { + case "org.springframework.boot" -> { + return 30; + } + case "io.quarkus" -> { + return 30; + } + case "org.apache.camel.quarkus" -> { + String a1 = o1.getArtifactId(); + // main/core/engine first + if ("camel-quarkus-core".equals(a1)) { + return 21; + } + return 20; + } + case "org.apache.camel.springboot" -> { + String a1 = o1.getArtifactId(); + // main/core/engine first + if ("camel-spring-boot-starter".equals(a1)) { + return 21; + } else if ("camel-spring-boot-engine-starter".equals(a1)) { + return 22; + } + return 20; + } + case "org.apache.camel" -> { + String a1 = o1.getArtifactId(); + // main/core/engine first + if ("camel-main".equals(a1)) { + return 11; + } + return 10; + } + case "org.apache.camel.kamelets" -> { + return 5; + } + default -> { + return 0; + } + } + } + }; + } + + /** + * Whether the directory is the current directory, or one that contains it, such as <tt>./</tt>, <tt>$PWD</tt> or + * <tt>..</tt>: cleaning it before the export deletes the files of the project, so it is only cleaned with + * --clean-dir. + */ + public static boolean isCurrentDirOrParent(String dir) { + Path path = Path.of(dir).toAbsolutePath().normalize(); + return Path.of("").toAbsolutePath().normalize().startsWith(path); + } + + /** + * The key=value properties of the given sources, where a later source overrides an earlier one. + */ + public static Map<String, String> propertiesMap(Printer printer, String[]... propertySources) { + Map<String, String> result = new LinkedHashMap<>(); + if (propertySources != null) { + for (String[] props : Arrays.stream(propertySources).filter(Objects::nonNull).toList()) { + for (String s : props) { + String[] kv = s.split("=", 2); + if (kv.length < 2) { + printer.printWarn("property '" + s + "' has a bad format (should be 'key=value'), skipping."); + } else { + result.put(kv[0], kv[1]); + } + } + } + } + return result; + } + + /** + * The given Maven build properties (prop=value) as properties. + */ + public static Properties mapBuildProperties(List<String> buildProperties) { + var answer = new Properties(); + buildProperties.stream() + .filter(item -> !item.isEmpty()) + .map(item -> item.split("=", 2)) + .filter(toks -> toks.length == 2) + .forEach(toks -> answer.setProperty(toks[0], toks[1])); + return answer; + } + + public static int httpManagementPort(Path settings) { + try { + List<String> lines = RuntimeUtil.loadPropertiesLines(settings); + String port = lines.stream().filter(l -> l.startsWith("camel.management.port=")) + .map(s -> StringHelper.after(s, "=")).findFirst().orElse("-1"); + return Integer.parseInt(port); + } catch (Exception e) { + // ignore + } + return -1; + } + + public static String jkubeMavenPluginVersion(Path settings, Properties props) { + String answer = null; + if (props != null) { + answer = props.getProperty(JKUBE_MAVEN_PLUGIN_VERSION); + } + if (answer == null) { + try { + List<String> lines = RuntimeUtil.loadPropertiesLines(settings); + answer = lines.stream() + .filter(l -> l.startsWith(JKUBE_MAVEN_PLUGIN_VERSION + "=") || l.startsWith("jkube.version=")) + .map(s -> StringHelper.after(s, "=")).findFirst().orElse(null); + } catch (Exception e) { + // ignore + } + } + return answer != null ? answer : "1.20.0"; + } } diff --git a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExport.java b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExport.java index b21cbec14f8c..117396050074 100644 --- a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExport.java +++ b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesExport.java @@ -45,7 +45,6 @@ import org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.model.Containe import org.apache.camel.dsl.jbang.core.commands.kubernetes.traits.model.Traits; import org.apache.camel.dsl.jbang.core.common.CommandLineHelper; import org.apache.camel.dsl.jbang.export.ExportRequest; -import org.apache.camel.dsl.jbang.export.Exporter; import org.apache.camel.dsl.jbang.export.common.CatalogLoader; import org.apache.camel.dsl.jbang.export.common.ExportHelper; import org.apache.camel.dsl.jbang.export.common.MavenResolverMixinSpec; @@ -316,7 +315,7 @@ public class KubernetesExport extends Export { Traits traitsSpec = getTraitSpec(applicationProfileProperties, applicationProperties); // Map properties to env variables (where needed) - var propsMap = Exporter.propertiesMap(printer(), applicationProfileProperties, applicationProperties); + var propsMap = ExportHelper.propertiesMap(printer(), applicationProfileProperties, applicationProperties); if (propsMap.containsKey("ssl.truststore.certificates")) { addEnvVar("SSL_TRUSTSTORE_CERTIFICATES", propsMap.get("ssl.truststore.certificates")); } @@ -383,8 +382,8 @@ public class KubernetesExport extends Export { } Path settingsPath = CommandLineHelper.getWorkDir().resolve(Run.RUN_SETTINGS_FILE); - var jkubeVersion = Exporter.jkubeMavenPluginVersion(settingsPath, Exporter.mapBuildProperties(buildProperties)); - var managementPort = Exporter.httpManagementPort(settingsPath); + var jkubeVersion = ExportHelper.jkubeMavenPluginVersion(settingsPath, ExportHelper.mapBuildProperties(buildProperties)); + var managementPort = ExportHelper.httpManagementPort(settingsPath); buildProperties.add("jkube.version=%s".formatted(jkubeVersion)); boolean cronJobEnabled = traitsSpec.getCronjob() != null
