Skip to content

Commit d0036a1

Browse files
committed
Overhauled handling of local extensions in Gradle Plugins
This completely changes how local extensions are handled by the Gradle plugins (`io.quarkus` and `io.quarkus.extension`) by now also resolving deployment modules in included builds and properly adding them and their artifacts as dependencies to the respective Quarkus code generation tasks and configurations. In addition it no longer depends on an extension descriptor to exist to determine the deployment module, conditional dependencies and dependency conditions. These are now read directly from the `QuarkusExtensionConfiguration` extension of any local extension module. Due to Gradle using different ClassLoaders for included builds this is done using Reflection. To achieve this deeper integration with Gradle a bit more internal classes have been used than I would normally be comfortable with, but they are pretty essential to the functioning of Gradle and Composite Builds so I'm fairly confident that they won't break any time soon.
1 parent 781060d commit d0036a1

File tree

60 files changed

+1476
-298
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1476
-298
lines changed

devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java

+36-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.gradle.api.UnknownTaskException;
1919
import org.gradle.api.artifacts.Configuration;
2020
import org.gradle.api.artifacts.ConfigurationContainer;
21+
import org.gradle.api.artifacts.ExternalModuleDependency;
2122
import org.gradle.api.artifacts.ProjectDependency;
2223
import org.gradle.api.file.FileCollection;
2324
import org.gradle.api.plugins.BasePlugin;
@@ -59,6 +60,10 @@
5960
import io.quarkus.gradle.tasks.QuarkusTestConfig;
6061
import io.quarkus.gradle.tasks.QuarkusUpdate;
6162
import io.quarkus.gradle.tooling.GradleApplicationModelBuilder;
63+
import io.quarkus.gradle.tooling.ToolingUtils;
64+
import io.quarkus.gradle.tooling.dependency.DependencyUtils;
65+
import io.quarkus.gradle.tooling.dependency.ExtensionDependency;
66+
import io.quarkus.gradle.tooling.dependency.ProjectExtensionDependency;
6267
import io.quarkus.runtime.LaunchMode;
6368

6469
public class QuarkusPlugin implements Plugin<Project> {
@@ -508,16 +513,15 @@ private void visitProjectDep(Project project, Project dep, Set<String> visited)
508513
if (dep.getState().getExecuted()) {
509514
setupQuarkusBuildTaskDeps(project, dep, visited);
510515
} else {
511-
dep.afterEvaluate(p -> {
512-
setupQuarkusBuildTaskDeps(project, p, visited);
513-
});
516+
dep.afterEvaluate(p -> setupQuarkusBuildTaskDeps(project, p, visited));
514517
}
515518
}
516519

517520
private void setupQuarkusBuildTaskDeps(Project project, Project dep, Set<String> visited) {
518-
if (!visited.add(dep.getPath())) {
521+
if (!visited.add(dep.getGroup() + ":" + dep.getName())) {
519522
return;
520523
}
524+
521525
project.getLogger().debug("Configuring {} task dependencies on {} tasks", project, dep);
522526

523527
getLazyTask(project, QUARKUS_BUILD_TASK_NAME)
@@ -555,13 +559,40 @@ protected void visitProjectDependencies(Project project, Project dep, Set<String
555559
}
556560
compilePlusRuntimeConfig.getIncoming().getDependencies()
557561
.forEach(d -> {
562+
Project depProject = null;
563+
558564
if (d instanceof ProjectDependency) {
559-
visitProjectDep(project, ((ProjectDependency) d).getDependencyProject(), visited);
565+
depProject = ((ProjectDependency) d).getDependencyProject();
566+
} else if (d instanceof ExternalModuleDependency) {
567+
depProject = ToolingUtils.findIncludedProject(project, (ExternalModuleDependency) d);
568+
}
569+
570+
if (depProject == null) {
571+
return;
572+
}
573+
574+
if (depProject.getState().getExecuted()) {
575+
visitLocalProject(project, depProject, visited);
576+
} else {
577+
depProject.afterEvaluate(p -> visitLocalProject(project, p, visited));
560578
}
561579
});
562580
}
563581
}
564582

583+
private void visitLocalProject(Project project, Project localProject, Set<String> visited) {
584+
// local dependency, so we collect also its dependencies
585+
visitProjectDep(project, localProject, visited);
586+
587+
ExtensionDependency<?> extensionDependency = DependencyUtils
588+
.getExtensionInfoOrNull(project, localProject);
589+
590+
if (extensionDependency instanceof ProjectExtensionDependency) {
591+
visitProjectDep(project,
592+
((ProjectExtensionDependency) extensionDependency).getDeploymentModule(), visited);
593+
}
594+
}
595+
565596
private Optional<TaskProvider<Task>> getLazyTask(Project project, String name) {
566597
try {
567598
return Optional.of(project.getTasks().named(name));

devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/QuarkusExtensionPlugin.java

+7-10
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,15 @@
2424
import io.quarkus.extension.gradle.tasks.ExtensionDescriptorTask;
2525
import io.quarkus.extension.gradle.tasks.ValidateExtensionTask;
2626
import io.quarkus.gradle.dependency.ApplicationDeploymentClasspathBuilder;
27+
import io.quarkus.gradle.extension.ExtensionConstants;
2728
import io.quarkus.gradle.tooling.ToolingUtils;
2829
import io.quarkus.gradle.tooling.dependency.DependencyUtils;
2930
import io.quarkus.runtime.LaunchMode;
3031

3132
public class QuarkusExtensionPlugin implements Plugin<Project> {
3233

3334
public static final String DEFAULT_DEPLOYMENT_PROJECT_NAME = "deployment";
34-
public static final String EXTENSION_CONFIGURATION_NAME = "quarkusExtension";
35+
public static final String EXTENSION_CONFIGURATION_NAME = ExtensionConstants.EXTENSION_CONFIGURATION_NAME;
3536

3637
public static final String EXTENSION_DESCRIPTOR_TASK_NAME = "extensionDescriptor";
3738
public static final String VALIDATE_EXTENSION_TASK_NAME = "validateExtension";
@@ -42,6 +43,7 @@ public class QuarkusExtensionPlugin implements Plugin<Project> {
4243
public void apply(Project project) {
4344
final QuarkusExtensionConfiguration quarkusExt = project.getExtensions().create(EXTENSION_CONFIGURATION_NAME,
4445
QuarkusExtensionConfiguration.class);
46+
4547
project.getPluginManager().apply(JavaPlugin.class);
4648
registerTasks(project, quarkusExt);
4749
}
@@ -141,17 +143,12 @@ private Project findDeploymentProject(Project project, QuarkusExtensionConfigura
141143
deploymentProjectName = DEFAULT_DEPLOYMENT_PROJECT_NAME;
142144
}
143145

144-
Project deploymentProject = project.getRootProject().findProject(deploymentProjectName);
146+
Project deploymentProject = ToolingUtils.findLocalProject(project, deploymentProjectName);
145147
if (deploymentProject == null) {
146-
if (project.getParent() != null) {
147-
deploymentProject = project.getParent().findProject(deploymentProjectName);
148-
}
149-
if (deploymentProject == null) {
150-
project.getLogger().warn("Unable to find deployment project with name: " + deploymentProjectName
151-
+ ". You can configure the deployment project name by setting the 'deploymentModule' property in the plugin extension.");
152-
}
148+
project.getLogger().warn("Unable to find deployment project with name: " + deploymentProjectName
149+
+ ". You can configure the deployment project name by setting the 'deploymentModule' property in the plugin extension.");
153150
}
151+
154152
return deploymentProject;
155153
}
156-
157154
}

devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/dependency/DeploymentClasspathBuilder.java

+13-18
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import io.quarkus.gradle.tooling.ToolingUtils;
1616
import io.quarkus.gradle.tooling.dependency.DependencyUtils;
1717
import io.quarkus.gradle.tooling.dependency.ExtensionDependency;
18-
import io.quarkus.gradle.tooling.dependency.LocalExtensionDependency;
1918

2019
public class DeploymentClasspathBuilder {
2120

@@ -32,27 +31,23 @@ public void exportDeploymentClasspath(String configurationName) {
3231
project.getConfigurations().create(deploymentConfigurationName, config -> {
3332
Configuration configuration = DependencyUtils.duplicateConfiguration(project,
3433
project.getConfigurations().getByName(configurationName));
35-
Set<ExtensionDependency> extensionDependencies = collectFirstMetQuarkusExtensions(configuration);
34+
Set<ExtensionDependency<?>> extensionDependencies = collectFirstMetQuarkusExtensions(configuration);
3635

3736
DependencyHandler dependencies = project.getDependencies();
3837

39-
for (ExtensionDependency extension : extensionDependencies) {
40-
if (extension instanceof LocalExtensionDependency) {
41-
DependencyUtils.addLocalDeploymentDependency(deploymentConfigurationName,
42-
(LocalExtensionDependency) extension,
43-
dependencies);
44-
} else {
45-
DependencyUtils.requireDeploymentDependency(deploymentConfigurationName, extension, dependencies);
46-
if (!alreadyProcessed.add(extension.getExtensionId())) {
47-
continue;
48-
}
38+
for (ExtensionDependency<?> extension : extensionDependencies) {
39+
if (!alreadyProcessed.add(extension.getExtensionId())) {
40+
continue;
4941
}
42+
43+
dependencies.add(deploymentConfigurationName,
44+
DependencyUtils.createDeploymentDependency(dependencies, extension));
5045
}
5146
});
5247
}
5348

54-
private Set<ExtensionDependency> collectFirstMetQuarkusExtensions(Configuration configuration) {
55-
Set<ExtensionDependency> firstLevelExtensions = new HashSet<>();
49+
private Set<ExtensionDependency<?>> collectFirstMetQuarkusExtensions(Configuration configuration) {
50+
Set<ExtensionDependency<?>> firstLevelExtensions = new HashSet<>();
5651
Set<ResolvedDependency> firstLevelModuleDependencies = configuration.getResolvedConfiguration()
5752
.getFirstLevelModuleDependencies();
5853

@@ -64,16 +59,16 @@ private Set<ExtensionDependency> collectFirstMetQuarkusExtensions(Configuration
6459
return firstLevelExtensions;
6560
}
6661

67-
private Set<ExtensionDependency> collectQuarkusExtensions(ResolvedDependency dependency,
62+
private Set<ExtensionDependency<?>> collectQuarkusExtensions(ResolvedDependency dependency,
6863
Set<ModuleVersionIdentifier> visitedArtifacts) {
6964
if (visitedArtifacts.contains(dependency.getModule().getId())) {
7065
return Collections.emptySet();
7166
} else {
7267
visitedArtifacts.add(dependency.getModule().getId());
7368
}
74-
Set<ExtensionDependency> extensions = new LinkedHashSet<>();
69+
Set<ExtensionDependency<?>> extensions = new LinkedHashSet<>();
7570
for (ResolvedArtifact moduleArtifact : dependency.getModuleArtifacts()) {
76-
ExtensionDependency extension = DependencyUtils.getExtensionInfoOrNull(project, moduleArtifact);
71+
ExtensionDependency<?> extension = DependencyUtils.getExtensionInfoOrNull(project, moduleArtifact);
7772
if (extension != null) {
7873
extensions.add(extension);
7974
return extensions;
@@ -83,7 +78,7 @@ private Set<ExtensionDependency> collectQuarkusExtensions(ResolvedDependency dep
8378
for (ResolvedDependency child : dependency.getChildren()) {
8479
extensions.addAll(collectQuarkusExtensions(child, visitedArtifacts));
8580
}
81+
8682
return extensions;
8783
}
88-
8984
}

devtools/gradle/gradle-extension-plugin/src/main/java/io/quarkus/extension/gradle/tasks/ValidateExtensionTask.java

+15-3
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717

1818
import io.quarkus.bootstrap.model.AppArtifactKey;
1919
import io.quarkus.extension.gradle.QuarkusExtensionConfiguration;
20+
import io.quarkus.gradle.tooling.dependency.ArtifactExtensionDependency;
2021
import io.quarkus.gradle.tooling.dependency.DependencyUtils;
2122
import io.quarkus.gradle.tooling.dependency.ExtensionDependency;
23+
import io.quarkus.gradle.tooling.dependency.ProjectExtensionDependency;
2224

2325
public class ValidateExtensionTask extends DefaultTask {
2426

@@ -82,10 +84,20 @@ public void validateExtension() {
8284
private List<AppArtifactKey> collectRuntimeExtensionsDeploymentKeys(Set<ResolvedArtifact> runtimeArtifacts) {
8385
List<AppArtifactKey> runtimeExtensions = new ArrayList<>();
8486
for (ResolvedArtifact resolvedArtifact : runtimeArtifacts) {
85-
ExtensionDependency extension = DependencyUtils.getExtensionInfoOrNull(getProject(), resolvedArtifact);
87+
ExtensionDependency<?> extension = DependencyUtils.getExtensionInfoOrNull(getProject(), resolvedArtifact);
8688
if (extension != null) {
87-
runtimeExtensions.add(new AppArtifactKey(extension.getDeploymentModule().getGroupId(),
88-
extension.getDeploymentModule().getArtifactId()));
89+
if (extension instanceof ProjectExtensionDependency) {
90+
final ProjectExtensionDependency ped = (ProjectExtensionDependency) extension;
91+
92+
runtimeExtensions
93+
.add(new AppArtifactKey(ped.getDeploymentModule().getGroup().toString(),
94+
ped.getDeploymentModule().getName()));
95+
} else if (extension instanceof ArtifactExtensionDependency) {
96+
final ArtifactExtensionDependency aed = (ArtifactExtensionDependency) extension;
97+
98+
runtimeExtensions.add(new AppArtifactKey(aed.getDeploymentModule().getGroupId(),
99+
aed.getDeploymentModule().getArtifactId()));
100+
}
89101
}
90102
}
91103
return runtimeExtensions;

devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/dependency/ApplicationDeploymentClasspathBuilder.java

+19-31
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@
3131
import io.quarkus.gradle.tooling.ToolingUtils;
3232
import io.quarkus.gradle.tooling.dependency.DependencyUtils;
3333
import io.quarkus.gradle.tooling.dependency.ExtensionDependency;
34-
import io.quarkus.gradle.tooling.dependency.IncludedBuildExtensionDependency;
35-
import io.quarkus.gradle.tooling.dependency.LocalExtensionDependency;
3634
import io.quarkus.runtime.LaunchMode;
3735

3836
public class ApplicationDeploymentClasspathBuilder {
@@ -224,11 +222,11 @@ private void setUpDeploymentConfiguration() {
224222
configuration.getDependencies().addAllLater(dependencyListProperty.value(project.provider(() -> {
225223
ConditionalDependenciesEnabler cdEnabler = new ConditionalDependenciesEnabler(project, mode,
226224
enforcedPlatforms);
227-
final Collection<ExtensionDependency> allExtensions = cdEnabler.getAllExtensions();
228-
Set<ExtensionDependency> extensions = collectFirstMetQuarkusExtensions(getRawRuntimeConfiguration(),
225+
final Collection<ExtensionDependency<?>> allExtensions = cdEnabler.getAllExtensions();
226+
Set<ExtensionDependency<?>> extensions = collectFirstMetQuarkusExtensions(getRawRuntimeConfiguration(),
229227
allExtensions);
230228
// Add conditional extensions
231-
for (ExtensionDependency knownExtension : allExtensions) {
229+
for (ExtensionDependency<?> knownExtension : allExtensions) {
232230
if (knownExtension.isConditional()) {
233231
extensions.add(knownExtension);
234232
}
@@ -237,23 +235,13 @@ private void setUpDeploymentConfiguration() {
237235
final Set<ModuleVersionIdentifier> alreadyProcessed = new HashSet<>(extensions.size());
238236
final DependencyHandler dependencies = project.getDependencies();
239237
final Set<Dependency> deploymentDependencies = new HashSet<>();
240-
for (ExtensionDependency extension : extensions) {
241-
if (extension instanceof IncludedBuildExtensionDependency) {
242-
deploymentDependencies.add(((IncludedBuildExtensionDependency) extension).getDeployment());
243-
} else if (extension instanceof LocalExtensionDependency) {
244-
LocalExtensionDependency localExtensionDependency = (LocalExtensionDependency) extension;
245-
deploymentDependencies.add(
246-
dependencies.project(Collections.singletonMap("path",
247-
localExtensionDependency.findDeploymentModulePath())));
248-
} else {
249-
if (!alreadyProcessed.add(extension.getExtensionId())) {
250-
continue;
251-
}
252-
deploymentDependencies.add(dependencies.create(
253-
extension.getDeploymentModule().getGroupId() + ":"
254-
+ extension.getDeploymentModule().getArtifactId() + ":"
255-
+ extension.getDeploymentModule().getVersion()));
238+
for (ExtensionDependency<?> extension : extensions) {
239+
if (!alreadyProcessed.add(extension.getExtensionId())) {
240+
continue;
256241
}
242+
243+
deploymentDependencies.add(
244+
DependencyUtils.createDeploymentDependency(dependencies, extension));
257245
}
258246
return deploymentDependencies;
259247
})));
@@ -307,10 +295,10 @@ public PlatformImports getPlatformImports() {
307295
return platformImports.get(this.platformImportName);
308296
}
309297

310-
private Set<ExtensionDependency> collectFirstMetQuarkusExtensions(Configuration configuration,
311-
Collection<ExtensionDependency> knownExtensions) {
298+
private Set<ExtensionDependency<?>> collectFirstMetQuarkusExtensions(Configuration configuration,
299+
Collection<ExtensionDependency<?>> knownExtensions) {
312300

313-
Set<ExtensionDependency> firstLevelExtensions = new HashSet<>();
301+
Set<ExtensionDependency<?>> firstLevelExtensions = new HashSet<>();
314302
Set<ResolvedDependency> firstLevelModuleDependencies = configuration.getResolvedConfiguration()
315303
.getFirstLevelModuleDependencies();
316304

@@ -322,15 +310,15 @@ private Set<ExtensionDependency> collectFirstMetQuarkusExtensions(Configuration
322310
return firstLevelExtensions;
323311
}
324312

325-
private Set<ExtensionDependency> collectQuarkusExtensions(ResolvedDependency dependency, Set<String> visitedArtifacts,
326-
Collection<ExtensionDependency> knownExtensions) {
313+
private Set<ExtensionDependency<?>> collectQuarkusExtensions(ResolvedDependency dependency, Set<String> visitedArtifacts,
314+
Collection<ExtensionDependency<?>> knownExtensions) {
327315
String artifactKey = String.format("%s:%s", dependency.getModuleGroup(), dependency.getModuleName());
328316
if (!visitedArtifacts.add(artifactKey)) {
329317
return Collections.emptySet();
330318
}
331319

332-
Set<ExtensionDependency> extensions = new LinkedHashSet<>();
333-
ExtensionDependency extension = getExtensionOrNull(dependency.getModuleGroup(), dependency.getModuleName(),
320+
Set<ExtensionDependency<?>> extensions = new LinkedHashSet<>();
321+
ExtensionDependency<?> extension = getExtensionOrNull(dependency.getModuleGroup(), dependency.getModuleName(),
334322
dependency.getModuleVersion(), knownExtensions);
335323
if (extension != null) {
336324
extensions.add(extension);
@@ -342,9 +330,9 @@ private Set<ExtensionDependency> collectQuarkusExtensions(ResolvedDependency dep
342330
return extensions;
343331
}
344332

345-
private ExtensionDependency getExtensionOrNull(String group, String artifact, String version,
346-
Collection<ExtensionDependency> knownExtensions) {
347-
for (ExtensionDependency knownExtension : knownExtensions) {
333+
private ExtensionDependency<?> getExtensionOrNull(String group, String artifact, String version,
334+
Collection<ExtensionDependency<?>> knownExtensions) {
335+
for (ExtensionDependency<?> knownExtension : knownExtensions) {
348336
if (group.equals(knownExtension.getGroup()) && artifact.equals(knownExtension.getName())
349337
&& version.equals(knownExtension.getVersion())) {
350338
return knownExtension;

0 commit comments

Comments
 (0)