You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/12/23 07:59:07 UTC
(camel) branch main updated: CAMEL-20270: Introduce JBang plugins (#12583)
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new d5c0ea0ee10 CAMEL-20270: Introduce JBang plugins (#12583)
d5c0ea0ee10 is described below
commit d5c0ea0ee10b243c34ad5d12e4b718718992a88a
Author: Christoph Deppisch <cd...@redhat.com>
AuthorDate: Sat Dec 23 08:59:01 2023 +0100
CAMEL-20270: Introduce JBang plugins (#12583)
- Introduce plugin mechanism to modularize Camel JBang
- Add new plugin sub-commands (add, get, delete) to manage plugins
- Plugin configuration is stored to user home directory
- Load plugin commands on demand
- Create 1st plugin for Camel K and move commands into separate Maven module camel-jbang-plugin-k
---
dsl/camel-jbang/camel-jbang-core/pom.xml | 20 --
.../dsl/jbang/core/commands/CamelJBangMain.java | 23 ++-
.../dsl/jbang/core/commands/plugin/PluginAdd.java | 112 +++++++++++
.../PluginBaseCommand.java} | 32 +--
.../KubeCommand.java => plugin/PluginCommand.java} | 16 +-
.../KubeCommand.java => plugin/PluginDelete.java} | 31 ++-
.../dsl/jbang/core/commands/plugin/PluginGet.java | 103 ++++++++++
.../CamelJBangPlugin.java} | 20 +-
.../k/TraitProfile.java => common/Plugin.java} | 18 +-
.../camel/dsl/jbang/core/common/PluginHelper.java | 222 +++++++++++++++++++++
.../camel/dsl/jbang/core/common/PluginType.java | 57 ++++++
.../jbang/core/commands/plugin/PluginAddTest.java | 111 +++++++++++
.../core/commands/plugin/PluginDeleteTest.java | 63 ++++++
.../jbang/core/commands/plugin/PluginGetTest.java | 133 ++++++++++++
dsl/camel-jbang/camel-jbang-plugin-k/pom.xml | 77 +++++++
.../camel/camel-jbang-plugin/camel-jbang-plugin-k | 2 +
.../jbang/core/commands/k/CompressionHelper.java | 0
.../jbang/core/commands/k/IntegrationDelete.java | 0
.../dsl/jbang/core/commands/k/IntegrationGet.java | 0
.../dsl/jbang/core/commands/k/IntegrationLogs.java | 0
.../dsl/jbang/core/commands/k/IntegrationRun.java | 0
.../dsl/jbang/core/commands/k/KubeBaseCommand.java | 0
.../dsl/jbang/core/commands/k/KubeCommand.java | 2 +-
.../dsl/jbang/core/commands/k/KubePlugin.java} | 26 +--
.../jbang/core/commands/k/KubernetesHelper.java | 0
.../dsl/jbang/core/commands/k/SourceScheme.java | 0
.../dsl/jbang/core/commands/k/TraitHelper.java | 0
.../dsl/jbang/core/commands/k/TraitProfile.java | 0
.../dsl/jbang/core/commands/StringPrinter.java | 78 ++++++++
.../core/commands/k/IntegrationDeleteTest.java | 0
.../jbang/core/commands/k/IntegrationGetTest.java | 0
.../jbang/core/commands/k/IntegrationLogsTest.java | 0
.../jbang/core/commands/k/IntegrationRunTest.java | 0
.../dsl/jbang/core/commands/k/KubeBaseTest.java | 6 +
.../jbang/core/commands/k/KubeCommandMainTest.java | 12 +-
.../dsl/jbang/core/commands/k/integration.yaml | 0
.../src/test/resources/pod.yaml | 0
.../src/test/resources/route.yaml | 0
dsl/camel-jbang/pom.xml | 1 +
39 files changed, 1072 insertions(+), 93 deletions(-)
diff --git a/dsl/camel-jbang/camel-jbang-core/pom.xml b/dsl/camel-jbang/camel-jbang-core/pom.xml
index be32224ebb1..415ade86ff1 100644
--- a/dsl/camel-jbang/camel-jbang-core/pom.xml
+++ b/dsl/camel-jbang/camel-jbang-core/pom.xml
@@ -87,20 +87,6 @@
<version>${ascii-table-version}</version>
</dependency>
- <!-- kubernetes -->
- <dependency>
- <groupId>io.fabric8</groupId>
- <artifactId>kubernetes-client</artifactId>
- <version>${kubernetes-client-version}</version>
- </dependency>
-
- <!-- camel k-->
- <dependency>
- <groupId>org.apache.camel.k</groupId>
- <artifactId>camel-k-crds</artifactId>
- <version>${camel-k-version}</version>
- </dependency>
-
<!-- jolokia -->
<dependency>
<groupId>org.jolokia</groupId>
@@ -174,12 +160,6 @@
<artifactId>camel-test-junit5</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>io.fabric8</groupId>
- <artifactId>kubernetes-server-mock</artifactId>
- <version>${kubernetes-client-version}</version>
- <scope>test</scope>
- </dependency>
</dependencies>
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
index 5933943ce37..f66f17b4ebe 100644
--- 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
@@ -33,17 +33,17 @@ import org.apache.camel.dsl.jbang.core.commands.config.ConfigGet;
import org.apache.camel.dsl.jbang.core.commands.config.ConfigList;
import org.apache.camel.dsl.jbang.core.commands.config.ConfigSet;
import org.apache.camel.dsl.jbang.core.commands.config.ConfigUnset;
-import org.apache.camel.dsl.jbang.core.commands.k.IntegrationDelete;
-import org.apache.camel.dsl.jbang.core.commands.k.IntegrationGet;
-import org.apache.camel.dsl.jbang.core.commands.k.IntegrationLogs;
-import org.apache.camel.dsl.jbang.core.commands.k.IntegrationRun;
-import org.apache.camel.dsl.jbang.core.commands.k.KubeCommand;
+import org.apache.camel.dsl.jbang.core.commands.plugin.PluginAdd;
+import org.apache.camel.dsl.jbang.core.commands.plugin.PluginCommand;
+import org.apache.camel.dsl.jbang.core.commands.plugin.PluginDelete;
+import org.apache.camel.dsl.jbang.core.commands.plugin.PluginGet;
import org.apache.camel.dsl.jbang.core.commands.process.*;
import org.apache.camel.dsl.jbang.core.commands.version.VersionCommand;
import org.apache.camel.dsl.jbang.core.commands.version.VersionGet;
import org.apache.camel.dsl.jbang.core.commands.version.VersionList;
import org.apache.camel.dsl.jbang.core.commands.version.VersionSet;
import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
+import org.apache.camel.dsl.jbang.core.common.PluginHelper;
import org.apache.camel.dsl.jbang.core.common.Printer;
import picocli.CommandLine;
import picocli.CommandLine.Command;
@@ -129,16 +129,17 @@ public class CamelJBangMain implements Callable<Integer> {
.addSubcommand("get", new CommandLine(new ConfigGet(main)))
.addSubcommand("unset", new CommandLine(new ConfigUnset(main)))
.addSubcommand("set", new CommandLine(new ConfigSet(main))))
- .addSubcommand("k", new CommandLine(new KubeCommand(main))
- .addSubcommand("get", new CommandLine(new IntegrationGet(main)))
- .addSubcommand("run", new CommandLine(new IntegrationRun(main)))
- .addSubcommand("delete", new CommandLine(new IntegrationDelete(main)))
- .addSubcommand("logs", new CommandLine(new IntegrationLogs(main))))
+ .addSubcommand("plugin", new CommandLine(new PluginCommand(main))
+ .addSubcommand("get", new CommandLine(new PluginGet(main)))
+ .addSubcommand("add", new CommandLine(new PluginAdd(main)))
+ .addSubcommand("delete", new CommandLine(new PluginDelete(main))))
.addSubcommand("version", new CommandLine(new VersionCommand(main))
.addSubcommand("get", new CommandLine(new VersionGet(main)))
.addSubcommand("set", new CommandLine(new VersionSet(main)))
.addSubcommand("list", new CommandLine(new VersionList(main))));
+ PluginHelper.addPlugins(commandLine, main);
+
commandLine.getCommandSpec().versionProvider(() -> {
CamelCatalog catalog = new DefaultCamelCatalog();
String v = catalog.getCatalogVersion();
@@ -156,7 +157,7 @@ public class CamelJBangMain implements Callable<Integer> {
*
* @param exitCode
*/
- protected void quit(int exitCode) {
+ public void quit(int exitCode) {
System.exit(exitCode);
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginAdd.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginAdd.java
new file mode 100644
index 00000000000..50a67124a00
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginAdd.java
@@ -0,0 +1,112 @@
+/*
+ * 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.plugin;
+
+import java.util.Optional;
+
+import org.apache.camel.catalog.CamelCatalog;
+import org.apache.camel.catalog.DefaultCamelCatalog;
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.common.PluginType;
+import org.apache.camel.util.json.JsonObject;
+import picocli.CommandLine;
+
+@CommandLine.Command(name = "add",
+ description = "Add new plugin.")
+public class PluginAdd extends PluginBaseCommand {
+
+ @CommandLine.Parameters(description = "The Camel plugin to add.",
+ paramLabel = "<name>")
+ String name;
+
+ @CommandLine.Option(names = { "--command", "-c" },
+ description = "The command that the plugin uses.")
+ String command;
+
+ @CommandLine.Option(names = { "--description", "-d" },
+ description = "A short description of the plugin.")
+ String description;
+
+ @CommandLine.Option(names = { "--artifactId", "-a" },
+ description = "Maven artifactId.")
+ String artifactId;
+
+ @CommandLine.Option(names = { "--groupId", "-g" },
+ defaultValue = "org.apache.camel",
+ description = "Maven groupId.")
+ String groupId = "org.apache.camel";
+
+ @CommandLine.Option(names = { "--version", "-v" },
+ defaultValue = "${camel-version}",
+ description = "Maven artifact version.")
+ String version;
+
+ @CommandLine.Option(names = { "--gav" },
+ description = "Maven group and artifact coordinates.")
+ String gav;
+
+ public PluginAdd(CamelJBangMain main) {
+ super(main);
+ }
+
+ @Override
+ public Integer doCall() throws Exception {
+ JsonObject pluginConfig = loadConfig();
+ JsonObject plugins = pluginConfig.getMap("plugins");
+
+ Optional<PluginType> camelPlugin = PluginType.findByName(name);
+ if (camelPlugin.isPresent()) {
+ if (command == null) {
+ command = camelPlugin.get().getCommand();
+ }
+
+ if (description == null) {
+ description = camelPlugin.get().getDescription();
+ }
+ }
+
+ if (command == null) {
+ // use plugin name as command
+ command = name;
+ }
+
+ JsonObject plugin = new JsonObject();
+ plugin.put("name", name);
+ plugin.put("command", command);
+ plugin.put("description",
+ description != null ? description : "Plugin %s called with command %s".formatted(name, command));
+
+ if (gav == null && (groupId != null && artifactId != null)) {
+ if (version == null) {
+ CamelCatalog catalog = new DefaultCamelCatalog();
+ version = catalog.getCatalogVersion();
+ }
+
+ gav = "%s:%s:%s".formatted(groupId, artifactId, version);
+ }
+
+ if (gav != null) {
+ plugin.put("dependency", gav);
+ }
+
+ plugins.put(name, plugin);
+
+ saveConfig(pluginConfig);
+ return 0;
+ }
+
+}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginBaseCommand.java
similarity index 53%
copy from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java
copy to dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginBaseCommand.java
index 8bc5105ceaa..da4ed6c635b 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginBaseCommand.java
@@ -14,27 +14,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.camel.dsl.jbang.core.commands.k;
-import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
-import picocli.CommandLine;
+package org.apache.camel.dsl.jbang.core.commands.plugin;
-@CommandLine.Command(name = "k",
- description = "Manage Camel integrations on Kubernetes (use config --help to see sub commands)")
-public class KubeCommand extends KubeBaseCommand {
+import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.common.PluginHelper;
+import org.apache.camel.util.json.JsonObject;
- public static final String OPERATOR_ID_LABEL = "camel.apache.org/operator.id";
- public static final String INTEGRATION_LABEL = "camel.apache.org/integration";
- public static final String INTEGRATION_CONTAINER_NAME = "integration";
+/**
+ * Base command supports Kubernetes client related options such as namespace or custom kube config option. Automatically
+ * applies the options to the Kubernetes client instance that is being used to run commands.
+ */
+abstract class PluginBaseCommand extends CamelCommand {
- public KubeCommand(CamelJBangMain main) {
+ public PluginBaseCommand(CamelJBangMain main) {
super(main);
}
- @Override
- public Integer doCall() throws Exception {
- // defaults to list integrations deployed on Kubernetes
- new CommandLine(new IntegrationGet(getMain())).execute();
- return 0;
+ JsonObject loadConfig() {
+ return PluginHelper.getOrCreatePluginConfig();
+ }
+
+ void saveConfig(JsonObject plugins) {
+ PluginHelper.savePluginConfig(plugins);
}
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginCommand.java
similarity index 63%
copy from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java
copy to dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginCommand.java
index 8bc5105ceaa..dd8c7451fdc 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginCommand.java
@@ -14,27 +14,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.camel.dsl.jbang.core.commands.k;
+package org.apache.camel.dsl.jbang.core.commands.plugin;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
import picocli.CommandLine;
-@CommandLine.Command(name = "k",
- description = "Manage Camel integrations on Kubernetes (use config --help to see sub commands)")
-public class KubeCommand extends KubeBaseCommand {
+@CommandLine.Command(name = "plugin",
+ description = "Manage plugins that add sub-commands to this CLI.")
+public class PluginCommand extends PluginBaseCommand {
- public static final String OPERATOR_ID_LABEL = "camel.apache.org/operator.id";
- public static final String INTEGRATION_LABEL = "camel.apache.org/integration";
- public static final String INTEGRATION_CONTAINER_NAME = "integration";
-
- public KubeCommand(CamelJBangMain main) {
+ public PluginCommand(CamelJBangMain main) {
super(main);
}
@Override
public Integer doCall() throws Exception {
// defaults to list integrations deployed on Kubernetes
- new CommandLine(new IntegrationGet(getMain())).execute();
+ new CommandLine(new PluginGet(getMain())).execute();
return 0;
}
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginDelete.java
similarity index 54%
copy from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java
copy to dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginDelete.java
index 8bc5105ceaa..f4172bb8f02 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginDelete.java
@@ -14,27 +14,38 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.camel.dsl.jbang.core.commands.k;
+package org.apache.camel.dsl.jbang.core.commands.plugin;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.util.json.JsonObject;
import picocli.CommandLine;
-@CommandLine.Command(name = "k",
- description = "Manage Camel integrations on Kubernetes (use config --help to see sub commands)")
-public class KubeCommand extends KubeBaseCommand {
+@CommandLine.Command(name = "delete",
+ description = "Removes a plugin.")
+public class PluginDelete extends PluginBaseCommand {
- public static final String OPERATOR_ID_LABEL = "camel.apache.org/operator.id";
- public static final String INTEGRATION_LABEL = "camel.apache.org/integration";
- public static final String INTEGRATION_CONTAINER_NAME = "integration";
+ @CommandLine.Parameters(description = "The Camel plugin to remove.",
+ paramLabel = "<plugin>")
+ String name;
- public KubeCommand(CamelJBangMain main) {
+ public PluginDelete(CamelJBangMain main) {
super(main);
}
@Override
public Integer doCall() throws Exception {
- // defaults to list integrations deployed on Kubernetes
- new CommandLine(new IntegrationGet(getMain())).execute();
+ JsonObject pluginConfig = loadConfig();
+ JsonObject plugins = pluginConfig.getMap("plugins");
+
+ Object plugin = plugins.remove(name);
+ if (plugin != null) {
+ printer().printf("Plugin %s removed%n", name);
+ saveConfig(pluginConfig);
+ } else {
+ printer().printf("Plugin %s not found in configuration%n", name);
+ }
+
return 0;
}
+
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginGet.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginGet.java
new file mode 100644
index 00000000000..8769323b56f
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginGet.java
@@ -0,0 +1,103 @@
+/*
+ * 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.plugin;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.github.freva.asciitable.AsciiTable;
+import com.github.freva.asciitable.Column;
+import com.github.freva.asciitable.HorizontalAlign;
+import com.github.freva.asciitable.OverflowBehaviour;
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.common.PluginType;
+import org.apache.camel.util.json.JsonObject;
+import picocli.CommandLine;
+
+@CommandLine.Command(name = "get",
+ description = "Display available plugins.")
+public class PluginGet extends PluginBaseCommand {
+
+ @CommandLine.Option(names = { "--all", "-a" }, defaultValue = "false", description = "Display all available plugins.")
+ public boolean all;
+
+ public PluginGet(CamelJBangMain main) {
+ super(main);
+ }
+
+ @Override
+ public Integer doCall() throws Exception {
+ List<Row> rows = new ArrayList<>();
+
+ JsonObject plugins = loadConfig().getMap("plugins");
+ plugins.forEach((key, value) -> {
+ JsonObject details = (JsonObject) value;
+
+ String name = details.getStringOrDefault("name", key);
+ String command = details.getStringOrDefault("command", name);
+ String dependency = details.getStringOrDefault("dependency",
+ "org.apache.camel:camel-jbang-plugin-%s".formatted(command));
+ String description
+ = details.getStringOrDefault("description", "Plugin %s called with command %s".formatted(name, command));
+
+ rows.add(new Row(name, command, dependency, description));
+ });
+
+ printRows(rows);
+
+ if (all) {
+ rows.clear();
+ for (PluginType camelPlugin : PluginType.values()) {
+ if (plugins.get(camelPlugin.getName()) == null) {
+ String dependency = "org.apache.camel:camel-jbang-plugin-%s".formatted(camelPlugin.getCommand());
+ rows.add(new Row(
+ camelPlugin.getName(), camelPlugin.getCommand(), dependency,
+ camelPlugin.getDescription()));
+ }
+ }
+
+ if (!rows.isEmpty()) {
+ printer().println();
+ printer().println("Supported plugins:");
+ printer().println();
+
+ printRows(rows);
+ }
+ }
+
+ return 0;
+ }
+
+ private void printRows(List<Row> rows) {
+ if (!rows.isEmpty()) {
+ printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList(
+ new Column().header("NAME").headerAlign(HorizontalAlign.LEFT).dataAlign(HorizontalAlign.LEFT)
+ .with(r -> r.name),
+ new Column().header("COMMAND").headerAlign(HorizontalAlign.LEFT).dataAlign(HorizontalAlign.LEFT)
+ .with(r -> r.command),
+ new Column().header("DEPENDENCY").headerAlign(HorizontalAlign.LEFT).dataAlign(HorizontalAlign.LEFT)
+ .with(r -> r.dependency),
+ new Column().header("DESCRIPTION").headerAlign(HorizontalAlign.LEFT).dataAlign(HorizontalAlign.LEFT)
+ .maxWidth(50, OverflowBehaviour.ELLIPSIS_RIGHT)
+ .with(r -> r.description))));
+ }
+ }
+
+ private record Row(String name, String command, String dependency, String description) {
+ }
+}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/TraitProfile.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CamelJBangPlugin.java
similarity index 62%
copy from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/TraitProfile.java
copy to dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CamelJBangPlugin.java
index 4d5e1664b12..95f824b7106 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/TraitProfile.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CamelJBangPlugin.java
@@ -15,11 +15,21 @@
* limitations under the License.
*/
-package org.apache.camel.dsl.jbang.core.commands.k;
+package org.apache.camel.dsl.jbang.core.common;
-public enum TraitProfile {
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
- OPENSHIFT,
- KUBERNETES,
- KNATIVE
+import org.apache.camel.spi.annotations.ServiceFactory;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Target({ ElementType.TYPE })
+@ServiceFactory("camel-jbang-plugin")
+public @interface CamelJBangPlugin {
+
+ String value();
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/TraitProfile.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/Plugin.java
similarity index 64%
copy from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/TraitProfile.java
copy to dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/Plugin.java
index 4d5e1664b12..3337d7c18f9 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/TraitProfile.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/Plugin.java
@@ -15,11 +15,19 @@
* limitations under the License.
*/
-package org.apache.camel.dsl.jbang.core.commands.k;
+package org.apache.camel.dsl.jbang.core.common;
-public enum TraitProfile {
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import picocli.CommandLine;
- OPENSHIFT,
- KUBERNETES,
- KNATIVE
+@FunctionalInterface
+public interface Plugin {
+
+ /**
+ * Customize given command line adding sub-commands in particular.
+ *
+ * @param commandLine the command line to adjust.
+ * @param main the current JBang main.
+ */
+ void customize(CommandLine commandLine, CamelJBangMain main);
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PluginHelper.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PluginHelper.java
new file mode 100644
index 00000000000..3b5514ca5d5
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PluginHelper.java
@@ -0,0 +1,222 @@
+/*
+ * 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 java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.catalog.CamelCatalog;
+import org.apache.camel.catalog.DefaultCamelCatalog;
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.impl.engine.DefaultClassResolver;
+import org.apache.camel.impl.engine.DefaultFactoryFinder;
+import org.apache.camel.spi.FactoryFinder;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.json.JsonObject;
+import org.apache.camel.util.json.Jsoner;
+import picocli.CommandLine;
+
+/**
+ * Helper for command line plugins that add sub-commands and functionality when enabled by the user. Loads and saves
+ * plugin configuration from/to the user home directory.
+ */
+public final class PluginHelper {
+
+ public static final String PLUGIN_CONFIG = ".camel-jbang-plugins.json";
+
+ private static final FactoryFinder FACTORY_FINDER
+ = new DefaultFactoryFinder(new DefaultClassResolver(), FactoryFinder.DEFAULT_PATH + "camel-jbang-plugin/");
+
+ private PluginHelper() {
+ // prevent instantiation of utility class
+ }
+
+ /**
+ * Loads the plugin Json configuration from the user home and goes through all configured plugins adding the plugin
+ * commands to the current command line. Tries to resolve each plugin from the classpath with the factory finder
+ * pattern. If present the plugin is called to customize the command line to add all sub-commands of the plugin.
+ *
+ * @param commandLine the command line to add commands to
+ * @param main the current Camel JBang main
+ */
+ public static void addPlugins(CommandLine commandLine, CamelJBangMain main) {
+ JsonObject config = getPluginConfig();
+
+ if (config != null) {
+ JsonObject plugins = config.getMap("plugins");
+ for (String pluginKey : plugins.keySet()) {
+ JsonObject properties = plugins.getMap(pluginKey);
+
+ String name = properties.getOrDefault("name", pluginKey).toString();
+ String command = properties.getOrDefault("command", name).toString();
+
+ Optional<Plugin> plugin = FACTORY_FINDER.newInstance("camel-jbang-plugin-" + command, Plugin.class);
+ if (plugin.isPresent()) {
+ plugin.get().customize(commandLine, main);
+ } else {
+ String description = properties.getOrDefault("description", "").toString();
+ String dependency = properties.getOrDefault("dependency",
+ "org.apache.camel:camel-jbang-plugin-%s:${camel-version}".formatted(command)).toString();
+ createSubCommand(commandLine, name, command, dependency, description, main);
+ }
+ }
+ }
+ }
+
+ /**
+ * Create sub-command as a placeholder for calling a plugin. When the command gets executed the plugin is added to
+ * the classpath and a new JBang process is spawned with the same arguments. The factory finder mechanism will be
+ * able to resolve the actual plugin from the classpath so the real plugin command is run.
+ *
+ * @param commandLine to receive the new command
+ * @param name the plugin name
+ * @param command the plugin command
+ * @param dependency the Maven dependency for the plugin
+ * @param description optional description of the plugin command
+ * @param main current Camel JBang main
+ */
+ private static void createSubCommand(
+ CommandLine commandLine, String name, String command,
+ String dependency, String description, CamelJBangMain main) {
+ commandLine.addSubcommand(command, CommandLine.Model.CommandSpec.wrapWithoutInspection(
+ (Runnable) () -> {
+ List<String> args = commandLine.getParseResult().originalArgs();
+ if (args.contains("--help") || args.contains("--h")) {
+ main.getOut().printf("Loading plugin %s for command %s%n", name, command);
+ }
+
+ String gav = dependency;
+ if (gav.endsWith(":${camel-version}")) {
+ gav = gav.substring(0, gav.length() - "${camel-version}".length()) + getCamelVersion(args);
+ }
+
+ // need to use jbang command to call plugin
+ List<String> jbangArgs = new ArrayList<>();
+ jbangArgs.add("jbang");
+ // Add plugin dependency, so it is present on the classpath for the new JBang process
+ jbangArgs.add("--deps=" + gav);
+
+ jbangArgs.add("camel");
+ jbangArgs.addAll(args);
+
+ try {
+ ProcessBuilder pb = new ProcessBuilder();
+ pb.command(jbangArgs);
+
+ pb.inheritIO(); // run in foreground (with IO so logs are visible)
+ Process p = pb.start();
+
+ // wait for that process to exit as we run in foreground
+ int exitCode = p.waitFor();
+ main.quit(exitCode);
+ } catch (IOException | InterruptedException e) {
+ main.getOut().printf("Unable to spawn JBang process - %s%n", e.getMessage());
+ main.quit(1);
+ }
+ })
+ .usageMessage(new CommandLine.Model.UsageMessageSpec().description(description))
+ .addUnmatchedArgsBinding(CommandLine.Model.UnmatchedArgsBinding
+ .forStringArrayConsumer(new CommandLine.Model.ISetter() {
+ @Override
+ public <T> T set(T value) throws Exception {
+ return value;
+ }
+ })));
+ }
+
+ private static String getCamelVersion(List<String> args) {
+ Optional<String> version = args.stream()
+ .filter(arg -> arg.startsWith("--camel.version="))
+ .map(arg -> arg.substring("camel.version=".length()))
+ .findFirst();
+
+ if (version.isPresent()) {
+ return version.get();
+ }
+
+ CamelCatalog catalog = new DefaultCamelCatalog();
+ return catalog.getCatalogVersion();
+ }
+
+ public static JsonObject getOrCreatePluginConfig() {
+ return Optional.ofNullable(getPluginConfig()).orElseGet(PluginHelper::createPluginConfig);
+ }
+
+ private static JsonObject getPluginConfig() {
+ try {
+ File f = new File(CommandLineHelper.getHomeDir(), PLUGIN_CONFIG);
+ if (f.exists()) {
+ try (FileInputStream fis = new FileInputStream(f)) {
+ String text = IOHelper.loadText(fis);
+ return (JsonObject) Jsoner.deserialize(text);
+ }
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+
+ return null;
+ }
+
+ public static JsonObject createPluginConfig() {
+ File f = new File(CommandLineHelper.getHomeDir(), PLUGIN_CONFIG);
+ JsonObject config = Jsoner.deserialize("{ \"plugins\": {} }", new JsonObject());
+ try {
+ Files.writeString(f.toPath(), config.toJson(),
+ StandardOpenOption.CREATE,
+ StandardOpenOption.WRITE,
+ StandardOpenOption.TRUNCATE_EXISTING);
+ } catch (IOException e) {
+ throw new RuntimeCamelException("Failed to create plugin configuration", e);
+ }
+
+ return config;
+ }
+
+ public static void savePluginConfig(JsonObject plugins) {
+ File f = new File(CommandLineHelper.getHomeDir(), PLUGIN_CONFIG);
+ try {
+ Files.writeString(f.toPath(), plugins.toJson(),
+ StandardOpenOption.CREATE,
+ StandardOpenOption.WRITE,
+ StandardOpenOption.TRUNCATE_EXISTING);
+ } catch (IOException e) {
+ throw new RuntimeCamelException("Failed to save plugin configuration", e);
+ }
+ }
+
+ public static void enable(PluginType pluginType) {
+ JsonObject pluginConfig = PluginHelper.getOrCreatePluginConfig();
+ JsonObject plugins = pluginConfig.getMap("plugins");
+
+ JsonObject kubePlugin = new JsonObject();
+ kubePlugin.put("name", pluginType.getName());
+ kubePlugin.put("command", pluginType.getCommand());
+ kubePlugin.put("description", pluginType.getDescription());
+ plugins.put(pluginType.getName(), kubePlugin);
+
+ PluginHelper.savePluginConfig(pluginConfig);
+ }
+}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PluginType.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PluginType.java
new file mode 100644
index 00000000000..c4389f28cc1
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PluginType.java
@@ -0,0 +1,57 @@
+/*
+ * 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 java.util.Arrays;
+import java.util.Optional;
+
+/**
+ * Known plugins in the Camel project.
+ */
+public enum PluginType {
+
+ CAMEL_K("camel-k", "k", "Manage Camel integrations on Kubernetes");
+
+ private final String name;
+ private final String command;
+ private final String description;
+
+ PluginType(String name, String command, String description) {
+ this.name = name;
+ this.command = command;
+ this.description = description;
+ }
+
+ public static Optional<PluginType> findByName(String name) {
+ return Arrays.stream(values())
+ .filter(p -> p.name.equalsIgnoreCase(name))
+ .findFirst();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getCommand() {
+ return command;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginAddTest.java b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginAddTest.java
new file mode 100644
index 00000000000..db43bc984e8
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginAddTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.plugin;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelCommandBaseTest;
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
+import org.apache.camel.dsl.jbang.core.common.PluginHelper;
+import org.apache.camel.dsl.jbang.core.common.PluginType;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class PluginAddTest extends CamelCommandBaseTest {
+
+ @BeforeEach
+ public void setup() {
+ super.setup();
+
+ CommandLineHelper.useHomeDir("target");
+ PluginHelper.createPluginConfig();
+ }
+
+ @Test
+ public void shouldAddDefaultPlugin() throws Exception {
+ PluginAdd command = new PluginAdd(new CamelJBangMain().withPrinter(printer));
+ command.name = "camel-k";
+ command.doCall();
+
+ Assertions.assertEquals("", printer.getOutput());
+
+ Assertions.assertEquals("{\"plugins\":{\"camel-k\":{\"name\":\"camel-k\",\"command\":\"k\",\"description\":\"%s\"}}}"
+ .formatted(PluginType.CAMEL_K.getDescription()), PluginHelper.getOrCreatePluginConfig().toJson());
+ }
+
+ @Test
+ public void shouldAddPlugin() throws Exception {
+ PluginAdd command = new PluginAdd(new CamelJBangMain().withPrinter(printer));
+ command.name = "foo-plugin";
+ command.command = "foo";
+ command.description = "Some plugin";
+ command.doCall();
+
+ Assertions.assertEquals("", printer.getOutput());
+
+ Assertions.assertEquals("{\"plugins\":{\"foo-plugin\":{\"name\":\"foo-plugin\",\"command\":\"foo\"," +
+ "\"description\":\"Some plugin\"}}}",
+ PluginHelper.getOrCreatePluginConfig().toJson());
+ }
+
+ @Test
+ public void shouldGenerateProperties() throws Exception {
+ PluginAdd command = new PluginAdd(new CamelJBangMain().withPrinter(printer));
+ command.name = "foo";
+ command.doCall();
+
+ Assertions.assertEquals("", printer.getOutput());
+
+ Assertions.assertEquals("{\"plugins\":{\"foo\":{\"name\":\"foo\",\"command\":\"foo\"," +
+ "\"description\":\"Plugin foo called with command foo\"}}}",
+ PluginHelper.getOrCreatePluginConfig().toJson());
+ }
+
+ @Test
+ public void shouldUseMavenGAV() throws Exception {
+ PluginAdd command = new PluginAdd(new CamelJBangMain().withPrinter(printer));
+ command.name = "foo-plugin";
+ command.command = "foo";
+ command.gav = "org.apache.camel:foo-plugin:1.0.0";
+ command.doCall();
+
+ Assertions.assertEquals("", printer.getOutput());
+
+ Assertions.assertEquals("{\"plugins\":{\"foo-plugin\":{\"name\":\"foo-plugin\",\"command\":\"foo\"," +
+ "\"description\":\"Plugin foo-plugin called with command foo\",\"dependency\":\"org.apache.camel:foo-plugin:1.0.0\"}}}",
+ PluginHelper.getOrCreatePluginConfig().toJson());
+ }
+
+ @Test
+ public void shouldUseArtifactIdAndVersion() throws Exception {
+ PluginAdd command = new PluginAdd(new CamelJBangMain().withPrinter(printer));
+ command.name = "foo-plugin";
+ command.command = "foo";
+ command.groupId = "org.foo";
+ command.artifactId = "foo-bar";
+ command.version = "1.0.0";
+ command.doCall();
+
+ Assertions.assertEquals("", printer.getOutput());
+
+ Assertions.assertEquals("{\"plugins\":{\"foo-plugin\":{\"name\":\"foo-plugin\",\"command\":\"foo\"," +
+ "\"description\":\"Plugin foo-plugin called with command foo\",\"dependency\":\"org.foo:foo-bar:1.0.0\"}}}",
+ PluginHelper.getOrCreatePluginConfig().toJson());
+ }
+
+}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginDeleteTest.java b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginDeleteTest.java
new file mode 100644
index 00000000000..e9377543f2b
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginDeleteTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.plugin;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelCommandBaseTest;
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
+import org.apache.camel.dsl.jbang.core.common.PluginHelper;
+import org.apache.camel.dsl.jbang.core.common.PluginType;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class PluginDeleteTest extends CamelCommandBaseTest {
+
+ @BeforeEach
+ public void setup() {
+ super.setup();
+
+ CommandLineHelper.useHomeDir("target");
+ PluginHelper.createPluginConfig();
+ }
+
+ @Test
+ public void shouldDeletePlugin() throws Exception {
+ PluginHelper.enable(PluginType.CAMEL_K);
+
+ PluginDelete command = new PluginDelete(new CamelJBangMain().withPrinter(printer));
+ command.name = "camel-k";
+ command.doCall();
+
+ Assertions.assertEquals("Plugin camel-k removed", printer.getOutput());
+
+ Assertions.assertEquals("{\"plugins\":{}}", PluginHelper.getOrCreatePluginConfig().toJson());
+ }
+
+ @Test
+ public void shouldHandleUnknownPlugin() throws Exception {
+ PluginDelete command = new PluginDelete(new CamelJBangMain().withPrinter(printer));
+ command.name = "foo";
+ command.doCall();
+
+ Assertions.assertEquals("Plugin foo not found in configuration", printer.getOutput());
+
+ Assertions.assertEquals("{\"plugins\":{}}", PluginHelper.getOrCreatePluginConfig().toJson());
+ }
+
+}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginGetTest.java b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginGetTest.java
new file mode 100644
index 00000000000..38377fa9f4f
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginGetTest.java
@@ -0,0 +1,133 @@
+/*
+ * 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.plugin;
+
+import java.util.List;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelCommandBaseTest;
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
+import org.apache.camel.dsl.jbang.core.common.PluginHelper;
+import org.apache.camel.dsl.jbang.core.common.PluginType;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class PluginGetTest extends CamelCommandBaseTest {
+
+ @BeforeEach
+ public void setup() {
+ super.setup();
+
+ CommandLineHelper.useHomeDir("target");
+ PluginHelper.createPluginConfig();
+ }
+
+ @Test
+ public void shouldGetEmptyPlugins() throws Exception {
+ PluginGet command = new PluginGet(new CamelJBangMain().withPrinter(printer));
+ command.doCall();
+
+ Assertions.assertEquals("", printer.getOutput());
+ }
+
+ @Test
+ public void shouldGetPlugin() throws Exception {
+ PluginHelper.enable(PluginType.CAMEL_K);
+
+ PluginGet command = new PluginGet(new CamelJBangMain().withPrinter(printer));
+ command.doCall();
+
+ List<String> output = printer.getLines();
+ Assertions.assertEquals(2, output.size());
+ Assertions.assertEquals("NAME COMMAND DEPENDENCY DESCRIPTION", output.get(0));
+ Assertions.assertEquals(
+ "camel-k k org.apache.camel:camel-jbang-plugin-k %s".formatted(PluginType.CAMEL_K.getDescription()),
+ output.get(1));
+ }
+
+ @Test
+ public void shouldGetDefaultPlugins() throws Exception {
+ PluginGet command = new PluginGet(new CamelJBangMain().withPrinter(printer));
+ command.all = true;
+ command.doCall();
+
+ List<String> output = printer.getLines();
+ Assertions.assertEquals(4, output.size());
+ Assertions.assertEquals("Supported plugins:", output.get(0));
+ Assertions.assertEquals("NAME COMMAND DEPENDENCY DESCRIPTION", output.get(2));
+ Assertions.assertEquals(
+ "camel-k k org.apache.camel:camel-jbang-plugin-k %s".formatted(PluginType.CAMEL_K.getDescription()),
+ output.get(3));
+ }
+
+ @Test
+ public void shouldGenerateDependencyAndDescription() throws Exception {
+ JsonObject pluginConfig = PluginHelper.getOrCreatePluginConfig();
+ JsonObject plugins = pluginConfig.getMap("plugins");
+
+ JsonObject fooPlugin = new JsonObject();
+ fooPlugin.put("name", "foo");
+ fooPlugin.put("command", "foo");
+ plugins.put("foo-plugin", fooPlugin);
+
+ PluginHelper.savePluginConfig(pluginConfig);
+
+ PluginGet command = new PluginGet(new CamelJBangMain().withPrinter(printer));
+ command.doCall();
+
+ List<String> output = printer.getLines();
+ Assertions.assertEquals(2, output.size());
+ Assertions.assertEquals("NAME COMMAND DEPENDENCY DESCRIPTION", output.get(0));
+ Assertions.assertEquals("foo foo org.apache.camel:camel-jbang-plugin-foo Plugin foo called with command foo",
+ output.get(1));
+ }
+
+ @Test
+ public void shouldGetAllPlugins() throws Exception {
+ JsonObject pluginConfig = PluginHelper.getOrCreatePluginConfig();
+ JsonObject plugins = pluginConfig.getMap("plugins");
+
+ JsonObject fooPlugin = new JsonObject();
+ fooPlugin.put("name", "foo-plugin");
+ fooPlugin.put("command", "foo");
+ fooPlugin.put("dependency", "org.apache.camel:foo-plugin:1.0.0");
+ plugins.put("foo-plugin", fooPlugin);
+
+ PluginHelper.savePluginConfig(pluginConfig);
+
+ PluginGet command = new PluginGet(new CamelJBangMain().withPrinter(printer));
+ command.all = true;
+ command.doCall();
+
+ List<String> output = printer.getLines();
+ Assertions.assertEquals(7, output.size());
+ Assertions.assertEquals("NAME COMMAND DEPENDENCY DESCRIPTION", output.get(0));
+ Assertions.assertEquals(
+ "foo-plugin foo org.apache.camel:foo-plugin:1.0.0 Plugin foo-plugin called with command foo",
+ output.get(1));
+
+ Assertions.assertEquals("Supported plugins:", output.get(3));
+ Assertions.assertEquals("NAME COMMAND DEPENDENCY DESCRIPTION", output.get(5));
+ Assertions.assertEquals(
+ "camel-k k org.apache.camel:camel-jbang-plugin-k %s".formatted(PluginType.CAMEL_K.getDescription()),
+ output.get(6));
+ }
+
+}
diff --git a/dsl/camel-jbang/camel-jbang-plugin-k/pom.xml b/dsl/camel-jbang/camel-jbang-plugin-k/pom.xml
new file mode 100644
index 00000000000..21301efb514
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-plugin-k/pom.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-jbang-parent</artifactId>
+ <version>4.4.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>camel-jbang-plugin-k</artifactId>
+
+ <name>Camel :: JBang :: Plugin :: Camel K</name>
+ <description>Camel JBang Camel K Plugin</description>
+
+ <properties>
+ <firstVersion>4.4.0</firstVersion>
+ <label>jbang</label>
+ <supportLevel>Preview</supportLevel>
+ <camel-prepare-component>false</camel-prepare-component>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-jbang-core</artifactId>
+ </dependency>
+
+ <!-- kubernetes -->
+ <dependency>
+ <groupId>io.fabric8</groupId>
+ <artifactId>kubernetes-client</artifactId>
+ <version>${kubernetes-client-version}</version>
+ </dependency>
+
+ <!-- camel k-->
+ <dependency>
+ <groupId>org.apache.camel.k</groupId>
+ <artifactId>camel-k-crds</artifactId>
+ <version>${camel-k-version}</version>
+ </dependency>
+
+ <!-- test dependencies -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test-junit5</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.fabric8</groupId>
+ <artifactId>kubernetes-server-mock</artifactId>
+ <version>${kubernetes-client-version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/dsl/camel-jbang/camel-jbang-plugin-k/src/generated/resources/META-INF/services/org/apache/camel/camel-jbang-plugin/camel-jbang-plugin-k b/dsl/camel-jbang/camel-jbang-plugin-k/src/generated/resources/META-INF/services/org/apache/camel/camel-jbang-plugin/camel-jbang-plugin-k
new file mode 100644
index 00000000000..5a3ee5c3e1b
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-plugin-k/src/generated/resources/META-INF/services/org/apache/camel/camel-jbang-plugin/camel-jbang-plugin-k
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.dsl.jbang.core.commands.k.KubePlugin
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/CompressionHelper.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/CompressionHelper.java
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/CompressionHelper.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/CompressionHelper.java
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationDelete.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationDelete.java
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationDelete.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationDelete.java
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationGet.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationGet.java
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationGet.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationGet.java
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationLogs.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationLogs.java
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationLogs.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationLogs.java
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationRun.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationRun.java
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationRun.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationRun.java
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeBaseCommand.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeBaseCommand.java
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeBaseCommand.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeBaseCommand.java
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java
similarity index 96%
copy from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java
copy to dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java
index 8bc5105ceaa..4bfc5202f74 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java
+++ b/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java
@@ -20,7 +20,7 @@ import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
import picocli.CommandLine;
@CommandLine.Command(name = "k",
- description = "Manage Camel integrations on Kubernetes (use config --help to see sub commands)")
+ description = "Manage Camel integrations on Kubernetes (use k --help to see sub commands)")
public class KubeCommand extends KubeBaseCommand {
public static final String OPERATOR_ID_LABEL = "camel.apache.org/operator.id";
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubePlugin.java
similarity index 57%
rename from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubePlugin.java
index 8bc5105ceaa..b344ee6e4e7 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommand.java
+++ b/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubePlugin.java
@@ -14,27 +14,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.apache.camel.dsl.jbang.core.commands.k;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.common.CamelJBangPlugin;
+import org.apache.camel.dsl.jbang.core.common.Plugin;
import picocli.CommandLine;
-@CommandLine.Command(name = "k",
- description = "Manage Camel integrations on Kubernetes (use config --help to see sub commands)")
-public class KubeCommand extends KubeBaseCommand {
-
- public static final String OPERATOR_ID_LABEL = "camel.apache.org/operator.id";
- public static final String INTEGRATION_LABEL = "camel.apache.org/integration";
- public static final String INTEGRATION_CONTAINER_NAME = "integration";
-
- public KubeCommand(CamelJBangMain main) {
- super(main);
- }
+@CamelJBangPlugin("camel-jbang-plugin-k")
+public class KubePlugin implements Plugin {
@Override
- public Integer doCall() throws Exception {
- // defaults to list integrations deployed on Kubernetes
- new CommandLine(new IntegrationGet(getMain())).execute();
- return 0;
+ public void customize(CommandLine commandLine, CamelJBangMain main) {
+ commandLine.addSubcommand("k", new picocli.CommandLine(new KubeCommand(main))
+ .addSubcommand("get", new picocli.CommandLine(new IntegrationGet(main)))
+ .addSubcommand("run", new picocli.CommandLine(new IntegrationRun(main)))
+ .addSubcommand("delete", new picocli.CommandLine(new IntegrationDelete(main)))
+ .addSubcommand("logs", new picocli.CommandLine(new IntegrationLogs(main))));
}
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubernetesHelper.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubernetesHelper.java
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubernetesHelper.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/KubernetesHelper.java
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/SourceScheme.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/SourceScheme.java
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/SourceScheme.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/SourceScheme.java
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/TraitHelper.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/TraitHelper.java
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/TraitHelper.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/TraitHelper.java
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/TraitProfile.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/TraitProfile.java
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/TraitProfile.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/main/java/org/apache/camel/dsl/jbang/core/commands/k/TraitProfile.java
diff --git a/dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/StringPrinter.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/StringPrinter.java
new file mode 100644
index 00000000000..0c44f197089
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/StringPrinter.java
@@ -0,0 +1,78 @@
+/*
+ * 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.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.dsl.jbang.core.common.Printer;
+
+public class StringPrinter implements Printer {
+
+ private final StringWriter writer = new StringWriter();
+
+ @Override
+ public void println() {
+ writer.write(System.lineSeparator());
+ }
+
+ @Override
+ public void println(String line) {
+ printf("%s%n", line);
+ }
+
+ @Override
+ public void print(String output) {
+ writer.write(output);
+ }
+
+ @Override
+ public void printf(String format, Object... args) {
+ writer.write(format.formatted(args));
+ }
+
+ /**
+ * Provides access to the cached output.
+ *
+ * @return
+ */
+ public String getOutput() {
+ return writer.toString().trim();
+ }
+
+ /**
+ * Provides access to all lines of the cached output.
+ *
+ * @return
+ * @throws IOException
+ */
+ public List<String> getLines() throws IOException {
+ BufferedReader buf = new BufferedReader(new StringReader(getOutput()));
+ List<String> lines = new ArrayList<>();
+ String line;
+ while ((line = buf.readLine()) != null) {
+ lines.add(line.trim());
+ }
+
+ return lines;
+ }
+}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationDeleteTest.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationDeleteTest.java
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationDeleteTest.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationDeleteTest.java
diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationGetTest.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationGetTest.java
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationGetTest.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationGetTest.java
diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationLogsTest.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationLogsTest.java
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationLogsTest.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationLogsTest.java
diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationRunTest.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationRunTest.java
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationRunTest.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/IntegrationRunTest.java
diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/KubeBaseTest.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/KubeBaseTest.java
similarity index 91%
rename from dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/KubeBaseTest.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/KubeBaseTest.java
index 86856f6a31c..ab3dde9278f 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/KubeBaseTest.java
+++ b/dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/KubeBaseTest.java
@@ -26,6 +26,9 @@ import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
import io.fabric8.mockwebserver.Context;
import okhttp3.mockwebserver.MockWebServer;
import org.apache.camel.dsl.jbang.core.commands.StringPrinter;
+import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
+import org.apache.camel.dsl.jbang.core.common.PluginHelper;
+import org.apache.camel.dsl.jbang.core.common.PluginType;
import org.apache.camel.util.IOHelper;
import org.apache.camel.v1.Integration;
import org.apache.camel.v1.IntegrationSpec;
@@ -52,6 +55,9 @@ public class KubeBaseTest {
new HashMap<>(), new KubernetesCrudDispatcher(), false);
kubernetesClient = k8sServer.createClient();
+
+ CommandLineHelper.useHomeDir("target");
+ PluginHelper.enable(PluginType.CAMEL_K);
}
@BeforeEach
diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommandMainTest.java b/dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommandMainTest.java
similarity index 89%
rename from dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommandMainTest.java
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommandMainTest.java
index 8333dc0b278..7cf10191c45 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommandMainTest.java
+++ b/dsl/camel-jbang/camel-jbang-plugin-k/src/test/java/org/apache/camel/dsl/jbang/core/commands/k/KubeCommandMainTest.java
@@ -24,6 +24,9 @@ import java.util.List;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.PodBuilder;
import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.impl.engine.DefaultClassResolver;
+import org.apache.camel.impl.engine.DefaultFactoryFinder;
+import org.apache.camel.spi.FactoryFinder;
import org.apache.camel.v1.Integration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -105,10 +108,17 @@ class KubeCommandMainTest extends KubeBaseTest {
traits: {}""", printer.getOutput());
}
+ @Test
+ public void shouldResolvePlugin() {
+ FactoryFinder factoryFinder
+ = new DefaultFactoryFinder(new DefaultClassResolver(), FactoryFinder.DEFAULT_PATH + "camel-jbang-plugin/");
+ Assertions.assertTrue(factoryFinder.newInstance("camel-jbang-plugin-k").isPresent());
+ }
+
private CamelJBangMain createMain() {
return new CamelJBangMain() {
@Override
- protected void quit(int exitCode) {
+ public void quit(int exitCode) {
if (exitCode != 0) {
Assertions.fail("Main finished with exit code %d".formatted(exitCode));
}
diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/resources/org/apache/camel/dsl/jbang/core/commands/k/integration.yaml b/dsl/camel-jbang/camel-jbang-plugin-k/src/test/resources/org/apache/camel/dsl/jbang/core/commands/k/integration.yaml
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/test/resources/org/apache/camel/dsl/jbang/core/commands/k/integration.yaml
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/test/resources/org/apache/camel/dsl/jbang/core/commands/k/integration.yaml
diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/resources/pod.yaml b/dsl/camel-jbang/camel-jbang-plugin-k/src/test/resources/pod.yaml
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/test/resources/pod.yaml
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/test/resources/pod.yaml
diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/resources/route.yaml b/dsl/camel-jbang/camel-jbang-plugin-k/src/test/resources/route.yaml
similarity index 100%
rename from dsl/camel-jbang/camel-jbang-core/src/test/resources/route.yaml
rename to dsl/camel-jbang/camel-jbang-plugin-k/src/test/resources/route.yaml
diff --git a/dsl/camel-jbang/pom.xml b/dsl/camel-jbang/pom.xml
index fe7c8a66317..1399ce4e14f 100644
--- a/dsl/camel-jbang/pom.xml
+++ b/dsl/camel-jbang/pom.xml
@@ -37,5 +37,6 @@
<module>camel-jbang-console</module>
<module>camel-jbang-core</module>
<module>camel-jbang-main</module>
+ <module>camel-jbang-plugin-k</module>
</modules>
</project>