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

commit de732222c34f7cb20a65572f7361c988ba3f4bd2
Author: Claus Ibsen <[email protected]>
AuthorDate: Sun Nov 6 10:52:25 2022 +0100

    CAMEL-18205: camel-jbang - Export as gradle project
---
 .../modules/ROOT/pages/camel-jbang.adoc            |  26 +++
 .../camel/dsl/jbang/core/commands/Export.java      |   5 +
 .../dsl/jbang/core/commands/ExportBaseCommand.java |  27 +++
 .../dsl/jbang/core/commands/ExportCamelMain.java   |  31 +--
 .../dsl/jbang/core/commands/ExportQuarkus.java     |  19 +-
 .../dsl/jbang/core/commands/ExportSpringBoot.java  | 109 ++++++++--
 .../resources/gradle-wrapper/gradle-wrapper.jar    | Bin 0 -> 60756 bytes
 .../gradle-wrapper/gradle-wrapper.properties       |   5 +
 .../src/main/resources/gradle-wrapper/gradlew      | 240 +++++++++++++++++++++
 .../src/main/resources/gradle-wrapper/gradlew.bat  |  91 ++++++++
 .../templates/spring-boot-build-gradle.tmpl        |  29 +++
 .../org/apache/camel/main/download/MavenGav.java   |   6 +-
 12 files changed, 551 insertions(+), 37 deletions(-)

diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
index 04a89cb9e30..90a08105215 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
@@ -1485,6 +1485,16 @@ camel export --runtime=camel-main 
--gav=com.foo:acme:1.0-SNAPSHOT --dir=../mypro
 
 TIP: See the possible options by running: `camel export --help` for more 
details.
 
+=== Exporting as Gradle Project
+
+Camel JBang exports by default as a Maven based project. To use Gradle 
instead, you can
+specify the `--project=gradle` when exporting, such as:
+
+[source,bash]
+----
+camel export --project=gradle --runtime=spring-boot 
--gav=com.foo:acme:1.0-SNAPSHOT --dir=../myproject
+----
+
 === Exporting with JMX management included
 
 Usually when exporting to Spring Boot, Quarkus or Camel Main, then JMX 
management is not included out of the box.
@@ -1495,6 +1505,16 @@ To include JMX, you need to add `camel:management` in 
the `--deps` option, as sh
 camel export --runtime=quarkus --gav=com.foo:acme:1.0-SNAPSHOT 
--deps=camel:management --dir=../myproject
 ----
 
+=== Exporting with Camel CLI included
+
+Usually when exporting to Spring Boot, Quarkus or Camel Main, then Camel JBang 
CLI is not included out of the box.
+To be able to continue to use Camel CLI (i.e. `camel`), you need to add 
`camel:cli-connector` in the `--deps` option, as shown below:
+
+[source,bash]
+----
+camel export --runtime=quarkus --gav=com.foo:acme:1.0-SNAPSHOT 
--deps=camel:cli-connector --dir=../myproject
+----
+
 === Configuring exporting
 
 The export command will by default load configuration from 
`application.properties`
@@ -1538,6 +1558,12 @@ The follow options related to _exporting_, can be 
configured in `application.pro
 |`camel.jbang.mavenWrapper`
 |Include Maven Wrapper files in exported project
 
+|`camel.jbang.gradleWrapper`
+|Include Gradle Wrapper files in exported project
+
+|`camel.jbang.project`
+|Project (either maven or gradle)
+
 |`camel.jbang.exportDir`
 |Directory where the project will be exported
 |===
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 dddca10f7c5..89e5839558c 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
@@ -56,7 +56,10 @@ class Export extends ExportBaseCommand {
             this.springBootVersion = 
prop.getProperty("camel.jbang.springBootVersion", this.springBootVersion);
             this.mavenWrapper
                     = 
"true".equals(prop.getProperty("camel.jbang.mavenWrapper", this.mavenWrapper ? 
"true" : "false"));
+            this.gradleWrapper
+                    = 
"true".equals(prop.getProperty("camel.jbang.gradleWrapper", this.gradleWrapper 
? "true" : "false"));
             this.exportDir = prop.getProperty("camel.jbang.exportDir", 
this.exportDir);
+            this.project = prop.getProperty("camel.jbang.project", 
this.project);
         }
 
         if (runtime == null) {
@@ -99,6 +102,8 @@ class Export extends ExportBaseCommand {
         cmd.quarkusVersion = this.quarkusVersion;
         cmd.springBootVersion = this.springBootVersion;
         cmd.mavenWrapper = this.mavenWrapper;
+        cmd.gradleWrapper = this.gradleWrapper;
+        cmd.project = this.project;
         cmd.quiet = this.quiet;
         // run export
         return cmd.export();
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 401420d77be..082169d14a3 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
@@ -105,6 +105,14 @@ abstract class ExportBaseCommand extends CamelCommand {
                         description = "Include Maven Wrapper files in exported 
project")
     protected boolean mavenWrapper;
 
+    @CommandLine.Option(names = { "--gradle-wrapper" }, defaultValue = "true",
+                        description = "Include Gradle Wrapper files in 
exported project")
+    protected boolean gradleWrapper;
+
+    @CommandLine.Option(names = { "--project" }, defaultValue = "maven",
+                        description = "Project (maven or gradle)")
+    protected String project;
+
     @CommandLine.Option(names = {
             "-dir",
             "--directory" }, description = "Directory where the project will 
be exported", defaultValue = ".")
@@ -416,6 +424,25 @@ abstract class ExportBaseCommand extends CamelCommand {
         file.setExecutable(true);
     }
 
+    protected void copyGradleWrapper() throws Exception {
+        File wrapper = new File(BUILD_DIR, "gradle/wrapper");
+        wrapper.mkdirs();
+        // copy files
+        InputStream is = 
ExportBaseCommand.class.getClassLoader().getResourceAsStream("gradle-wrapper/gradlew");
+        IOHelper.copyAndCloseInput(is, new FileOutputStream(new 
File(BUILD_DIR, "gradlew")));
+        is = 
ExportBaseCommand.class.getClassLoader().getResourceAsStream("gradle-wrapper/gradlew.bat");
+        IOHelper.copyAndCloseInput(is, new FileOutputStream(new 
File(BUILD_DIR, "gradlew.bat")));
+        is = 
ExportBaseCommand.class.getClassLoader().getResourceAsStream("gradle-wrapper/gradle-wrapper.jar");
+        IOHelper.copyAndCloseInput(is, new FileOutputStream(new File(wrapper, 
"gradle-wrapper.jar")));
+        is = 
ExportBaseCommand.class.getClassLoader().getResourceAsStream("gradle-wrapper/gradle-wrapper.properties");
+        IOHelper.copyAndCloseInput(is, new FileOutputStream(new File(wrapper, 
"gradle-wrapper.properties")));
+        // set execute file permission on gradlew/gradlew.cmd files
+        File file = new File(BUILD_DIR, "gradlew");
+        file.setExecutable(true);
+        file = new File(BUILD_DIR, "gradlew.bat");
+        file.setExecutable(true);
+    }
+
     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 ef9d01898a3..d434155ed23 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
@@ -46,6 +46,10 @@ class ExportCamelMain extends Export {
             System.err.println("--gav must be in syntax: 
groupId:artifactId:version");
             return 1;
         }
+        if (!project.equals("maven") && !project.equals("gradle")) {
+            System.err.println("--project must either be maven or gradle, was: 
" + project);
+            return 1;
+        }
 
         File profile = new File(getProfile() + ".properties");
 
@@ -95,24 +99,21 @@ class ExportCamelMain extends Export {
         createMainClassSource(srcJavaDir, packageName, mainClassname);
         // gather dependencies
         Set<String> deps = resolveDependencies(settings, profile);
-        // create pom
-        createPom(settings, new File(BUILD_DIR, "pom.xml"), deps, packageName);
-        // maven wrapper
-        if (mavenWrapper) {
-            copyMavenWrapper();
-        }
-
-        if (exportDir.equals(".")) {
-            // we export to current dir so prepare for this by cleaning up 
existing files
-            File target = new File(exportDir);
-            for (File f : target.listFiles()) {
-                if (!f.isHidden() && f.isDirectory()) {
-                    FileUtil.removeDir(f);
-                } else if (!f.isHidden() && f.isFile()) {
-                    f.delete();
+        // maven project
+        if ("maven".equals(project)) {
+            createPom(settings, new File(BUILD_DIR, "pom.xml"), deps, 
packageName);
+            if (mavenWrapper) {
+                copyMavenWrapper();
+            } else if ("gradle".equals(project)) {
+                if (gradleWrapper) {
+                    copyGradleWrapper();
                 }
             }
         }
+
+        if (!exportDir.equals(".")) {
+            CommandHelper.cleanExportDir(exportDir);
+        }
         // copy to export dir and remove work dir
         FileUtils.copyDirectory(new File(BUILD_DIR), new File(exportDir));
         FileUtil.removeDir(new File(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 bd3c9cb4a71..d0c70e68627 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
@@ -66,6 +66,10 @@ class ExportQuarkus extends Export {
             System.err.println("--gav must be in syntax: 
groupId:artifactId:version");
             return 1;
         }
+        if (!project.equals("maven") && !project.equals("gradle")) {
+            System.err.println("--project must either be maven or gradle, was: 
" + project);
+            return 1;
+        }
 
         File profile = new File(getProfile() + ".properties");
 
@@ -114,11 +118,16 @@ class ExportQuarkus extends Export {
         copyDockerFiles();
         // gather dependencies
         Set<String> deps = resolveDependencies(settings, profile);
-        // create pom
-        createPom(settings, new File(BUILD_DIR, "pom.xml"), deps);
-        // maven wrapper
-        if (mavenWrapper) {
-            copyMavenWrapper();
+        // maven project
+        if ("maven".equals(project)) {
+            createPom(settings, new File(BUILD_DIR, "pom.xml"), deps);
+            if (mavenWrapper) {
+                copyMavenWrapper();
+            } else if ("gradle".equals(project)) {
+                if (gradleWrapper) {
+                    copyGradleWrapper();
+                }
+            }
         }
 
         if (!exportDir.equals(".")) {
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 de59e716031..e94442e7a68 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
@@ -54,6 +54,10 @@ class ExportSpringBoot extends Export {
             System.err.println("--gav must be in syntax: 
groupId:artifactId:version");
             return 1;
         }
+        if (!project.equals("maven") && !project.equals("gradle")) {
+            System.err.println("--project must either be maven or gradle, was: 
" + project);
+            return 1;
+        }
 
         File profile = new File(getProfile() + ".properties");
 
@@ -98,23 +102,22 @@ class ExportSpringBoot extends Export {
         createMainClassSource(srcJavaDir, packageName, mainClassname);
         // gather dependencies
         Set<String> deps = resolveDependencies(settings, profile);
-        // create pom
-        createPom(settings, new File(BUILD_DIR, "pom.xml"), deps);
-        // maven wrapper
-        if (mavenWrapper) {
-            copyMavenWrapper();
+        // maven project
+        if ("maven".equals(project)) {
+            createMavenPom(settings, new File(BUILD_DIR, "pom.xml"), deps);
+            if (mavenWrapper) {
+                copyMavenWrapper();
+            }
+        } else if ("gradle".equals(project)) {
+            createSettingsGradle(new File(BUILD_DIR, "settings.gradle"));
+            createBuildGradle(settings, new File(BUILD_DIR, "build.gradle"), 
deps);
+            if (gradleWrapper) {
+                copyGradleWrapper();
+            }
         }
 
-        if (exportDir.equals(".")) {
-            // we export to current dir so prepare for this by cleaning up 
existing files
-            File target = new File(exportDir);
-            for (File f : target.listFiles()) {
-                if (!f.isHidden() && f.isDirectory()) {
-                    FileUtil.removeDir(f);
-                } else if (!f.isHidden() && f.isFile()) {
-                    f.delete();
-                }
-            }
+        if (!exportDir.equals(".")) {
+            CommandHelper.cleanExportDir(exportDir);
         }
         // copy to export dir and remove work dir
         FileUtils.copyDirectory(new File(BUILD_DIR), new File(exportDir));
@@ -123,7 +126,14 @@ class ExportSpringBoot extends Export {
         return 0;
     }
 
-    private void createPom(File settings, File pom, Set<String> deps) throws 
Exception {
+    private void createSettingsGradle(File file) throws Exception {
+        String[] ids = gav.split(":");
+
+        String text = String.format("rootProject.name = '%s'", ids[1]);
+        IOHelper.writeText(text, new FileOutputStream(file, false));
+    }
+
+    private void createMavenPom(File settings, File pom, Set<String> deps) 
throws Exception {
         String[] ids = gav.split(":");
 
         InputStream is = 
ExportSpringBoot.class.getClassLoader().getResourceAsStream("templates/spring-boot-pom.tmpl");
@@ -200,6 +210,73 @@ class ExportSpringBoot extends Export {
         IOHelper.writeText(context, new FileOutputStream(pom, false));
     }
 
+    private void createBuildGradle(File settings, File gradleBuild, 
Set<String> deps) throws Exception {
+        String[] ids = gav.split(":");
+
+        InputStream is = 
ExportSpringBoot.class.getClassLoader().getResourceAsStream("templates/spring-boot-build-gradle.tmpl");
+        String context = IOHelper.loadText(is);
+        IOHelper.close(is);
+
+        CamelCatalog catalog = loadSpringBootCatalog();
+        String camelVersion = catalog.getCatalogVersion();
+
+        context = context.replaceFirst("\\{\\{ \\.GroupId }}", ids[0]);
+        context = context.replaceFirst("\\{\\{ \\.ArtifactId }}", ids[1]);
+        context = context.replaceFirst("\\{\\{ \\.Version }}", ids[2]);
+        context = context.replaceAll("\\{\\{ \\.SpringBootVersion }}", 
springBootVersion);
+        context = context.replaceFirst("\\{\\{ \\.JavaVersion }}", 
javaVersion);
+        context = context.replaceAll("\\{\\{ \\.CamelVersion }}", 
camelVersion);
+
+        Properties prop = new CamelCaseOrderedProperties();
+        RuntimeUtil.loadProperties(prop, settings);
+        String repos = prop.getProperty("camel.jbang.repos");
+        if (repos == null) {
+            context = context.replaceFirst("\\{\\{ \\.MavenRepositories }}", 
"");
+        } else {
+            StringBuilder sb = new StringBuilder();
+            for (String repo : repos.split(",")) {
+                sb.append("    maven {\n");
+                sb.append("        url: '").append(repo).append("'\n");
+                sb.append("    }\n");
+            }
+            context = context.replaceFirst("\\{\\{ \\.MavenRepositories }}", 
sb.toString());
+        }
+
+        List<MavenGav> gavs = new ArrayList<>();
+        for (String dep : deps) {
+            MavenGav gav = MavenGav.parseGav(dep);
+            String gid = gav.getGroupId();
+            String aid = gav.getArtifactId();
+            String v = gav.getVersion();
+
+            // transform to camel-spring-boot starter GAV
+            if ("org.apache.camel".equals(gid)) {
+                ArtifactModel<?> am = 
catalog.modelFromMavenGAV("org.apache.camel.springboot", aid + "-starter", 
null);
+                if (am != null) {
+                    // use spring-boot starter
+                    gav.setGroupId(am.getGroupId());
+                    gav.setArtifactId(am.getArtifactId());
+                    gav.setVersion(am.getVersion());
+                } else {
+                    // there is no spring boot starter so use plain camel
+                    gav.setVersion(camelVersion);
+                }
+            }
+            gavs.add(gav);
+        }
+
+        // sort artifacts
+        gavs.sort(mavenGavComparator());
+
+        StringBuilder sb = new StringBuilder();
+        for (MavenGav gav : gavs) {
+            sb.append("    implementation 
'").append(gav.toString()).append("'\n");
+        }
+        context = context.replaceFirst("\\{\\{ \\.CamelDependencies }}", 
sb.toString());
+
+        IOHelper.writeText(context, new FileOutputStream(gradleBuild, false));
+    }
+
     @Override
     protected Set<String> resolveDependencies(File settings, File profile) 
throws Exception {
         Set<String> answer = super.resolveDependencies(settings, profile);
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/resources/gradle-wrapper/gradle-wrapper.jar
 
b/dsl/camel-jbang/camel-jbang-core/src/main/resources/gradle-wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000000..249e5832f09
Binary files /dev/null and 
b/dsl/camel-jbang/camel-jbang-core/src/main/resources/gradle-wrapper/gradle-wrapper.jar
 differ
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/resources/gradle-wrapper/gradle-wrapper.properties
 
b/dsl/camel-jbang/camel-jbang-core/src/main/resources/gradle-wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000000..ae04661ee73
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/resources/gradle-wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/resources/gradle-wrapper/gradlew 
b/dsl/camel-jbang/camel-jbang-core/src/main/resources/gradle-wrapper/gradlew
new file mode 100755
index 00000000000..a69d9cb6c20
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/resources/gradle-wrapper/gradlew
@@ -0,0 +1,240 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       
https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no 
leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to 
pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+    echo "$*"
+} >&2
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD=$JAVA_HOME/jre/sh/java
+    else
+        JAVACMD=$JAVA_HOME/bin/java
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD=java
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 
'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with 
options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX 
filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
+        fi
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
+    done
+fi
+
+# Collect all arguments for the java command;
+#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+#     shell script including quotes and variable substitutions, so put them in
+#     double quotes to make sure that they get re-expanded; and
+#   * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        org.gradle.wrapper.GradleWrapperMain \
+        "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+    die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes 
removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/resources/gradle-wrapper/gradlew.bat
 
b/dsl/camel-jbang/camel-jbang-core/src/main/resources/gradle-wrapper/gradlew.bat
new file mode 100644
index 00000000000..53a6b238d41
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/resources/gradle-wrapper/gradlew.bat
@@ -0,0 +1,91 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS 
to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your 
PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% 
"-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" 
org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code 
instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-build-gradle.tmpl
 
b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-build-gradle.tmpl
new file mode 100644
index 00000000000..1f0ffc6cd8f
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/resources/templates/spring-boot-build-gradle.tmpl
@@ -0,0 +1,29 @@
+plugins {
+    id 'org.springframework.boot' version '{{ .SpringBootVersion }}'
+    id 'io.spring.dependency-management' version '1.0.15.RELEASE'
+    id 'java'
+}
+
+group = '{{ .GroupId }}'
+version = '{{ .Version }}'
+sourceCompatibility = '{{ .JavaVersion }}'
+
+repositories {
+    mavenLocal()
+    mavenCentral()
+{{ .MavenRepositories }}
+}
+
+dependencies {
+    implementation 'org.springframework.boot:spring-boot-starter-web'
+    implementation 'org.springframework.boot:spring-boot-starter-actuator'
+    implementation 
'org.apache.camel.springboot:camel-spring-boot-engine-starter:{{ .CamelVersion 
}}'
+    implementation 'org.apache.camel.springboot:camel-dsl-modeline-starter:{{ 
.CamelVersion }}'
+{{ .CamelDependencies }}
+    testImplementation 'org.springframework.boot:spring-boot-starter-test'
+    testImplementation 'org.apache.camel:camel-test-spring-junit5:{{ 
.CamelVersion }}'
+}
+
+tasks.named('test') {
+    useJUnitPlatform()
+}
\ No newline at end of file
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MavenGav.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MavenGav.java
index 322371bb3f1..91c06ab8ea6 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MavenGav.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MavenGav.java
@@ -177,6 +177,10 @@ public final class MavenGav {
 
     @Override
     public String toString() {
-        return groupId + ":" + artifactId + ":" + version;
+        if (version != null) {
+            return groupId + ":" + artifactId + ":" + version;
+        } else {
+            return groupId + ":" + artifactId;
+        }
     }
 }

Reply via email to