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

orpiske 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 fb6275a  CAMEL-17018: rework the Camel JBang code to avoid build-time 
version alignment
fb6275a is described below

commit fb6275a5a0c892e3c9bc7c8c3e83c57fd805952b
Author: Otavio Rodolfo Piske <[email protected]>
AuthorDate: Tue Oct 12 17:16:11 2021 +0200

    CAMEL-17018: rework the Camel JBang code to avoid build-time version
    alignment
    
    This should prevent Camel JBang from aligning to snapshot versions of
    the dependencies during release builds.
---
 dsl/camel-jbang/camel-jbang-core/pom.xml           |  37 +-
 .../dsl/jbang/core/commands/CamelJBangMain.java    |  51 ++
 .../apache/camel/dsl/jbang/core/commands/Init.java |  39 ++
 .../camel/dsl/jbang/core/commands/InitBinding.java |  77 +++
 .../camel/dsl/jbang/core/commands/InitKamelet.java | 121 +++++
 .../apache/camel/dsl/jbang/core/commands/Run.java  | 130 +++++
 .../camel/dsl/jbang/core/commands/Search.java      |  47 ++
 .../dsl/jbang/core/commands/SearchComponents.java  |  89 ++++
 .../dsl/jbang/core/commands/SearchKamelets.java    |  82 +++
 .../dsl/jbang/core/commands/SearchLanguages.java   |  87 +++
 .../dsl/jbang/core/commands/SearchOthers.java      |  88 +++
 .../camel/dsl/jbang/core/common/RuntimeUtil.java   |  59 +++
 dsl/camel-jbang/camel-jbang-main/README.md         |  36 +-
 .../camel-jbang-main/dist/CamelJBang.java          | 589 +--------------------
 dsl/camel-jbang/camel-jbang-main/pom.xml           |  65 +--
 .../src/main/jbang/main/CamelJBang.java            | 589 +--------------------
 16 files changed, 920 insertions(+), 1266 deletions(-)

diff --git a/dsl/camel-jbang/camel-jbang-core/pom.xml 
b/dsl/camel-jbang/camel-jbang-core/pom.xml
index dc284c5..4912b71 100644
--- a/dsl/camel-jbang/camel-jbang-core/pom.xml
+++ b/dsl/camel-jbang/camel-jbang-core/pom.xml
@@ -36,9 +36,29 @@
         </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
+            <artifactId>camel-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-core-model</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
             <artifactId>camel-kamelet-main</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-resourceresolver-github</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-file-watch</artifactId>
+        </dependency>
+        <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
         </dependency>
@@ -47,7 +67,22 @@
             <artifactId>velocity-engine-core</artifactId>
             <version>${velocity-version}</version>
         </dependency>
-
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>info.picocli</groupId>
+            <artifactId>picocli</artifactId>
+        </dependency>
     </dependencies>
 
 </project>
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
new file mode 100644
index 0000000..eb97e83
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.
+ */
+
+package org.apache.camel.dsl.jbang.core.commands;
+
+import java.util.concurrent.Callable;
+
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+
+@Command(name = "CamelJBang", mixinStandardHelpOptions = true, version = 
"CamelJBang",
+         description = "A JBang-based Camel app")
+public class CamelJBangMain implements Callable<Integer> {
+    private static CommandLine commandLine;
+
+    public static void run(String... args) {
+        commandLine = new CommandLine(new CamelJBangMain())
+                .addSubcommand("run", new Run())
+                .addSubcommand("search", new CommandLine(new Search())
+                        .addSubcommand("kamelets", new SearchKamelets())
+                        .addSubcommand("components", new SearchComponents())
+                        .addSubcommand("languages", new SearchLanguages())
+                        .addSubcommand("others", new SearchOthers()))
+                .addSubcommand("init", new CommandLine(new Init())
+                        .addSubcommand("kamelet", new InitKamelet())
+                        .addSubcommand("binding", new InitBinding()));
+
+        int exitCode = commandLine.execute(args);
+        System.exit(exitCode);
+    }
+
+    @Override
+    public Integer call() throws Exception {
+        commandLine.execute("--help");
+        return 0;
+    }
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Init.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Init.java
new file mode 100644
index 0000000..5d195dd
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Init.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.
+ */
+
+package org.apache.camel.dsl.jbang.core.commands;
+
+import java.util.concurrent.Callable;
+
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+
+@Command(name = "init", description = "Provide init templates for kamelets and 
bindings")
+class Init implements Callable<Integer> {
+    //CHECKSTYLE:OFF
+    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
+    private boolean helpRequested = false;
+    //CHECKSTYLE:ON
+
+    @Override
+    public Integer call() throws Exception {
+        new CommandLine(this).execute("--help");
+
+        return 0;
+    }
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/InitBinding.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/InitBinding.java
new file mode 100644
index 0000000..7ff14d6
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/InitBinding.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.
+ */
+
+package org.apache.camel.dsl.jbang.core.commands;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.concurrent.Callable;
+
+import org.apache.camel.CamelException;
+import org.apache.camel.dsl.jbang.core.common.exceptions.ResourceAlreadyExists;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+
+@Command(name = "binding", description = "Provide init templates for kamelet 
bindings")
+class InitBinding extends AbstractInitKamelet implements Callable<Integer> {
+    //CHECKSTYLE:OFF
+    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
+    private boolean helpRequested = false;
+    //CHECKSTYLE:ON
+
+    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
+            description = "Where to download the resources from (used for 
development/testing)")
+    private String baseResourceLocation;
+
+    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
+            description = "The branch to use when downloading resources from 
(used for development/testing)")
+    private String branch;
+
+    @Option(names = { "--destination" }, defaultValue = "work",
+            description = "The destination directory where to download the 
files")
+    private String destination;
+
+    @Option(names = { "--kamelet" }, defaultValue = "",
+            description = "The kamelet to create a binding for")
+    private String kamelet;
+
+    @Option(names = { "--project" }, defaultValue = "camel-k",
+            description = "The project to create a binding for (either camel-k 
or core)")
+    private String project;
+
+    private int downloadSample() throws IOException, CamelException {
+        setBranch(branch);
+
+        String resourcePath = 
String.format("camel-kamelets:templates/bindings/%s/%s-binding.yaml", project, 
kamelet);
+
+        setResourceLocation(baseResourceLocation, resourcePath);
+
+        try {
+            resolveResource(new File(destination));
+        } catch (ResourceAlreadyExists e) {
+            System.err.println(e.getMessage());
+            return 1;
+        }
+
+        return 0;
+    }
+
+    @Override
+    public Integer call() throws Exception {
+        return downloadSample();
+    }
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/InitKamelet.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/InitKamelet.java
new file mode 100644
index 0000000..072cd22
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/InitKamelet.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.
+ */
+
+package org.apache.camel.dsl.jbang.core.commands;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.concurrent.Callable;
+
+import org.apache.camel.CamelException;
+import org.apache.camel.dsl.jbang.core.common.exceptions.ResourceAlreadyExists;
+import org.apache.camel.dsl.jbang.core.templates.VelocityTemplateParser;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+
+@Command(name = "kamelet", description = "Provide init templates for kamelets")
+class InitKamelet extends AbstractInitKamelet implements Callable<Integer> {
+    //CHECKSTYLE:OFF
+    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
+    private boolean helpRequested = false;
+    //CHECKSTYLE:ON
+
+    @CommandLine.ArgGroup(exclusive = true, multiplicity = "1")
+    private ProcessOptions processOptions;
+
+    static class ProcessOptions {
+        //CHECKSTYLE:OFF
+        @Option(names = { "--bootstrap" },
+                description = "Bootstrap the Kamelet template generator - 
download the properties file for editing")
+        private boolean bootstrap = false;
+        //CHECKSTYLE:ON
+
+        @Option(names = { "--properties-path" }, defaultValue = "", 
description = "Kamelet name")
+        private String propertiesPath;
+    }
+
+    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
+            description = "Where to download the resources from (used for 
development/testing)")
+    private String baseResourceLocation;
+
+    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
+            description = "The branch to use when downloading resources from 
(used for development/testing)")
+    private String branch;
+
+    @Option(names = { "--destination" }, defaultValue = "work",
+            description = "The destination directory where to download the 
files")
+    private String destination;
+
+    @Override
+    public Integer call() throws Exception {
+        if (processOptions.bootstrap) {
+            bootstrap();
+        } else {
+            generateTemplate();
+        }
+
+        return 0;
+    }
+
+    private int generateTemplate() throws IOException, CamelException {
+        setBranch(branch);
+        setResourceLocation(baseResourceLocation, 
"camel-kamelets:templates/init-template.kamelet.yaml.vm");
+
+        File workDirectory = new File(destination);
+
+        File localTemplateFile;
+        try {
+            localTemplateFile = resolveResource(workDirectory);
+        } catch (ResourceAlreadyExists e) {
+            System.err.println(e.getMessage());
+            return 1;
+        }
+        localTemplateFile.deleteOnExit();
+
+        VelocityTemplateParser templateParser = new VelocityTemplateParser(
+                localTemplateFile.getParentFile(),
+                processOptions.propertiesPath);
+
+        File outputFile;
+        try {
+            outputFile = templateParser.getOutputFile(workDirectory);
+        } catch (ResourceAlreadyExists e) {
+            System.err.println(e.getMessage());
+            return 1;
+        }
+
+        try (FileWriter fw = new FileWriter(outputFile)) {
+            templateParser.parse(localTemplateFile.getName(), fw);
+            System.out.println("Template file was written to " + outputFile);
+        }
+
+        return 0;
+    }
+
+    private int bootstrap() throws IOException, CamelException {
+        try {
+            super.bootstrap(branch, baseResourceLocation, destination);
+            return 0;
+        } catch (ResourceAlreadyExists e) {
+            System.err.println(e.getMessage());
+
+            return 1;
+        }
+    }
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
new file mode 100644
index 0000000..b8c3a0b
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.
+ */
+
+package org.apache.camel.dsl.jbang.core.commands;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.concurrent.Callable;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.dsl.jbang.core.common.RuntimeUtil;
+import org.apache.camel.main.KameletMain;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.Parameters;
+
+@Command(name = "run", description = "Run a Kamelet")
+class Run implements Callable<Integer> {
+    private CamelContext context;
+
+    @Parameters(description = "The path to the kamelet binding", arity = 
"0..1")
+    private String binding;
+
+    //CHECKSTYLE:OFF
+    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
+    private boolean helpRequested = false;
+    //CHECKSTYLE:ON
+
+    @Option(names = { "--debug-level" }, defaultValue = "info", description = 
"Default debug level")
+    private String debugLevel;
+
+    @Option(names = { "--stop" }, description = "Stop all running instances of 
Camel JBang")
+    private boolean stopRequested;
+
+    @Option(names = { "--max-messages" }, defaultValue = "0", description = 
"Max number of messages to process before stopping")
+    private int maxMessages;
+
+    class ShutdownRoute extends RouteBuilder {
+        private File lockFile;
+
+        public ShutdownRoute(File lockFile) {
+            this.lockFile = lockFile;
+        }
+
+        public void configure() {
+            fromF("file-watch://%s?events=DELETE&antInclude=%s", 
lockFile.getParent(), lockFile.getName())
+                    .process(p -> context.shutdown());
+        }
+    }
+
+    @Override
+    public Integer call() throws Exception {
+        System.setProperty("camel.main.name", "CamelJBang");
+
+        if (stopRequested) {
+            stop();
+        } else {
+            run();
+        }
+
+        return 0;
+    }
+
+    private int stop() {
+        File currentDir = new File(".");
+
+        File[] lockFiles = currentDir.listFiles(f -> 
f.getName().endsWith(".camel.lock"));
+
+        for (File lockFile : lockFiles) {
+            System.out.println("Removing file " + lockFile);
+            if (!lockFile.delete()) {
+                System.err.println("Failed to remove lock file " + lockFile);
+            }
+        }
+
+        return 0;
+    }
+
+    private int run() throws Exception {
+        if (maxMessages > 0) {
+            System.setProperty("camel.main.durationMaxMessages", 
String.valueOf(maxMessages));
+        }
+
+        System.setProperty("camel.main.routes-include-pattern", "file:" + 
binding);
+
+        RuntimeUtil.configureLog(debugLevel);
+
+        File bindingFile = new File(binding);
+        if (!bindingFile.exists()) {
+            System.err.println("The binding file does not exist");
+
+            return 1;
+        }
+
+        System.out.println("Starting Camel JBang!");
+        KameletMain main = new KameletMain();
+
+        main.configure().addRoutesBuilder(new ShutdownRoute(createLockFile()));
+        main.start();
+        context = main.getCamelContext();
+
+        main.run();
+        return 0;
+    }
+
+    public File createLockFile() throws IOException {
+        File lockFile = File.createTempFile(".run", ".camel.lock", new 
File("."));
+
+        System.out.printf("A new lock file was created on %s. Delete this file 
to stop running%n",
+                lockFile.getAbsolutePath());
+        lockFile.deleteOnExit();
+
+        return lockFile;
+    }
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Search.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Search.java
new file mode 100644
index 0000000..5419d1d
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Search.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.
+ */
+
+package org.apache.camel.dsl.jbang.core.commands;
+
+import java.util.concurrent.Callable;
+
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+
+@Command(name = "search", description = "Search for kameletes, components and 
patterns (use --help)")
+class Search extends AbstractSearch implements Callable<Integer> {
+    //CHECKSTYLE:OFF
+    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
+    private boolean helpRequested = false;
+    //CHECKSTYLE:ON
+
+    public Search() {
+        super(null, null);
+    }
+
+    public void printHeader() {
+        // NO-OP
+    }
+
+    @Override
+    public Integer call() throws Exception {
+        new CommandLine(this).execute("--help");
+
+        return 0;
+    }
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/SearchComponents.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/SearchComponents.java
new file mode 100644
index 0000000..da228bb
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/SearchComponents.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.
+ */
+
+package org.apache.camel.dsl.jbang.core.commands;
+
+import java.util.concurrent.Callable;
+import java.util.regex.Pattern;
+
+import org.apache.camel.dsl.jbang.core.common.MatchExtractor;
+import org.apache.camel.dsl.jbang.core.common.exceptions.ResourceDoesNotExist;
+import org.apache.camel.dsl.jbang.core.components.ComponentConverter;
+import org.apache.camel.dsl.jbang.core.components.ComponentDescriptionMatching;
+import org.apache.camel.dsl.jbang.core.components.ComponentPrinter;
+import org.apache.camel.dsl.jbang.core.types.Component;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+
+@Command(name = "components", description = "Search for Camel Core components")
+class SearchComponents extends AbstractSearch implements Callable<Integer> {
+
+    /*
+     * Matches the following line. Separate them into groups and pick the last
+     * which contains the description:
+     *
+     * * xref:ROOT:index.adoc[Components]
+     */
+    private static final Pattern PATTERN = 
Pattern.compile("(.*):(.*)\\[(.*)\\]");
+
+    //CHECKSTYLE:OFF
+    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
+    private boolean helpRequested = false;
+    //CHECKSTYLE:ON
+
+    @Option(names = { "--search-term" }, defaultValue = "", description = 
"Default debug level")
+    private String searchTerm;
+
+    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
+            description = "Where to download the resources from")
+    private String resourceLocation;
+
+    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
+            description = "The branch to use when downloading or searching 
resources (mostly used for development/testing)")
+    private String branch;
+
+    @Override
+    public void printHeader() {
+        System.out.printf("%-35s %-45s %s%n", "COMPONENT", "DESCRIPTION", 
"LINK");
+        System.out.printf("%-35s %-45s %s%n", "-------", "-----------", 
"-----");
+    }
+
+    @Override
+    public Integer call() throws Exception {
+        setResourceLocation(resourceLocation, 
"camel:docs/components/modules/ROOT/nav.adoc");
+        setBranch(branch);
+
+        MatchExtractor<Component> matchExtractor;
+        if (searchTerm.isEmpty()) {
+            matchExtractor = new MatchExtractor<>(PATTERN, new 
ComponentConverter(), new ComponentPrinter());
+
+        } else {
+            matchExtractor = new MatchExtractor<>(
+                    PATTERN, new ComponentConverter(),
+                    new ComponentDescriptionMatching(searchTerm));
+
+        }
+
+        try {
+            search(matchExtractor);
+            return 0;
+        } catch (ResourceDoesNotExist e) {
+            System.err.println(e.getMessage());
+            return 1;
+        }
+    }
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/SearchKamelets.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/SearchKamelets.java
new file mode 100644
index 0000000..40347c2
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/SearchKamelets.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.
+ */
+
+package org.apache.camel.dsl.jbang.core.commands;
+
+import java.util.concurrent.Callable;
+import java.util.regex.Pattern;
+
+import org.apache.camel.dsl.jbang.core.common.MatchExtractor;
+import org.apache.camel.dsl.jbang.core.kamelets.KameletConverter;
+import org.apache.camel.dsl.jbang.core.kamelets.KameletDescriptionMatching;
+import org.apache.camel.dsl.jbang.core.kamelets.KameletPrinter;
+import org.apache.camel.dsl.jbang.core.types.Kamelet;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+
+@Command(name = "kamelets", description = "Search for a Kamelet in the Kamelet 
catalog")
+class SearchKamelets extends AbstractSearch implements Callable<Integer> {
+    /*
+     * Matches the following line. Separate them into groups and pick the last
+     * which contains the description:
+     *
+     * xref:ROOT:mariadb-sink.adoc[image:kamelets/mariadb-sink.svg[] MariaDB 
Sink]
+     */
+    private static final Pattern PATTERN = 
Pattern.compile("(.*):(.*):(.*)\\[(.*)\\[\\] (.*)\\]");
+
+    //CHECKSTYLE:OFF
+    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
+    private boolean helpRequested = false;
+    //CHECKSTYLE:ON
+
+    @Option(names = { "--search-term" }, defaultValue = "", description = 
"Default debug level")
+    private String searchTerm;
+
+    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
+            description = "Where to download the resources from")
+    private String resourceLocation;
+
+    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
+            description = "The branch to use when downloading resources from 
(used for development/testing)")
+    private String branch;
+
+    @Override
+    public void printHeader() {
+        System.out.printf("%-35s %-45s %s%n", "KAMELET", "DESCRIPTION", 
"LINK");
+        System.out.printf("%-35s %-45s %s%n", "-------", "-----------", 
"-----");
+    }
+
+    @Override
+    public Integer call() throws Exception {
+        setResourceLocation(resourceLocation, 
"camel-kamelets:docs/modules/ROOT/nav.adoc");
+        setBranch(branch);
+
+        MatchExtractor<Kamelet> matchExtractor;
+
+        if (searchTerm.isEmpty()) {
+            matchExtractor = new MatchExtractor<>(PATTERN, new 
KameletConverter(), new KameletPrinter());
+        } else {
+            matchExtractor = new MatchExtractor<>(
+                    PATTERN, new KameletConverter(),
+                    new KameletDescriptionMatching(searchTerm));
+        }
+
+        search(matchExtractor);
+
+        return 0;
+    }
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/SearchLanguages.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/SearchLanguages.java
new file mode 100644
index 0000000..92095f7
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/SearchLanguages.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.
+ */
+
+package org.apache.camel.dsl.jbang.core.commands;
+
+import java.util.concurrent.Callable;
+import java.util.regex.Pattern;
+
+import org.apache.camel.dsl.jbang.core.common.MatchExtractor;
+import org.apache.camel.dsl.jbang.core.common.exceptions.ResourceDoesNotExist;
+import org.apache.camel.dsl.jbang.core.languages.LanguageConverter;
+import org.apache.camel.dsl.jbang.core.languages.LanguageDescriptionMatching;
+import org.apache.camel.dsl.jbang.core.languages.LanguagePrinter;
+import org.apache.camel.dsl.jbang.core.types.Language;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+
+@Command(name = "languages", description = "Search for Camel expression 
languages")
+class SearchLanguages extends AbstractSearch implements Callable<Integer> {
+    /*
+     * Matches the following line. Separate them into groups and pick the last
+     * which contains the description:
+     *
+     * * xref:ROOT:index.adoc[Components]
+     */
+    private static final Pattern PATTERN = 
Pattern.compile("(.*):(.*)\\[(.*)\\]");
+
+    //CHECKSTYLE:OFF
+    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
+    private boolean helpRequested = false;
+    //CHECKSTYLE:ON
+
+    @Option(names = { "--search-term" }, defaultValue = "", description = 
"Default debug level")
+    private String searchTerm;
+
+    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
+            description = "Where to download the resources from")
+    private String resourceLocation;
+
+    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
+            description = "The branch to use when downloading or searching 
resources (mostly used for development/testing)")
+    private String branch;
+
+    @Override
+    public void printHeader() {
+        System.out.printf("%-35s %-45s %s%n", "LANGUAGE", "DESCRIPTION", 
"LINK");
+        System.out.printf("%-35s %-45s %s%n", "-------", "-----------", 
"-----");
+    }
+
+    @Override
+    public Integer call() throws Exception {
+        setResourceLocation(resourceLocation, 
"camel:docs/components/modules/languages/nav.adoc");
+        setBranch(branch);
+
+        MatchExtractor<Language> matchExtractor;
+        if (searchTerm.isEmpty()) {
+            matchExtractor = new MatchExtractor<>(PATTERN, new 
LanguageConverter(), new LanguagePrinter());
+
+        } else {
+            matchExtractor = new MatchExtractor<>(
+                    PATTERN, new LanguageConverter(),
+                    new LanguageDescriptionMatching(searchTerm));
+
+        }
+        try {
+            search(matchExtractor);
+            return 0;
+        } catch (ResourceDoesNotExist e) {
+            System.err.println(e.getMessage());
+            return 1;
+        }
+    }
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/SearchOthers.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/SearchOthers.java
new file mode 100644
index 0000000..fab64fc
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/SearchOthers.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.
+ */
+
+package org.apache.camel.dsl.jbang.core.commands;
+
+import java.util.concurrent.Callable;
+import java.util.regex.Pattern;
+
+import org.apache.camel.dsl.jbang.core.common.MatchExtractor;
+import org.apache.camel.dsl.jbang.core.common.exceptions.ResourceDoesNotExist;
+import org.apache.camel.dsl.jbang.core.others.OtherConverter;
+import org.apache.camel.dsl.jbang.core.others.OtherDescriptionMatching;
+import org.apache.camel.dsl.jbang.core.others.OtherPrinter;
+import org.apache.camel.dsl.jbang.core.types.Other;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+
+@Command(name = "others", description = "Search for Camel miscellaneous 
components")
+class SearchOthers extends AbstractSearch implements Callable<Integer> {
+    /*
+     * Matches the following line. Separate them into groups and pick the last
+     * which contains the description:
+     *
+     * * xref:ROOT:index.adoc[Components]
+     */
+    private static final Pattern PATTERN = 
Pattern.compile("(.*):(.*)\\[(.*)\\]");
+
+    //CHECKSTYLE:OFF
+    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
+    private boolean helpRequested = false;
+    //CHECKSTYLE:ON
+
+    @Option(names = { "--search-term" }, defaultValue = "", description = 
"Default debug level")
+    private String searchTerm;
+
+    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
+            description = "Where to download the resources from")
+    private String resourceLocation;
+
+    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
+            description = "The branch to use when downloading or searching 
resources (mostly used for development/testing)")
+    private String branch;
+
+    @Override
+    public void printHeader() {
+        System.out.printf("%-35s %-45s %s%n", "COMPONENT", "DESCRIPTION", 
"LINK");
+        System.out.printf("%-35s %-45s %s%n", "-------", "-----------", 
"-----");
+    }
+
+    @Override
+    public Integer call() throws Exception {
+        setResourceLocation(resourceLocation, 
"camel:docs/components/modules/others/nav.adoc");
+        setBranch(branch);
+
+        MatchExtractor<Other> matchExtractor;
+        if (searchTerm.isEmpty()) {
+            matchExtractor = new MatchExtractor<>(PATTERN, new 
OtherConverter(), new OtherPrinter());
+
+        } else {
+            matchExtractor = new MatchExtractor<>(
+                    PATTERN, new OtherConverter(),
+                    new OtherDescriptionMatching(searchTerm));
+
+        }
+
+        try {
+            search(matchExtractor);
+            return 0;
+        } catch (ResourceDoesNotExist e) {
+            System.err.println(e.getMessage());
+            return 1;
+        }
+    }
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/RuntimeUtil.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/RuntimeUtil.java
new file mode 100644
index 0000000..a4b0dc1
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/RuntimeUtil.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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.
+ */
+
+package org.apache.camel.dsl.jbang.core.common;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.config.Configurator;
+import org.apache.logging.log4j.core.config.DefaultConfiguration;
+import org.slf4j.LoggerFactory;
+
+public final class RuntimeUtil {
+
+    static {
+        Configurator.initialize(new DefaultConfiguration());
+    }
+
+    private RuntimeUtil() {
+
+    }
+
+    public static void configureLog(String debugLevel) {
+        switch (debugLevel) {
+            case "trace":
+                Configurator.setRootLevel(Level.TRACE);
+                break;
+            case "debug":
+                Configurator.setRootLevel(Level.DEBUG);
+                break;
+            case "info":
+                Configurator.setRootLevel(Level.INFO);
+                break;
+            case "warn":
+                Configurator.setRootLevel(Level.WARN);
+                break;
+            case "fatal":
+                Configurator.setRootLevel(Level.FATAL);
+                break;
+            default: {
+                Configurator.setRootLevel(Level.INFO);
+                LoggerFactory.getLogger(RuntimeUtil.class).warn("Invalid debug 
level: {}", debugLevel);
+            }
+        }
+    }
+
+}
diff --git a/dsl/camel-jbang/camel-jbang-main/README.md 
b/dsl/camel-jbang/camel-jbang-main/README.md
index 5e59c0a..c89f296 100644
--- a/dsl/camel-jbang/camel-jbang-main/README.md
+++ b/dsl/camel-jbang/camel-jbang-main/README.md
@@ -62,44 +62,12 @@ available for Kafka, such as the Confluent one and the 
Strimzi project one.
 
 ### Handling Dependencies Versions
 
-This module aims to be both simple and practical, as such, there are a few 
recommendations to follow when contributing 
-to the code on
-this particular module. 
-
-The module leverages JBang's ability to [parameterize 
dependencies](https://www.jbang.dev/documentation/guide/latest/dependencies.html#system-properties-and-environment-variables)
 along with Antrun's
-ability to process source code on the fly and perform string substitution to 
replace strings on files. 
-
-During the build, the *perfectly valid* Java-based JBang script code is copied 
to the `dist` directory. Then the antrun 
-plugin replaces the references to parameterized dependencies. The 
parameterized dependencies are in the format `${name}`. 
-
-In order to minimize the problems caused by CVEs in dependencies and ensure 
the correct alignment of dependencies within 
-Camel, all references to dependencies should use parameterized ones. Such as: 
-
-```
-//DEPS org.apache.camel:camel-bom:${camel.jbang.version}@pom
-```
-
-After being processed by antrun, during the build, the aforementioned line 
would be transformed to something like (for 
-a Camel 3.13.0-SNAPSHOT build):
+If needed for development and debugging purposes, dependencies can be 
referenced by correctly resolving the parameterized variables on the command 
line. Such as: 
 
 ```
-//DEPS org.apache.camel:camel-bom:3.13.0-SNAPSHOT@pom
+jbang -Dcamel.jbang.version=3.13.0-SNAPSHOT CamelJBang.java
 ```
 
-The same applies to Camel version references, which should rely on the 
`${camel.jbang.version}` parameter (such 
-as when displaying help information).
-
-Despite this transformation, the code in `src/main/jbang` should be valid 
nonetheless and can be executed for development 
-and debugging purposes by correctly resolving the parameterized variables on 
the command line. Such as: 
-
-```
-jbang -Dcamel.jbang.version=3.13.0-SNAPSHOT 
-Dcamel.jbang.log4j2.version=2.13.3 -Dcamel.jbang.picocli.version=4.5.0 
CamelJBang.java
-```
-
-Alternatively, it is possible to just build the module and then execute the 
post-processed script on the `dist` directory.
-
-```mvn clean package && ./dist/Camel```
-
 ### Checkstyle
 
 Because the first line of the script requires a she-bang like line, it 
violates the default checkstyle used by the 
diff --git a/dsl/camel-jbang/camel-jbang-main/dist/CamelJBang.java 
b/dsl/camel-jbang/camel-jbang-main/dist/CamelJBang.java
index 93b1061..a52dcb0 100755
--- a/dsl/camel-jbang/camel-jbang-main/dist/CamelJBang.java
+++ b/dsl/camel-jbang/camel-jbang-main/dist/CamelJBang.java
@@ -19,597 +19,14 @@
 
 //REPOS mavencentral,apache=https://repository.apache.org/snapshots
 //DEPS org.apache.camel:camel-bom:${camel.jbang.version:RELEASE}@pom
-//DEPS org.apache.camel:camel-core
-//DEPS org.apache.camel:camel-api
-//DEPS org.apache.camel:camel-core-model
-//DEPS org.apache.camel:camel-main
-//DEPS org.apache.camel:camel-kamelet-main
-//DEPS org.apache.camel:camel-file-watch
-//DEPS org.apache.camel:camel-resourceresolver-github
 //DEPS org.apache.camel:camel-jbang-core:${camel.jbang.version:RELEASE}
-//DEPS org.apache.logging.log4j:log4j-api:2.13.3
-//DEPS org.apache.logging.log4j:log4j-core:2.13.3
-//DEPS org.apache.logging.log4j:log4j-slf4j-impl:2.13.3
-//DEPS org.apache.velocity:velocity-engine-core:2.3
-//DEPS info.picocli:picocli:4.6.1
 
 package main;
 
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.concurrent.Callable;
-import java.util.regex.Pattern;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.CamelException;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.dsl.jbang.core.commands.AbstractInitKamelet;
-import org.apache.camel.dsl.jbang.core.commands.AbstractSearch;
-import org.apache.camel.dsl.jbang.core.common.MatchExtractor;
-import org.apache.camel.dsl.jbang.core.common.exceptions.ResourceAlreadyExists;
-import org.apache.camel.dsl.jbang.core.common.exceptions.ResourceDoesNotExist;
-import org.apache.camel.dsl.jbang.core.components.ComponentConverter;
-import org.apache.camel.dsl.jbang.core.components.ComponentDescriptionMatching;
-import org.apache.camel.dsl.jbang.core.components.ComponentPrinter;
-import org.apache.camel.dsl.jbang.core.kamelets.KameletConverter;
-import org.apache.camel.dsl.jbang.core.kamelets.KameletDescriptionMatching;
-import org.apache.camel.dsl.jbang.core.kamelets.KameletPrinter;
-import org.apache.camel.dsl.jbang.core.languages.LanguageConverter;
-import org.apache.camel.dsl.jbang.core.languages.LanguageDescriptionMatching;
-import org.apache.camel.dsl.jbang.core.languages.LanguagePrinter;
-import org.apache.camel.dsl.jbang.core.others.OtherConverter;
-import org.apache.camel.dsl.jbang.core.others.OtherDescriptionMatching;
-import org.apache.camel.dsl.jbang.core.others.OtherPrinter;
-import org.apache.camel.dsl.jbang.core.templates.VelocityTemplateParser;
-import org.apache.camel.dsl.jbang.core.types.Component;
-import org.apache.camel.dsl.jbang.core.types.Kamelet;
-import org.apache.camel.dsl.jbang.core.types.Language;
-import org.apache.camel.dsl.jbang.core.types.Other;
-import org.apache.camel.main.KameletMain;
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.core.config.Configurator;
-import org.apache.logging.log4j.core.config.DefaultConfiguration;
-import picocli.CommandLine;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Option;
-import picocli.CommandLine.Parameters;
-
-@Command(name = "run", description = "Run a Kamelet")
-class Run implements Callable<Integer> {
-    private CamelContext context;
-
-    @Parameters(description = "The path to the kamelet binding", arity = 
"0..1")
-    private String binding;
-
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    @Option(names = { "--debug-level" }, defaultValue = "info", description = 
"Default debug level")
-    private String debugLevel;
-
-    @Option(names = { "--stop" }, description = "Stop all running instances of 
Camel JBang")
-    private boolean stopRequested;
-
-    @Option(names = { "--max-messages" }, defaultValue = "0", description = 
"Max number of messages to process before stopping")
-    private int maxMessages;
-
-    class ShutdownRoute extends RouteBuilder {
-        private File lockFile;
-
-        public ShutdownRoute(File lockFile) {
-            this.lockFile = lockFile;
-        }
-
-        public void configure() {
-            fromF("file-watch://%s?events=DELETE&antInclude=%s", 
lockFile.getParent(), lockFile.getName())
-                    .process(p -> context.shutdown());
-        }
-    }
-
-    @Override
-    public Integer call() throws Exception {
-        System.setProperty("camel.main.name", "CamelJBang");
-
-        if (stopRequested) {
-            stop();
-        } else {
-            run();
-        }
-
-        return 0;
-    }
-
-    private int stop() {
-        File currentDir = new File(".");
-
-        File[] lockFiles = currentDir.listFiles(f -> 
f.getName().endsWith(".camel.lock"));
-
-        for (File lockFile : lockFiles) {
-            System.out.println("Removing file " + lockFile);
-            if (!lockFile.delete()) {
-                System.err.println("Failed to remove lock file " + lockFile);
-            }
-        }
-
-        return 0;
-    }
-
-    private int run() throws Exception {
-        if (maxMessages > 0) {
-            System.setProperty("camel.main.durationMaxMessages", 
String.valueOf(maxMessages));
-        }
-
-        System.setProperty("camel.main.routes-include-pattern", "file:" + 
binding);
-
-        switch (debugLevel) {
-            case "trace":
-                Configurator.setRootLevel(Level.TRACE);
-                break;
-            case "debug":
-                Configurator.setRootLevel(Level.DEBUG);
-                break;
-            case "info":
-                Configurator.setRootLevel(Level.INFO);
-                break;
-            case "warn":
-                Configurator.setRootLevel(Level.WARN);
-                break;
-            case "fatal":
-                Configurator.setRootLevel(Level.FATAL);
-                break;
-            default: {
-                System.err.println("Invalid debug level " + debugLevel);
-                return 1;
-            }
-        }
-
-        File bindingFile = new File(binding);
-        if (!bindingFile.exists()) {
-            System.err.println("The binding file does not exist");
-
-            return 1;
-        }
-
-        System.out.println("Starting Camel JBang!");
-        KameletMain main = new KameletMain();
-
-        main.configure().addRoutesBuilder(new ShutdownRoute(createLockFile()));
-        main.start();
-        context = main.getCamelContext();
-
-        main.run();
-        return 0;
-    }
-
-    public File createLockFile() throws IOException {
-        File lockFile = File.createTempFile(".run", ".camel.lock", new 
File("."));
-
-        System.out.printf("A new lock file was created on %s. Delete this file 
to stop running%n",
-                lockFile.getAbsolutePath());
-        lockFile.deleteOnExit();
-
-        return lockFile;
-    }
-}
-
-@Command(name = "search", description = "Search for kameletes, components and 
patterns (use --help)")
-class Search extends AbstractSearch implements Callable<Integer> {
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    public Search() {
-        super(null, null);
-    }
-
-    public void printHeader() {
-        // NO-OP
-    }
-
-    @Override
-    public Integer call() throws Exception {
-        new CommandLine(this).execute("--help");
-
-        return 0;
-    }
-}
-
-@Command(name = "kamelets", description = "Search for a Kamelet in the Kamelet 
catalog")
-class SearchKamelets extends AbstractSearch implements Callable<Integer> {
-
-    /*
-     * Matches the following line. Separate them into groups and pick the last
-     * which contains the description:
-     *
-     * xref:ROOT:mariadb-sink.adoc[image:kamelets/mariadb-sink.svg[] MariaDB 
Sink]
-     */
-    private static final Pattern PATTERN = 
Pattern.compile("(.*):(.*):(.*)\\[(.*)\\[\\] (.*)\\]");
-
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    @Option(names = { "--search-term" }, defaultValue = "", description = 
"Default debug level")
-    private String searchTerm;
-
-    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
-            description = "Where to download the resources from")
-    private String resourceLocation;
-
-    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
-            description = "The branch to use when downloading resources from 
(used for development/testing)")
-    private String branch;
-
-    @Override
-    public void printHeader() {
-        System.out.printf("%-35s %-45s %s%n", "KAMELET", "DESCRIPTION", 
"LINK");
-        System.out.printf("%-35s %-45s %s%n", "-------", "-----------", 
"-----");
-    }
-
-    @Override
-    public Integer call() throws Exception {
-        setResourceLocation(resourceLocation, 
"camel-kamelets:docs/modules/ROOT/nav.adoc");
-        setBranch(branch);
-
-        MatchExtractor<Kamelet> matchExtractor;
-
-        if (searchTerm.isEmpty()) {
-            matchExtractor = new MatchExtractor<>(PATTERN, new 
KameletConverter(), new KameletPrinter());
-        } else {
-            matchExtractor = new MatchExtractor<>(
-                    PATTERN, new KameletConverter(),
-                    new KameletDescriptionMatching(searchTerm));
-        }
-
-        search(matchExtractor);
-
-        return 0;
-    }
-}
-
-@Command(name = "components", description = "Search for Camel Core components")
-class SearchComponents extends AbstractSearch implements Callable<Integer> {
-
-    /*
-     * Matches the following line. Separate them into groups and pick the last
-     * which contains the description:
-     *
-     * * xref:ROOT:index.adoc[Components]
-     */
-    private static final Pattern PATTERN = 
Pattern.compile("(.*):(.*)\\[(.*)\\]");
-
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    @Option(names = { "--search-term" }, defaultValue = "", description = 
"Default debug level")
-    private String searchTerm;
-
-    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
-            description = "Where to download the resources from")
-    private String resourceLocation;
-
-    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
-            description = "The branch to use when downloading or searching 
resources (mostly used for development/testing)")
-    private String branch;
-
-    @Override
-    public void printHeader() {
-        System.out.printf("%-35s %-45s %s%n", "COMPONENT", "DESCRIPTION", 
"LINK");
-        System.out.printf("%-35s %-45s %s%n", "-------", "-----------", 
"-----");
-    }
-
-    @Override
-    public Integer call() throws Exception {
-        setResourceLocation(resourceLocation, 
"camel:docs/components/modules/ROOT/nav.adoc");
-        setBranch(branch);
-
-        MatchExtractor<Component> matchExtractor;
-        if (searchTerm.isEmpty()) {
-            matchExtractor = new MatchExtractor<>(PATTERN, new 
ComponentConverter(), new ComponentPrinter());
-
-        } else {
-            matchExtractor = new MatchExtractor<>(
-                    PATTERN, new ComponentConverter(),
-                    new ComponentDescriptionMatching(searchTerm));
-
-        }
-
-        try {
-            search(matchExtractor);
-            return 0;
-        } catch (ResourceDoesNotExist e) {
-            System.err.println(e.getMessage());
-            return 1;
-        }
-    }
-}
-
-@Command(name = "languages", description = "Search for Camel expression 
languages")
-class SearchLanguages extends AbstractSearch implements Callable<Integer> {
-    /*
-     * Matches the following line. Separate them into groups and pick the last
-     * which contains the description:
-     *
-     * * xref:ROOT:index.adoc[Components]
-     */
-    private static final Pattern PATTERN = 
Pattern.compile("(.*):(.*)\\[(.*)\\]");
-
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    @Option(names = { "--search-term" }, defaultValue = "", description = 
"Default debug level")
-    private String searchTerm;
-
-    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
-            description = "Where to download the resources from")
-    private String resourceLocation;
-
-    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
-            description = "The branch to use when downloading or searching 
resources (mostly used for development/testing)")
-    private String branch;
-
-    @Override
-    public void printHeader() {
-        System.out.printf("%-35s %-45s %s%n", "LANGUAGE", "DESCRIPTION", 
"LINK");
-        System.out.printf("%-35s %-45s %s%n", "-------", "-----------", 
"-----");
-    }
-
-    @Override
-    public Integer call() throws Exception {
-        setResourceLocation(resourceLocation, 
"camel:docs/components/modules/languages/nav.adoc");
-        setBranch(branch);
-
-        MatchExtractor<Language> matchExtractor;
-        if (searchTerm.isEmpty()) {
-            matchExtractor = new MatchExtractor<>(PATTERN, new 
LanguageConverter(), new LanguagePrinter());
-
-        } else {
-            matchExtractor = new MatchExtractor<>(
-                    PATTERN, new LanguageConverter(),
-                    new LanguageDescriptionMatching(searchTerm));
-
-        }
-        try {
-            search(matchExtractor);
-            return 0;
-        } catch (ResourceDoesNotExist e) {
-            System.err.println(e.getMessage());
-            return 1;
-        }
-    }
-}
-
-@Command(name = "others", description = "Search for Camel miscellaneous 
components")
-class SearchOthers extends AbstractSearch implements Callable<Integer> {
-    /*
-     * Matches the following line. Separate them into groups and pick the last
-     * which contains the description:
-     *
-     * * xref:ROOT:index.adoc[Components]
-     */
-    private static final Pattern PATTERN = 
Pattern.compile("(.*):(.*)\\[(.*)\\]");
-
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    @Option(names = { "--search-term" }, defaultValue = "", description = 
"Default debug level")
-    private String searchTerm;
-
-    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
-            description = "Where to download the resources from")
-    private String resourceLocation;
-
-    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
-            description = "The branch to use when downloading or searching 
resources (mostly used for development/testing)")
-    private String branch;
-
-    @Override
-    public void printHeader() {
-        System.out.printf("%-35s %-45s %s%n", "COMPONENT", "DESCRIPTION", 
"LINK");
-        System.out.printf("%-35s %-45s %s%n", "-------", "-----------", 
"-----");
-    }
-
-    @Override
-    public Integer call() throws Exception {
-        setResourceLocation(resourceLocation, 
"camel:docs/components/modules/others/nav.adoc");
-        setBranch(branch);
-
-        MatchExtractor<Other> matchExtractor;
-        if (searchTerm.isEmpty()) {
-            matchExtractor = new MatchExtractor<>(PATTERN, new 
OtherConverter(), new OtherPrinter());
-
-        } else {
-            matchExtractor = new MatchExtractor<>(
-                    PATTERN, new OtherConverter(),
-                    new OtherDescriptionMatching(searchTerm));
-
-        }
-
-        try {
-            search(matchExtractor);
-            return 0;
-        } catch (ResourceDoesNotExist e) {
-            System.err.println(e.getMessage());
-            return 1;
-        }
-    }
-}
-
-@Command(name = "init", description = "Provide init templates for kamelets and 
bindings")
-class Init implements Callable<Integer> {
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    @Override
-    public Integer call() throws Exception {
-        new CommandLine(this).execute("--help");
-
-        return 0;
-    }
-}
-
-@Command(name = "kamelet", description = "Provide init templates for kamelets")
-class InitKamelet extends AbstractInitKamelet implements Callable<Integer> {
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    @CommandLine.ArgGroup(exclusive = true, multiplicity = "1")
-    private ProcessOptions processOptions;
-
-    static class ProcessOptions {
-        @Option(names = { "--bootstrap" },
-                description = "Bootstrap the Kamelet template generator - 
download the properties file for editing")
-        private boolean bootstrap = false;
-
-        @Option(names = { "--properties-path" }, defaultValue = "", 
description = "Kamelet name")
-        private String propertiesPath;
-    }
-
-    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
-            description = "Where to download the resources from (used for 
development/testing)")
-    private String baseResourceLocation;
-
-    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
-            description = "The branch to use when downloading resources from 
(used for development/testing)")
-    private String branch;
-
-    @Option(names = { "--destination" }, defaultValue = "work",
-            description = "The destination directory where to download the 
files")
-    private String destination;
-
-    @Override
-    public Integer call() throws Exception {
-        if (processOptions.bootstrap) {
-            bootstrap();
-        } else {
-            generateTemplate();
-        }
-
-        return 0;
-    }
-
-    private int generateTemplate() throws IOException, CamelException {
-        setBranch(branch);
-        setResourceLocation(baseResourceLocation, 
"camel-kamelets:templates/init-template.kamelet.yaml.vm");
-
-        File workDirectory = new File(destination);
-
-        File localTemplateFile;
-        try {
-            localTemplateFile = resolveResource(workDirectory);
-        } catch (ResourceAlreadyExists e) {
-            System.err.println(e.getMessage());
-            return 1;
-        }
-        localTemplateFile.deleteOnExit();
-
-        VelocityTemplateParser templateParser = new VelocityTemplateParser(
-                localTemplateFile.getParentFile(),
-                processOptions.propertiesPath);
-
-        File outputFile;
-        try {
-            outputFile = templateParser.getOutputFile(workDirectory);
-        } catch (ResourceAlreadyExists e) {
-            System.err.println(e.getMessage());
-            return 1;
-        }
-
-        try (FileWriter fw = new FileWriter(outputFile)) {
-            templateParser.parse(localTemplateFile.getName(), fw);
-            System.out.println("Template file was written to " + outputFile);
-        }
-
-        return 0;
-    }
-
-    private int bootstrap() throws IOException, CamelException {
-        try {
-            super.bootstrap(branch, baseResourceLocation, destination);
-            return 0;
-        } catch (ResourceAlreadyExists e) {
-            System.err.println(e.getMessage());
-
-            return 1;
-        }
-    }
-}
-
-@Command(name = "binding", description = "Provide init templates for kamelet 
bindings")
-class InitBinding extends AbstractInitKamelet implements Callable<Integer> {
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
-            description = "Where to download the resources from (used for 
development/testing)")
-    private String baseResourceLocation;
-
-    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
-            description = "The branch to use when downloading resources from 
(used for development/testing)")
-    private String branch;
-
-    @Option(names = { "--destination" }, defaultValue = "work",
-            description = "The destination directory where to download the 
files")
-    private String destination;
-
-    @Option(names = { "--kamelet" }, defaultValue = "",
-            description = "The kamelet to create a binding for")
-    private String kamelet;
-
-    @Option(names = { "--project" }, defaultValue = "camel-k",
-            description = "The project to create a binding for (either camel-k 
or core)")
-    private String project;
-
-    private int downloadSample() throws IOException, CamelException {
-        setBranch(branch);
-
-        String resourcePath = 
String.format("camel-kamelets:templates/bindings/%s/%s-binding.yaml", project, 
kamelet);
-
-        setResourceLocation(baseResourceLocation, resourcePath);
-
-        try {
-            resolveResource(new File(destination));
-        } catch (ResourceAlreadyExists e) {
-            System.err.println(e.getMessage());
-            return 1;
-        }
-
-        return 0;
-    }
-
-    @Override
-    public Integer call() throws Exception {
-        return downloadSample();
-    }
-}
-
-@Command(name = "CamelJBang", mixinStandardHelpOptions = true, version = 
"CamelJBang",
-         description = "A JBang-based Camel app for running Kamelets")
-public class CamelJBang implements Callable<Integer> {
-    private static CommandLine commandLine;
-
-    static {
-        Configurator.initialize(new DefaultConfiguration());
-    }
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
 
+public class CamelJBang {
     public static void main(String... args) {
-        commandLine = new CommandLine(new CamelJBang())
-                .addSubcommand("run", new Run())
-                .addSubcommand("search", new CommandLine(new Search())
-                        .addSubcommand("kamelets", new SearchKamelets())
-                        .addSubcommand("components", new SearchComponents())
-                        .addSubcommand("languages", new SearchLanguages())
-                        .addSubcommand("others", new SearchOthers()))
-                .addSubcommand("init", new CommandLine(new Init())
-                        .addSubcommand("kamelet", new InitKamelet())
-                        .addSubcommand("binding", new InitBinding()));
-
-        int exitCode = commandLine.execute(args);
-        System.exit(exitCode);
-    }
-
-    @Override
-    public Integer call() throws Exception {
-        commandLine.execute("--help");
-        return 0;
+        CamelJBangMain.run(args);
     }
 }
diff --git a/dsl/camel-jbang/camel-jbang-main/pom.xml 
b/dsl/camel-jbang/camel-jbang-main/pom.xml
index 0885e632..f684b80 100644
--- a/dsl/camel-jbang/camel-jbang-main/pom.xml
+++ b/dsl/camel-jbang/camel-jbang-main/pom.xml
@@ -42,59 +42,9 @@
     <dependencies>
         <dependency>
             <groupId>org.apache.camel</groupId>
-            <artifactId>camel-core</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-core-model</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-main</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-kamelet-main</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-file-watch</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.camel</groupId>
-            <artifactId>camel-resourceresolver-github</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.camel</groupId>
             <artifactId>camel-jbang-core</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-core</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-slf4j-impl</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>info.picocli</groupId>
-            <artifactId>picocli</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.velocity</groupId>
-            <artifactId>velocity-engine-core</artifactId>
-            <version>${velocity-version}</version>
-        </dependency>
     </dependencies>
 
     <build>
@@ -114,6 +64,7 @@
                 <artifactId>maven-checkstyle-plugin</artifactId>
                 <configuration>
                     <skip>${checkstyle.skip}</skip>
+                    <failOnViolation>false</failOnViolation>
                 </configuration>
             </plugin>
 
@@ -124,15 +75,11 @@
                         <phase>prepare-package</phase>
                         <configuration>
                             <tasks>
-                                <replace token="${camel.jbang.log4j2.version}" 
value="${log4j2-version}" dir="${dist.dir}">
-                                    <include name="**/*.java"/>
-                                </replace>
-                                <replace 
token="${camel.jbang.picocli.version}" value="${picocli-version}" 
dir="${dist.dir}">
-                                    <include name="**/*.java"/>
-                                </replace>
-                                <replace 
token="${camel.jbang.velocity.version}" value="${velocity-version}" 
dir="${dist.dir}">
-                                    <include name="**/*.java"/>
-                                </replace>
+                                <copy todir="${dist.dir}">
+                                    <fileset dir="${project.build.directory}">
+                                        <include name="**/*.java"/>
+                                    </fileset>
+                                </copy>
                                 <chmod file="${dist.dir}/*.java" perm="u+x" />
                             </tasks>
                         </configuration>
diff --git 
a/dsl/camel-jbang/camel-jbang-main/src/main/jbang/main/CamelJBang.java 
b/dsl/camel-jbang/camel-jbang-main/src/main/jbang/main/CamelJBang.java
index 358f871..a52dcb0 100755
--- a/dsl/camel-jbang/camel-jbang-main/src/main/jbang/main/CamelJBang.java
+++ b/dsl/camel-jbang/camel-jbang-main/src/main/jbang/main/CamelJBang.java
@@ -19,597 +19,14 @@
 
 //REPOS mavencentral,apache=https://repository.apache.org/snapshots
 //DEPS org.apache.camel:camel-bom:${camel.jbang.version:RELEASE}@pom
-//DEPS org.apache.camel:camel-core
-//DEPS org.apache.camel:camel-api
-//DEPS org.apache.camel:camel-core-model
-//DEPS org.apache.camel:camel-main
-//DEPS org.apache.camel:camel-kamelet-main
-//DEPS org.apache.camel:camel-file-watch
-//DEPS org.apache.camel:camel-resourceresolver-github
 //DEPS org.apache.camel:camel-jbang-core:${camel.jbang.version:RELEASE}
-//DEPS org.apache.logging.log4j:log4j-api:${camel.jbang.log4j2.version}
-//DEPS org.apache.logging.log4j:log4j-core:${camel.jbang.log4j2.version}
-//DEPS org.apache.logging.log4j:log4j-slf4j-impl:${camel.jbang.log4j2.version}
-//DEPS org.apache.velocity:velocity-engine-core:${camel.jbang.velocity.version}
-//DEPS info.picocli:picocli:${camel.jbang.picocli.version}
 
 package main;
 
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.concurrent.Callable;
-import java.util.regex.Pattern;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.CamelException;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.dsl.jbang.core.commands.AbstractInitKamelet;
-import org.apache.camel.dsl.jbang.core.commands.AbstractSearch;
-import org.apache.camel.dsl.jbang.core.common.MatchExtractor;
-import org.apache.camel.dsl.jbang.core.common.exceptions.ResourceAlreadyExists;
-import org.apache.camel.dsl.jbang.core.common.exceptions.ResourceDoesNotExist;
-import org.apache.camel.dsl.jbang.core.components.ComponentConverter;
-import org.apache.camel.dsl.jbang.core.components.ComponentDescriptionMatching;
-import org.apache.camel.dsl.jbang.core.components.ComponentPrinter;
-import org.apache.camel.dsl.jbang.core.kamelets.KameletConverter;
-import org.apache.camel.dsl.jbang.core.kamelets.KameletDescriptionMatching;
-import org.apache.camel.dsl.jbang.core.kamelets.KameletPrinter;
-import org.apache.camel.dsl.jbang.core.languages.LanguageConverter;
-import org.apache.camel.dsl.jbang.core.languages.LanguageDescriptionMatching;
-import org.apache.camel.dsl.jbang.core.languages.LanguagePrinter;
-import org.apache.camel.dsl.jbang.core.others.OtherConverter;
-import org.apache.camel.dsl.jbang.core.others.OtherDescriptionMatching;
-import org.apache.camel.dsl.jbang.core.others.OtherPrinter;
-import org.apache.camel.dsl.jbang.core.templates.VelocityTemplateParser;
-import org.apache.camel.dsl.jbang.core.types.Component;
-import org.apache.camel.dsl.jbang.core.types.Kamelet;
-import org.apache.camel.dsl.jbang.core.types.Language;
-import org.apache.camel.dsl.jbang.core.types.Other;
-import org.apache.camel.main.KameletMain;
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.core.config.Configurator;
-import org.apache.logging.log4j.core.config.DefaultConfiguration;
-import picocli.CommandLine;
-import picocli.CommandLine.Command;
-import picocli.CommandLine.Option;
-import picocli.CommandLine.Parameters;
-
-@Command(name = "run", description = "Run a Kamelet")
-class Run implements Callable<Integer> {
-    private CamelContext context;
-
-    @Parameters(description = "The path to the kamelet binding", arity = 
"0..1")
-    private String binding;
-
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    @Option(names = { "--debug-level" }, defaultValue = "info", description = 
"Default debug level")
-    private String debugLevel;
-
-    @Option(names = { "--stop" }, description = "Stop all running instances of 
Camel JBang")
-    private boolean stopRequested;
-
-    @Option(names = { "--max-messages" }, defaultValue = "0", description = 
"Max number of messages to process before stopping")
-    private int maxMessages;
-
-    class ShutdownRoute extends RouteBuilder {
-        private File lockFile;
-
-        public ShutdownRoute(File lockFile) {
-            this.lockFile = lockFile;
-        }
-
-        public void configure() {
-            fromF("file-watch://%s?events=DELETE&antInclude=%s", 
lockFile.getParent(), lockFile.getName())
-                    .process(p -> context.shutdown());
-        }
-    }
-
-    @Override
-    public Integer call() throws Exception {
-        System.setProperty("camel.main.name", "CamelJBang");
-
-        if (stopRequested) {
-            stop();
-        } else {
-            run();
-        }
-
-        return 0;
-    }
-
-    private int stop() {
-        File currentDir = new File(".");
-
-        File[] lockFiles = currentDir.listFiles(f -> 
f.getName().endsWith(".camel.lock"));
-
-        for (File lockFile : lockFiles) {
-            System.out.println("Removing file " + lockFile);
-            if (!lockFile.delete()) {
-                System.err.println("Failed to remove lock file " + lockFile);
-            }
-        }
-
-        return 0;
-    }
-
-    private int run() throws Exception {
-        if (maxMessages > 0) {
-            System.setProperty("camel.main.durationMaxMessages", 
String.valueOf(maxMessages));
-        }
-
-        System.setProperty("camel.main.routes-include-pattern", "file:" + 
binding);
-
-        switch (debugLevel) {
-            case "trace":
-                Configurator.setRootLevel(Level.TRACE);
-                break;
-            case "debug":
-                Configurator.setRootLevel(Level.DEBUG);
-                break;
-            case "info":
-                Configurator.setRootLevel(Level.INFO);
-                break;
-            case "warn":
-                Configurator.setRootLevel(Level.WARN);
-                break;
-            case "fatal":
-                Configurator.setRootLevel(Level.FATAL);
-                break;
-            default: {
-                System.err.println("Invalid debug level " + debugLevel);
-                return 1;
-            }
-        }
-
-        File bindingFile = new File(binding);
-        if (!bindingFile.exists()) {
-            System.err.println("The binding file does not exist");
-
-            return 1;
-        }
-
-        System.out.println("Starting Camel JBang!");
-        KameletMain main = new KameletMain();
-
-        main.configure().addRoutesBuilder(new ShutdownRoute(createLockFile()));
-        main.start();
-        context = main.getCamelContext();
-
-        main.run();
-        return 0;
-    }
-
-    public File createLockFile() throws IOException {
-        File lockFile = File.createTempFile(".run", ".camel.lock", new 
File("."));
-
-        System.out.printf("A new lock file was created on %s. Delete this file 
to stop running%n",
-                lockFile.getAbsolutePath());
-        lockFile.deleteOnExit();
-
-        return lockFile;
-    }
-}
-
-@Command(name = "search", description = "Search for kameletes, components and 
patterns (use --help)")
-class Search extends AbstractSearch implements Callable<Integer> {
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    public Search() {
-        super(null, null);
-    }
-
-    public void printHeader() {
-        // NO-OP
-    }
-
-    @Override
-    public Integer call() throws Exception {
-        new CommandLine(this).execute("--help");
-
-        return 0;
-    }
-}
-
-@Command(name = "kamelets", description = "Search for a Kamelet in the Kamelet 
catalog")
-class SearchKamelets extends AbstractSearch implements Callable<Integer> {
-
-    /*
-     * Matches the following line. Separate them into groups and pick the last
-     * which contains the description:
-     *
-     * xref:ROOT:mariadb-sink.adoc[image:kamelets/mariadb-sink.svg[] MariaDB 
Sink]
-     */
-    private static final Pattern PATTERN = 
Pattern.compile("(.*):(.*):(.*)\\[(.*)\\[\\] (.*)\\]");
-
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    @Option(names = { "--search-term" }, defaultValue = "", description = 
"Default debug level")
-    private String searchTerm;
-
-    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
-            description = "Where to download the resources from")
-    private String resourceLocation;
-
-    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
-            description = "The branch to use when downloading resources from 
(used for development/testing)")
-    private String branch;
-
-    @Override
-    public void printHeader() {
-        System.out.printf("%-35s %-45s %s%n", "KAMELET", "DESCRIPTION", 
"LINK");
-        System.out.printf("%-35s %-45s %s%n", "-------", "-----------", 
"-----");
-    }
-
-    @Override
-    public Integer call() throws Exception {
-        setResourceLocation(resourceLocation, 
"camel-kamelets:docs/modules/ROOT/nav.adoc");
-        setBranch(branch);
-
-        MatchExtractor<Kamelet> matchExtractor;
-
-        if (searchTerm.isEmpty()) {
-            matchExtractor = new MatchExtractor<>(PATTERN, new 
KameletConverter(), new KameletPrinter());
-        } else {
-            matchExtractor = new MatchExtractor<>(
-                    PATTERN, new KameletConverter(),
-                    new KameletDescriptionMatching(searchTerm));
-        }
-
-        search(matchExtractor);
-
-        return 0;
-    }
-}
-
-@Command(name = "components", description = "Search for Camel Core components")
-class SearchComponents extends AbstractSearch implements Callable<Integer> {
-
-    /*
-     * Matches the following line. Separate them into groups and pick the last
-     * which contains the description:
-     *
-     * * xref:ROOT:index.adoc[Components]
-     */
-    private static final Pattern PATTERN = 
Pattern.compile("(.*):(.*)\\[(.*)\\]");
-
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    @Option(names = { "--search-term" }, defaultValue = "", description = 
"Default debug level")
-    private String searchTerm;
-
-    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
-            description = "Where to download the resources from")
-    private String resourceLocation;
-
-    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
-            description = "The branch to use when downloading or searching 
resources (mostly used for development/testing)")
-    private String branch;
-
-    @Override
-    public void printHeader() {
-        System.out.printf("%-35s %-45s %s%n", "COMPONENT", "DESCRIPTION", 
"LINK");
-        System.out.printf("%-35s %-45s %s%n", "-------", "-----------", 
"-----");
-    }
-
-    @Override
-    public Integer call() throws Exception {
-        setResourceLocation(resourceLocation, 
"camel:docs/components/modules/ROOT/nav.adoc");
-        setBranch(branch);
-
-        MatchExtractor<Component> matchExtractor;
-        if (searchTerm.isEmpty()) {
-            matchExtractor = new MatchExtractor<>(PATTERN, new 
ComponentConverter(), new ComponentPrinter());
-
-        } else {
-            matchExtractor = new MatchExtractor<>(
-                    PATTERN, new ComponentConverter(),
-                    new ComponentDescriptionMatching(searchTerm));
-
-        }
-
-        try {
-            search(matchExtractor);
-            return 0;
-        } catch (ResourceDoesNotExist e) {
-            System.err.println(e.getMessage());
-            return 1;
-        }
-    }
-}
-
-@Command(name = "languages", description = "Search for Camel expression 
languages")
-class SearchLanguages extends AbstractSearch implements Callable<Integer> {
-    /*
-     * Matches the following line. Separate them into groups and pick the last
-     * which contains the description:
-     *
-     * * xref:ROOT:index.adoc[Components]
-     */
-    private static final Pattern PATTERN = 
Pattern.compile("(.*):(.*)\\[(.*)\\]");
-
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    @Option(names = { "--search-term" }, defaultValue = "", description = 
"Default debug level")
-    private String searchTerm;
-
-    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
-            description = "Where to download the resources from")
-    private String resourceLocation;
-
-    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
-            description = "The branch to use when downloading or searching 
resources (mostly used for development/testing)")
-    private String branch;
-
-    @Override
-    public void printHeader() {
-        System.out.printf("%-35s %-45s %s%n", "LANGUAGE", "DESCRIPTION", 
"LINK");
-        System.out.printf("%-35s %-45s %s%n", "-------", "-----------", 
"-----");
-    }
-
-    @Override
-    public Integer call() throws Exception {
-        setResourceLocation(resourceLocation, 
"camel:docs/components/modules/languages/nav.adoc");
-        setBranch(branch);
-
-        MatchExtractor<Language> matchExtractor;
-        if (searchTerm.isEmpty()) {
-            matchExtractor = new MatchExtractor<>(PATTERN, new 
LanguageConverter(), new LanguagePrinter());
-
-        } else {
-            matchExtractor = new MatchExtractor<>(
-                    PATTERN, new LanguageConverter(),
-                    new LanguageDescriptionMatching(searchTerm));
-
-        }
-        try {
-            search(matchExtractor);
-            return 0;
-        } catch (ResourceDoesNotExist e) {
-            System.err.println(e.getMessage());
-            return 1;
-        }
-    }
-}
-
-@Command(name = "others", description = "Search for Camel miscellaneous 
components")
-class SearchOthers extends AbstractSearch implements Callable<Integer> {
-    /*
-     * Matches the following line. Separate them into groups and pick the last
-     * which contains the description:
-     *
-     * * xref:ROOT:index.adoc[Components]
-     */
-    private static final Pattern PATTERN = 
Pattern.compile("(.*):(.*)\\[(.*)\\]");
-
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    @Option(names = { "--search-term" }, defaultValue = "", description = 
"Default debug level")
-    private String searchTerm;
-
-    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
-            description = "Where to download the resources from")
-    private String resourceLocation;
-
-    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
-            description = "The branch to use when downloading or searching 
resources (mostly used for development/testing)")
-    private String branch;
-
-    @Override
-    public void printHeader() {
-        System.out.printf("%-35s %-45s %s%n", "COMPONENT", "DESCRIPTION", 
"LINK");
-        System.out.printf("%-35s %-45s %s%n", "-------", "-----------", 
"-----");
-    }
-
-    @Override
-    public Integer call() throws Exception {
-        setResourceLocation(resourceLocation, 
"camel:docs/components/modules/others/nav.adoc");
-        setBranch(branch);
-
-        MatchExtractor<Other> matchExtractor;
-        if (searchTerm.isEmpty()) {
-            matchExtractor = new MatchExtractor<>(PATTERN, new 
OtherConverter(), new OtherPrinter());
-
-        } else {
-            matchExtractor = new MatchExtractor<>(
-                    PATTERN, new OtherConverter(),
-                    new OtherDescriptionMatching(searchTerm));
-
-        }
-
-        try {
-            search(matchExtractor);
-            return 0;
-        } catch (ResourceDoesNotExist e) {
-            System.err.println(e.getMessage());
-            return 1;
-        }
-    }
-}
-
-@Command(name = "init", description = "Provide init templates for kamelets and 
bindings")
-class Init implements Callable<Integer> {
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    @Override
-    public Integer call() throws Exception {
-        new CommandLine(this).execute("--help");
-
-        return 0;
-    }
-}
-
-@Command(name = "kamelet", description = "Provide init templates for kamelets")
-class InitKamelet extends AbstractInitKamelet implements Callable<Integer> {
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    @CommandLine.ArgGroup(exclusive = true, multiplicity = "1")
-    private ProcessOptions processOptions;
-
-    static class ProcessOptions {
-        @Option(names = { "--bootstrap" },
-                description = "Bootstrap the Kamelet template generator - 
download the properties file for editing")
-        private boolean bootstrap = false;
-
-        @Option(names = { "--properties-path" }, defaultValue = "", 
description = "Kamelet name")
-        private String propertiesPath;
-    }
-
-    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
-            description = "Where to download the resources from (used for 
development/testing)")
-    private String baseResourceLocation;
-
-    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
-            description = "The branch to use when downloading resources from 
(used for development/testing)")
-    private String branch;
-
-    @Option(names = { "--destination" }, defaultValue = "work",
-            description = "The destination directory where to download the 
files")
-    private String destination;
-
-    @Override
-    public Integer call() throws Exception {
-        if (processOptions.bootstrap) {
-            bootstrap();
-        } else {
-            generateTemplate();
-        }
-
-        return 0;
-    }
-
-    private int generateTemplate() throws IOException, CamelException {
-        setBranch(branch);
-        setResourceLocation(baseResourceLocation, 
"camel-kamelets:templates/init-template.kamelet.yaml.vm");
-
-        File workDirectory = new File(destination);
-
-        File localTemplateFile;
-        try {
-            localTemplateFile = resolveResource(workDirectory);
-        } catch (ResourceAlreadyExists e) {
-            System.err.println(e.getMessage());
-            return 1;
-        }
-        localTemplateFile.deleteOnExit();
-
-        VelocityTemplateParser templateParser = new VelocityTemplateParser(
-                localTemplateFile.getParentFile(),
-                processOptions.propertiesPath);
-
-        File outputFile;
-        try {
-            outputFile = templateParser.getOutputFile(workDirectory);
-        } catch (ResourceAlreadyExists e) {
-            System.err.println(e.getMessage());
-            return 1;
-        }
-
-        try (FileWriter fw = new FileWriter(outputFile)) {
-            templateParser.parse(localTemplateFile.getName(), fw);
-            System.out.println("Template file was written to " + outputFile);
-        }
-
-        return 0;
-    }
-
-    private int bootstrap() throws IOException, CamelException {
-        try {
-            super.bootstrap(branch, baseResourceLocation, destination);
-            return 0;
-        } catch (ResourceAlreadyExists e) {
-            System.err.println(e.getMessage());
-
-            return 1;
-        }
-    }
-}
-
-@Command(name = "binding", description = "Provide init templates for kamelet 
bindings")
-class InitBinding extends AbstractInitKamelet implements Callable<Integer> {
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = 
"Display the help and sub-commands")
-    private boolean helpRequested = false;
-
-    @Option(names = { "--base-resource-location" }, defaultValue = 
"github:apache", hidden = true,
-            description = "Where to download the resources from (used for 
development/testing)")
-    private String baseResourceLocation;
-
-    @Option(names = { "--branch" }, defaultValue = "main", hidden = true,
-            description = "The branch to use when downloading resources from 
(used for development/testing)")
-    private String branch;
-
-    @Option(names = { "--destination" }, defaultValue = "work",
-            description = "The destination directory where to download the 
files")
-    private String destination;
-
-    @Option(names = { "--kamelet" }, defaultValue = "",
-            description = "The kamelet to create a binding for")
-    private String kamelet;
-
-    @Option(names = { "--project" }, defaultValue = "camel-k",
-            description = "The project to create a binding for (either camel-k 
or core)")
-    private String project;
-
-    private int downloadSample() throws IOException, CamelException {
-        setBranch(branch);
-
-        String resourcePath = 
String.format("camel-kamelets:templates/bindings/%s/%s-binding.yaml", project, 
kamelet);
-
-        setResourceLocation(baseResourceLocation, resourcePath);
-
-        try {
-            resolveResource(new File(destination));
-        } catch (ResourceAlreadyExists e) {
-            System.err.println(e.getMessage());
-            return 1;
-        }
-
-        return 0;
-    }
-
-    @Override
-    public Integer call() throws Exception {
-        return downloadSample();
-    }
-}
-
-@Command(name = "CamelJBang", mixinStandardHelpOptions = true, version = 
"CamelJBang",
-         description = "A JBang-based Camel app for running Kamelets")
-public class CamelJBang implements Callable<Integer> {
-    private static CommandLine commandLine;
-
-    static {
-        Configurator.initialize(new DefaultConfiguration());
-    }
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
 
+public class CamelJBang {
     public static void main(String... args) {
-        commandLine = new CommandLine(new CamelJBang())
-                .addSubcommand("run", new Run())
-                .addSubcommand("search", new CommandLine(new Search())
-                        .addSubcommand("kamelets", new SearchKamelets())
-                        .addSubcommand("components", new SearchComponents())
-                        .addSubcommand("languages", new SearchLanguages())
-                        .addSubcommand("others", new SearchOthers()))
-                .addSubcommand("init", new CommandLine(new Init())
-                        .addSubcommand("kamelet", new InitKamelet())
-                        .addSubcommand("binding", new InitBinding()));
-
-        int exitCode = commandLine.execute(args);
-        System.exit(exitCode);
-    }
-
-    @Override
-    public Integer call() throws Exception {
-        commandLine.execute("--help");
-        return 0;
+        CamelJBangMain.run(args);
     }
 }

Reply via email to