Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure quarkus-bom platform does not force its BOM over other platforms found in the project #15444

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import org.gradle.api.GradleException;
import org.gradle.api.Project;
Expand Down Expand Up @@ -107,70 +108,75 @@ private QuarkusPlatformDescriptor resolvePlatformDescriptor(QuarkusJsonPlatformD
final Configuration boms = project.getConfigurations()
.detachedConfiguration(bomDeps.toArray(new org.gradle.api.artifacts.Dependency[0]));
final Set<AppArtifactKey> processedKeys = new HashSet<>(1);
final List<ResolvedArtifact> descriptorDeps = new ArrayList<>(2);

final List<Dependency> descriptorDeps = new ArrayList<>();
final AtomicInteger quarkusBomIndex = new AtomicInteger(-1);
final AtomicInteger quarkusUniverseBomIndex = new AtomicInteger(-1);
boms.getResolutionStrategy().eachDependency(d -> {
if (!d.getTarget().getName().endsWith(BootstrapConstants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX)
|| !processedKeys.add(new AppArtifactKey(d.getTarget().getGroup(), d.getTarget().getName()))) {
final String name = d.getTarget().getName();
if (!name.endsWith(BootstrapConstants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX)
|| !processedKeys.add(new AppArtifactKey(d.getTarget().getGroup(), name))) {
return;
}

if (name.startsWith("quarkus-bom")) {
if (quarkusBomIndex.get() < 0) {
quarkusBomIndex.set(descriptorDeps.size());
} else {
// the first one wins
return;
}
} else if (name.startsWith("quarkus-universe-bom")) {
if (quarkusUniverseBomIndex.get() < 0) {
quarkusUniverseBomIndex.set(descriptorDeps.size());
} else {
// the first one wins
return;
}
}

final DefaultDependencyArtifact dep = new DefaultDependencyArtifact();
dep.setExtension("json");
dep.setType("json");
dep.setClassifier(d.getTarget().getVersion());
dep.setName(d.getTarget().getName());
dep.setName(name);

final DefaultExternalModuleDependency gradleDep = new DefaultExternalModuleDependency(
d.getTarget().getGroup(), d.getTarget().getName(), d.getTarget().getVersion(), null);
d.getTarget().getGroup(), name, d.getTarget().getVersion(), null);
gradleDep.addArtifact(dep);
descriptorDeps.add(gradleDep);
});
boms.getResolvedConfiguration();

if (descriptorDeps.isEmpty()) {
return null;
}

final List<ResolvedArtifact> resolvedDescriptors = new ArrayList<>(descriptorDeps.size());
for (int i = 0; i < descriptorDeps.size(); ++i) {
if (quarkusBomIndex.get() == i && quarkusUniverseBomIndex.get() >= 0) {
continue;
}
final Dependency descriptor = descriptorDeps.get(i);
try {
for (ResolvedArtifact a : project.getConfigurations().detachedConfiguration(gradleDep)
for (ResolvedArtifact a : project.getConfigurations().detachedConfiguration(descriptor)
.getResolvedConfiguration().getResolvedArtifacts()) {
if (a.getName().equals(d.getTarget().getName())) {
descriptorDeps.add(a);
if (a.getName().equals(descriptor.getName())) {
resolvedDescriptors.add(a);
break;
}
}
} catch (Exception e) {
// ignore for now
}
});
boms.getResolvedConfiguration();

if (descriptorDeps.isEmpty()) {
return null;
}
if (descriptorDeps.size() == 1) {
return descriptorResolver.resolveFromJson(descriptorDeps.get(0).getFile().toPath());
}

// Typically, quarkus-bom platform will appear first.
// The descriptors that are generated today are not fragmented and include everything
// a platform offers. Which means if the quarkus-bom platform appears first and its version
// matches the Quarkus core version of the platform built on top of the quarkus-bom
// (e.g. quarkus-universe-bom) the quarkus-bom platform can be skipped,
// since it will already be included in the platform that's built on top of it
int i = 0;
ResolvedArtifact platformArtifact = descriptorDeps.get(0);
final String quarkusBomPlatformArtifactId = "quarkus-bom-"
+ BootstrapConstants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX;
ResolvedArtifact quarkusBomPlatformArtifact = null;
if (quarkusBomPlatformArtifactId.equals(platformArtifact.getName())) {
quarkusBomPlatformArtifact = platformArtifact;
if (resolvedDescriptors.size() == 1) {
return descriptorResolver.resolveFromJson(resolvedDescriptors.get(0).getFile().toPath());
}

final CombinedQuarkusPlatformDescriptor.Builder builder = CombinedQuarkusPlatformDescriptor.builder();
while (++i < descriptorDeps.size()) {
platformArtifact = descriptorDeps.get(i);
final QuarkusPlatformDescriptor descriptor = descriptorResolver
.resolveFromJson(platformArtifact.getFile().toPath());
if (quarkusBomPlatformArtifact != null) {
if (!quarkusBomPlatformArtifact.getModuleVersion().getId().getVersion()
.equals(descriptor.getQuarkusVersion())) {
builder.addPlatform(descriptorResolver.resolveFromJson(quarkusBomPlatformArtifact.getFile().toPath()));
}
quarkusBomPlatformArtifact = null;
}
for (ResolvedArtifact platformArtifact : resolvedDescriptors) {
builder.addPlatform(descriptorResolver.resolveFromJson(platformArtifact.getFile().toPath()));
}
return builder.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,32 +147,8 @@ private QuarkusPlatformDescriptor resolvePlatformDescriptor(final MessageWriter
return descriptorResolver.resolveFromJson(descrArtifactList.get(0).getFile().toPath());
}

// Typically, quarkus-bom platform will appear first.
// The descriptors that are generated today are not fragmented and include everything
// a platform offers. Which means if the quarkus-bom platform appears first and its version
// matches the Quarkus core version of the platform built on top of the quarkus-bom
// (e.g. quarkus-universe-bom) the quarkus-bom platform can be skipped,
// since it will already be included in the platform that's built on top of it
int i = 0;
Artifact platformArtifact = descrArtifactList.get(0);
final String quarkusBomPlatformArtifactId = "quarkus-bom"
+ BootstrapConstants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX;
Artifact quarkusBomPlatformArtifact = null;
if (quarkusBomPlatformArtifactId.equals(platformArtifact.getArtifactId())) {
quarkusBomPlatformArtifact = platformArtifact;
}
final CombinedQuarkusPlatformDescriptor.Builder builder = CombinedQuarkusPlatformDescriptor.builder();
while (++i < descrArtifactList.size()) {
platformArtifact = descrArtifactList.get(i);
final QuarkusPlatformDescriptor descriptor = descriptorResolver
.resolveFromJson(platformArtifact.getFile().toPath());
if (quarkusBomPlatformArtifact != null) {
if (!quarkusBomPlatformArtifact.getVersion().equals(descriptor.getQuarkusVersion())) {
builder.addPlatform(
descriptorResolver.resolveFromJson(quarkusBomPlatformArtifact.getFile().toPath()));
}
quarkusBomPlatformArtifact = null;
}
for (Artifact platformArtifact : descrArtifactList) {
builder.addPlatform(descriptorResolver.resolveFromJson(platformArtifact.getFile().toPath()));
}
return builder.build();
Expand Down Expand Up @@ -223,24 +199,60 @@ private List<Artifact> resolveLegacyQuarkusPlatformDescriptors(MessageWriter log

private List<Artifact> collectQuarkusPlatformDescriptors(MessageWriter log, MavenArtifactResolver mvn)
throws MojoExecutionException {
final List<Artifact> descrArtifactList = new ArrayList<>(2);
final List<Dependency> constraints = project.getDependencyManagement() == null ? Collections.emptyList()
: project.getDependencyManagement().getDependencies();
if (!constraints.isEmpty()) {
for (Dependency d : constraints) {
if (!("json".equals(d.getType())
&& d.getArtifactId().endsWith(BootstrapConstants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX))) {
if (constraints.isEmpty()) {
return Collections.emptyList();
}

// Here we are about to collect platform descriptors found among the project's dependency constraints.
// Normally, it's a straightforward exercise, i.e. simply collect dependencies that match a pre-defined artifactId suffix.
// The ordering of the descriptors in our platform BOMs might not be consistent across different builds though.
// So this code is doing rough filtering to make sure the base platform (quarkus-bom) descriptor
// does not appear to be forcing its BOM over the other platforms found in the project.
// Luckily, though, this code is going to be replaced in the next version using the new extension catalog API.
final List<Dependency> descriptors = new ArrayList<>();
int quarkusBomIndex = -1;
int quarkusUniverseBomIndex = -1;
for (Dependency d : constraints) {
final String artifactId = d.getArtifactId();
if (!("json".equals(d.getType())
&& artifactId.endsWith(BootstrapConstants.PLATFORM_DESCRIPTOR_ARTIFACT_ID_SUFFIX))) {
continue;
}
if (artifactId.startsWith("quarkus-bom")) {
if (quarkusBomIndex < 0) {
quarkusBomIndex = descriptors.size();
} else {
// the first one wins
continue;
}
final Artifact a = new DefaultArtifact(d.getGroupId(), d.getArtifactId(), d.getClassifier(),
d.getType(), d.getVersion());
try {
log.debug("Found platform descriptor %s", a);
descrArtifactList.add(mvn.resolve(a).getArtifact());
} catch (Exception e) {
throw new MojoExecutionException("Failed to resolve the platform descriptor " + a, e);
} else if (artifactId.startsWith("quarkus-universe-bom")) {
if (quarkusUniverseBomIndex < 0) {
quarkusUniverseBomIndex = descriptors.size();
} else {
// the first one wins
continue;
}
}
descriptors.add(d);
}

final List<Artifact> descrArtifactList = new ArrayList<>(descriptors.size());
for (int i = 0; i < descriptors.size(); ++i) {
if (quarkusBomIndex == i && quarkusUniverseBomIndex >= 0) {
log.debug("Filtered platform descriptor %s", descriptors.get(i));
continue;
}
final Dependency d = descriptors.get(i);
final Artifact a = new DefaultArtifact(d.getGroupId(), d.getArtifactId(), d.getClassifier(),
d.getType(), d.getVersion());
try {
log.debug("Found platform descriptor %s", a);
descrArtifactList.add(mvn.resolve(a).getArtifact());
} catch (Exception e) {
throw new MojoExecutionException("Failed to resolve the platform descriptor " + a, e);
}
}
return descrArtifactList;
}
Expand Down