You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/03/07 14:35:29 UTC

[camel] 01/03: CAMEL-18508: camel-jbang - User config. WIP

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

davsclaus pushed a commit to branch jbang-user-config
in repository https://gitbox.apache.org/repos/asf/camel.git

commit bd29dbde43ca4d8878277854b946a5021d75d283
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Mar 7 15:23:23 2023 +0100

    CAMEL-18508: camel-jbang - User config. WIP
---
 .../dsl/jbang/core/commands/CamelJBangMain.java    |   2 +
 .../dsl/jbang/core/common/CommandLineHelper.java   | 103 +++++++++++++++++++++
 2 files changed, 105 insertions(+)

diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
index 2dd2531aa54..eb5ecc5f287 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/CamelJBangMain.java
@@ -62,6 +62,7 @@ import org.apache.camel.dsl.jbang.core.commands.process.ListProcess;
 import org.apache.camel.dsl.jbang.core.commands.process.ListService;
 import org.apache.camel.dsl.jbang.core.commands.process.ListVault;
 import org.apache.camel.dsl.jbang.core.commands.process.StopProcess;
+import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
 import picocli.CommandLine;
 import picocli.CommandLine.Command;
 
@@ -132,6 +133,7 @@ public class CamelJBangMain implements Callable<Integer> {
             return new String[] { v };
         });
 
+        CommandLineHelper.augmentWithUserConfiguration(commandLine, args);
         int exitCode = commandLine.execute(args);
         System.exit(exitCode);
     }
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CommandLineHelper.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CommandLineHelper.java
new file mode 100644
index 00000000000..d189d1321a4
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CommandLineHelper.java
@@ -0,0 +1,103 @@
+/*
+ * 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.io.File;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import org.apache.camel.util.IOHelper;
+import picocli.CommandLine;
+
+/**
+ * Helper for CLI command line.
+ */
+public class CommandLineHelper {
+
+    public static final String USER_CONFIG = ".camel-jbang-user.properties";
+
+    public static void augmentWithUserConfiguration(CommandLine commandLine, String... args) {
+        File file = new File(System.getProperty("user.home"), USER_CONFIG);
+        if (file.isFile() && file.exists()) {
+            FileInputStream fis = null;
+            try {
+                fis = new FileInputStream(file);
+                Properties prop = new Properties();
+                prop.load(fis);
+                IOHelper.close(fis);
+                if (!prop.isEmpty()) {
+                    commandLine.setDefaultValueProvider(new CommandLine.PropertiesDefaultProvider(prop));
+                }
+            } catch (Exception e) {
+                throw new RuntimeException("Cannot load user configuration: " + file);
+            } finally {
+                IOHelper.close(fis);
+            }
+        }
+
+        // TODO: if we need to do this (must be slower due all the command options parsing)
+        // this filters the list of options to only what the commands support
+        // Properties options = augmentConfiguration(configuration, commandLine);
+        // commandLine.setDefaultValueProvider(new CommandLine.PropertiesDefaultProvider(options));
+    }
+
+    private static Properties augmentConfiguration(Properties configuration, CommandLine commandLine) {
+        Properties answer = new Properties();
+
+        // gather for all commands every option they have
+        List<String> allOptions
+                = commonArgumentList(new ArrayList<>(), commandLine.getSubcommands(), commandLine.getCommandName());
+        allOptions.forEach(key -> {
+            String[] parts = key.split(Pattern.quote("."));
+            String arg = parts[parts.length - 1];
+            // for every option see if we have a configuration for that
+            String value = configuration.getProperty(arg);
+            if (value != null) {
+                answer.setProperty(arg, value);
+            }
+        });
+        return configuration;
+    }
+
+    private static List<String> commonArgumentList(
+            List<String> list, Map<String, CommandLine> commandLines, String parentPrefix) {
+        commandLines.forEach((name, subCommand) -> {
+            subCommand.getCommandSpec().args().stream()
+                    .filter(arg -> arg instanceof CommandLine.Model.OptionSpec)
+                    .map(arg -> (CommandLine.Model.OptionSpec) arg)
+                    .map(arg -> arg.longestName().replace("--", ""))
+                    .forEach(arg -> list.add(generateParameter(parentPrefix, subCommand.getCommandName(), arg)));
+            // add arguments for sub commands as well
+            list.addAll(
+                    commonArgumentList(new ArrayList<>(), subCommand.getSubcommands(), generateParameter(parentPrefix, name)));
+        });
+        return list;
+    }
+
+    private static String generateParameter(String... prefix) {
+        return Arrays.stream(prefix)
+                .filter(Objects::nonNull)
+                .collect(Collectors.joining("."));
+    }
+}