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 2022/01/25 09:23:35 UTC

[camel] branch main updated (2a74ea8 -> a8ae278)

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

davsclaus pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git.


    from 2a74ea8  Regen for commit 0158960a4b65a55f3850e89b6f4b2598ce9a82f0
     new b89f223  CAMEL-17280: camel-jbang - Run from github using wildcards
     new a8ae278  CAMEL-17280: camel-jbang - Run from github using wildcards

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../modules/ROOT/pages/camel-jbang.adoc            |  48 ++++++--
 .../apache/camel/dsl/jbang/core/commands/Run.java  | 135 ++++++++++++++++++++-
 2 files changed, 166 insertions(+), 17 deletions(-)

[camel] 01/02: CAMEL-17280: camel-jbang - Run from github using wildcards

Posted by da...@apache.org.
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

commit b89f2238f936116e18d1c7a2514117a67830879b
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Jan 25 10:12:34 2022 +0100

    CAMEL-17280: camel-jbang - Run from github using wildcards
---
 .../apache/camel/dsl/jbang/core/commands/Run.java  | 135 ++++++++++++++++++++-
 1 file changed, 131 insertions(+), 4 deletions(-)

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 2283fe1..e0bf1f6 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
@@ -18,17 +18,26 @@ package org.apache.camel.dsl.jbang.core.commands;
 
 import java.io.File;
 import java.io.IOException;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
 import java.nio.file.FileSystems;
+import java.time.Duration;
 import java.util.StringJoiner;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.camel.CamelContext;
 import org.apache.camel.dsl.jbang.core.common.RuntimeUtil;
 import org.apache.camel.main.KameletMain;
 import org.apache.camel.support.ResourceHelper;
+import org.apache.camel.util.AntPathMatcher;
+import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.ObjectHelper;
 import picocli.CommandLine.Command;
 import picocli.CommandLine.Option;
@@ -44,7 +53,7 @@ class Run implements Callable<Integer> {
     private String[] files;
 
     //CHECKSTYLE:OFF
-    @Option(names = { "-h", "--help" }, usageHelp = true, description = "Display the help and sub-commands")
+    @Option(names = {"-h", "--help"}, usageHelp = true, description = "Display the help and sub-commands")
     private boolean helpRequested;
     //CHECKSTYLE:ON
 
@@ -220,7 +229,33 @@ class Run implements Callable<Integer> {
 
             // automatic map github https urls to github resolver
             if (file.startsWith("https://github.com/")) {
-                file = mapGithubUrl(file);
+                String ext = FileUtil.onlyExt(file);
+                boolean wildcard = FileUtil.onlyName(file, false).contains("*");
+                if (ext != null && !wildcard) {
+                    // it is a single file so map to
+                    file = asGithubSingleUrl(file);
+                } else {
+                    StringJoiner files = new StringJoiner(",");
+                    StringJoiner kamelets = new StringJoiner(",");
+                    StringJoiner properties = new StringJoiner(",");
+                    fetchGithubUrls(file, files, kamelets, properties);
+
+                    if (files.length() > 0) {
+                        file = files.toString();
+                    }
+                    if (properties.length() > 0) {
+                        main.addInitialProperty("camel.component.properties.location", properties.toString());
+                    }
+                    if (kamelets.length() > 0) {
+                        String loc = main.getInitialProperties().getProperty("camel.component.kamelet.location");
+                        if (loc != null) {
+                            loc = loc + "," + kamelets;
+                        } else {
+                            loc = kamelets.toString();
+                        }
+                        main.addInitialProperty("camel.component.kamelet.location", loc);
+                    }
+                }
             }
 
             js.add(file);
@@ -253,7 +288,14 @@ class Run implements Callable<Integer> {
                 }
                 locations.append(file).append(",");
             }
-            main.addInitialProperty("camel.component.properties.location", locations.toString());
+            // there may be existing properties
+            String loc = main.getInitialProperties().getProperty("camel.component.properties.location");
+            if (loc != null) {
+                loc = loc + "," + locations;
+            } else {
+                loc = locations.toString();
+            }
+            main.addInitialProperty("camel.component.properties.location", loc);
         }
 
         System.out.println("Starting CamelJBang");
@@ -277,7 +319,7 @@ class Run implements Callable<Integer> {
         return lockFile;
     }
 
-    private static String mapGithubUrl(String url) {
+    private static String asGithubSingleUrl(String url) throws Exception {
         // strip https://github.com/
         url = url.substring(19);
         // https://github.com/apache/camel-k/blob/main/examples/languages/routes.kts
@@ -288,4 +330,89 @@ class Run implements Callable<Integer> {
         url = url.replaceFirst("/", ":");
         return "github:" + url;
     }
+
+    private static void fetchGithubUrls(String url, StringJoiner files, StringJoiner kamelets, StringJoiner properties)
+            throws Exception {
+        // this is a directory, so we need to query github which files are there and filter them
+
+        // URL: https://api.github.com/repos/apache/camel-k/contents/examples/kamelets/kameletbindings
+        // URL: https://api.github.com/repos/apache/camel-k/contents/examples/kamelets/kameletbindings?ref=v1.7.0
+        // https://github.com/apache/camel-k/tree/main/examples/kamelets/kameletbindings
+        // https://github.com/apache/camel-k/tree/v1.7.0/examples/kamelets/kameletbindings
+
+        // strip https://github.com/
+        url = url.substring(19);
+
+        String[] parts = url.split("/");
+        if (parts.length < 5) {
+            return;
+        }
+
+        String org = parts[0];
+        String repo = parts[1];
+        String action = parts[2];
+        String branch = parts[3];
+        String path;
+        String wildcard = null;
+        StringJoiner sj = new StringJoiner("/");
+        for (int i = 4; i < parts.length; i++) {
+            if (i == parts.length - 1) {
+                // last element uses wildcard to filter which files to include
+                if (parts[i].contains("*")) {
+                    wildcard = parts[i];
+                    break;
+                }
+            }
+            sj.add(parts[i]);
+        }
+        path = sj.toString();
+
+        if ("tree".equals(action)) {
+            // https://api.github.com/repos/apache/camel-k/contents/examples/kamelets/kameletbindings?ref=v1.7.0
+            url = "https://api.github.com/repos/" + org + "/" + repo + "/contents/" + path;
+            if (!"main".equals(branch) && !"master".equals(branch)) {
+                url = url + "?ref=" + branch;
+            }
+        }
+
+        downloadGithubFiles(url, wildcard, files, kamelets, properties);
+    }
+
+    private static void downloadGithubFiles(
+            String url, String wildcard, StringJoiner files, StringJoiner kamelets, StringJoiner properties)
+            throws Exception {
+
+        // use JDK http client to call github api
+        HttpClient hc = HttpClient.newHttpClient();
+        HttpResponse<String> res = hc.send(HttpRequest.newBuilder(new URI(url)).timeout(Duration.ofSeconds(20)).build(),
+                HttpResponse.BodyHandlers.ofString());
+
+        if (res.statusCode() == 200) {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode root = mapper.readTree(res.body());
+            for (JsonNode c : root) {
+                String name = c.get("name").asText();
+                String ext = FileUtil.onlyExt(name, false);
+                boolean match = wildcard == null || AntPathMatcher.INSTANCE.match(wildcard, name, false);
+                if (match) {
+                    if ("kamelet.yaml".equalsIgnoreCase(ext)) {
+                        String htmlUrl = c.get("html_url").asText();
+                        String u = asGithubSingleUrl(htmlUrl);
+                        kamelets.add(u);
+                    } else if ("properties".equalsIgnoreCase(ext)) {
+                        String htmlUrl = c.get("html_url").asText();
+                        String u = asGithubSingleUrl(htmlUrl);
+                        properties.add(u);
+                    } else if ("java".equalsIgnoreCase(ext) || "xml".equalsIgnoreCase(ext) || "yaml".equalsIgnoreCase(ext)
+                            || "groovy".equalsIgnoreCase(ext) || "js".equalsIgnoreCase(ext) || "jsh".equalsIgnoreCase(ext)
+                            || "kts".equalsIgnoreCase(ext)) {
+                        String htmlUrl = c.get("html_url").asText();
+                        String u = asGithubSingleUrl(htmlUrl);
+                        files.add(u);
+                    }
+                }
+            }
+        }
+    }
+
 }

[camel] 02/02: CAMEL-17280: camel-jbang - Run from github using wildcards

Posted by da...@apache.org.
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

commit a8ae278c66094c9dde0cf929b4bbd9f65b8d0d4b
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Jan 25 10:19:55 2022 +0100

    CAMEL-17280: camel-jbang - Run from github using wildcards
---
 .../modules/ROOT/pages/camel-jbang.adoc            | 48 ++++++++++++++++------
 1 file changed, 35 insertions(+), 13 deletions(-)

diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
index 76f8dbb..e380d51 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
@@ -13,7 +13,7 @@ It is not necessary to install Camel JBang. However, if you prefer to do so, JBa
 jbang app install camel@apache/camel
 ----
 
-*Note*: up to Camel 3.14, the app was named `CamelJBang`. From 3.15 and newer, the app is named `camel`. It is still possible to use the older name by installing it using `CamelJBang@apache/camel` but this approach is deprecated and should not be used in the future.
+NOTE: Up to Camel 3.14, the app was named `CamelJBang`. From 3.15 and newer, the app is named `camel`. It is still possible to use the older name by installing it using `CamelJBang@apache/camel` but this approach is deprecated and should not be used in the future.
 
 == Using Camel JBang
 
@@ -24,11 +24,11 @@ The CamelJBang supports multiple commands. Running the command below, will print
 jbang camel@apache/camel [command]
 ----
 
-*Note*: the first time you run this command, it may cause dependencies to be cached, therefore taking a few extra seconds to run.
+TIP: The first time you run this command, it may cause dependencies to be cached, therefore taking a few extra seconds to run.
 
 All the commands support the `--help` and will display the appropriate help if that flag is provided.
 
-However if you have installed CamelJBang with `jbang app install` then you can use `CamelJBang` instead of `jbang camel@apache/camel`
+However, if you have installed CamelJBang with `jbang app install` then you can use `CamelJBang` instead of `jbang camel@apache/camel`
 
 === Troubleshooting
 
@@ -77,7 +77,7 @@ Execute the following command to run this route:
 
 [source,bash]
 ----
-CamelJBang run jms-amqp-10-sink-binding.yaml
+camel run jms-amqp-10-sink-binding.yaml
 ----
 
 NOTE: it is necessary to have a AMQP 1.0 broker, such as Apache Artemis, running locally and listening on port 61616. Adjust the route accordingly if using a different address for the broker.
@@ -88,28 +88,28 @@ You can run more than 1 file, for example to run two YAML files you can do:
 
 [source,bash]
 ----
-CamelJBang run one.yaml two.yaml
+camel run one.yaml two.yaml
 ----
 
 You can also mix different xref:dsl.adoc[DSLs] such as yaml and Java:
 
 [source,bash]
 ----
-CamelJBang run one.yaml hello.java
+camel run one.yaml hello.java
 ----
 
 You can also use wildcards (i.e. `*`) to match multiple files, such as running all the yaml files:
 
 [source,bash]
 ----
-CamelJBang run *.yaml
+camel run *.yaml
 ----
 
 Or you can run all files starting with foo*
 
 [source,bash]
 ----
-CamelJBang run foo*
+camel run foo*
 ----
 
 TIP: The run goal can also detect files that are `properties`.
@@ -121,7 +121,7 @@ using the `--reload` options as shown:
 
 [source,bash]
 ----
-CamelJBang run jms-amqp-10-sink-binding.yaml --reload
+camel run jms-amqp-10-sink-binding.yaml --reload
 ----
 
 Then while the Camel application is running, you can update the YAML route and update when saving.
@@ -137,7 +137,29 @@ For example to run one of the Camel K examples you can do:
 
 [source,bash]
 ----
-CamelJBang run run github:apache:camel-k:examples/languages/routes.yaml
+camel run run github:apache:camel-k:examples/languages/routes.yaml
+----
+
+You can also use the `https` URL for GitHub. For example, you can browse the examples from a web-browser and
+then copy the URL from the browser window and run the example with Camel JBang:
+
+[source,bash]
+----
+camel run https://github.com/apache/camel-k/blob/main/examples/languages/routes.yaml
+----
+
+You can also use wildcards (i.e. `*`) to match multiple files, such as running all the groovy files:
+
+[source,bash]
+----
+camel run https://github.com/apache/camel-k/tree/main/examples/languages/*.groovy
+----
+
+Or you can run all files starting with rou*
+
+[source,bash]
+----
+camel run https://github.com/apache/camel-k/tree/main/examples/languages/rou*
 ----
 
 === Running local Kamelets
@@ -146,7 +168,7 @@ You can also use Camel JBang to try local Kamelets, without the need to publish
 
 [source,bash]
 ----
-CamelJBang run --local-kamelet-dir=/path/to/local/kamelets earthquake.yaml
+camel run --local-kamelet-dir=/path/to/local/kamelets earthquake.yaml
 ----
 
 === Running Camel K integrations or bindings
@@ -179,11 +201,11 @@ spec:
       show-headers: false
 ----
 
-Can be run with CamelJBang:
+Can be run with camel:
 
 [source,bash]
 ----
-CamelJBang run joke.yaml
+camel run joke.yaml
 ----
 
 === Using platform-http component