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 2d707da62273 CAMEL-26930: camel-jbang - an example run in the 
background deletes its folder when it ends (#29982)
2d707da62273 is described below

commit 2d707da62273cedf10b7bee56a0adebab85827fb
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Nov 14 21:57:32 2026 +0100

    CAMEL-26930: camel-jbang - an example run in the background deletes its 
folder when it ends (#29982)
    
    
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../apache/camel/dsl/jbang/core/commands/Run.java  |  8 ++++
 .../camel/dsl/jbang/core/common/ExampleHelper.java | 38 +++++++++++++++
 .../core/common/ExampleHelperExampleDirTest.java   | 56 ++++++++++++++++++++++
 3 files changed, 102 insertions(+)

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 5b5eada118ec..8062ef890a96 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
@@ -695,6 +695,10 @@ public class Run extends CamelCommand implements 
CommandLifecycle {
         }
         ProcessBuilder pb = new ProcessBuilder(cmds);
         pb.directory(dir.toFile());
+        if (background) {
+            // the JVM that runs the example in the background deletes its 
folder when it ends
+            pb.environment().put(ExampleHelper.EXAMPLE_DIR_ENV, 
dir.toString());
+        }
         pb.inheritIO(); // run in foreground (with IO so logs are visible)
         Process p = pb.start();
         this.spawnPid = p.pid();
@@ -1621,6 +1625,10 @@ public class Run extends CamelCommand implements 
CommandLifecycle {
      * Runs Camel in this JVM, which the run configured, and waits for it to 
end.
      */
     protected int runKameletMain(ConfiguredRun run) throws Exception {
+        if (spawned) {
+            // the JVM that runs an example started in the background: its 
folder goes when it ends
+            
ExampleHelper.deleteExampleDirOnExit(System.getenv(ExampleHelper.EXAMPLE_DIR_ENV));
+        }
         return withChaosVerdict(run.start().waitFor());
     }
 
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/ExampleHelper.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/ExampleHelper.java
index 382c4b2a335e..a72292720ae8 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/ExampleHelper.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/ExampleHelper.java
@@ -574,6 +574,44 @@ public final class ExampleHelper {
         Runtime.getRuntime().addShutdownHook(new Thread(() -> 
FileUtil.removeDir(dir.toFile()), "CamelExampleCleanup"));
     }
 
+    /**
+     * The environment variable with the folder of an example run in the 
background, for the JVM that runs it: that JVM
+     * outlives the camel run that made the folder, and deletes it when it 
ends, such as by camel stop. The folder was
+     * left in the temporary directory (CAMEL-26930).
+     */
+    public static final String EXAMPLE_DIR_ENV = "CAMEL_CLI_EXAMPLE_DIR";
+
+    /**
+     * Deletes the folder of the example when this JVM exits, when the folder 
is one this CLI made for an example: a
+     * {@value #EXAMPLE_DIR_PREFIX} folder in the temporary directory. Any 
other folder is left alone.
+     *
+     * @param dir the folder, from {@link #EXAMPLE_DIR_ENV}, or null
+     */
+    public static void deleteExampleDirOnExit(String dir) {
+        Path path = exampleDir(dir);
+        if (path != null) {
+            deleteOnExit(path);
+        }
+    }
+
+    /** The folder, when it is a folder of an example in the temporary 
directory; else null. */
+    static Path exampleDir(String dir) {
+        return exampleDir(dir, Path.of(System.getProperty("java.io.tmpdir")));
+    }
+
+    static Path exampleDir(String dir, Path tmp) {
+        if (dir == null || dir.isBlank()) {
+            return null;
+        }
+        Path path = realPath(Path.of(dir));
+        if (!Files.isDirectory(path) || path.getFileName() == null
+                || 
!path.getFileName().toString().startsWith(EXAMPLE_DIR_PREFIX)
+                || !realPath(tmp).equals(path.getParent())) {
+            return null;
+        }
+        return path;
+    }
+
     /**
      * The folders of examples in the temporary directory that are older than 
the given age and that none of the given
      * folders (those of running integrations) is in: left behind by runs that 
ended, or by a process that was killed.
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/ExampleHelperExampleDirTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/ExampleHelperExampleDirTest.java
new file mode 100644
index 000000000000..7a33228ab30e
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/ExampleHelperExampleDirTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.nio.file.Files;
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The JVM that runs an example in the background deletes the folder of the 
example when it ends, and only a folder the
+ * CLI made for an example (CAMEL-26930).
+ */
+class ExampleHelperExampleDirTest {
+
+    @TempDir
+    Path tmp;
+
+    @Test
+    void anExampleFolderInTheTemporaryDirectory() throws Exception {
+        Path example = 
Files.createDirectory(tmp.resolve(ExampleHelper.EXAMPLE_DIR_PREFIX + "123"));
+
+        assertThat(ExampleHelper.exampleDir(example.toString(), 
tmp)).isEqualTo(example.toRealPath());
+    }
+
+    @Test
+    void anyOtherFolderIsLeftAlone() throws Exception {
+        Path other = Files.createDirectory(tmp.resolve("my-project"));
+        Path nested = 
Files.createDirectories(tmp.resolve("x").resolve(ExampleHelper.EXAMPLE_DIR_PREFIX
 + "1"));
+
+        assertThat(ExampleHelper.exampleDir(other.toString(), tmp)).isNull();
+        // not directly in the temporary directory
+        assertThat(ExampleHelper.exampleDir(nested.toString(), tmp)).isNull();
+        
assertThat(ExampleHelper.exampleDir(tmp.resolve(ExampleHelper.EXAMPLE_DIR_PREFIX
 + "gone").toString(), tmp))
+                .isNull();
+        assertThat(ExampleHelper.exampleDir(null, tmp)).isNull();
+        assertThat(ExampleHelper.exampleDir("", tmp)).isNull();
+    }
+}

Reply via email to