This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch copy-shroud
in repository https://gitbox.apache.org/repos/asf/camel.git

commit df6b1abb4bb10876460a1e15b087a3fb8de40caf
Author: Guillaume Nodet <[email protected]>
AuthorDate: Tue Mar 24 07:53:46 2026 +0100

    CAMEL-23236: Add interactive template picker to camel init
    
    When `camel init` is invoked with no arguments in an interactive terminal
    (TTY, non-CI), show an interactive template picker that guides the user
    through selecting a category, template, and filename. Non-interactive
    behavior is unchanged.
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 .../apache/camel/dsl/jbang/core/commands/Init.java | 93 ++++++++++++++++++++++
 1 file changed, 93 insertions(+)

diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Init.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Init.java
index 1a0f967b8bff..c4fb6846e299 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Init.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Init.java
@@ -22,8 +22,11 @@ import java.io.OutputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.ArrayList;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.Scanner;
 import java.util.Stack;
 import java.util.StringJoiner;
 
@@ -95,7 +98,12 @@ public class Init extends CamelCommand {
             return listTemplates();
         }
         if (file == null) {
+            // try interactive picker if running in a TTY and not in CI
+            if (System.console() != null && System.getenv("CI") == null) {
+                return interactivePicker();
+            }
             printer().printErr("Missing required parameter: <file>");
+            printer().printErr("Run 'camel init --list' to see available 
templates, or run interactively in a terminal.");
             return 1;
         }
         int code = execute();
@@ -271,6 +279,91 @@ public class Init extends CamelCommand {
         return 0;
     }
 
+    private int interactivePicker() throws Exception {
+        // Build template categories
+        Map<String, List<String[]>> categories = new LinkedHashMap<>();
+        categories.put("Routes", List.of(
+                new String[] { "yaml", "YAML DSL route", ".yaml" },
+                new String[] { "java", "Java DSL route", ".java" },
+                new String[] { "xml", "XML DSL route", ".xml" }));
+        categories.put("Kamelets", List.of(
+                new String[] { "kamelet-source.yaml", "Kamelet source 
connector", ".kamelet.yaml" },
+                new String[] { "kamelet-sink.yaml", "Kamelet sink connector", 
".kamelet.yaml" },
+                new String[] { "kamelet-action.yaml", "Kamelet action 
processor", ".kamelet.yaml" }));
+        categories.put("Pipes and CRs", List.of(
+                new String[] { "init-pipe.yaml", "Pipe CR (source to sink)", 
".yaml" }));
+
+        Scanner scanner = new Scanner(System.in);
+
+        // Step 1: Pick a category
+        printer().println("Select a template category:");
+        List<String> categoryNames = new ArrayList<>(categories.keySet());
+        for (int i = 0; i < categoryNames.size(); i++) {
+            printer().printf("  %d) %s%n", i + 1, categoryNames.get(i));
+        }
+        printer().print("Choice [1]: ");
+        String categoryInput = scanner.nextLine().trim();
+        int categoryIdx = categoryInput.isEmpty() ? 0 : 
Integer.parseInt(categoryInput) - 1;
+        if (categoryIdx < 0 || categoryIdx >= categoryNames.size()) {
+            printer().printErr("Invalid choice.");
+            return 1;
+        }
+
+        // Step 2: Pick a template
+        String selectedCategory = categoryNames.get(categoryIdx);
+        List<String[]> templates = categories.get(selectedCategory);
+        printer().println();
+        printer().println("Select a template:");
+        for (int i = 0; i < templates.size(); i++) {
+            printer().printf("  %d) %s%n", i + 1, templates.get(i)[1]);
+        }
+        printer().print("Choice [1]: ");
+        String templateInput = scanner.nextLine().trim();
+        int templateIdx = templateInput.isEmpty() ? 0 : 
Integer.parseInt(templateInput) - 1;
+        if (templateIdx < 0 || templateIdx >= templates.size()) {
+            printer().printErr("Invalid choice.");
+            return 1;
+        }
+
+        String[] selected = templates.get(templateIdx);
+        String ext = selected[2];
+        String defaultName = "MyRoute" + ext;
+        if (ext.endsWith(".kamelet.yaml")) {
+            if (selected[0].contains("source")) {
+                defaultName = "my-source.kamelet.yaml";
+            } else if (selected[0].contains("sink")) {
+                defaultName = "my-sink.kamelet.yaml";
+            } else {
+                defaultName = "my-action.kamelet.yaml";
+            }
+        } else if (selected[0].contains("pipe")) {
+            defaultName = "my-pipe.yaml";
+            pipe = true;
+        }
+
+        // Step 3: Prompt for filename
+        printer().println();
+        printer().printf("Filename [%s]: ", defaultName);
+        String filename = scanner.nextLine().trim();
+        if (filename.isEmpty()) {
+            filename = defaultName;
+        }
+
+        this.file = filename;
+        int code = execute();
+        if (code == 0) {
+            createWorkingDirectoryIfAbsent();
+            printer().println();
+            printer().println("Created: " + filename);
+            printer().println();
+            printer().println("Next steps:");
+            printer().println("  Run:           camel run " + filename);
+            printer().println("  Run (live):    camel run " + filename + " 
--dev");
+            printer().println("  Documentation: camel doc <component>");
+        }
+        return code;
+    }
+
     private void createWorkingDirectoryIfAbsent() {
         Path work = CommandLineHelper.getWorkDir();
         if (!Files.exists(work)) {

Reply via email to