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 b6871876d71cd8299a79d94b5ec8b7b64962bfc4 Author: Claus Ibsen <[email protected]> AuthorDate: Thu Apr 21 13:27:53 2022 +0200 CAMEL-17998: camel-jbang - fat-jar command --- .../dsl/jbang/core/commands/CamelJBangMain.java | 2 + .../dsl/jbang/core/commands/DependencyTree.java | 72 ++++++++++++++++ .../camel/dsl/jbang/core/commands/FarJar.java | 98 ++++++++++++++++++++++ .../apache/camel/dsl/jbang/core/commands/Run.java | 18 ++++ 4 files changed, 190 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 c3b671af9ad..57a4c2d0ed8 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 @@ -37,6 +37,8 @@ public class CamelJBangMain implements Callable<Integer> { .addSubcommand("languages", new SearchLanguages()) .addSubcommand("others", new SearchOthers())) .addSubcommand("create", new CommandLine(new Create()) + .addSubcommand("fat-jar", new FarJar()) + .addSubcommand("dependency-tree", new DependencyTree()) .addSubcommand("project", new Project())) .addSubcommand("generate", new CommandLine(new CodeGenerator()) .addSubcommand("rest", new CodeRestGenerator())); diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyTree.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyTree.java new file mode 100644 index 00000000000..54cd9bd85ca --- /dev/null +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/DependencyTree.java @@ -0,0 +1,72 @@ +/* + * 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.io.File; +import java.net.URI; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; + +import groovy.grape.Grape; +import groovy.lang.GroovyClassLoader; +import org.apache.camel.main.KameletMain; +import org.apache.camel.main.MavenGav; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; + +@Command(name = "dependency-tree", description = "Displays the dependency tree") +@Deprecated +class DependencyTree implements Callable<Integer> { + + //CHECKSTYLE:OFF + @Option(names = { "-h", "--help" }, usageHelp = true, description = "Display the help and sub-commands") + private boolean helpRequested = false; + //CHECKSTYLE:ON + + @Override + public Integer call() throws Exception { + File file = new File(Run.DEPENDENCY_FILE); + if (!file.exists()) { + System.out.println("Run Camel first to generate dependency file"); + return 0; + } + + ClassLoader parentCL = KameletMain.class.getClassLoader(); + final GroovyClassLoader gcl = new GroovyClassLoader(parentCL); + final List<String> lines = Files.readAllLines(file.toPath()); + for (String l : lines) { + MavenGav gav = MavenGav.parseGav(null, l); + + Map<String, Object> map = new HashMap<>(); + map.put("classLoader", gcl); + map.put("group", gav.getGroupId()); + map.put("module", gav.getArtifactId()); + map.put("version", gav.getVersion()); + map.put("classifier", ""); + + URI[] u = Grape.resolve(map, map); + System.out.println(Arrays.asList(u)); + } + + return 0; + } + +} diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/FarJar.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/FarJar.java new file mode 100644 index 00000000000..07b189026c7 --- /dev/null +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/FarJar.java @@ -0,0 +1,98 @@ +/* + * 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.io.File; +import java.net.URI; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.Callable; + +import groovy.grape.Grape; +import groovy.lang.GroovyClassLoader; +import org.apache.camel.main.KameletMain; +import org.apache.camel.main.MavenGav; +import org.apache.camel.util.FileUtil; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; + +@Command(name = "fat-jar", description = "Package application as a single fat-jar") +class FarJar implements Callable<Integer> { + + //CHECKSTYLE:OFF + @Option(names = { "-h", "--help" }, usageHelp = true, description = "Display the help and sub-commands") + private boolean helpRequested = false; + //CHECKSTYLE:ON + + @Override + public Integer call() throws Exception { + File file = new File(Run.DEPENDENCY_FILE); + if (!file.exists()) { + System.out.println("Run Camel first to generate dependency file"); + return 0; + } + + File target = new File("target/camel-app/lib"); + FileUtil.removeDir(target); + target.mkdirs(); + + // resolve all the needed dependencies + ClassLoader parentCL = KameletMain.class.getClassLoader(); + final GroovyClassLoader gcl = new GroovyClassLoader(parentCL); + + List<String> lines = Files.readAllLines(file.toPath()); + + // include camel-kamelet-main as its a core dependency needed + Optional<MavenGav> first = lines.stream() + .map(l -> MavenGav.parseGav(null, l)) + .filter(g -> "org.apache.camel".equals(g.getGroupId())) + .findFirst(); + if (first.isPresent()) { + String v = first.get().getVersion(); + lines.add(0, "mvn:org.apache.camel:camel-kamelet-main:" + v); + } + + for (String l : lines) { + MavenGav gav = MavenGav.parseGav(null, l); + Map<String, Object> map = new HashMap<>(); + map.put("classLoader", gcl); + map.put("group", gav.getGroupId()); + map.put("module", gav.getArtifactId()); + map.put("version", gav.getVersion()); + map.put("classifier", ""); + + URI[] u = Grape.resolve(map, map); + copyJars(u, target); + } + + return 0; + } + + private void copyJars(URI[] uris, File target) throws Exception { + for (URI u : uris) { + File f = new File(u.toURL().getFile()); + File out = new File(target, f.getName()); + if (!out.exists()) { + Files.copy(f.toPath(), out.toPath()); + } + } + } + +} 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 cb4c6f75cc5..9faa9e29a5c 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 @@ -17,7 +17,9 @@ package org.apache.camel.dsl.jbang.core.commands; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.FileSystems; import java.util.Arrays; import java.util.Locale; @@ -32,6 +34,7 @@ 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.FileUtil; +import org.apache.camel.util.IOHelper; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.StringHelper; import picocli.CommandLine.Command; @@ -44,6 +47,8 @@ import static org.apache.camel.dsl.jbang.core.commands.GitHubHelper.fetchGithubU @Command(name = "run", description = "Run Camel") class Run implements Callable<Integer> { + public static final String DEPENDENCY_FILE = ".camel-jbang-runtime-dependency-tree.yaml"; + private static final String[] ACCEPTED_FILE_EXT = new String[] { "properties", "java", "groovy", "js", "jsh", "kts", "xml", "yaml" }; @@ -170,6 +175,17 @@ class Run implements Callable<Integer> { } else { main = new KameletMain("file://" + localKameletDir); } + + final FileOutputStream fos = new FileOutputStream(DEPENDENCY_FILE, false); + main.setDownloadListener((groupId, artifactId, version) -> { + String line = "mvn:" + groupId + ":" + artifactId + ":" + version; + try { + fos.write(line.getBytes(StandardCharsets.UTF_8)); + fos.write(System.lineSeparator().getBytes(StandardCharsets.UTF_8)); + } catch (Exception e) { + // ignore + } + }); main.setAppName("Apache Camel (JBang)"); main.addInitialProperty("camel.main.name", name); @@ -384,6 +400,8 @@ class Run implements Callable<Integer> { main.run(); + IOHelper.close(fos); + int code = main.getExitCode(); return code; }
