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);

Reply via email to