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
The following commit(s) were added to refs/heads/main by this push:
new ea48e37e5838 (#29353)
ea48e37e5838 is described below
commit ea48e37e5838c787c40c1481389e5eb67613429c
Author: Serdar Gökay <[email protected]>
AuthorDate: Sat Nov 7 10:00:48 2026 +0300
(#29353)
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Co-Authored-By: Claude Opus 5 <[email protected]>
---
.../camel/dsl/jbang/core/commands/ExportTest.java | 137 +++++++++++++++++++--
.../resources/golden/expected/options.export.txt | 2 -
.../camel/dsl/jbang/run/common/ExportHelper.java | 25 ++++
.../dsl/jbang/run/export/CamelMainExporter.java | 10 +-
.../camel/dsl/jbang/run/export/Exporter.java | 53 +++++++-
.../dsl/jbang/run/export/QuarkusExporter.java | 6 +-
.../dsl/jbang/run/export/SpringBootExporter.java | 15 ++-
.../dsl/jbang/run/common/ExportHelperTest.java | 33 +++++
8 files changed, 254 insertions(+), 27 deletions(-)
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java
index e5ea17857398..e816a81a103f 100644
---
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java
+++
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java
@@ -43,6 +43,7 @@ import org.apache.maven.model.Repository;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@@ -1558,11 +1559,13 @@ class ExportTest {
}
}
- @Test
- void shouldNotDuplicateMetricsDependency() throws Exception {
+ @ParameterizedTest
+ @ValueSource(strings = { "camel.metrics.enabled",
"camel.management.metricsEnabled", "camel.server.metricsEnabled" })
+ void shouldNotDuplicateMetricsDependency(String metricsOption) throws
Exception {
+ LOG.info("shouldNotDuplicateMetricsDependency {}", metricsOption);
File profile = new File(".", "application.properties");
try {
- Files.writeString(profile.toPath(),
"camel.management.metricsEnabled=true\n");
+ Files.writeString(profile.toPath(), metricsOption + "=true\n");
Export command = new Export(new CamelJBangMain());
CommandLineTestHelper.parse(command,
@@ -1574,17 +1577,133 @@ class ExportTest {
assertThat(exit).isEqualTo(0);
Model model = readMavenModel();
- long count = model.getDependencies().stream()
- .filter(d ->
"camel-micrometer-prometheus".equals(d.getArtifactId()))
- .count();
- assertThat(count)
- .as("camel-micrometer-prometheus should appear exactly
once")
- .isEqualTo(1);
+
assertThat(model.getDependencies()).extracting(Dependency::getArtifactId)
+ .as("the metrics option adds camel-micrometer-prometheus")
+ .contains("camel-micrometer-prometheus");
+ assertEachArtifactOnce(model);
+ } finally {
+ FileUtil.deleteFile(profile);
+ }
+ }
+
+ @ParameterizedTest
+ @MethodSource("runtimeProvider")
+ void shouldNotDuplicateConsoleDependencies(RuntimeType rt) throws
Exception {
+ LOG.info("shouldNotDuplicateConsoleDependencies {}", rt);
+ File profile = new File(".", "application.properties");
+ try {
+ // a project that has the console options itself, exported with
--console: the dependencies of the
+ // console are added for the options and for the flag
+ Files.writeString(profile.toPath(), """
+ camel.management.devConsoleEnabled=true
+ camel.management.healthCheckEnabled=true
+ camel.management.jolokiaEnabled=true
+ """);
+ int exit = exportWithConsole(rt);
+
+ assertThat(exit).isEqualTo(0);
+ Model model = readMavenModel();
+
+ assertConsoleDependencies(model, rt);
+ assertEachArtifactOnce(model);
} finally {
FileUtil.deleteFile(profile);
}
}
+ private static Stream<Arguments> consoleArtifactProvider() {
+ Stream.Builder<Arguments> builder = Stream.builder();
+ builder.add(Arguments.of(RuntimeType.quarkus,
"org.apache.camel.quarkus", "camel-quarkus-console"));
+ // camel-spring-boot 4.19+ requires JDK 21 (Spring Boot 4)
+ if (Runtime.version().feature() >= 21) {
+ builder.add(Arguments.of(RuntimeType.springBoot,
"org.apache.camel.springboot", "camel-console-starter"));
+ }
+ return builder.build();
+ }
+
+ @ParameterizedTest
+ @MethodSource("consoleArtifactProvider")
+ void shouldNotDuplicateConsoleDependencyGivenAsRuntimeArtifact(RuntimeType
rt, String groupId, String artifactId)
+ throws Exception {
+ LOG.info("shouldNotDuplicateConsoleDependencyGivenAsRuntimeArtifact
{}", rt);
+ // --console adds org.apache.camel:camel-console, which the runtime
maps to its own artifact: the same artifact
+ // as the --dep names, with other coordinates before the mapping
+ int exit = exportWithConsole(rt, "--dep=" + groupId + ":" +
artifactId);
+
+ assertThat(exit).isEqualTo(0);
+ Model model = readMavenModel();
+
+
assertThat(model.getDependencies()).extracting(Dependency::getArtifactId)
+ .contains(artifactId);
+ assertEachArtifactOnce(model);
+ }
+
+ @Test
+ void shouldKeepTheRunControllerOutWhenPlatformHttpIsGivenInAnyNotation()
throws Exception {
+
LOG.info("shouldKeepTheRunControllerOutWhenPlatformHttpIsGivenInAnyNotation");
+ // camel-spring-boot 4.19+ requires JDK 21 (Spring Boot 4), as
runtimeProvider has it
+ Assumptions.assumeTrue(Runtime.version().feature() >= 21,
"camel-spring-boot requires JDK 21");
+
+ File profile = new File(".", "application.properties");
+ try {
+ // a profile, so the exported project has an
application.properties to read
+ Files.writeString(profile.toPath(),
"camel.main.name=platform-http-demo\n");
+
+ // --dep=camel-platform-http becomes camel:platform-http, and it
is the HTTP server of the exported
+ // project, so the run controller is not needed to keep it alive
+ Export command = new Export(new CamelJBangMain());
+ CommandLineTestHelper.parse(command,
+ "--gav=examples:route:1.0.0", "--dir=" + workingDir,
"--quiet",
+ "--runtime=spring-boot", "--camel-version=" +
RELEASED_CAMEL_VERSION,
+ CamelCommandBaseTestSupport.quarkusExtRegistry(),
+ "--dep=camel-platform-http",
+ "src/test/resources/route.yaml");
+ int exit = command.doCall();
+
+ assertThat(exit).isEqualTo(0);
+ Properties props =
loadExportedProperties("application.properties");
+ assertThat(exportedProperty(props, "camel.main.run-controller"))
+ .as("the export has an HTTP server of its own")
+ .isNull();
+ assertEachArtifactOnce(readMavenModel());
+ } finally {
+ FileUtil.deleteFile(profile);
+ }
+ }
+
+ @Test
+ void shouldReplacePlatformHttpInAnyNotation() throws Exception {
+ LOG.info("shouldReplacePlatformHttpInAnyNotation");
+ // --dep=camel-platform-http becomes camel:platform-http, which the
camel-main runtime replaces with
+ // camel-platform-http-main as well: the runtime exporter sees the
dependencies before the duplicates are
+ // removed, so it compares artifacts and not dependency strings
+ Export command = new Export(new CamelJBangMain());
+ CommandLineTestHelper.parse(command,
+ "--gav=examples:route:1.0.0", "--dir=" + workingDir, "--quiet",
+ "--runtime=camel-main",
+ "--dep=camel-platform-http",
+ "src/test/resources/route.yaml");
+ int exit = command.doCall();
+
+ assertThat(exit).isEqualTo(0);
+ Model model = readMavenModel();
+
+
assertThat(model.getDependencies()).extracting(Dependency::getArtifactId)
+ .contains("camel-platform-http-main")
+ .doesNotContain("camel-platform-http",
"camel-platform-http-vertx");
+ assertEachArtifactOnce(model);
+ }
+
+ /**
+ * A pom.xml may name an artifact only once: Maven 3.10 onwards fails the
build of a project that names one twice.
+ */
+ private static void assertEachArtifactOnce(Model model) {
+ assertThat(model.getDependencies())
+ .extracting(d -> d.getGroupId() + ":" + d.getArtifactId())
+ .as("each artifact is named once in the exported pom.xml")
+ .doesNotHaveDuplicates();
+ }
+
@Test
void shouldOverrideAutoDetectedDriverVersion() throws Exception {
LOG.info("shouldOverrideAutoDetectedDriverVersion");
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/test/resources/golden/expected/options.export.txt
b/dsl/camel-jbang/camel-jbang-core/src/test/resources/golden/expected/options.export.txt
index f8e5da614207..bea6226d1990 100644
---
a/dsl/camel-jbang/camel-jbang-core/src/test/resources/golden/expected/options.export.txt
+++
b/dsl/camel-jbang/camel-jbang-core/src/test/resources/golden/expected/options.export.txt
@@ -63,8 +63,6 @@ dependency org.apache.camel:camel-micrometer-prometheus
dependency org.apache.camel:camel-observability-services
dependency org.apache.camel:camel-opentelemetry2
dependency org.apache.camel:camel-platform-http-jolokia
-dependency org.apache.camel:camel-platform-http-jolokia
-dependency org.apache.camel:camel-platform-http-main
dependency org.apache.camel:camel-platform-http-main
dependency org.apache.camel:camel-timer
dependency org.apache.camel:camel-yaml-dsl
diff --git
a/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/common/ExportHelper.java
b/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/common/ExportHelper.java
index f42c63621d0a..03c8acb5d7ff 100644
---
a/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/common/ExportHelper.java
+++
b/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/common/ExportHelper.java
@@ -216,6 +216,31 @@ public final class ExportHelper {
return sb.toString();
}
+ /**
+ * Keeps a single dependency per groupId:artifactId in the dependencies of
a pom.xml, which may name an artifact
+ * only once (Maven 3.10 onwards fails the build of a project that names
one twice). Two dependencies with other
+ * coordinates become the same artifact through the mapping of a runtime:
{@code org.apache.camel:camel-console} and
+ * {@code org.apache.camel.quarkus:camel-quarkus-console} are the same
artifact of the Quarkus runtime. The first is
+ * kept, in its position, except that a dependency with a version wins
over one without: the mapping of a runtime
+ * leaves the version of its own artifacts to the BOM, so the coordinates
a user gave with a version survive it.
+ */
+ public static void removeDuplicateArtifacts(List<MavenGav> gavs) {
+ Map<String, MavenGav> kept = new LinkedHashMap<>();
+ for (MavenGav gav : gavs) {
+ String ga = gav.getGroupId() + ":" + gav.getArtifactId();
+ MavenGav existing = kept.get(ga);
+ if (existing == null || (!hasVersion(existing) &&
hasVersion(gav))) {
+ kept.put(ga, gav);
+ }
+ }
+ gavs.clear();
+ gavs.addAll(kept.values());
+ }
+
+ private static boolean hasVersion(MavenGav gav) {
+ return gav.getVersion() != null && !gav.getVersion().isBlank();
+ }
+
public static Comparator<MavenGav> mavenGavComparator() {
return new Comparator<MavenGav>() {
@Override
diff --git
a/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/export/CamelMainExporter.java
b/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/export/CamelMainExporter.java
index ff547c2bcf47..8a673b9514e8 100644
---
a/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/export/CamelMainExporter.java
+++
b/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/export/CamelMainExporter.java
@@ -307,8 +307,8 @@ class CamelMainExporter extends Exporter {
}
@Override
- protected Set<String> resolveDependencies(Path settings, Path profile)
throws Exception {
- Set<String> answer = super.resolveDependencies(settings, profile);
+ protected Set<String> doResolveDependencies(Path settings, Path profile)
throws Exception {
+ Set<String> answer = super.doResolveDependencies(settings, profile);
// remove out of the box dependencies
answer.removeIf(s -> s.contains("camel-core"));
@@ -341,7 +341,7 @@ class CamelMainExporter extends Exporter {
answer.add("mvn:org.apache.camel:camel-platform-http-jolokia");
}
- boolean main = answer.stream().anyMatch(s ->
s.contains("mvn:org.apache.camel:camel-platform-http-main"));
+ boolean main = hasCamelArtifact(answer, "camel-platform-http-main");
if (hasOpenapi(answer) && !main) {
// include http server if using openapi
answer.add("mvn:org.apache.camel:camel-platform-http-main");
@@ -352,8 +352,8 @@ class CamelMainExporter extends Exporter {
main = true;
}
if (main) {
- answer.removeIf(s ->
s.contains("org.apache.camel:camel-platform-http:"));
- answer.removeIf(s ->
s.contains("org.apache.camel:camel-platform-http-vertx:"));
+ removeCamelArtifact(answer, "camel-platform-http");
+ removeCamelArtifact(answer, "camel-platform-http-vertx");
}
return answer;
diff --git
a/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/export/Exporter.java
b/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/export/Exporter.java
index 6960df98d326..c7b0f4cb9a52 100644
---
a/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/export/Exporter.java
+++
b/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/export/Exporter.java
@@ -160,6 +160,8 @@ abstract class Exporter {
gavs.add(gav);
}
+ ExportHelper.removeDuplicateArtifacts(gavs);
+
// sort artifacts
gavs.sort(ExportHelper.mavenGavComparator());
@@ -243,7 +245,24 @@ abstract class Exporter {
return context;
}
- protected Set<String> resolveDependencies(Path settings, Path profile)
throws Exception {
+ /**
+ * The dependencies of the exported project, with a single one per
groupId:artifactId, whatever notation each of
+ * them uses, as a pom.xml may name an artifact only once (Maven 3.10
onwards fails the build when it does).
+ */
+ protected final Set<String> resolveDependencies(Path settings, Path
profile) throws Exception {
+ Set<String> answer = doResolveDependencies(settings, profile);
+ removeDuplicateDependencies(answer);
+ return answer;
+ }
+
+ /**
+ * Collects the dependencies of the exported project. A runtime exporter
adds its own dependencies by overriding
+ * this method and calling super first. The duplicates are removed
afterwards by
+ * {@link #resolveDependencies(Path, Path)}, as the same artifact can be
named in another notation
+ * ({@code camel:micrometer-prometheus} and {@code
mvn:org.apache.camel:camel-micrometer-prometheus:4.23.0} are the
+ * same artifact).
+ */
+ protected Set<String> doResolveDependencies(Path settings, Path profile)
throws Exception {
Set<String> answer = new TreeSet<>((o1, o2) -> {
// favour org.apache.camel first
boolean c1 = o1.contains("org.apache.camel:");
@@ -446,9 +465,15 @@ abstract class Exporter {
}
GenAiDependencyHelper.addAiObservabilityIfNeeded(answer,
exportProperties, request.observe);
- // remove duplicate versions (keep first) but an explicit --dep
version always wins over
- // an auto-detected dependency for the same groupId:artifactId (e.g. a
JDBC driver whose
- // version is inferred from the camel-dependencies BOM)
+ return answer;
+ }
+
+ /**
+ * Keeps a single dependency per groupId:artifactId (the first), whatever
notation each of them uses, but an
+ * explicit --dep version always wins over an auto-detected dependency for
the same groupId:artifactId (e.g. a JDBC
+ * driver whose version is inferred from the camel-dependencies BOM).
+ */
+ private void removeDuplicateDependencies(Set<String> answer) {
Set<String> preferred = new HashSet<>();
for (String d : request.dependencies) {
String line = normalizeDependency(d);
@@ -474,8 +499,26 @@ abstract class Exporter {
}
}
answer.removeAll(toBeRemoved);
+ }
- return answer;
+ /**
+ * Whether the dependencies name the given {@code org.apache.camel}
artifact, in any of the notations they use
+ * ({@code camel:platform-http} and {@code
mvn:org.apache.camel:camel-platform-http:4.23.0} are the same artifact).
+ */
+ protected static boolean hasCamelArtifact(Set<String> deps, String
artifactId) {
+ return deps.stream().anyMatch(d -> isCamelArtifact(d, artifactId));
+ }
+
+ /**
+ * Removes the given {@code org.apache.camel} artifact from the
dependencies, in any of the notations they use.
+ */
+ protected static void removeCamelArtifact(Set<String> deps, String
artifactId) {
+ deps.removeIf(d -> isCamelArtifact(d, artifactId));
+ }
+
+ private static boolean isCamelArtifact(String dep, String artifactId) {
+ MavenGav gav = MavenGav.parseGav(dep);
+ return "org.apache.camel".equals(gav.getGroupId()) &&
artifactId.equals(gav.getArtifactId());
}
private static void addRuntimeSpecificDependencies(String deps,
Set<String> answer) {
diff --git
a/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/export/QuarkusExporter.java
b/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/export/QuarkusExporter.java
index 87e0f5b142d0..08527f199bfb 100644
---
a/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/export/QuarkusExporter.java
+++
b/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/export/QuarkusExporter.java
@@ -530,6 +530,8 @@ class QuarkusExporter extends Exporter {
// replace dependencies with special quarkus dependencies if we can
find any
replaceQuarkusDependencies(gavs);
+ ExportHelper.removeDuplicateArtifacts(gavs);
+
// sort artifacts
gavs.sort(ExportHelper.mavenGavComparator());
@@ -572,8 +574,8 @@ class QuarkusExporter extends Exporter {
}
@Override
- protected Set<String> resolveDependencies(Path settings, Path profile)
throws Exception {
- Set<String> answer = super.resolveDependencies(settings, profile);
+ protected Set<String> doResolveDependencies(Path settings, Path profile)
throws Exception {
+ Set<String> answer = super.doResolveDependencies(settings, profile);
// remove out of the box dependencies
answer.removeIf(s -> s.contains("camel-core"));
diff --git
a/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/export/SpringBootExporter.java
b/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/export/SpringBootExporter.java
index b728cef5b449..d87ff8947fd4 100644
---
a/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/export/SpringBootExporter.java
+++
b/dsl/camel-jbang/camel-jbang-run/src/main/java/org/apache/camel/dsl/jbang/run/export/SpringBootExporter.java
@@ -138,7 +138,8 @@ class SpringBootExporter extends Exporter {
prop.remove("camel.main.modeline");
}
// ensure spring-boot keeps running if no HTTP server included
- boolean http = deps.stream().anyMatch(s ->
s.contains("mvn:org.apache.camel:camel-platform-http"));
+ boolean http = hasCamelArtifact(deps, "camel-platform-http")
+ || hasCamelArtifact(deps, "camel-platform-http-vertx");
if (!http) {
prop.put("camel.main.run-controller", "true");
}
@@ -297,6 +298,8 @@ class SpringBootExporter extends Exporter {
gavs.add(gav);
}
+ ExportHelper.removeDuplicateArtifacts(gavs);
+
gavs.sort(ExportHelper.mavenGavComparator());
List<Map<String, Object>> result = new ArrayList<>();
@@ -356,6 +359,9 @@ class SpringBootExporter extends Exporter {
}
gavs.add(gav);
}
+
+ ExportHelper.removeDuplicateArtifacts(gavs);
+
gavs.sort(ExportHelper.mavenGavComparator());
StringBuilder sb = new StringBuilder();
@@ -434,13 +440,14 @@ class SpringBootExporter extends Exporter {
}
@Override
- protected Set<String> resolveDependencies(Path settings, Path profile)
throws Exception {
- Set<String> answer = super.resolveDependencies(settings, profile);
+ protected Set<String> doResolveDependencies(Path settings, Path profile)
throws Exception {
+ Set<String> answer = super.doResolveDependencies(settings, profile);
// remove out of the box dependencies
answer.removeIf(s -> s.contains("camel-core"));
- boolean http = answer.stream().anyMatch(s ->
s.contains("mvn:org.apache.camel:camel-platform-http"));
+ boolean http = hasCamelArtifact(answer, "camel-platform-http")
+ || hasCamelArtifact(answer, "camel-platform-http-vertx");
if (hasOpenapi(answer) && !http) {
// include http server if using openapi
answer.add("mvn:org.apache.camel:camel-platform-http");
diff --git
a/dsl/camel-jbang/camel-jbang-run/src/test/java/org/apache/camel/dsl/jbang/run/common/ExportHelperTest.java
b/dsl/camel-jbang/camel-jbang-run/src/test/java/org/apache/camel/dsl/jbang/run/common/ExportHelperTest.java
index d6bbd6201e9a..25beee6532eb 100644
---
a/dsl/camel-jbang/camel-jbang-run/src/test/java/org/apache/camel/dsl/jbang/run/common/ExportHelperTest.java
+++
b/dsl/camel-jbang/camel-jbang-run/src/test/java/org/apache/camel/dsl/jbang/run/common/ExportHelperTest.java
@@ -21,7 +21,10 @@ import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.camel.tooling.maven.MavenGav;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
@@ -216,4 +219,34 @@ public class ExportHelperTest {
// Verify target exists
Assertions.assertTrue(Files.exists(target));
}
+
+ @Test
+ public void testRemoveDuplicateArtifactsKeepsTheVersionThatIsGiven() {
+ List<MavenGav> gavs = new ArrayList<>(
+ List.of(
+
MavenGav.parseGav("org.apache.camel.quarkus:camel-quarkus-console"),
+
MavenGav.parseGav("org.apache.camel.quarkus:camel-quarkus-log"),
+
MavenGav.parseGav("org.apache.camel.quarkus:camel-quarkus-console:3.2.0")));
+
+ ExportHelper.removeDuplicateArtifacts(gavs);
+
+ // the duplicate keeps the position of the first, with the version
that is given
+ Assertions.assertEquals(2, gavs.size());
+ Assertions.assertEquals("camel-quarkus-console",
gavs.get(0).getArtifactId());
+ Assertions.assertEquals("3.2.0", gavs.get(0).getVersion());
+ Assertions.assertEquals("camel-quarkus-log",
gavs.get(1).getArtifactId());
+ }
+
+ @Test
+ public void testRemoveDuplicateArtifactsKeepsTheFirstOfTwoVersions() {
+ List<MavenGav> gavs = new ArrayList<>(
+ List.of(
+ MavenGav.parseGav("org.postgresql:postgresql:42.7.9"),
+
MavenGav.parseGav("org.postgresql:postgresql:42.7.99")));
+
+ ExportHelper.removeDuplicateArtifacts(gavs);
+
+ Assertions.assertEquals(1, gavs.size());
+ Assertions.assertEquals("42.7.9", gavs.get(0).getVersion());
+ }
}