This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch fix/CAMEL-23973 in repository https://gitbox.apache.org/repos/asf/camel.git
commit ad3d17f972389dc8466c44a6de25ec9bcfa4ae37 Author: Claus Ibsen <[email protected]> AuthorDate: Sun Jul 19 14:10:31 2026 +0200 CAMEL-23973: camel export - Add --parent-pom option to set parent POM Co-Authored-By: Claude Opus 4.6 <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../ROOT/pages/camel-jbang-configuration.adoc | 3 +- .../modules/ROOT/pages/camel-jbang-projects.adoc | 34 ++++++++++++ .../camel-jbang-dependency-copy.adoc | 1 + .../camel-jbang-dependency-list.adoc | 1 + .../camel-jbang-dependency-update.adoc | 1 + .../pages/jbang-commands/camel-jbang-export.adoc | 1 + .../pages/jbang-commands/camel-jbang-sbom.adoc | 1 + .../META-INF/camel-jbang-commands-metadata.json | 6 +-- .../camel-jbang-configuration-metadata.json | 1 + .../camel/dsl/jbang/core/commands/Export.java | 3 ++ .../dsl/jbang/core/commands/ExportBaseCommand.java | 14 +++++ .../dsl/jbang/core/commands/ExportCamelMain.java | 1 + .../dsl/jbang/core/commands/ExportQuarkus.java | 1 + .../dsl/jbang/core/commands/ExportSpringBoot.java | 1 + .../dsl/jbang/core/common/CamelJBangConstants.java | 4 ++ .../resources/templates/main-kubernetes-pom.ftl | 9 ++++ .../src/main/resources/templates/main-pom.ftl | 9 ++++ .../resources/templates/quarkus-kubernetes-pom.ftl | 9 ++++ .../src/main/resources/templates/quarkus-pom.ftl | 9 ++++ .../templates/spring-boot-kubernetes-pom.ftl | 9 ++++ .../main/resources/templates/spring-boot-pom.ftl | 9 ++++ .../camel/dsl/jbang/core/commands/ExportTest.java | 61 ++++++++++++++++++++++ 22 files changed, 184 insertions(+), 4 deletions(-) diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang-configuration.adoc b/docs/user-manual/modules/ROOT/pages/camel-jbang-configuration.adoc index f6c9408aa0f6..4a38e58f513a 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-jbang-configuration.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-jbang-configuration.adoc @@ -4,7 +4,7 @@ This page covers configuring the Camel CLI — available options, configuration // jbang options: START == Camel CLI configurations -The camel.jbang supports 48 options, which are listed below. +The camel.jbang supports 49 options, which are listed below. [width="100%",cols="2,5,^1,2",options="header"] |=== @@ -43,6 +43,7 @@ The camel.jbang supports 48 options, which are listed below. | *camel.jbang.metrics* | Metrics (Micrometer and Prometheus) at /observe/metrics on local HTTP server (port 8080 by default) when running standalone Camel | false | boolean | *camel.jbang.openApi* | File name of open-api spec file (JSON or YAML) to generate routes from the swagger/openapi API spec file. | | String | *camel.jbang.packageScanJars* | Whether to automatic package scan JARs for custom Spring or Quarkus beans making them available for Camel CLI | false | boolean +| *camel.jbang.parentPom* | Parent POM coordinate (groupId:artifactId:version) to use in the exported project | | String | *camel.jbang.prompt* | Allow user to type in required parameters in prompt if not present in application | false | boolean | *camel.jbang.quarkusArtifactId* | artifactId of Quarkus Platform BOM | | String | *camel.jbang.quarkusExtensionRegistryBaseUri* | The base URI of Quarkus Extension Registry | | String diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang-projects.adoc b/docs/user-manual/modules/ROOT/pages/camel-jbang-projects.adoc index 5d416f666882..26b621316a9b 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-jbang-projects.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-jbang-projects.adoc @@ -23,6 +23,40 @@ Notes: - The `--profile` option is not supported when exporting to Quarkus. - For Spring Boot, you can override versions with `--camel-spring-boot-version`. +=== Exporting with a parent POM + +When organizations run many Camel integrations, they typically use a parent POM to standardize +plugin versions, required extensions, and common dependencies. Use `--parent-pom` to set the +parent POM in the exported project: + +[source,bash] +---- +camel export --runtime=quarkus --gav=com.foo:acme:1.0-SNAPSHOT --parent-pom=com.ourorg:camel-parent:1.0 +---- + +This generates the `<parent>` block in the exported `pom.xml`: + +[source,xml] +---- +<parent> + <groupId>com.ourorg</groupId> + <artifactId>camel-parent</artifactId> + <version>1.0</version> + <relativePath/> +</parent> +---- + +For Spring Boot, specifying `--parent-pom` replaces the default `spring-boot-starter-parent`. +The Spring Boot BOM (`spring-boot-dependencies`) remains in `<dependencyManagement>`, so version +management continues to work. + +You can also configure this in `application.properties`: + +[source,properties] +---- +camel.jbang.parentPom=com.ourorg:camel-parent:1.0 +---- + === Exporting with Java Agent included NOTE: Only `camel-main` runtime supports Java Agents. diff --git a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-copy.adoc b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-copy.adoc index 655fa496ce3e..d8c90d2e84ef 100644 --- a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-copy.adoc +++ b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-copy.adoc @@ -55,6 +55,7 @@ camel dependency copy [options] | `--output-directory` | Directory where dependencies should be copied | lib | String | `--package-name` | For Java source files should they have the given package name. By default the package name is computed from the Maven GAV. Use false to turn off and not include package name in the Java source files. | | String | `--package-scan-jars` | Whether to automatic package scan JARs for custom Spring or Quarkus beans making them available for Camel CLI | false | boolean +| `--parent-pom` | The Maven parent POM group:artifact:version | | String | `--port` | Embeds a local HTTP server on this port | | int | `--profile` | Profile to export (dev, test, prod). | | String | `--prop,--property` | Camel application properties, ex. --property=prop1=foo | | String diff --git a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-list.adoc b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-list.adoc index 496d702ec96e..575369f1c32b 100644 --- a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-list.adoc +++ b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-list.adoc @@ -54,6 +54,7 @@ camel dependency list [options] | `--output` | Output format (gav, maven, jbang) | gav | String | `--package-name` | For Java source files should they have the given package name. By default the package name is computed from the Maven GAV. Use false to turn off and not include package name in the Java source files. | | String | `--package-scan-jars` | Whether to automatic package scan JARs for custom Spring or Quarkus beans making them available for Camel CLI | false | boolean +| `--parent-pom` | The Maven parent POM group:artifact:version | | String | `--port` | Embeds a local HTTP server on this port | | int | `--profile` | Profile to export (dev, test, prod). | | String | `--prop,--property` | Camel application properties, ex. --property=prop1=foo | | String diff --git a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-update.adoc b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-update.adoc index a5b022885b9e..f5310726df1c 100644 --- a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-update.adoc +++ b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-dependency-update.adoc @@ -55,6 +55,7 @@ camel dependency update [options] | `--output` | Output format (gav, maven, jbang) | gav | String | `--package-name` | For Java source files should they have the given package name. By default the package name is computed from the Maven GAV. Use false to turn off and not include package name in the Java source files. | | String | `--package-scan-jars` | Whether to automatic package scan JARs for custom Spring or Quarkus beans making them available for Camel CLI | false | boolean +| `--parent-pom` | The Maven parent POM group:artifact:version | | String | `--port` | Embeds a local HTTP server on this port | | int | `--profile` | Profile to export (dev, test, prod). | | String | `--prop,--property` | Camel application properties, ex. --property=prop1=foo | | String diff --git a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-export.adoc b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-export.adoc index e1551ba4d721..b78a1b2349f6 100644 --- a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-export.adoc +++ b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-export.adoc @@ -53,6 +53,7 @@ camel export [options] | `--open-api` | Adds an OpenAPI spec from the given file (json or yaml file) | | String | `--package-name` | For Java source files should they have the given package name. By default the package name is computed from the Maven GAV. Use false to turn off and not include package name in the Java source files. | | String | `--package-scan-jars` | Whether to automatic package scan JARs for custom Spring or Quarkus beans making them available for Camel CLI | false | boolean +| `--parent-pom` | The Maven parent POM group:artifact:version | | String | `--port` | Embeds a local HTTP server on this port | | int | `--profile` | Profile to export (dev, test, prod). | | String | `--prop,--property` | Camel application properties, ex. --property=prop1=foo | | String diff --git a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-sbom.adoc b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-sbom.adoc index 45f5d60a14ec..06036a020a35 100644 --- a/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-sbom.adoc +++ b/docs/user-manual/modules/ROOT/pages/jbang-commands/camel-jbang-sbom.adoc @@ -56,6 +56,7 @@ camel sbom [options] | `--output-name` | Output name of the SBOM file | sbom | String | `--package-name` | For Java source files should they have the given package name. By default the package name is computed from the Maven GAV. Use false to turn off and not include package name in the Java source files. | | String | `--package-scan-jars` | Whether to automatic package scan JARs for custom Spring or Quarkus beans making them available for Camel CLI | false | boolean +| `--parent-pom` | The Maven parent POM group:artifact:version | | String | `--port` | Embeds a local HTTP server on this port | | int | `--profile` | Profile to export (dev, test, prod). | | String | `--prop,--property` | Camel application properties, ex. --property=prop1=foo | | String diff --git a/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json b/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json index 42de90d02fe7..7f66b663a036 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json +++ b/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-commands-metadata.json @@ -7,14 +7,14 @@ { "name": "completion", "fullName": "completion", "description": "Generate completion script for bash\/zsh", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Complete", "options": [ { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ] }, { "name": "config", "fullName": "config", "description": "Get and set user configuration values", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.config.ConfigCommand", "options": [ { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name": "get", "fullName": "config get", "description": "Display user configuration value", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.config. [...] { "name": "debug", "fullName": "debug", "description": "Debug local Camel integration", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Debug", "options": [ { "names": "--ago", "description": "Use ago instead of yyyy-MM-dd HH:mm:ss in timestamp.", "javaType": "boolean", "type": "boolean" }, { "names": "--background", "description": "Run in the background", "defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": "--background-wait", "description": "To [...] - { "name": "dependency", "fullName": "dependency", "description": "Displays all Camel dependencies required to run", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.DependencyCommand", "options": [ { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name": "copy", "fullName": "dependency copy", "description": "Copies all Camel dependencies required to run to a specific directory", "sourc [...] + { "name": "dependency", "fullName": "dependency", "description": "Displays all Camel dependencies required to run", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.DependencyCommand", "options": [ { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name": "copy", "fullName": "dependency copy", "description": "Copies all Camel dependencies required to run to a specific directory", "sourc [...] { "name": "dev", "fullName": "dev", "description": "Run in dev mode with live reload", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Dev", "options": [ { "names": "--background", "description": "Run in the background", "defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": "--background-wait", "description": "To wait for run in background to startup successfully, before returning", "defaultValue": "true", "javaType": "boolean", "type": "boolean" }, [...] { "name": "dirty", "fullName": "dirty", "description": "Check if there are dirty files from previous Camel runs that did not terminate gracefully", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.process.Dirty", "options": [ { "names": "--clean", "description": "Clean dirty files which are no longer in use", "defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", " [...] { "name": "doc", "fullName": "doc", "description": "Shows documentation for kamelet, component, and other Camel resources", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.catalog.CatalogDoc", "options": [ { "names": "--camel-version", "description": "To use a different Camel version than the default version", "javaType": "java.lang.String", "type": "string" }, { "names": "--download", "description": "Whether to allow automatic downloading JAR dependencies (over the internet [...] { "name": "doctor", "fullName": "doctor", "description": "Checks the environment and reports potential issues", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Doctor", "options": [ { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ] }, { "name": "eval", "fullName": "eval", "description": "Evaluate Camel expressions and scripts", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.EvalCommand", "options": [ { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name": "expression", "fullName": "eval expression", "description": "Evaluates Camel expression", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.action.EvalEx [...] { "name": "explain", "fullName": "explain", "description": "Explain what a Camel route does using AI\/LLM", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Explain", "options": [ { "names": "--api-key", "description": "API key for authentication. Also reads ANTHROPIC_API_KEY, OPENAI_API_KEY, or LLM_API_KEY env vars", "javaType": "java.lang.String", "type": "string" }, { "names": "--api-type", "description": "API type: 'ollama', 'openai' (OpenAI-compatible), or 'anthropic' (A [...] - { "name": "export", "fullName": "export", "description": "Export to other runtimes (Camel Main, Spring Boot, or Quarkus)", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Export", "options": [ { "names": "--build-property", "description": "Maven build properties, ex. --build-property=prop1=foo", "javaType": "java.util.List", "type": "array" }, { "names": "--camel-spring-boot-version", "description": "Camel version to use with Spring Boot", "javaType": "java.lang.String", "ty [...] + { "name": "export", "fullName": "export", "description": "Export to other runtimes (Camel Main, Spring Boot, or Quarkus)", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Export", "options": [ { "names": "--build-property", "description": "Maven build properties, ex. --build-property=prop1=foo", "javaType": "java.util.List", "type": "array" }, { "names": "--camel-spring-boot-version", "description": "Camel version to use with Spring Boot", "javaType": "java.lang.String", "ty [...] { "name": "get", "fullName": "get", "description": "Get status of Camel integrations", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.process.CamelStatus", "options": [ { "names": "--watch", "description": "Execute periodically and showing output fullscreen", "javaType": "boolean", "type": "boolean" }, { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ], "subcommands": [ { "name": "activity", "fullName": " [...] { "name": "harden", "fullName": "harden", "description": "Suggest security hardening for Camel routes using AI\/LLM", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Harden", "options": [ { "names": "--api-key", "description": "API key for authentication. Also reads OPENAI_API_KEY or LLM_API_KEY env vars", "javaType": "java.lang.String", "type": "string" }, { "names": "--api-type", "description": "API type: 'ollama' or 'openai' (OpenAI-compatible)", "defaultValue": "ollama", [...] { "name": "hawtio", "fullName": "hawtio", "description": "Launch Hawtio web console", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.process.Hawtio", "options": [ { "names": "--host", "description": "Hostname to bind the Hawtio web console to", "defaultValue": "127.0.0.1", "javaType": "java.lang.String", "type": "string" }, { "names": "--openUrl", "description": "To automatic open Hawtio web console in the web browser", "defaultValue": "true", "javaType": "boolean", "type": [...] @@ -27,7 +27,7 @@ { "name": "ps", "fullName": "ps", "description": "List running Camel integrations", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.process.ListProcess", "options": [ { "names": "--json", "description": "Output in JSON Format", "javaType": "boolean", "type": "boolean" }, { "names": "--pid", "description": "List only pid in the output", "javaType": "boolean", "type": "boolean" }, { "names": "--remote", "description": "Break down counters into remote\/total pairs", "javaType": [...] { "name": "restart", "fullName": "restart", "description": "Restarts running Camel integrations (stop + re-launch)", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.process.RestartProcess", "options": [ { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ] }, { "name": "run", "fullName": "run", "description": "Run as local Camel integration", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Run", "options": [ { "names": "--background", "description": "Run in the background", "defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": "--background-wait", "description": "To wait for run in background to startup successfully, before returning", "defaultValue": "true", "javaType": "boolean", "type": "boolean" }, { [...] - { "name": "sbom", "fullName": "sbom", "description": "Generate a CycloneDX or SPDX SBOM for a specific project", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.SBOMGenerator", "options": [ { "names": "--build-property", "description": "Maven build properties, ex. --build-property=prop1=foo", "javaType": "java.util.List", "type": "array" }, { "names": "--camel-spring-boot-version", "description": "Camel version to use with Spring Boot", "javaType": "java.lang.String", "type" [...] + { "name": "sbom", "fullName": "sbom", "description": "Generate a CycloneDX or SPDX SBOM for a specific project", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.SBOMGenerator", "options": [ { "names": "--build-property", "description": "Maven build properties, ex. --build-property=prop1=foo", "javaType": "java.util.List", "type": "array" }, { "names": "--camel-spring-boot-version", "description": "Camel version to use with Spring Boot", "javaType": "java.lang.String", "type" [...] { "name": "script", "fullName": "script", "description": "Run Camel integration as shell script for terminal scripting", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Script", "options": [ { "names": "--logging", "description": "Can be used to turn on logging (logs to file in <user home>\/.camel directory)", "defaultValue": "false", "javaType": "boolean", "type": "boolean" }, { "names": "--logging-level", "description": "Logging level (ERROR, WARN, INFO, DEBUG, TRACE)", "d [...] { "name": "shell", "fullName": "shell", "description": "Interactive Camel CLI shell.", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.Shell", "options": [ { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ] }, { "name": "stop", "fullName": "stop", "description": "Shuts down running Camel integrations", "sourceClass": "org.apache.camel.dsl.jbang.core.commands.process.StopProcess", "options": [ { "names": "--kill", "description": "To force killing the process (SIGKILL)", "javaType": "boolean", "type": "boolean" }, { "names": "-h,--help", "description": "Display the help and sub-commands", "javaType": "boolean", "type": "boolean" } ] }, diff --git a/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-configuration-metadata.json b/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-configuration-metadata.json index 822581e20943..c28faba036ef 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-configuration-metadata.json +++ b/dsl/camel-jbang/camel-jbang-core/src/generated/resources/META-INF/camel-jbang-configuration-metadata.json @@ -37,6 +37,7 @@ { "name": "camel.jbang.metrics", "required": false, "description": "Metrics (Micrometer and Prometheus) at \/observe\/metrics on local HTTP server (port 8080 by default) when running standalone Camel", "type": "boolean", "javaType": "boolean", "defaultValue": false, "secret": false, "deprecated": true }, { "name": "camel.jbang.openApi", "required": false, "description": "File name of open-api spec file (JSON or YAML) to generate routes from the swagger\/openapi API spec file.", "type": "string", "javaType": "String", "secret": false }, { "name": "camel.jbang.packageScanJars", "required": false, "description": "Whether to automatic package scan JARs for custom Spring or Quarkus beans making them available for Camel CLI", "label": "advanced", "type": "boolean", "javaType": "boolean", "defaultValue": false, "secret": false }, + { "name": "camel.jbang.parentPom", "required": false, "description": "Parent POM coordinate (groupId:artifactId:version) to use in the exported project", "type": "string", "javaType": "String", "secret": false }, { "name": "camel.jbang.prompt", "required": false, "description": "Allow user to type in required parameters in prompt if not present in application", "label": "advanced", "type": "boolean", "javaType": "boolean", "defaultValue": false, "secret": false }, { "name": "camel.jbang.quarkusArtifactId", "required": false, "description": "artifactId of Quarkus Platform BOM", "label": "quarkus", "type": "string", "javaType": "String", "secret": false, "deprecated": true }, { "name": "camel.jbang.quarkusExtensionRegistryBaseUri", "required": false, "description": "The base URI of Quarkus Extension Registry", "label": "quarkus", "type": "string", "javaType": "String", "secret": false }, diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Export.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Export.java index 09912a00615e..f7538ec227ff 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Export.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Export.java @@ -51,6 +51,7 @@ import static org.apache.camel.dsl.jbang.core.common.CamelJBangConstants.MAVEN_S import static org.apache.camel.dsl.jbang.core.common.CamelJBangConstants.MAVEN_SETTINGS_SECURITY; import static org.apache.camel.dsl.jbang.core.common.CamelJBangConstants.MAVEN_WRAPPER; import static org.apache.camel.dsl.jbang.core.common.CamelJBangConstants.OPEN_API; +import static org.apache.camel.dsl.jbang.core.common.CamelJBangConstants.PARENT_POM; import static org.apache.camel.dsl.jbang.core.common.CamelJBangConstants.SPRING_BOOT_VERSION; @Command(name = "export", @@ -190,6 +191,7 @@ public class Export extends ExportBaseCommand { this.runtime = RuntimeType.fromValue(rt); } this.gav = props.getProperty(GAV, this.gav); + this.parentPom = props.getProperty(PARENT_POM, this.parentPom); // allow configuring versions from profile this.javaVersion = props.getProperty(JAVA_VERSION, this.javaVersion); this.camelVersion = props.getProperty(CAMEL_VERSION, this.camelVersion); @@ -234,6 +236,7 @@ public class Export extends ExportBaseCommand { cmd.managementPort = this.managementPort; cmd.observe = this.observe; cmd.gav = this.gav; + cmd.parentPom = this.parentPom; cmd.mavenSettings = this.mavenSettings; cmd.mavenSettingsSecurity = this.mavenSettingsSecurity; cmd.mavenCentralEnabled = this.mavenCentralEnabled; 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 66393190a527..edbc545cb544 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 @@ -135,6 +135,9 @@ public abstract class ExportBaseCommand extends CamelCommand { @CommandLine.Option(names = { "--gav" }, description = "The Maven group:artifact:version") protected String gav; + @CommandLine.Option(names = { "--parent-pom" }, description = "The Maven parent POM group:artifact:version") + protected String parentPom; + @CommandLine.Option(names = { "--exclude" }, description = "Exclude files by name or pattern") protected List<String> excludes = new ArrayList<>(); @@ -514,6 +517,17 @@ public abstract class ExportBaseCommand extends CamelCommand { /** * Formats build properties as XML property lines for inclusion in POM templates. */ + protected void enrichParentPom(Map<String, Object> model) { + if (parentPom != null) { + String[] parts = parentPom.split(":"); + if (parts.length == 3) { + model.put("ParentGroupId", parts[0]); + model.put("ParentArtifactId", parts[1]); + model.put("ParentVersion", parts[2]); + } + } + } + protected String formatBuildProperties() { Properties properties = mapBuildProperties(); diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportCamelMain.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportCamelMain.java index 4dcbc8b41f57..63c39a4ca544 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportCamelMain.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportCamelMain.java @@ -217,6 +217,7 @@ class ExportCamelMain extends Export { model.put("Repositories", buildRepositoryList(repos)); model.put("Dependencies", buildDependencyList(deps)); model.put("JibMavenPluginVersion", jibMavenPluginVersion(settings, prop)); + enrichParentPom(model); // kubernetes/docker properties enrichKubernetesModel(model, settings, profile); diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java index d7f18af8efe3..dded02aa0d54 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java @@ -396,6 +396,7 @@ class ExportQuarkus extends Export { model.put("Repositories", buildRepositoryList(repos)); model.put("Dependencies", depList); model.put("JibMavenPluginVersion", jibMavenPluginVersion(settings, prop)); + enrichParentPom(model); String context = TemplateHelper.processTemplate(pomTemplateName, model); Files.writeString(pom, context); diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportSpringBoot.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportSpringBoot.java index dd5919f5b1a3..3893b16e36e8 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportSpringBoot.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportSpringBoot.java @@ -228,6 +228,7 @@ class ExportSpringBoot extends Export { model.put("Repositories", buildRepositoryList(repos)); model.put("Dependencies", depList); model.put("JibMavenPluginVersion", jibMavenPluginVersion(settings, prop)); + enrichParentPom(model); String context = TemplateHelper.processTemplate(pomTemplateName, model); IOHelper.writeText(context, Files.newOutputStream(pom)); diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CamelJBangConstants.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CamelJBangConstants.java index de13ed94b4f4..403761e5997f 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CamelJBangConstants.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CamelJBangConstants.java @@ -68,6 +68,10 @@ public final class CamelJBangConstants { javaType = "String") public static final String GAV = "camel.jbang.gav"; + @Metadata(description = "Parent POM coordinate (groupId:artifactId:version) to use in the exported project", + javaType = "String") + public static final String PARENT_POM = "camel.jbang.parentPom"; + @Metadata(description = "Java version", javaType = "String", enums = "21", defaultValue = "21") public static final String JAVA_VERSION = "camel.jbang.javaVersion"; diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/main-kubernetes-pom.ftl b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/main-kubernetes-pom.ftl index 784b56ef6a16..6e9171ca79d6 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/main-kubernetes-pom.ftl +++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/main-kubernetes-pom.ftl @@ -21,6 +21,15 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> +[#if ParentGroupId??] + <parent> + <groupId>[=ParentGroupId]</groupId> + <artifactId>[=ParentArtifactId]</artifactId> + <version>[=ParentVersion]</version> + <relativePath/> + </parent> + +[/#if] <groupId>[=GroupId]</groupId> <artifactId>[=ArtifactId]</artifactId> <version>[=Version]</version> diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/main-pom.ftl b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/main-pom.ftl index a5bf0a3966ec..7fcf6c241dbb 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/main-pom.ftl +++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/main-pom.ftl @@ -21,6 +21,15 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> +[#if ParentGroupId??] + <parent> + <groupId>[=ParentGroupId]</groupId> + <artifactId>[=ParentArtifactId]</artifactId> + <version>[=ParentVersion]</version> + <relativePath/> + </parent> + +[/#if] <groupId>[=GroupId]</groupId> <artifactId>[=ArtifactId]</artifactId> <version>[=Version]</version> diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/quarkus-kubernetes-pom.ftl b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/quarkus-kubernetes-pom.ftl index afddc007214a..625455e127f0 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/quarkus-kubernetes-pom.ftl +++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/quarkus-kubernetes-pom.ftl @@ -22,6 +22,15 @@ <modelVersion>4.0.0</modelVersion> +[#if ParentGroupId??] + <parent> + <groupId>[=ParentGroupId]</groupId> + <artifactId>[=ParentArtifactId]</artifactId> + <version>[=ParentVersion]</version> + <relativePath/> + </parent> + +[/#if] <groupId>[=GroupId]</groupId> <artifactId>[=ArtifactId]</artifactId> <version>[=Version]</version> diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/quarkus-pom.ftl b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/quarkus-pom.ftl index c5f393931c17..61a60b31e9bb 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/quarkus-pom.ftl +++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/quarkus-pom.ftl @@ -21,6 +21,15 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> +[#if ParentGroupId??] + <parent> + <groupId>[=ParentGroupId]</groupId> + <artifactId>[=ParentArtifactId]</artifactId> + <version>[=ParentVersion]</version> + <relativePath/> + </parent> + +[/#if] <groupId>[=GroupId]</groupId> <artifactId>[=ArtifactId]</artifactId> <version>[=Version]</version> diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-kubernetes-pom.ftl b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-kubernetes-pom.ftl index 03b0975f706f..844b4c59b660 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-kubernetes-pom.ftl +++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-kubernetes-pom.ftl @@ -21,12 +21,21 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> +[#if ParentGroupId??] + <parent> + <groupId>[=ParentGroupId]</groupId> + <artifactId>[=ParentArtifactId]</artifactId> + <version>[=ParentVersion]</version> + <relativePath/> + </parent> +[#else] <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>[=SpringBootVersion]</version> <relativePath/> <!-- lookup parent from repository --> </parent> +[/#if] <groupId>[=GroupId]</groupId> <artifactId>[=ArtifactId]</artifactId> diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-pom.ftl b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-pom.ftl index 839893fd627c..6ef05a172a9e 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-pom.ftl +++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-pom.ftl @@ -21,12 +21,21 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> +[#if ParentGroupId??] + <parent> + <groupId>[=ParentGroupId]</groupId> + <artifactId>[=ParentArtifactId]</artifactId> + <version>[=ParentVersion]</version> + <relativePath/> + </parent> +[#else] <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>[=SpringBootVersion]</version> <relativePath/> <!-- lookup parent from repository --> </parent> +[/#if] <groupId>[=GroupId]</groupId> <artifactId>[=ArtifactId]</artifactId> diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java index ca623d5cdbab..3f943ff9eae0 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java +++ b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java @@ -987,6 +987,67 @@ class ExportTest { } } + @ParameterizedTest + @MethodSource("runtimeProvider") + public void shouldExportWithParentPom(RuntimeType rt) throws Exception { + LOG.info("shouldExportWithParentPom {}", rt); + Export command = new Export(new CamelJBangMain()); + List<String> cmdArgs = new ArrayList<>( + List.of("--gav=examples:route:1.0.0", "--dir=" + workingDir, + "--runtime=%s".formatted(rt.runtime()), + "--parent-pom=com.ourorg:camel-parent:1.0")); + if (rt == RuntimeType.springBoot) { + cmdArgs.add("--camel-version=" + RELEASED_CAMEL_VERSION); + } + cmdArgs.add("target/test-classes/route.yaml"); + CommandLine.populateCommand(command, cmdArgs.toArray(String[]::new)); + int exit = command.doCall(); + + Assertions.assertEquals(0, exit); + Model model = readMavenModel(); + Assertions.assertEquals("examples", model.getGroupId()); + Assertions.assertEquals("route", model.getArtifactId()); + Assertions.assertEquals("1.0.0", model.getVersion()); + + // verify parent POM is set + Assertions.assertNotNull(model.getParent(), "Parent POM should be set"); + Assertions.assertEquals("com.ourorg", model.getParent().getGroupId()); + Assertions.assertEquals("camel-parent", model.getParent().getArtifactId()); + Assertions.assertEquals("1.0", model.getParent().getVersion()); + + if (rt == RuntimeType.springBoot) { + // Spring Boot BOM should still be in dependencyManagement + assertThat(model.getDependencyManagement().getDependencies()) + .as("Spring Boot BOM must be in dependencyManagement when using custom parent") + .anySatisfy(dep -> { + assertThat(dep.getGroupId()).isEqualTo("org.springframework.boot"); + assertThat(dep.getArtifactId()).isEqualTo("spring-boot-dependencies"); + }); + } + } + + @ParameterizedTest + @MethodSource("runtimeProvider") + public void shouldExportWithoutParentPom(RuntimeType rt) throws Exception { + LOG.info("shouldExportWithoutParentPom {}", rt); + Export command = createCommand(rt, new String[] { "classpath:route.yaml" }, + "--gav=examples:route:1.0.0", "--dir=" + workingDir, "--quiet"); + int exit = command.doCall(); + + Assertions.assertEquals(0, exit); + Model model = readMavenModel(); + + if (rt == RuntimeType.springBoot) { + // default Spring Boot parent should be used + Assertions.assertNotNull(model.getParent(), "Spring Boot parent should be set by default"); + Assertions.assertEquals("org.springframework.boot", model.getParent().getGroupId()); + Assertions.assertEquals("spring-boot-starter-parent", model.getParent().getArtifactId()); + } else { + // Quarkus and Main should have no parent by default + Assertions.assertNull(model.getParent(), "No parent POM should be set by default for " + rt); + } + } + @ParameterizedTest @MethodSource("runtimeProvider") public void shouldContainJibProfile(RuntimeType rt) throws Exception {
