Skip to content
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 @@ -29,6 +29,7 @@
import org.gradle.api.internal.tasks.TaskDependencyFactory;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Property;

import io.quarkus.bootstrap.BootstrapConstants;
import io.quarkus.bootstrap.model.PlatformImports;
Expand All @@ -38,6 +39,7 @@
import io.quarkus.gradle.tooling.dependency.DependencyUtils;
import io.quarkus.gradle.tooling.dependency.ExtensionDependency;
import io.quarkus.maven.dependency.ArtifactCoords;
import io.quarkus.maven.dependency.ArtifactKey;
import io.quarkus.runtime.LaunchMode;

public class ApplicationDeploymentClasspathBuilder {
Expand Down Expand Up @@ -93,13 +95,14 @@ public static void initConfigurations(Project project) {
final ConfigurationContainer configContainer = project.getConfigurations();

// Custom configuration for dev mode
configContainer.register(ToolingUtils.DEV_MODE_CONFIGURATION_NAME, config -> {
config.extendsFrom(configContainer.getByName(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME));
config.setCanBeConsumed(false);
if (!isDisableComponentVariants(project)) {
QuarkusComponentVariants.setConditionalAttributes(config, project, LaunchMode.DEVELOPMENT);
}
});
configContainer
.register(ToolingUtils.DEV_MODE_CONFIGURATION_NAME, config -> {
config.extendsFrom(configContainer.getByName(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME));
config.setCanBeConsumed(false);
if (!isDisableComponentVariants(project)) {
QuarkusComponentVariants.setConditionalAttributes(config, project, LaunchMode.DEVELOPMENT);
}
});

// Base runtime configurations for every launch mode
configContainer
Expand Down Expand Up @@ -178,6 +181,7 @@ private static Configuration[] getOriginalRuntimeClasspaths(Project project, Lau
private final String platformImportName;

private final List<Dependency> platformDataDeps = new ArrayList<>();
private final Map<ArtifactKey, PlatformSpec.Constraint> platformConstraints = new HashMap<>();

public ApplicationDeploymentClasspathBuilder(Project project, LaunchMode mode,
TaskDependencyFactory taskDependencyFactory) {
Expand Down Expand Up @@ -239,6 +243,13 @@ private void setUpPlatformConfiguration() {
break;
}
}
} else {
ArtifactKey artifactKey = ArtifactKey.ga(d.getTarget().getGroup(), name);
platformConstraints.computeIfAbsent(artifactKey,
k -> new PlatformSpec.Constraint(
d.getTarget().getGroup(),
name,
d.getTarget().getVersion()));
}
});
});
Expand Down Expand Up @@ -276,14 +287,22 @@ private List<Dependency> resolvePlatformDependencies() {
return platformDataDeps;
}

private PlatformSpec resolvePlatformSpec() {
getPlatformConfiguration().resolve();
return new PlatformSpec(platformConstraints, getPlatformConfiguration().getExcludeRules());
}

private void setUpRuntimeConfiguration() {
if (!project.getConfigurations().getNames().contains(this.runtimeConfigurationName)) {
final String baseConfig;
final boolean disableComponentVariants = isDisableComponentVariants(project);
if (disableComponentVariants) {
baseConfig = ApplicationDeploymentClasspathBuilder.getBaseRuntimeConfigName(mode);
} else {
QuarkusComponentVariants.addVariants(project, mode);
Property<PlatformSpec> platformSpecProperty = project.getObjects()
.property(PlatformSpec.class);
QuarkusComponentVariants.addVariants(project, mode,
platformSpecProperty.value(project.provider(this::resolvePlatformSpec)));
baseConfig = QuarkusComponentVariants.getConditionalConfigurationName(mode);
}
project.getConfigurations().register(this.runtimeConfigurationName, configuration -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.quarkus.gradle.dependency;

import java.util.Map;
import java.util.Set;

import org.gradle.api.artifacts.ExcludeRule;

import io.quarkus.maven.dependency.ArtifactKey;

class PlatformSpec {
private final Map<ArtifactKey, Constraint> constraints;
private final Set<ExcludeRule> exclusions;

public PlatformSpec(Map<ArtifactKey, Constraint> constraints, Set<ExcludeRule> exclusions) {
this.constraints = constraints;
this.exclusions = exclusions;
}

public Map<ArtifactKey, Constraint> getConstraints() {
return constraints;
}

public Set<ExcludeRule> getExclusions() {
return exclusions;
}

static class Constraint {
private final String groupId;
private final String artifactId;
private final String version;

public Constraint(String groupId, String artifactId, String version) {
this.groupId = groupId;
this.artifactId = artifactId;
this.version = version;
}

public String getGroupId() {
return groupId;
}

public String getArtifactId() {
return artifactId;
}

public String getVersion() {
return version;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

Expand All @@ -28,6 +30,7 @@
import org.gradle.api.attributes.java.TargetJvmEnvironment;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Property;

import io.quarkus.gradle.tooling.dependency.DependencyUtils;
import io.quarkus.gradle.tooling.dependency.ExtensionDependency;
Expand Down Expand Up @@ -169,22 +172,26 @@ public static void setCommonAttributes(AttributeContainer attrs, ObjectFactory o
* @param project project
* @param mode launch mode
*/
public static void addVariants(Project project, LaunchMode mode) {
new QuarkusComponentVariants(project, mode).configureAndAddVariants();
public static void addVariants(Project project, LaunchMode mode,
Property<PlatformSpec> platformSpecProperty) {
new QuarkusComponentVariants(project, mode, platformSpecProperty).configureAndAddVariants();
}

private final Attribute<String> quarkusDepAttr;
private final Project project;
private final Property<PlatformSpec> platformSpecProperty;
private final Map<ArtifactKey, ProcessedDependency> processedDeps = new HashMap<>();
private final Map<ArtifactKey, ConditionalDependency> allConditionalDeps = new HashMap<>();
private final List<ConditionalDependencyVariant> dependencyVariantQueue = new ArrayList<>();
private final Map<String, SatisfiedExtensionDeps> satisfiedExtensionDeps = new HashMap<>();
private final LaunchMode mode;
private final AtomicInteger configCopyCounter = new AtomicInteger();

private QuarkusComponentVariants(Project project, LaunchMode mode) {
private QuarkusComponentVariants(Project project, LaunchMode mode,
Property<PlatformSpec> platformSpecProperty) {
this.project = project;
this.mode = mode;
this.platformSpecProperty = platformSpecProperty;
this.quarkusDepAttr = getConditionalDependencyAttribute(project.getName(), mode);
project.getDependencies().getAttributesSchema().attribute(quarkusDepAttr);
project.getDependencies().getAttributesSchema().attribute(getDeploymentDependencyAttribute(project.getName(), mode));
Expand Down Expand Up @@ -407,7 +414,10 @@ private void processDependency(ProcessedDependency parent,
}

private void queueConditionalDependency(ProcessedDependency parent, Dependency dep) {
dependencyVariantQueue.add(new ConditionalDependencyVariant(parent.extension, getOrCreateConditionalDep(dep)));
var conditionalDep = getOrCreateConditionalDep(dep);
if (conditionalDep != null) {
dependencyVariantQueue.add(new ConditionalDependencyVariant(parent.extension, conditionalDep));
}
}

private ConditionalDependency getOrCreateConditionalDep(Dependency dep) {
Expand All @@ -417,7 +427,7 @@ private ConditionalDependency getOrCreateConditionalDep(Dependency dep) {
}

private ResolvedArtifact tryResolvingRelocationArtifact(Dependency dep) {
final Configuration configForRelocated = project.getConfigurations().detachedConfiguration(dep).setTransitive(true);
final Configuration configForRelocated = getDetachedWithExclusions(dep).setTransitive(true);
setConditionalAttributes(configForRelocated, project, mode);

var firstLevelDeps = configForRelocated.getResolvedConfiguration().getFirstLevelModuleDependencies();
Expand Down Expand Up @@ -447,8 +457,10 @@ private ResolvedArtifact tryResolvingRelocationArtifact(Dependency dep) {
return artifact;
}

private ConditionalDependency newConditionalDep(Dependency dep) {
final Configuration config = project.getConfigurations().detachedConfiguration(dep).setTransitive(false);
private ConditionalDependency newConditionalDep(Dependency originalDep) {
var dep = getConstrainedDep(originalDep);
final Configuration config = getDetachedWithExclusions(dep).setTransitive(false);

setConditionalAttributes(config, project, mode);
ResolvedArtifact resolvedArtifact = null;

Expand All @@ -464,6 +476,11 @@ private ConditionalDependency newConditionalDep(Dependency dep) {
}

if (resolvedArtifact == null) {
// check if that's due to exclude rules, and if yes, ignore
if (isExplicitlyExcluded(dep)) {
project.getLogger().info("Conditional dependency {} ignored due to exclusion rule", dep);
return null;
}
throw new RuntimeException(dep + " did not resolve to any artifacts");
}

Expand All @@ -474,6 +491,42 @@ private ConditionalDependency newConditionalDep(Dependency dep) {

}

private boolean isExplicitlyExcluded(Dependency dep) {
return platformSpecProperty.get().getExclusions().stream().anyMatch(rule -> {
// Do not abort if the group is null, allow the next comparison to take place
if (rule.getGroup() != null && !Objects.equals(rule.getGroup(), dep.getGroup())) {
return false;
}
// If we reached this point, and module of the rule is null, it is a match
return rule.getModule() == null || Objects.equals(rule.getModule(), dep.getName());
});
}

private Configuration getDetachedWithExclusions(Dependency dep) {
var c = project.getConfigurations().detachedConfiguration(dep);
PlatformSpec platformSpec = platformSpecProperty.get();
platformSpec.getExclusions().forEach(rule -> {
Map<String, String> excludeProperties = new HashMap<>(2);
excludeProperties.put("group", rule.getGroup());
excludeProperties.put("module", rule.getModule());
c.exclude(excludeProperties);
});
return c;
}

private Dependency getConstrainedDep(Dependency dep) {
return findMatchingConstraint(dep).map(c -> project.getDependencies().create(
dep.getGroup() + ":" + dep.getName() + ":" + c.getVersion())).orElse(dep);
}

private Optional<PlatformSpec.Constraint> findMatchingConstraint(Dependency dep) {
PlatformSpec platformSpec = platformSpecProperty.get();
Map<ArtifactKey, PlatformSpec.Constraint> constraints = platformSpec.getConstraints();
PlatformSpec.Constraint matchingConstraint = constraints
.get(ArtifactKey.ga(dep.getGroup(), dep.getName()));
return Optional.ofNullable(matchingConstraint);
}

private class ProcessedDependency {
private final ResolvedArtifact artifact;
private final ExtensionDependency<?> extension;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
quarkusPlatformArtifactId=quarkus-bom
quarkusPlatformGroupId=io.quarkus
org.gradle.logging.level=INFO
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
plugins {
id 'java'
id 'io.quarkus'
}

repositories {
mavenLocal {
content {
includeGroup 'org.enforcing.deps' // for dependencies built in this test
includeGroup 'org.enforcing.conditional' // for dependencies built in this test
includeGroupByRegex 'io.quarkus.*'
includeGroup 'org.hibernate.orm'
}
}
mavenCentral()
}

dependencies {
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
implementation enforcedPlatform("org.enforcing.deps:test-bom:1.0.0")
implementation 'io.quarkus:quarkus-rest'
implementation 'org.enforcing.deps:ext-a:1.0-SNAPSHOT'
testImplementation 'io.quarkus:quarkus-junit5'
testImplementation 'io.rest-assured:rest-assured'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.acme;

import org.eclipse.microprofile.config.inject.ConfigProperty;

import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;

@Path("/hello")
public class HelloResource {

@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
plugins {
id 'java'
id 'io.quarkus'
}

repositories {
mavenLocal {
content {
includeGroup 'org.enforcing.deps' // for dependencies built in this test
includeGroup 'org.enforcing.conditional' // for dependencies built in this test
includeGroupByRegex 'io.quarkus.*'
includeGroup 'org.hibernate.orm'
}
}
mavenCentral()
}

dependencies {
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
implementation enforcedPlatform("org.enforcing.deps:test-bom:1.0.0")
implementation 'io.quarkus:quarkus-rest'
implementation 'org.enforcing.deps:ext-a:1.0-SNAPSHOT'
testImplementation 'io.quarkus:quarkus-junit5'
testImplementation 'io.rest-assured:rest-assured'
}

configurations {
configureEach {
exclude group: 'org.enforcing.conditional', module: 'dev-mode-only-lib'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.acme;

import org.eclipse.microprofile.config.inject.ConfigProperty;

import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;

@Path("/hello")
public class HelloResource {

@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}
}
Loading
Loading