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 3ff57c15325e CAMEL-25434: camel-jbang - Show the properties file a 
property comes from (#27534)
3ff57c15325e is described below

commit 3ff57c15325ea1857c25a72976476ac39729faa9
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Oct 8 08:31:00 2026 +0200

    CAMEL-25434: camel-jbang - Show the properties file a property comes from 
(#27534)
    
    camel get properties showed an empty LOCATION for properties from
    application.properties: the dev console reports the location, but the
    CLI turned every location it had no readable name for into an empty
    string. Keep such a location, the properties file, as it is.
    
    The monitor's Configuration tab showed only the source a placeholder
    was resolved from, so a property that no route used yet had an empty
    SOURCE. Show the location then, and widen the column so
    file:application.properties fits.
    
    
    Claude-Session: https://claude.ai/code/session_01STT6whBgK1AqsSsUKrnE8m
    
    Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
---
 .../core/commands/process/ListProperties.java      | 21 +++++++++--------
 .../core/commands/process/ListPropertiesTest.java  | 26 +++++++++++++++++++++
 .../jbang/core/commands/tui/ConfigurationTab.java  | 27 +++++++++++++++-------
 .../commands/tui/ConfigurationTabRenderTest.java   | 27 ++++++++++++++++++++++
 4 files changed, 84 insertions(+), 17 deletions(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProperties.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProperties.java
index 16ff85b34f4d..2e5680cbc80a 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProperties.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProperties.java
@@ -231,18 +231,21 @@ public class ListProperties extends ProcessWatchCommand {
         }
     }
 
-    private static String sanitizeLocation(String loc) {
+    /**
+     * A readable name of where a property comes from, such as 
application.properties or OS Environment Variable.
+     */
+    public static String sanitizeLocation(String loc) {
         if (loc == null) {
             return "";
         }
-        switch (loc) {
-            case "initial", "override" -> loc = "camel-main";
-            case "SYS" -> loc = "JVM System Property";
-            case "ENV", "env" -> loc = "OS Environment Variable";
-            case "arguments", "CLI" -> loc = "Command Line";
-            default -> loc = "";
-        }
-        return loc;
+        return switch (loc) {
+            case "initial", "override" -> "camel-main";
+            case "SYS" -> "JVM System Property";
+            case "ENV", "env" -> "OS Environment Variable";
+            case "arguments", "CLI" -> "Command Line";
+            // a properties file, such as application.properties
+            default -> loc;
+        };
     }
 
 }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/process/ListPropertiesTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/process/ListPropertiesTest.java
index 8ab0232b492f..bfb7b6fffb09 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/process/ListPropertiesTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/process/ListPropertiesTest.java
@@ -145,6 +145,32 @@ class ListPropertiesTest extends ProcessCommandTestSupport 
{
         }
     }
 
+    @Test
+    void testPropertiesFileLocationShown() throws Exception {
+        JsonObject root = new JsonObject();
+        root.put("context", contextObj());
+        root.put("properties", propertyContainer("properties",
+                property("greeting", "Hello", "Hello", false, null, 
"application.properties")));
+        writeStatusFile(TEST_PID, root);
+
+        ListProperties command = new ListProperties(new 
CamelJBangMain().withPrinter(printer));
+        command.sort = "pid";
+        command.jsonOutput = true;
+
+        try (MockedStatic<ProcessHandle> mocked = 
mockStatic(ProcessHandle.class)) {
+            ProcessHandle ph = mockProcessHandle(TEST_PID);
+            ProcessHandle currentHandle = mockCurrentHandle();
+            mocked.when(ProcessHandle::current).thenReturn(currentHandle);
+            mocked.when(ProcessHandle::allProcesses).thenAnswer(inv -> 
Stream.of(ph));
+
+            int exit = command.doCall();
+
+            assertEquals(0, exit);
+            
assertTrue(printer.getOutput().contains("\"location\":\"application.properties\""),
+                    "The properties file should be shown as the location");
+        }
+    }
+
     private static JsonObject contextObj() {
         JsonObject ctx = new JsonObject();
         ctx.put("name", "myApp");
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTab.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTab.java
index f7b07bde5676..57d1cfa4b8bf 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTab.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTab.java
@@ -43,6 +43,7 @@ import dev.tamboui.widgets.table.Cell;
 import dev.tamboui.widgets.table.Row;
 import dev.tamboui.widgets.table.Table;
 import org.apache.camel.catalog.CamelCatalog;
+import org.apache.camel.dsl.jbang.core.commands.process.ListProperties;
 import org.apache.camel.dsl.jbang.core.common.CatalogLoader;
 import org.apache.camel.tooling.model.BaseOptionModel;
 import org.apache.camel.tooling.model.ComponentModel;
@@ -158,7 +159,7 @@ class ConfigurationTab extends AbstractTableTab {
         result.sort((a, b) -> {
             int cmp = switch (sort) {
                 case "value" -> compareStr(a.value, b.value);
-                case "source" -> compareStr(a.source, b.source);
+                case "source" -> compareStr(sourceOf(a), sourceOf(b));
                 default -> compareCamelFirst(a, b);
             };
             return sortReversed ? -cmp : cmp;
@@ -166,6 +167,17 @@ class ConfigurationTab extends AbstractTableTab {
         return result;
     }
 
+    /**
+     * Where a property comes from: the source it was resolved from, or else 
the location it was loaded from (a property
+     * that no placeholder has used yet has no source).
+     */
+    static String sourceOf(ConfigProperty p) {
+        if (p.source != null && !p.source.isEmpty()) {
+            return FileUtil.stripPath(p.source);
+        }
+        return ListProperties.sanitizeLocation(p.location);
+    }
+
     private void renderTable(Frame frame, Rect area, List<ConfigProperty> 
props) {
         List<Row> rows = new ArrayList<>();
         for (ConfigProperty p : props) {
@@ -173,10 +185,7 @@ class ConfigurationTab extends AbstractTableTab {
             String value = p.value != null ? p.value : "";
             Style valStyle = secret ? SECRET_STYLE : Style.EMPTY;
 
-            String source = "";
-            if (p.source != null && !p.source.isEmpty()) {
-                source = FileUtil.stripPath(p.source);
-            }
+            String source = sourceOf(p);
 
             rows.add(Row.from(
                     Cell.from(Span.styled(p.key, 
Style.EMPTY.fg(Theme.accent()))),
@@ -202,7 +211,8 @@ class ConfigurationTab extends AbstractTableTab {
                 .widths(
                         Constraint.percentage(35),
                         Constraint.fill(),
-                        Constraint.length(20))
+                        // wide enough for file:application.properties and OS 
Environment Variable
+                        Constraint.length(28))
                 .highlightStyle(detailFocused ? Theme.selectionBg().dim() : 
Theme.selectionBg())
                 .highlightSpacing(Table.HighlightSpacing.ALWAYS)
                 
.block(Block.builder().borderType(BorderType.ROUNDED).borders(Borders.ALL)
@@ -274,8 +284,9 @@ class ConfigurationTab extends AbstractTableTab {
         String value = prop.value != null ? prop.value : "";
         boolean secret = "xxxxxx".equals(value);
         addDetailField(lines, "Current value", secret ? "xxxxxx (masked)" : 
value, area.width());
-        if (prop.source != null && !prop.source.isEmpty()) {
-            addDetailField(lines, "Source", FileUtil.stripPath(prop.source), 
area.width());
+        String source = sourceOf(prop);
+        if (!source.isEmpty()) {
+            addDetailField(lines, "Source", source, area.width());
         }
 
         if (option == null) {
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTabRenderTest.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTabRenderTest.java
index 9e0a05b98c66..b10edea7d037 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTabRenderTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTabRenderTest.java
@@ -26,6 +26,7 @@ import dev.tamboui.terminal.Frame;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
@@ -138,6 +139,32 @@ class ConfigurationTabRenderTest {
 
     // ---- Helper methods ----
 
+    @Test
+    void sourceFallsBackToLocation() {
+        // a property that no placeholder has used yet has no source, only the 
file it was loaded from
+        ConfigurationTab.ConfigProperty prop = addProperty("greeting", 
"Hello", null);
+        prop.location = "application.properties";
+
+        ConfigurationTab tab = new ConfigurationTab(ctx);
+        String rendered = TuiTestHelper.renderToString(tab, 120, 20);
+
+        assertTrue(rendered.contains("application.properties"), "Should render 
the location as the source");
+    }
+
+    @Test
+    void sourceOfPrefersResolvedSource() {
+        ConfigurationTab.ConfigProperty prop = new 
ConfigurationTab.ConfigProperty();
+        prop.source = "file:application.properties";
+        prop.location = "initial";
+        assertEquals("file:application.properties", 
ConfigurationTab.sourceOf(prop));
+
+        prop.source = null;
+        assertEquals("camel-main", ConfigurationTab.sourceOf(prop));
+
+        prop.location = null;
+        assertEquals("", ConfigurationTab.sourceOf(prop));
+    }
+
     private ConfigurationTab.ConfigProperty addProperty(String key, String 
value, String source) {
         ConfigurationTab.ConfigProperty prop = new 
ConfigurationTab.ConfigProperty();
         prop.key = key;

Reply via email to