This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch version-list in repository https://gitbox.apache.org/repos/asf/camel.git
commit 7a18a461f198a3ca43fd4d3360e5f61850c307f0 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Mon Mar 13 09:55:47 2023 +0100 CAMEL-19128: camel-jbang - Add version command --- .../jbang/core/commands/version/VersionList.java | 39 +++++---- .../camel/main/download/DependencyDownloader.java | 7 +- .../main/download/MavenDependencyDownloader.java | 97 ++++++++++++++++++++-- .../org/apache/camel/main/util/VersionHelper.java | 86 +++++++++++++++++++ 4 files changed, 201 insertions(+), 28 deletions(-) diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/version/VersionList.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/version/VersionList.java index 7e6ab2be88c..0c9a85f76de 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/version/VersionList.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/version/VersionList.java @@ -23,6 +23,7 @@ import java.util.stream.Collectors; import com.github.freva.asciitable.AsciiTable; import com.github.freva.asciitable.Column; +import com.github.freva.asciitable.HorizontalAlign; import org.apache.camel.dsl.jbang.core.commands.CamelCommand; import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain; import org.apache.camel.dsl.jbang.core.common.RuntimeCompletionCandidates; @@ -35,7 +36,6 @@ import picocli.CommandLine; public class VersionList extends CamelCommand { private static final String MINIMUM_VERSION = "3.14.0"; - private static final String MINIMUM_QUARKUS_VERSION = "2.13.0"; // TODO: Filter for minimum camel version // TODO: grab Q and SB runtime version @@ -46,11 +46,14 @@ public class VersionList extends CamelCommand { @CommandLine.Option(names = { "--runtime" }, completionCandidates = RuntimeCompletionCandidates.class, description = "Runtime (spring-boot, quarkus, or camel-main)") - protected String runtime; + String runtime; @CommandLine.Option(names = { "--repo", "--repos" }, description = "Maven repository for downloading available versions") String repo; + @CommandLine.Option(names = { "--fresh" }, description = "Make sure we use fresh (i.e. non-cached) resources") + boolean fresh; + public VersionList(CamelJBangMain main) { super(main); } @@ -60,8 +63,10 @@ public class VersionList extends CamelCommand { configureLoggingOff(); KameletMain main = new KameletMain(); - List<String> versions; + List<String[]> versions; try { + main.setFresh(fresh); + main.setRepos(repo); main.start(); // use kamelet-main to download from maven @@ -77,8 +82,8 @@ public class VersionList extends CamelCommand { a = "camel-quarkus-catalog"; } - versions = downloader.downloadAvailableVersions(g, a, repo); - versions = versions.stream().filter(this::acceptVersion).collect(Collectors.toList()); + versions = downloader.resolveAvailableVersions(g, a, repo); + versions = versions.stream().filter(v -> acceptVersion(v[0])).collect(Collectors.toList()); main.stop(); } catch (Exception e) { @@ -87,20 +92,23 @@ public class VersionList extends CamelCommand { } List<Row> rows = new ArrayList<>(); - for (String v : versions) { + for (String[] v : versions) { Row row = new Row(); rows.add(row); - row.coreVersion = v; + row.coreVersion = v[0]; + row.runtimeVersion = v[1]; } // sort rows rows.sort(this::sortRow); System.out.println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( - new Column().header("QUARKUS VERSION").visible("quarkus".equalsIgnoreCase(runtime)).with(r -> r.runtimeVersion), - new Column().header("SPRING BOOT VERSION").visible("spring-boot".equalsIgnoreCase(runtime)) - .with(r -> r.runtimeVersion), - new Column().header("CAMEL VERSION").with(r -> r.coreVersion)))); + new Column().header("QUARKUS").visible("quarkus".equalsIgnoreCase(runtime)) + .headerAlign(HorizontalAlign.CENTER).dataAlign(HorizontalAlign.CENTER).with(r -> r.runtimeVersion), + new Column().header("SPRING-BOOT").visible("spring-boot".equalsIgnoreCase(runtime)) + .headerAlign(HorizontalAlign.CENTER).dataAlign(HorizontalAlign.CENTER).with(r -> r.runtimeVersion), + new Column().header("CAMEL VERSION") + .headerAlign(HorizontalAlign.CENTER).dataAlign(HorizontalAlign.CENTER).with(r -> r.coreVersion)))); return 0; } @@ -123,16 +131,15 @@ public class VersionList extends CamelCommand { } private boolean acceptVersion(String version) { - String min = MINIMUM_VERSION; - if ("quarkus".equalsIgnoreCase(runtime)) { - min = MINIMUM_QUARKUS_VERSION; + if (version == null) { + return false; } - return VersionHelper.isGE(version, min); + return VersionHelper.isGE(version, MINIMUM_VERSION); } private static class Row { - String runtimeVersion; String coreVersion; + String runtimeVersion; } } diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloader.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloader.java index ccab96ea85f..bb8f94572ab 100644 --- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloader.java +++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/DependencyDownloader.java @@ -123,14 +123,15 @@ public interface DependencyDownloader extends CamelContextAware, StaticService { MavenArtifact downloadArtifact(String groupId, String artifactId, String version); /** - * Downloads the available versions for the given maven artifact + * Resolves the available versions for the given maven artifact * * @param groupId maven group id * @param artifactId maven artifact id * @param repo to use specific maven repository instead of maven central - * @return list of versions of the given artifact + * @return list of versions of the given artifact (0=camel-core version, 1=runtime version, such as + * spring-boot or quarkus) */ - List<String> downloadAvailableVersions(String groupId, String artifactId, String repo); + List<String[]> resolveAvailableVersions(String groupId, String artifactId, String repo); /** * Checks whether the dependency is already on the classpath diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MavenDependencyDownloader.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MavenDependencyDownloader.java index 362c52e82e1..972d0a3fe12 100644 --- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MavenDependencyDownloader.java +++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/MavenDependencyDownloader.java @@ -47,6 +47,7 @@ import org.w3c.dom.NodeList; import org.apache.camel.CamelContext; import org.apache.camel.CamelContextAware; import org.apache.camel.main.injection.DIRegistry; +import org.apache.camel.main.util.VersionHelper; import org.apache.camel.main.util.XmlHelper; import org.apache.camel.support.service.ServiceHelper; import org.apache.camel.support.service.ServiceSupport; @@ -225,6 +226,9 @@ public class MavenDependencyDownloader extends ServiceSupport implements Depende private static final Logger LOG = LoggerFactory.getLogger(MavenDependencyDownloader.class); private static final String CP = System.getProperty("java.class.path"); + private static final String MINIMUM_CAMEL_VERSION = "3.14.0"; + private static final String MINIMUM_QUARKUS_VERSION = "2.13.0"; + private static final RepositoryPolicy POLICY_DEFAULT = new RepositoryPolicy( true, RepositoryPolicy.UPDATE_POLICY_NEVER, RepositoryPolicy.CHECKSUM_POLICY_WARN); private static final RepositoryPolicy POLICY_FRESH = new RepositoryPolicy( @@ -465,7 +469,7 @@ public class MavenDependencyDownloader extends ServiceSupport implements Depende } @Override - public List<String> downloadAvailableVersions(String groupId, String artifactId, String repo) { + public List<String[]> resolveAvailableVersions(String groupId, String artifactId, String repo) { String gav = groupId + ":" + artifactId; LOG.debug("DownloadAvailableVersions: {}", gav); @@ -477,11 +481,7 @@ public class MavenDependencyDownloader extends ServiceSupport implements Depende repository = extra.get(0); } } - List<String> versions = resolveAvailableVersions(groupId, artifactId, repository); - if (LOG.isDebugEnabled()) { - LOG.debug("DownloadAvailableVersions {} -> [{}]", gav, versions); - } - + List<String[]> versions = resolveAvailableVersions(groupId, artifactId, repository); return versions; } @@ -1323,10 +1323,10 @@ public class MavenDependencyDownloader extends ServiceSupport implements Depende } } - public List<String> resolveAvailableVersions( + public List<String[]> resolveAvailableVersions( String groupId, String artifactId, RemoteRepository repository) { - List<String> answer = new ArrayList<>(); + List<String[]> answer = new ArrayList<>(); try { MetadataRequest ar = new MetadataRequest(); @@ -1347,13 +1347,28 @@ public class MavenDependencyDownloader extends ServiceSupport implements Depende Element node = (Element) nl.item(i); String v = node.getTextContent(); if (v != null) { - answer.add(v); + if ("camel-catalog-provider-springboot".equals(artifactId)) { + String sbv = null; + if (VersionHelper.isGE(v, MINIMUM_CAMEL_VERSION)) { + sbv = resolveSpringBootVersionByCamelVersion(v, repository); + } + answer.add(new String[] { v, sbv }); + } else if ("camel-quarkus-catalog".equals(artifactId)) { + String cv = null; + if (VersionHelper.isGE(v, MINIMUM_QUARKUS_VERSION)) { + cv = resolveCamelVersionByQuarkusVersion(v, repository); + } + answer.add(new String[] { cv, v }); + } else { + answer.add(new String[] { v, null }); + } } } } } } } catch (Exception e) { + e.printStackTrace(); // TODO: String msg = "Cannot resolve available versions in " + repository.getUrl(); throw new DownloadException(msg, e); } @@ -1361,6 +1376,70 @@ public class MavenDependencyDownloader extends ServiceSupport implements Depende return answer; } + private String resolveCamelVersionByQuarkusVersion(String quarkusVersion, RemoteRepository repository) throws Exception { + String gav = "org.apache.camel.quarkus" + ":" + "camel-quarkus" + ":pom:" + quarkusVersion; + // always include maven central + List<RemoteRepository> repos; + if (repository == remoteRepositories.get(0)) { + repos = List.of(repository); + } else { + repos = List.of(remoteRepositories.get(0), repository); + } + List<MavenArtifact> artifacts = resolveDependenciesViaAether(List.of(gav), repos, false); + if (!artifacts.isEmpty()) { + MavenArtifact ma = artifacts.get(0); + if (ma != null && ma.getFile() != null) { + String name = ma.getFile().getAbsolutePath(); + File file = new File(name); + if (file.exists()) { + DocumentBuilderFactory dbf = XmlHelper.createDocumentBuilderFactory(); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document dom = db.parse(file); + // the camel version is in <parent> + NodeList nl = dom.getElementsByTagName("parent"); + if (nl.getLength() == 1) { + Element node = (Element) nl.item(0); + return node.getElementsByTagName("version").item(0).getTextContent(); + } + } + } + } + + return null; + } + + private String resolveSpringBootVersionByCamelVersion(String camelVersion, RemoteRepository repository) throws Exception { + String gav = "org.apache.camel.springboot" + ":" + "spring-boot" + ":pom:" + camelVersion; + // always include maven central + List<RemoteRepository> repos; + if (repository == remoteRepositories.get(0)) { + repos = List.of(repository); + } else { + repos = List.of(remoteRepositories.get(0), repository); + } + List<MavenArtifact> artifacts = resolveDependenciesViaAether(List.of(gav), repos, false); + if (!artifacts.isEmpty()) { + MavenArtifact ma = artifacts.get(0); + if (ma != null && ma.getFile() != null) { + String name = ma.getFile().getAbsolutePath(); + File file = new File(name); + if (file.exists()) { + DocumentBuilderFactory dbf = XmlHelper.createDocumentBuilderFactory(); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document dom = db.parse(file); + // the camel version is in <properties> + NodeList nl = dom.getElementsByTagName("properties"); + if (nl.getLength() > 0) { + Element node = (Element) nl.item(0); + return node.getElementsByTagName("spring-boot-version").item(0).getTextContent(); + } + } + } + } + + return null; + } + private static class AcceptAllDependencyFilter implements DependencyFilter { @Override public boolean accept(DependencyNode node, List<DependencyNode> parents) { diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/util/VersionHelper.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/util/VersionHelper.java new file mode 100644 index 00000000000..5ada3e4c766 --- /dev/null +++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/util/VersionHelper.java @@ -0,0 +1,86 @@ +/* + * 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.main.util; + +import org.apache.camel.util.StringHelper; + +public final class VersionHelper { + + private VersionHelper() { + } + + public static boolean isGE(String source, String target) { + return compare(source, target) >= 0; + } + + public static int compare(String source, String target) { + if (source == null || target == null) { + return 0; + } + String s1 = StringHelper.before(source, "."); + String s2 = StringHelper.after(source, "."); + if (s1 == null) { + s1 = StringHelper.before(source, ","); + s2 = StringHelper.after(source, ","); + } + String t1 = StringHelper.before(target, "."); + String t2 = StringHelper.after(target, "."); + if (t1 == null) { + t1 = StringHelper.before(target, ","); + t2 = StringHelper.after(target, ","); + } + String s3 = StringHelper.after(s2, "."); + if (s3 != null) { + s2 = StringHelper.before(s2, "."); + } else { + s3 = ""; + } + String t3 = StringHelper.after(t2, "."); + if (t3 != null) { + t2 = StringHelper.before(t2, "."); + } else { + t3 = ""; + } + // convert to 2-digit numbers + if (s1.length() < 2) { + s1 = "0" + s1; + } + if (s2.length() < 2) { + s2 = "0" + s2; + } + if (s2.length() < 2) { + s2 = "0" + s2; + } + if (s3.length() < 2) { + s3 = "0" + s3; + } + if (t1.length() < 2) { + t1 = "0" + t1; + } + if (t2.length() < 2) { + t2 = "0" + t2; + } + if (t3.length() < 2) { + t3 = "0" + t3; + } + + String s = s1 + s2 + s3; + String t = t1 + t2 + t3; + return s.compareTo(t); + } + +}