This is an automated email from the ASF dual-hosted git repository. christophd pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit 3c3f5b456808b3e47a52f52cbeb4e6a07e2df649 Author: Christoph Deppisch <[email protected]> AuthorDate: Wed Nov 11 12:25:19 2026 +0100 CAMEL-26766: Address review feedback (round 2) - Treat existing regular files without .json suffix as config files - Use Locale.ROOT for case-insensitive suffix check - Import InvalidPathException instead of using FQN - Add 'list' to the documented plugin subcommands - Document non-existing non-.json path treated as directory - Fix testDefaultPluginConfigPath to not read real environment - Add tests for existing non-.json file, upper-case .JSON, and non-existing non-.json directory path Co-Authored-By: Claude Opus 4.6 <[email protected]> --- .../modules/ROOT/pages/camel-jbang-projects.adoc | 5 +++-- .../core/commands/plugin/PluginBaseCommand.java | 3 ++- .../camel/dsl/jbang/core/common/PluginHelper.java | 8 ++++++-- .../dsl/jbang/core/common/PluginHelperTest.java | 24 +++++++++++++++++++++- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang-projects.adoc b/docs/user-manual/modules/ROOT/pages/camel-jbang-projects.adoc index 305ff888f5e2..19a3bd7a267c 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-jbang-projects.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-jbang-projects.adoc @@ -285,7 +285,8 @@ camel plugin get --plugin-config /path/to/my-plugins.json camel plugin add kubernetes --plugin-config /path/to/my-plugins.json ---- -The path can point to a JSON file or to a directory (in which case the default filename `.camel-jbang-plugins.json` is resolved inside it). +The path can point to a JSON file, an existing file with any name, or a directory (in which case the default filename `.camel-jbang-plugins.json` is resolved inside it). +A path that does not exist and does not end with `.json` is treated as a directory and created on first save. Alternatively, set the `CAMEL_CLI_PLUGIN_CONFIG` environment variable: @@ -297,7 +298,7 @@ camel plugin get The resolution order is: `--plugin-config` option > `CAMEL_CLI_PLUGIN_CONFIG` environment variable > default `~/.camel-jbang-plugins.json`. -NOTE: The `--plugin-config` option only applies to the `plugin` subcommands (`add`, `get`, `delete`). +NOTE: The `--plugin-config` option only applies to the `plugin` subcommands (`add`, `get`, `delete`, `list`). Running a plugin's own command (e.g. `camel kubernetes ...`) discovers plugins only through the environment variable or the default file. So a plugin added with `camel plugin add --plugin-config X` is not seen unless `CAMEL_CLI_PLUGIN_CONFIG` is also set. diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginBaseCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginBaseCommand.java index 9f3112a3ad72..41369ea4e64b 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginBaseCommand.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginBaseCommand.java @@ -17,6 +17,7 @@ package org.apache.camel.dsl.jbang.core.commands.plugin; +import java.nio.file.InvalidPathException; import java.nio.file.Path; import org.apache.camel.dsl.jbang.core.commands.CamelCommand; @@ -46,7 +47,7 @@ abstract class PluginBaseCommand extends CamelCommand { if (pluginConfig != null) { try { return Path.of(pluginConfig); - } catch (java.nio.file.InvalidPathException e) { + } catch (InvalidPathException e) { throw new IllegalStateException( "Invalid path in --plugin-config option: " + pluginConfig, e); } 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 index 2824454fce8b..dd07e5de658d 100644 --- 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 @@ -24,6 +24,7 @@ import java.net.URL; import java.net.URLClassLoader; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.ArrayList; @@ -32,6 +33,7 @@ import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -114,7 +116,7 @@ public final class PluginHelper { if (envValue != null && !envValue.isBlank()) { try { pluginConfigPath = Path.of(envValue); - } catch (java.nio.file.InvalidPathException e) { + } catch (InvalidPathException e) { throw new IllegalStateException( "Invalid path in " + PLUGIN_CONFIG_ENV + " environment variable: " + envValue, e); } @@ -127,9 +129,11 @@ public final class PluginHelper { return pluginConfigPath.resolve(PLUGIN_CONFIG); } Path fileName = pluginConfigPath.getFileName(); - if (fileName != null && fileName.toString().toLowerCase().endsWith(".json")) { + if (Files.isRegularFile(pluginConfigPath) + || fileName != null && fileName.toString().toLowerCase(Locale.ROOT).endsWith(".json")) { return pluginConfigPath; } + // does not exist and has no .json suffix — treated as a directory (created on first save) return pluginConfigPath.resolve(PLUGIN_CONFIG); } diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/PluginHelperTest.java b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/PluginHelperTest.java index 9f6e1a3f1fd4..28bd8bc64d5c 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/PluginHelperTest.java +++ b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/PluginHelperTest.java @@ -415,7 +415,7 @@ public class PluginHelperTest { @Test public void testDefaultPluginConfigPath() { Path expected = CommandLineHelper.getHomeDir().resolve(PluginHelper.PLUGIN_CONFIG); - assertEquals(expected, PluginHelper.getCustomPluginConfigPath()); + assertEquals(expected, PluginHelper.resolvePluginConfigPath(null, null)); } @Test @@ -544,6 +544,28 @@ public class PluginHelperTest { () -> PluginHelper.resolvePluginConfigPath(null, "\u0000invalid")); } + @Test + public void testExistingNonJsonFileUsedAsConfig() throws Exception { + Path configFile = tempDir.resolve("plugins.conf"); + Files.writeString(configFile, "{}", StandardOpenOption.CREATE); + Path result = PluginHelper.resolvePluginConfigPath(configFile, null); + assertEquals(configFile, result); + } + + @Test + public void testUpperCaseJsonSuffixTreatedAsFile() { + Path configFile = tempDir.resolve("PLUGINS.JSON"); + Path result = PluginHelper.resolvePluginConfigPath(configFile, null); + assertEquals(configFile, result); + } + + @Test + public void testNonExistingNonJsonPathTreatedAsDirectory() { + Path dirPath = tempDir.resolve("custom-config-dir"); + Path result = PluginHelper.resolvePluginConfigPath(dirPath, null); + assertEquals(dirPath.resolve(PluginHelper.PLUGIN_CONFIG), result); + } + private void writeConfig(JsonObject pluginEntry) throws Exception { JsonObject plugins = new JsonObject(); plugins.put(pluginEntry.getString("name"), pluginEntry);
