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 c06b3a6f4ac1 CAMEL-25349: camel-jbang - camel run . --dev reloads 
changed and new route files (#27384)
c06b3a6f4ac1 is described below

commit c06b3a6f4ac1398d72c9b3edd9e9bd2f9b22ed5c
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Oct 5 20:33:17 2026 +0200

    CAMEL-25349: camel-jbang - camel run . --dev reloads changed and new route 
files (#27384)
    
    Running a directory (camel run . or camel run mycode) now runs it as 
--source-dir,
    so dev mode watches the directory: changed files are reloaded and new files 
are loaded.
    Before, the directory was expanded to ./orders.camel.yaml and so on, which 
never
    matched the reload pattern, so camel run . --dev reloaded nothing. A 
directory with a
    pom.xml, and the spring-boot and quarkus runtimes, still run the files in 
it.
    
    RunHelper.dirToFiles now names the files of the current directory without a 
leading ./
    
    Signed-off-by: Claus Ibsen <[email protected]>
    Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
---
 .../ROOT/pages/camel-4x-upgrade-guide-4_23.adoc    |  5 ++
 .../modules/ROOT/pages/camel-jbang-running.adoc    |  4 ++
 .../apache/camel/dsl/jbang/core/commands/Run.java  | 18 ++++-
 .../camel/dsl/jbang/core/commands/RunHelper.java   |  8 ++-
 .../dsl/jbang/core/commands/RunDirectoryTest.java  | 78 ++++++++++++++++++++++
 5 files changed, 110 insertions(+), 3 deletions(-)

diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
index b95f0c3b64ab..8afd5488a35a 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_23.adoc
@@ -1796,6 +1796,11 @@ cost of a slower startup. If you passed `--runtime=main` 
explicitly and want the
 run, use `--runtime=jbang` (or leave the option out). The options 
`--background`, `--code`, `--open-api`,
 `--empty` and `--mcp-stdio` are not supported with `--runtime=main`.
 
+Running a directory (`camel run .` or `camel run mycode`) is now the same as 
`--source-dir`: the route files in
+its subfolders are loaded too, and in `--dev` mode changed and new files are 
reloaded (before, the directory was
+expanded to the files directly in it, and in `--dev` mode `camel run .` 
reloaded nothing). A directory with a
+`pom.xml`, and the `spring-boot` and `quarkus` runtimes, still run the files 
directly in the directory.
+
 Running an existing Maven project (`camel run pom.xml`) is unchanged, and 
still detects the runtime
 from the `pom.xml`. The other commands that take `--runtime` (such as `camel 
export`,
 `camel dependency list` and `camel version list`) accept `jbang` as an alias 
for `main`.
diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang-running.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-jbang-running.adoc
index 22d7504d4295..8370e7887b5b 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-jbang-running.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-jbang-running.adoc
@@ -50,6 +50,10 @@ and automatically detects new, modified, and deleted files:
 camel run --source-dir=mycode --dev
 ----
 
+Running a directory is the same as `--source-dir`, so `camel run . --dev` and 
`camel run mycode --dev` also reload
+changed files and pick up new ones. A directory with a `pom.xml` (an existing 
Maven project), and the Spring Boot and
+Quarkus runtimes, run the files in the directory instead.
+
 Without `--source-dir`, Camel only watches the specific files you listed on 
the command line.
 
 NOTE: You cannot combine files and source dir: `camel run abc.java 
--source-dir=mycode` is not allowed.
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
index 39f92ce7a567..60b810c670a5 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
@@ -737,6 +737,16 @@ public class Run extends CamelCommand {
         return prop;
     }
 
+    /**
+     * Whether a directory given as the only file (camel run . or camel run 
dirName) runs as --source-dir. A Maven
+     * project keeps running its files, and so do the Spring Boot and Quarkus 
runtimes, which export the files to run
+     * them.
+     */
+    boolean runsDirectoryAsSourceDir(Path dir) {
+        return (RuntimeType.jbang == runtime || RuntimeType.main == runtime)
+                && !Files.exists(dir.resolve("pom.xml"));
+    }
+
     private int run() throws Exception {
         if (!empty && !files.isEmpty() && sourceDir != null) {
             // cannot have both files and source dir at the same time
@@ -753,7 +763,13 @@ public class Run extends CamelCommand {
                 Path first = Path.of(name);
                 if (Files.isDirectory(first)) {
                     baseDir = first;
-                    RunHelper.dirToFiles(name, files);
+                    if (runsDirectoryAsSourceDir(first)) {
+                        // run the directory as --source-dir, so dev mode 
watches it: changed and new files are reloaded
+                        sourceDir = name;
+                        files.clear();
+                    } else {
+                        RunHelper.dirToFiles(name, files);
+                    }
                 }
             }
         }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/RunHelper.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/RunHelper.java
index b0089a0a40e3..dccf404e15c7 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/RunHelper.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/RunHelper.java
@@ -306,10 +306,14 @@ public final class RunHelper {
     }
 
     /**
-     * When using camel run . or camel export . then dot should include all 
the files in the current folder.
+     * When using camel run . or camel export . then dot should include all 
the files in the current folder. The files
+     * of the current folder are named without a leading ./ 
(orders.camel.yaml), so they match the reload pattern in dev
+     * mode.
      */
     public static void dirToFiles(String dir, List<String> files) {
         files.clear();
+        boolean currentDir = Paths.get(dir).normalize().toString().isEmpty();
+        String base = currentDir ? "" : FileUtil.stripTrailingSeparator(dir) + 
"/";
         try (Stream<Path> paths = Files.list(Paths.get(dir))) {
             paths.filter(p -> {
                 try {
@@ -318,7 +322,7 @@ public final class RunHelper {
                     return false;
                 }
             })
-                    .forEach(f -> files.add(dir + "/" + f.getFileName()));
+                    .forEach(f -> files.add(base + f.getFileName()));
         } catch (IOException e) {
             // Ignore
         }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/RunDirectoryTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/RunDirectoryTest.java
new file mode 100644
index 000000000000..79673b81949b
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/RunDirectoryTest.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.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import picocli.CommandLine;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * camel run . (or camel run dirName) runs the directory as --source-dir, so 
dev mode reloads changed and new files.
+ */
+class RunDirectoryTest {
+
+    private static Run run(String... args) {
+        Run command = new Run(new CamelJBangMain());
+        CommandLine.populateCommand(command, args);
+        return command;
+    }
+
+    @Test
+    void directoryOfRouteFilesRunsAsSourceDir(@TempDir Path dir) throws 
Exception {
+        Files.writeString(dir.resolve("orders.camel.yaml"), "- route:\n");
+
+        assertThat(run(dir.toString()).runsDirectoryAsSourceDir(dir)).isTrue();
+        assertThat(run(dir.toString(), 
"--runtime=main").runsDirectoryAsSourceDir(dir)).isTrue();
+    }
+
+    @Test
+    void mavenProjectKeepsRunningItsFiles(@TempDir Path dir) throws Exception {
+        Files.writeString(dir.resolve("pom.xml"), "<project/>");
+
+        
assertThat(run(dir.toString()).runsDirectoryAsSourceDir(dir)).isFalse();
+    }
+
+    @Test
+    void exportedRuntimesKeepRunningTheFiles(@TempDir Path dir) {
+        assertThat(run(dir.toString(), 
"--runtime=spring-boot").runsDirectoryAsSourceDir(dir)).isFalse();
+        assertThat(run(dir.toString(), 
"--runtime=quarkus").runsDirectoryAsSourceDir(dir)).isFalse();
+    }
+
+    @Test
+    void filesOfTheCurrentDirectoryHaveNoDotPrefix() {
+        List<String> files = new ArrayList<>();
+        RunHelper.dirToFiles(".", files);
+
+        assertThat(files).isNotEmpty().contains("pom.xml").noneMatch(f -> 
f.startsWith("./"));
+    }
+
+    @Test
+    void filesOfAnotherDirectoryKeepTheDirectory(@TempDir Path dir) throws 
Exception {
+        Files.writeString(dir.resolve("orders.camel.yaml"), "- route:\n");
+        List<String> files = new ArrayList<>();
+        RunHelper.dirToFiles(dir + "/", files);
+
+        assertThat(files).containsExactly(dir + "/orders.camel.yaml");
+    }
+}

Reply via email to