diff --git a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GACTV.java b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GACTV.java index def1d5db83303..cdf931ffbd0d2 100644 --- a/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GACTV.java +++ b/independent-projects/bootstrap/app-model/src/main/java/io/quarkus/maven/dependency/GACTV.java @@ -39,7 +39,7 @@ protected static String[] split(String str, String[] parts) { protected GACTV(String[] parts) { groupId = parts[0]; artifactId = parts[1]; - classifier = parts[2]; + classifier = parts[2] == null ? DEFAULT_CLASSIFIER : parts[2]; type = parts[3] == null ? TYPE_JAR : parts[3]; version = parts[4]; } @@ -54,17 +54,17 @@ public GACTV(ArtifactKey key, String version) { } public GACTV(String groupId, String artifactId, String version) { - this(groupId, artifactId, "", TYPE_JAR, version); + this(groupId, artifactId, DEFAULT_CLASSIFIER, TYPE_JAR, version); } public GACTV(String groupId, String artifactId, String type, String version) { - this(groupId, artifactId, "", type, version); + this(groupId, artifactId, DEFAULT_CLASSIFIER, type, version); } public GACTV(String groupId, String artifactId, String classifier, String type, String version) { this.groupId = groupId; this.artifactId = artifactId; - this.classifier = classifier == null ? "" : classifier; + this.classifier = classifier == null ? DEFAULT_CLASSIFIER : classifier; this.type = type == null ? TYPE_JAR : type; this.version = version; } diff --git a/independent-projects/tools/artifact-api/src/main/java/io/quarkus/maven/ArtifactCoords.java b/independent-projects/tools/artifact-api/src/main/java/io/quarkus/maven/ArtifactCoords.java index 09b165d795ebb..66b48de5a7ec2 100644 --- a/independent-projects/tools/artifact-api/src/main/java/io/quarkus/maven/ArtifactCoords.java +++ b/independent-projects/tools/artifact-api/src/main/java/io/quarkus/maven/ArtifactCoords.java @@ -34,7 +34,7 @@ protected static String[] split(String str, String[] parts) { protected ArtifactCoords(String[] parts) { groupId = parts[0]; artifactId = parts[1]; - classifier = parts[2]; + classifier = parts[2] == null ? DEFAULT_CLASSIFIER : parts[2]; type = parts[3] == null ? TYPE_JAR : parts[3]; version = parts[4]; } @@ -49,17 +49,17 @@ public ArtifactCoords(ArtifactKey key, String version) { } public ArtifactCoords(String groupId, String artifactId, String version) { - this(groupId, artifactId, "", TYPE_JAR, version); + this(groupId, artifactId, DEFAULT_CLASSIFIER, TYPE_JAR, version); } public ArtifactCoords(String groupId, String artifactId, String type, String version) { - this(groupId, artifactId, "", type, version); + this(groupId, artifactId, DEFAULT_CLASSIFIER, type, version); } public ArtifactCoords(String groupId, String artifactId, String classifier, String type, String version) { this.groupId = groupId; this.artifactId = artifactId; - this.classifier = classifier == null ? "" : classifier; + this.classifier = classifier == null ? DEFAULT_CLASSIFIER : classifier; this.type = type == null ? TYPE_JAR : type; this.version = version; } diff --git a/independent-projects/tools/artifact-api/src/main/java/io/quarkus/maven/ArtifactKey.java b/independent-projects/tools/artifact-api/src/main/java/io/quarkus/maven/ArtifactKey.java index e6acb2cf43cda..b22f9663b4123 100644 --- a/independent-projects/tools/artifact-api/src/main/java/io/quarkus/maven/ArtifactKey.java +++ b/independent-projects/tools/artifact-api/src/main/java/io/quarkus/maven/ArtifactKey.java @@ -24,7 +24,7 @@ public ArtifactKey(String[] parts) { this.classifier = parts[2]; } if (parts.length <= 3 || parts[3] == null) { - this.type = "jar"; + this.type = ArtifactCoords.TYPE_JAR; } else { this.type = parts[3]; } diff --git a/independent-projects/tools/devtools-testing/src/main/java/io/quarkus/devtools/testing/registry/client/TestRegistryClientBuilder.java b/independent-projects/tools/devtools-testing/src/main/java/io/quarkus/devtools/testing/registry/client/TestRegistryClientBuilder.java index 7c120b5a39eb5..99f6dee3dca29 100644 --- a/independent-projects/tools/devtools-testing/src/main/java/io/quarkus/devtools/testing/registry/client/TestRegistryClientBuilder.java +++ b/independent-projects/tools/devtools-testing/src/main/java/io/quarkus/devtools/testing/registry/client/TestRegistryClientBuilder.java @@ -376,6 +376,7 @@ private void configure(Path registryDir) { } else { final Path platformsDir = getRegistryPlatformsDir(registryDir); final Map platformsByQuarkusVersion = new HashMap<>(); + final PlatformCatalog.Mutable allPlatforms = PlatformCatalog.builder(); if (platformCatalog != null) { persistPlatformCatalog(platformCatalog.build(), platformsDir); for (Platform p : platformCatalog.getPlatforms()) { @@ -389,19 +390,8 @@ private void configure(Path registryDir) { final PlatformCatalog.Mutable c = platformsByQuarkusVersion.computeIfAbsent( r.getQuarkusCoreVersion(), v -> PlatformCatalog.builder()); - Platform.Mutable platform = (Platform.Mutable) c.getPlatform(p.getPlatformKey()); - if (platform == null) { - platform = Platform.builder() - .setPlatformKey(p.getPlatformKey()); - c.addPlatform(platform); - } - PlatformStream.Mutable stream = (PlatformStream.Mutable) platform.getStream(s.getId()); - if (stream == null) { - stream = PlatformStream.builder() - .setId(s.getId()); - platform.addStream(stream); - } - stream.addRelease(r); + addPlatformRelease(p, s, r, c); + addPlatformRelease(p, s, r, allPlatforms); } } } @@ -419,19 +409,8 @@ private void configure(Path registryDir) { final PlatformCatalog.Mutable c = platformsByQuarkusVersion.computeIfAbsent( r.getQuarkusCoreVersion(), v -> PlatformCatalog.builder()); - Platform.Mutable platform = (Platform.Mutable) c.getPlatform(p.getPlatformKey()); - if (platform == null) { - platform = Platform.builder(); - platform.setPlatformKey(p.getPlatformKey()); - c.addPlatform(platform); - } - PlatformStream.Mutable stream = (PlatformStream.Mutable) platform.getStream(s.getId()); - if (stream == null) { - stream = PlatformStream.builder(); - stream.setId(s.getId()); - platform.addStream(stream); - } - stream.addRelease(r); + addPlatformRelease(p, s, r, c); + addPlatformRelease(p, s, r, allPlatforms); } } } @@ -441,6 +420,8 @@ private void configure(Path registryDir) { persistPlatformCatalog(entry.getValue().build(), platformsDir.resolve(entry.getKey())); } + persistPlatformCatalog(allPlatforms.build(), platformsDir.resolve(Constants.QUARKUS_VERSION_CLASSIFIER_ALL)); + if (memberCatalogs != null && !memberCatalogs.isEmpty()) { platformConfig.setExtensionCatalogsIncluded(true); } @@ -480,6 +461,23 @@ private void configure(Path registryDir) { } } + protected void addPlatformRelease(Platform platform, PlatformStream stream, PlatformRelease release, + final PlatformCatalog.Mutable catalog) { + Platform.Mutable mp = (Platform.Mutable) catalog.getPlatform(platform.getPlatformKey()); + if (mp == null) { + mp = Platform.builder() + .setPlatformKey(platform.getPlatformKey()); + catalog.addPlatform(mp); + } + PlatformStream.Mutable ms = (PlatformStream.Mutable) mp.getStream(stream.getId()); + if (ms == null) { + ms = PlatformStream.builder() + .setId(stream.getId()); + mp.addStream(ms); + } + ms.addRelease(release); + } + private ArtifactCoords getRegistryNonPlatformCatalogArtifact() { return new ArtifactCoords(registryGroupId, Constants.DEFAULT_REGISTRY_NON_PLATFORM_EXTENSIONS_CATALOG_ARTIFACT_ID, null, "json", Constants.DEFAULT_REGISTRY_ARTIFACT_VERSION); @@ -504,6 +502,28 @@ public TestPlatformCatalogStreamBuilder newStream(String id) { return new TestPlatformCatalogStreamBuilder(this, stream); } + public TestPlatformCatalogStreamBuilder newArchivedStream(String id) { + + if (registry.archivedPlatformCatalog == null) { + registry.archivedPlatformCatalog = PlatformCatalog.builder(); + } + + Platform.Mutable archivedPlatform = (Platform.Mutable) registry.archivedPlatformCatalog + .getPlatform(platform.getPlatformKey()); + if (archivedPlatform == null) { + archivedPlatform = Platform.builder() + .setPlatformKey(platform.getPlatformKey()); + registry.archivedPlatformCatalog.addPlatform(archivedPlatform); + } + + PlatformStream.Mutable archivedStream = (PlatformStream.Mutable) archivedPlatform.getStream(id); + if (archivedStream == null) { + archivedStream = PlatformStream.builder().setId(id); + archivedPlatform.addStream(archivedStream); + } + return new TestPlatformCatalogStreamBuilder(this, archivedStream); + } + public TestRegistryBuilder registry() { return registry; } diff --git a/independent-projects/tools/devtools-testing/src/test/java/io/quarkus/devtools/project/create/ArchivedStreamTest.java b/independent-projects/tools/devtools-testing/src/test/java/io/quarkus/devtools/project/create/ArchivedStreamTest.java new file mode 100644 index 0000000000000..b72f242e087e2 --- /dev/null +++ b/independent-projects/tools/devtools-testing/src/test/java/io/quarkus/devtools/project/create/ArchivedStreamTest.java @@ -0,0 +1,61 @@ +package io.quarkus.devtools.project.create; + +import io.quarkus.devtools.testing.registry.client.TestRegistryClientBuilder; +import io.quarkus.maven.ArtifactCoords; +import io.quarkus.registry.catalog.PlatformStreamCoords; +import java.nio.file.Path; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class ArchivedStreamTest extends MultiplePlatformBomsTestBase { + + private static final String PLATFORM_KEY = "io.test.platform"; + + @BeforeAll + public static void setup() throws Exception { + TestRegistryClientBuilder.newInstance() + //.debug() + .baseDir(configDir()) + // registry + .newRegistry("registry.test.io") + // platform key + .newPlatform(PLATFORM_KEY) + .newStream("1.0") + // 1.0.4 release + .newRelease("1.1.1") + .quarkusVersion("1.1.1") + // default bom including quarkus-core + essential metadata + .addCoreMember().release() + // foo platform member + .newMember("acme-a-bom").addExtension("ext-a").release() + .stream().platform() + .newArchivedStream("0.5") + .newArchivedRelease("0.5.1") + .quarkusVersion("0.5.1") + // default bom including quarkus-core + essential metadata + .addCoreMember().release() + // foo platform member + .newMember("acme-a-bom").addExtension("ext-a").release() + .registry() + .clientBuilder() + .build(); + + enableRegistryClient(); + } + + protected String getMainPlatformKey() { + return PLATFORM_KEY; + } + + @Test + public void createUsingStream2_0() throws Exception { + final Path projectDir = newProjectDir("created-using-archive-stream-0.5"); + createProject(projectDir, new PlatformStreamCoords(null, "0.5"), List.of("ext-a")); + + assertModel(projectDir, + List.of(mainPlatformBom(), platformMemberBomCoords("acme-a-bom")), + List.of(new ArtifactCoords("io.test.platform", "ext-a", null)), + "0.5.1"); + } +} diff --git a/independent-projects/tools/registry-client/src/main/java/io/quarkus/registry/Constants.java b/independent-projects/tools/registry-client/src/main/java/io/quarkus/registry/Constants.java index 0383fc1c39d85..c0c855765a579 100644 --- a/independent-projects/tools/registry-client/src/main/java/io/quarkus/registry/Constants.java +++ b/independent-projects/tools/registry-client/src/main/java/io/quarkus/registry/Constants.java @@ -15,6 +15,8 @@ public interface Constants { String PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX = "-quarkus-platform-descriptor"; String PLATFORM_PROPERTIES_ARTIFACT_ID_SUFFIX = "-quarkus-platform-properties"; + String QUARKUS_VERSION_CLASSIFIER_ALL = "all"; + String JSON = "json"; String LAST_UPDATED = "last-updated"; diff --git a/independent-projects/tools/registry-client/src/main/java/io/quarkus/registry/ExtensionCatalogResolver.java b/independent-projects/tools/registry-client/src/main/java/io/quarkus/registry/ExtensionCatalogResolver.java index f79720cf9157b..f08d5d0119c76 100644 --- a/independent-projects/tools/registry-client/src/main/java/io/quarkus/registry/ExtensionCatalogResolver.java +++ b/independent-projects/tools/registry-client/src/main/java/io/quarkus/registry/ExtensionCatalogResolver.java @@ -486,80 +486,98 @@ public ExtensionCatalog resolveExtensionCatalog(PlatformStreamCoords streamCoord ensureRegistriesConfigured(); - final String platformKey = streamCoords.getPlatformKey(); - final String streamId = streamCoords.getStreamId(); + final PlatformStream stream = findPlatformStreamOrFail(streamCoords); + final List catalogs = new ArrayList<>(); + for (PlatformRelease release : stream.getReleases()) { + catalogs.add(resolveExtensionCatalog(release.getMemberBoms())); + } + return CatalogMergeUtility.merge(catalogs); + } + + protected PlatformStream findPlatformStreamOrFail(PlatformStreamCoords streamCoords) + throws RegistryResolutionException { + var stream = findPlatformStreamOrNull(streamCoords, true); + if (stream != null) { + return stream; + } + stream = findPlatformStreamOrNull(streamCoords, false); + if (stream != null) { + return stream; + } + throw unknownStreamException(streamCoords, false); + } - PlatformStream stream = null; + protected PlatformStream findPlatformStreamOrNull(PlatformStreamCoords streamCoords, boolean amongRecommended) + throws RegistryResolutionException { int registryIndex = 0; - while (registryIndex < registries.size() && stream == null) { + while (registryIndex < registries.size()) { final RegistryExtensionResolver qer = registries.get(registryIndex++); - final PlatformCatalog platforms = qer.resolvePlatformCatalog(); + final PlatformCatalog platforms = amongRecommended ? qer.resolvePlatformCatalog() + : qer.resolvePlatformCatalog(Constants.QUARKUS_VERSION_CLASSIFIER_ALL); if (platforms == null) { continue; } - if (platformKey == null) { + if (streamCoords.getPlatformKey() == null) { for (Platform p : platforms.getPlatforms()) { - stream = p.getStream(streamId); + var stream = p.getStream(streamCoords.getStreamId()); if (stream != null) { - break; + return stream; } } } else { - final Platform platform = platforms.getPlatform(platformKey); + final Platform platform = platforms.getPlatform(streamCoords.getPlatformKey()); if (platform == null) { continue; } - stream = platform.getStream(streamId); + var stream = platform.getStream(streamCoords.getStreamId()); if (stream != null) { - break; + return stream; } } } + return null; + } - if (stream == null) { - Platform requestedPlatform = null; - final List knownPlatforms = new ArrayList<>(); - for (RegistryExtensionResolver qer : registries) { - final PlatformCatalog platforms = qer.resolvePlatformCatalog(); - if (platforms == null) { - continue; - } - if (platformKey != null) { - requestedPlatform = platforms.getPlatform(platformKey); - if (requestedPlatform != null) { - break; - } - } - for (Platform platform : platforms.getPlatforms()) { - knownPlatforms.add(platform); - } + protected RegistryResolutionException unknownStreamException(PlatformStreamCoords stream, boolean amongRecommended) + throws RegistryResolutionException { + Platform requestedPlatform = null; + final List knownPlatforms = new ArrayList<>(); + for (RegistryExtensionResolver qer : registries) { + final PlatformCatalog platforms = amongRecommended ? qer.resolvePlatformCatalog() + : qer.resolvePlatformCatalog(Constants.QUARKUS_VERSION_CLASSIFIER_ALL); + if (platforms == null) { + continue; } - - final StringBuilder buf = new StringBuilder(); - if (requestedPlatform != null) { - buf.append("Failed to locate stream ").append(streamId) - .append(" in platform " + requestedPlatform.getPlatformKey()); - } else if (knownPlatforms.isEmpty()) { - buf.append("None of the registries provided any platform"); - } else { - if (platformKey == null) { - buf.append("Failed to locate stream ").append(streamId).append(" in platform(s): "); - } else { - buf.append("Failed to locate platform ").append(platformKey).append(" among available platform(s): "); - } - buf.append(knownPlatforms.get(0).getPlatformKey()); - for (int i = 1; i < knownPlatforms.size(); ++i) { - buf.append(", ").append(knownPlatforms.get(i).getPlatformKey()); + if (stream.getPlatformKey() != null) { + requestedPlatform = platforms.getPlatform(stream.getPlatformKey()); + if (requestedPlatform != null) { + break; } } - throw new RegistryResolutionException(buf.toString()); + for (Platform platform : platforms.getPlatforms()) { + knownPlatforms.add(platform); + } } - final List catalogs = new ArrayList<>(); - for (PlatformRelease release : stream.getReleases()) { - catalogs.add(resolveExtensionCatalog(release.getMemberBoms())); + final StringBuilder buf = new StringBuilder(); + if (requestedPlatform != null) { + buf.append("Failed to locate stream ").append(stream.getStreamId()) + .append(" in platform " + requestedPlatform.getPlatformKey()); + } else if (knownPlatforms.isEmpty()) { + buf.append("None of the registries provided any platform"); + } else { + if (stream.getPlatformKey() == null) { + buf.append("Failed to locate stream ").append(stream.getStreamId()).append(" in platform(s): "); + } else { + buf.append("Failed to locate platform ").append(stream.getPlatformKey()) + .append(" among available platform(s): "); + } + buf.append(knownPlatforms.get(0).getPlatformKey()); + for (int i = 1; i < knownPlatforms.size(); ++i) { + buf.append(", ").append(knownPlatforms.get(i).getPlatformKey()); + } } - return CatalogMergeUtility.merge(catalogs); + return new RegistryResolutionException(buf.toString()); } @SuppressWarnings("unchecked")