This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new ddb7154e9089 CAMEL-23441: camel-jbang - Export to support install 
camel wrapper
ddb7154e9089 is described below

commit ddb7154e9089b33735ae5345606880cb2bd1d840
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Aug 5 19:36:53 2026 +0200

    CAMEL-23441: camel-jbang - Export to support install camel wrapper
    
    Add --camel-wrapper option to camel export so the Camel Wrapper scripts
    are included in the exported project for version pinning, similar to how
    --maven-wrapper includes the Maven Wrapper.
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 .../jbang/camel-jbang-configuration-metadata.json  |  1 +
 .../ROOT/pages/camel-jbang-configuration.adoc      |  3 +-
 .../modules/ROOT/pages/camel-jbang-projects.adoc   | 29 ++++++++++++++++
 .../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      |  4 +++
 .../dsl/jbang/core/commands/ExportBaseCommand.java | 34 +++++++++++++++++++
 .../dsl/jbang/core/commands/ExportCamelMain.java   |  3 ++
 .../dsl/jbang/core/commands/ExportQuarkus.java     |  3 ++
 .../dsl/jbang/core/commands/ExportSpringBoot.java  |  3 ++
 .../dsl/jbang/core/common/CamelJBangConstants.java |  4 +++
 .../camel/dsl/jbang/core/commands/ExportTest.java  | 39 ++++++++++++++++++++++
 .../core/commands/kubernetes/KubernetesExport.java |  2 ++
 .../core/commands/kubernetes/KubernetesRun.java    |  1 +
 19 files changed, 134 insertions(+), 4 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/jbang/camel-jbang-configuration-metadata.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/jbang/camel-jbang-configuration-metadata.json
index 2009c64f7a0c..f4b422e1b40c 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/jbang/camel-jbang-configuration-metadata.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/jbang/camel-jbang-configuration-metadata.json
@@ -5,6 +5,7 @@
   "properties": [
     { "name": "camel.jbang.camel-version", "required": false, "description": 
"The version of Apache Camel to use", "type": "string", "javaType": "String", 
"secret": false },
     { "name": "camel.jbang.camelSpringBootVersion", "required": false, 
"description": "To use a custom Camel version when running or export to Spring 
Boot", "label": "spring-boot", "type": "string", "javaType": "String", 
"secret": false },
+    { "name": "camel.jbang.camelWrapper", "required": false, "description": 
"Include Camel Wrapper scripts in the exported project for version pinning", 
"type": "boolean", "javaType": "boolean", "defaultValue": false, "secret": 
false },
     { "name": "camel.jbang.classpathFiles", "required": false, "description": 
"Additional files to add to classpath (Use commas to separate multiple 
files).", "type": "string", "javaType": "String", "secret": false },
     { "name": "camel.jbang.compileWorkDir", "required": false, "description": 
"Work directory for compiler. Can be used to write compiled classes or other 
resources.", "label": "advanced", "type": "string", "javaType": "String", 
"defaultValue": ".camel-jbang\/compile", "secret": false },
     { "name": "camel.jbang.console", "required": false, "description": 
"Developer console at \/q\/dev on local HTTP server (port 8080 by default)", 
"type": "boolean", "javaType": "boolean", "defaultValue": false, "secret": 
false },
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 16d59ff73148..58d8bc24c988 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-jbang-configuration.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-jbang-configuration.adoc
@@ -4,13 +4,14 @@ This page covers configuring the Camel CLI — available 
options, configuration
 
 // jbang options: START
 == Camel CLI configurations
-The camel.jbang supports 51 options, which are listed below.
+The camel.jbang supports 52 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
 | *camel.jbang.camel-version* | The version of Apache Camel to use |  | String
 | *camel.jbang.camelSpringBootVersion* | To use a custom Camel version when 
running or export to Spring Boot |  | String
+| *camel.jbang.camelWrapper* | Include Camel Wrapper scripts in the exported 
project for version pinning | false | boolean
 | *camel.jbang.classpathFiles* | Additional files to add to classpath (Use 
commas to separate multiple files). |  | String
 | *camel.jbang.compileWorkDir* | Work directory for compiler. Can be used to 
write compiled classes or other resources. | .camel-jbang/compile | String
 | *camel.jbang.console* | Developer console at /q/dev on local HTTP server 
(port 8080 by default) | false | boolean
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 05e53e7039e5..b924553da6c9 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-jbang-projects.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-jbang-projects.adoc
@@ -93,6 +93,35 @@ camel export bar.xml cheese.yaml --runtime=spring-boot 
--gav=com.foo:cheese:1.0-
 
 NOTE: `application.properties` is included in all exports automatically.
 
+=== Exporting with Camel Wrapper
+
+Use `--camel-wrapper` to include Camel Wrapper scripts in the exported project.
+This works like the Maven Wrapper — it pins a specific Camel CLI version so 
that anyone
+working on the project uses the same version without a separate install:
+
+[source,bash]
+----
+camel export --runtime=spring-boot --gav=com.foo:acme:1.0-SNAPSHOT 
--camel-wrapper
+----
+
+This adds the following files to the exported project:
+
+- `camel` and `camel.cmd` — launcher scripts that download and run the pinned 
Camel CLI version
+- `.camel/camel-wrapper.properties` — contains the pinned `camel.version` and 
download URL
+
+The pinned version matches the Camel version used in the export. After 
exporting, use `./camel`
+instead of a globally installed `camel` to ensure the project always uses the 
correct version.
+
+You can also set this in `application.properties`:
+
+[source,properties]
+----
+camel.jbang.camelWrapper=true
+----
+
+TIP: The Camel Wrapper can also be installed standalone with `camel wrapper`.
+See xref:camel-jbang-installation.adoc[Installation Options] for details.
+
 === Including JMX management or CLI connector
 
 JMX management and CLI connector are not included by default. Add them with 
`--dep`:
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 2149196f292e..73e75c571797 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
@@ -22,6 +22,7 @@ camel dependency copy [options]
 | `--build-property` | Maven build properties, ex. --build-property=prop1=foo 
|  | List
 | `--camel-spring-boot-version` | Camel version to use with Spring Boot |  | 
String
 | `--camel-version` | To export using a different Camel version than the 
default version. |  | String
+| `--camel-wrapper` | Include Camel Wrapper scripts in exported project for 
version pinning | false | boolean
 | `--clean-dir` | If exporting to current directory (default) then all 
existing files are preserved. Enabling this option will force cleaning current 
directory including all sub dirs (use this with care) | false | boolean
 | `--dep,--dependency` | Add additional dependencies |  | List
 | `--dir,--directory` | Directory where the project will be exported | . | 
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 a87b96fed253..7c779c5ace2d 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
@@ -22,6 +22,7 @@ camel dependency list [options]
 | `--build-property` | Maven build properties, ex. --build-property=prop1=foo 
|  | List
 | `--camel-spring-boot-version` | Camel version to use with Spring Boot |  | 
String
 | `--camel-version` | To export using a different Camel version than the 
default version. |  | String
+| `--camel-wrapper` | Include Camel Wrapper scripts in exported project for 
version pinning | false | boolean
 | `--clean-dir` | If exporting to current directory (default) then all 
existing files are preserved. Enabling this option will force cleaning current 
directory including all sub dirs (use this with care) | false | boolean
 | `--dep,--dependency` | Add additional dependencies |  | List
 | `--dir,--directory` | Directory where the project will be exported | . | 
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 bc3ff5357e69..6efe4940e982 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
@@ -22,6 +22,7 @@ camel dependency update [options]
 | `--build-property` | Maven build properties, ex. --build-property=prop1=foo 
|  | List
 | `--camel-spring-boot-version` | Camel version to use with Spring Boot |  | 
String
 | `--camel-version` | To export using a different Camel version than the 
default version. |  | String
+| `--camel-wrapper` | Include Camel Wrapper scripts in exported project for 
version pinning | false | boolean
 | `--clean` | Regenerate list of dependencies (do not keep existing 
dependencies). Not supported for pom.xml |  | boolean
 | `--clean-dir` | If exporting to current directory (default) then all 
existing files are preserved. Enabling this option will force cleaning current 
directory including all sub dirs (use this with care) | false | boolean
 | `--dep,--dependency` | Add additional dependencies |  | List
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 12278c201622..b3ad3dc2c39c 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
@@ -22,6 +22,7 @@ camel export [options]
 | `--build-property` | Maven build properties, ex. --build-property=prop1=foo 
|  | List
 | `--camel-spring-boot-version` | Camel version to use with Spring Boot |  | 
String
 | `--camel-version` | To export using a different Camel version than the 
default version. |  | String
+| `--camel-wrapper` | Include Camel Wrapper scripts in exported project for 
version pinning | false | boolean
 | `--clean-dir` | If exporting to current directory (default) then all 
existing files are preserved. Enabling this option will force cleaning current 
directory including all sub dirs (use this with care) | false | boolean
 | `--dep,--dependency` | Add additional dependencies |  | List
 | `--dir,--directory` | Directory where the project will be exported | . | 
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 d0540d8eabbd..2e28d215b7e4 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
@@ -22,6 +22,7 @@ camel sbom [options]
 | `--build-property` | Maven build properties, ex. --build-property=prop1=foo 
|  | List
 | `--camel-spring-boot-version` | Camel version to use with Spring Boot |  | 
String
 | `--camel-version` | To export using a different Camel version than the 
default version. |  | String
+| `--camel-wrapper` | Include Camel Wrapper scripts in exported project for 
version pinning | false | boolean
 | `--clean-dir` | If exporting to current directory (default) then all 
existing files are preserved. Enabling this option will force cleaning current 
directory including all sub dirs (use this with care) | false | boolean
 | `--cyclonedx-plugin-version` | The CycloneDX Maven Plugin version | 2.9.1 | 
String
 | `--dep,--dependency` | Add additional dependencies |  | List
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 cda747041dbc..aa34ac5e55bf 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, WATSONX_APIKEY, or LLM_API_KEY env vars", 
"javaType": "java.lang.String", "type": "string" }, { "names": "--api-type", 
"description": "API type: 'ollama', 'openai' (OpenAI-compatible), ' [...]
-    { "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 2009c64f7a0c..f4b422e1b40c 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
@@ -5,6 +5,7 @@
   "properties": [
     { "name": "camel.jbang.camel-version", "required": false, "description": 
"The version of Apache Camel to use", "type": "string", "javaType": "String", 
"secret": false },
     { "name": "camel.jbang.camelSpringBootVersion", "required": false, 
"description": "To use a custom Camel version when running or export to Spring 
Boot", "label": "spring-boot", "type": "string", "javaType": "String", 
"secret": false },
+    { "name": "camel.jbang.camelWrapper", "required": false, "description": 
"Include Camel Wrapper scripts in the exported project for version pinning", 
"type": "boolean", "javaType": "boolean", "defaultValue": false, "secret": 
false },
     { "name": "camel.jbang.classpathFiles", "required": false, "description": 
"Additional files to add to classpath (Use commas to separate multiple 
files).", "type": "string", "javaType": "String", "secret": false },
     { "name": "camel.jbang.compileWorkDir", "required": false, "description": 
"Work directory for compiler. Can be used to write compiled classes or other 
resources.", "label": "advanced", "type": "string", "javaType": "String", 
"defaultValue": ".camel-jbang\/compile", "secret": false },
     { "name": "camel.jbang.console", "required": false, "description": 
"Developer console at \/q\/dev on local HTTP server (port 8080 by default)", 
"type": "boolean", "javaType": "boolean", "defaultValue": false, "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 f7538ec227ff..32ed859614af 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
@@ -39,6 +39,7 @@ import picocli.CommandLine.Command;
 
 import static 
org.apache.camel.dsl.jbang.core.common.CamelJBangConstants.CAMEL_SPRING_BOOT_VERSION;
 import static 
org.apache.camel.dsl.jbang.core.common.CamelJBangConstants.CAMEL_VERSION;
+import static 
org.apache.camel.dsl.jbang.core.common.CamelJBangConstants.CAMEL_WRAPPER;
 import static 
org.apache.camel.dsl.jbang.core.common.CamelJBangConstants.EXCLUDES;
 import static 
org.apache.camel.dsl.jbang.core.common.CamelJBangConstants.EXPORT_DIR;
 import static org.apache.camel.dsl.jbang.core.common.CamelJBangConstants.GAV;
@@ -202,6 +203,8 @@ public class Export extends ExportBaseCommand {
             this.springBootVersion = props.getProperty(SPRING_BOOT_VERSION, 
this.springBootVersion);
             this.mavenWrapper
                     = "true".equals(props.getProperty(MAVEN_WRAPPER, 
this.mavenWrapper ? "true" : "false"));
+            this.camelWrapper
+                    = "true".equals(props.getProperty(CAMEL_WRAPPER, 
this.camelWrapper ? "true" : "false"));
             this.exportDir = props.getProperty(EXPORT_DIR, this.exportDir);
             this.openapi = props.getProperty(OPEN_API, this.openapi);
             this.mavenResolver = MavenResolverMixin.of(props, 
this.mavenResolver);
@@ -259,6 +262,7 @@ public class Export extends ExportBaseCommand {
         cmd.quarkusPackageType = this.quarkusPackageType;
         cmd.springBootVersion = this.springBootVersion;
         cmd.mavenWrapper = this.mavenWrapper;
+        cmd.camelWrapper = this.camelWrapper;
         cmd.docker = this.docker;
         cmd.quiet = this.quiet;
         cmd.buildProperties = this.buildProperties;
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 6fe3c6fa9f59..272df1fbe6b2 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
@@ -207,6 +207,10 @@ public abstract class ExportBaseCommand extends 
CamelCommand {
                         description = "Include Maven Wrapper files in exported 
project")
     protected boolean mavenWrapper = true;
 
+    @CommandLine.Option(names = { "--camel-wrapper" }, defaultValue = "false",
+                        description = "Include Camel Wrapper scripts in 
exported project for version pinning")
+    protected boolean camelWrapper;
+
     @CommandLine.Option(names = { "--docker" }, defaultValue = "true",
                         description = "Include Docker files in exported 
project")
     protected boolean docker = true;
@@ -1189,6 +1193,36 @@ public abstract class ExportBaseCommand extends 
CamelCommand {
         FileUtil.setPosixFilePermissions(mvnwCmdPath, "rwxr-xr-x");
     }
 
+    protected void copyCamelWrapper() throws Exception {
+        Path camelDir = Paths.get(BUILD_DIR, ".camel");
+        Files.createDirectories(camelDir);
+
+        // write camel-wrapper.properties with the export's camel version
+        String distributionUrl = "https://repo1.maven.org/maven2";
+                                 + "/org/apache/camel/camel-launcher/"
+                                 + camelVersion
+                                 + "/camel-launcher-"
+                                 + camelVersion
+                                 + ".jar";
+        String content = "camel.version=" + camelVersion + "\n"
+                         + "distributionUrl=" + distributionUrl + "\n";
+        Files.writeString(camelDir.resolve("camel-wrapper.properties"), 
content);
+
+        // copy wrapper scripts
+        Path camelPath = Paths.get(BUILD_DIR, "camel");
+        Path camelCmdPath = Paths.get(BUILD_DIR, "camel.cmd");
+        try (InputStream is = 
ExportBaseCommand.class.getClassLoader().getResourceAsStream("camel-wrapper/camelw"))
 {
+            Files.copy(is, camelPath, StandardCopyOption.REPLACE_EXISTING);
+        }
+        try (InputStream is = 
ExportBaseCommand.class.getClassLoader().getResourceAsStream("camel-wrapper/camelw.cmd"))
 {
+            Files.copy(is, camelCmdPath, StandardCopyOption.REPLACE_EXISTING);
+        }
+
+        // set execute file permission on camel/camel.cmd files
+        FileUtil.setPosixFilePermissions(camelPath, "rwxr-xr-x");
+        FileUtil.setPosixFilePermissions(camelCmdPath, "rwxr-xr-x");
+    }
+
     protected String applicationPropertyLine(String key, String value) {
         return key + "=" + value;
     }
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 2f84107492c3..339f0985a139 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
@@ -172,6 +172,9 @@ class ExportCamelMain extends Export {
         if (mavenWrapper) {
             copyMavenWrapper();
         }
+        if (camelWrapper) {
+            copyCamelWrapper();
+        }
         if (docker) {
             copyDockerFiles(BUILD_DIR);
         }
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 652843f5ae02..7da2264a211e 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
@@ -173,6 +173,9 @@ class ExportQuarkus extends Export {
         if (mavenWrapper) {
             copyMavenWrapper();
         }
+        if (camelWrapper) {
+            copyCamelWrapper();
+        }
 
         if (cleanExportDir || !exportDir.equals(".")) {
             // cleaning current dir can be a bit dangerous so only clean if 
explicit enabled
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 5da20b8589e5..ecb772df57e9 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
@@ -166,6 +166,9 @@ class ExportSpringBoot extends Export {
         if (mavenWrapper) {
             copyMavenWrapper();
         }
+        if (camelWrapper) {
+            copyCamelWrapper();
+        }
         if (docker) {
             copyDockerFiles(BUILD_DIR);
         }
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 334cd054afb5..b95d4668448c 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
@@ -110,6 +110,10 @@ public final class CamelJBangConstants {
               javaType = "boolean", defaultValue = "true")
     public static final String MAVEN_WRAPPER = "camel.jbang.mavenWrapper";
 
+    @Metadata(description = "Include Camel Wrapper scripts in the exported 
project for version pinning",
+              javaType = "boolean", defaultValue = "false")
+    public static final String CAMEL_WRAPPER = "camel.jbang.camelWrapper";
+
     @Metadata(description = "Directory where the project will be exported",
               javaType = "String", defaultValue = ".")
     public static final String EXPORT_DIR = "camel.jbang.exportDir";
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 e4b45890ae7b..9685fdba7ffc 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
@@ -505,6 +505,45 @@ class ExportTest {
         Assertions.assertTrue(new File(workingDir, "AGENTS.md").exists(), 
"Missing AGENTS.md");
     }
 
+    @ParameterizedTest
+    @MethodSource("runtimeProvider")
+    public void shouldExportCamelWrapper(RuntimeType rt) throws Exception {
+        LOG.info("shouldExportCamelWrapper {}", rt);
+        Export command = createCommand(rt, new String[] { 
"src/test/resources/route.yaml" },
+                "--gav=examples:route:1.0.0", "--dir=" + workingDir, 
"--quiet", "--camel-wrapper");
+        int exit = command.doCall();
+
+        Assertions.assertEquals(0, exit);
+        Assertions.assertTrue(new File(workingDir, "camel").exists(), "Missing 
camel wrapper script");
+        Assertions.assertTrue(new File(workingDir, "camel.cmd").exists(), 
"Missing camel.cmd wrapper script");
+        Assertions.assertTrue(new File(workingDir, 
".camel/camel-wrapper.properties").exists(),
+                "Missing .camel/camel-wrapper.properties");
+
+        String properties = 
Files.readString(workingDir.toPath().resolve(".camel/camel-wrapper.properties"));
+        assertThat(properties).contains("camel.version=");
+        assertThat(properties).contains("distributionUrl=");
+        assertThat(properties).contains("camel-launcher-");
+
+        String camelScript = 
Files.readString(workingDir.toPath().resolve("camel"));
+        assertThat(camelScript).startsWith("#!/bin/sh");
+        assertThat(camelScript).contains("camel-wrapper.properties");
+    }
+
+    @ParameterizedTest
+    @MethodSource("runtimeProvider")
+    public void shouldNotExportCamelWrapperByDefault(RuntimeType rt) throws 
Exception {
+        LOG.info("shouldNotExportCamelWrapperByDefault {}", rt);
+        Export command = createCommand(rt, new String[] { 
"src/test/resources/route.yaml" },
+                "--gav=examples:route:1.0.0", "--dir=" + workingDir, 
"--quiet");
+        int exit = command.doCall();
+
+        Assertions.assertEquals(0, exit);
+        Assertions.assertFalse(new File(workingDir, "camel").exists(),
+                "Camel wrapper script should not exist by default");
+        Assertions.assertFalse(new File(workingDir, 
".camel/camel-wrapper.properties").exists(),
+                "Camel wrapper properties should not exist by default");
+    }
+
     @ParameterizedTest
     @MethodSource("runtimeProvider")
     public void shouldSkipDockerFiles(RuntimeType rt) throws Exception {
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 57243c453ba6..89f027806e8c 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
@@ -179,6 +179,7 @@ public class KubernetesExport extends Export {
         javaLiveReload = configurer.javaLiveReload;
         ignoreLoadingError = configurer.ignoreLoadingError;
         mavenWrapper = configurer.mavenWrapper;
+        camelWrapper = configurer.camelWrapper;
         skipPlugins = configurer.skipPlugins;
         packageScanJars = configurer.packageScanJars;
         quiet = configurer.quiet;
@@ -655,6 +656,7 @@ public class KubernetesExport extends Export {
             boolean javaLiveReload,
             boolean ignoreLoadingError,
             boolean mavenWrapper,
+            boolean camelWrapper,
             boolean fresh,
             boolean download,
             boolean packageScanJars,
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesRun.java
 
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesRun.java
index d4aad60ce30c..f2355b240ac7 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesRun.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-kubernetes/src/main/java/org/apache/camel/dsl/jbang/core/commands/kubernetes/KubernetesRun.java
@@ -480,6 +480,7 @@ public class KubernetesRun extends KubernetesBaseCommand {
                 true,
                 true,
                 false,
+                false,
                 mavenResolver.download(),
                 packageScanJars,
                 (quiet || output != null),

Reply via email to