Skip to content

Commit cc4b1f6

Browse files
authored
Merge pull request quarkusio#48250 from n-hass/composite-build-with-kmp
Fix Gradle composite build with Kotlin Multiplatform dependencies
2 parents a59503c + 5a41c2f commit cc4b1f6

File tree

33 files changed

+521
-83
lines changed

33 files changed

+521
-83
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,13 @@
7070
import io.quarkus.gradle.tasks.QuarkusTestConfig;
7171
import io.quarkus.gradle.tasks.QuarkusUpdate;
7272
import io.quarkus.gradle.tasks.services.ForcedPropertieBuildService;
73+
import io.quarkus.gradle.tooling.DefaultProjectDescriptor;
7374
import io.quarkus.gradle.tooling.GradleApplicationModelBuilder;
75+
import io.quarkus.gradle.tooling.ProjectDescriptorBuilder;
7476
import io.quarkus.gradle.tooling.ToolingUtils;
7577
import io.quarkus.gradle.tooling.dependency.DependencyUtils;
7678
import io.quarkus.gradle.tooling.dependency.ExtensionDependency;
7779
import io.quarkus.gradle.tooling.dependency.ProjectExtensionDependency;
78-
import io.quarkus.gradle.workspace.descriptors.DefaultProjectDescriptor;
79-
import io.quarkus.gradle.workspace.descriptors.ProjectDescriptorBuilder;
8080
import io.quarkus.runtime.LaunchMode;
8181

8282
public class QuarkusPlugin implements Plugin<Project> {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@
6464
import io.quarkus.bootstrap.workspace.WorkspaceModule;
6565
import io.quarkus.bootstrap.workspace.WorkspaceModuleId;
6666
import io.quarkus.fs.util.ZipUtils;
67+
import io.quarkus.gradle.tooling.DefaultProjectDescriptor;
68+
import io.quarkus.gradle.tooling.ProjectDescriptor;
6769
import io.quarkus.gradle.tooling.ToolingUtils;
68-
import io.quarkus.gradle.workspace.descriptors.DefaultProjectDescriptor;
69-
import io.quarkus.gradle.workspace.descriptors.ProjectDescriptor;
7070
import io.quarkus.maven.dependency.ArtifactCoords;
7171
import io.quarkus.maven.dependency.ArtifactDependency;
7272
import io.quarkus.maven.dependency.ArtifactKey;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.quarkus.gradle.workspace.descriptors;
1+
package io.quarkus.gradle.tooling;
22

33
import java.io.Serializable;
44

devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/GradleApplicationModelBuilder.java

Lines changed: 25 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import io.quarkus.bootstrap.workspace.DefaultWorkspaceModule;
5454
import io.quarkus.bootstrap.workspace.SourceDir;
5555
import io.quarkus.bootstrap.workspace.WorkspaceModule;
56+
import io.quarkus.bootstrap.workspace.WorkspaceModuleId;
5657
import io.quarkus.fs.util.ZipUtils;
5758
import io.quarkus.gradle.dependency.ApplicationDeploymentClasspathBuilder;
5859
import io.quarkus.maven.dependency.ArtifactCoords;
@@ -355,50 +356,31 @@ private void collectDependencies(org.gradle.api.artifacts.ResolvedDependency res
355356
PathCollection paths = null;
356357
if (workspaceDiscovery && a.getId().getComponentIdentifier() instanceof ProjectComponentIdentifier compId) {
357358
Project projectDep = project.getRootProject().findProject(compId.getProjectPath());
358-
SourceSetContainer sourceSets = projectDep == null ? null
359-
: projectDep.getExtensions().findByType(SourceSetContainer.class);
360359

361360
final String classifier = a.getClassifier();
362361
if (classifier == null || classifier.isEmpty()) {
363362
final IncludedBuild includedBuild = ToolingUtils.includedBuild(project.getRootProject(),
364363
compId.getBuild().getName());
365364
if (includedBuild != null) {
366-
final PathList.Builder pathBuilder = PathList.builder();
367-
368365
if (includedBuild instanceof IncludedBuildInternal ib) {
369366
projectDep = ToolingUtils.includedBuildProject(ib, compId.getProjectPath());
370367
}
371368
if (projectDep != null) {
372-
projectModule = initProjectModuleAndBuildPaths(projectDep, a, modelBuilder, depBuilder,
373-
pathBuilder, SourceSet.MAIN_SOURCE_SET_NAME, false);
374-
addSubstitutedProject(pathBuilder, projectDep.getProjectDir());
369+
initProjectModuleAndBuildPaths(projectDep, a, modelBuilder, depBuilder);
375370
} else {
371+
final PathList.Builder pathBuilder = PathList.builder();
376372
addSubstitutedProject(pathBuilder, includedBuild.getProjectDir());
373+
paths = pathBuilder.build();
377374
}
378-
paths = pathBuilder.build();
379-
} else if (sourceSets != null) {
380-
final PathList.Builder pathBuilder = PathList.builder();
381-
projectModule = initProjectModuleAndBuildPaths(projectDep, a, modelBuilder, depBuilder,
382-
pathBuilder, SourceSet.MAIN_SOURCE_SET_NAME, false);
383-
paths = pathBuilder.build();
384-
}
385-
} else if (sourceSets != null) {
386-
if (SourceSet.TEST_SOURCE_SET_NAME.equals(classifier)) {
387-
final PathList.Builder pathBuilder = PathList.builder();
388-
projectModule = initProjectModuleAndBuildPaths(projectDep, a, modelBuilder, depBuilder,
389-
pathBuilder, SourceSet.TEST_SOURCE_SET_NAME, true);
390-
paths = pathBuilder.build();
391-
} else if ("test-fixtures".equals(classifier)) {
392-
final PathList.Builder pathBuilder = PathList.builder();
393-
projectModule = initProjectModuleAndBuildPaths(projectDep, a, modelBuilder, depBuilder,
394-
pathBuilder, "testFixtures", true);
395-
paths = pathBuilder.build();
375+
} else {
376+
initProjectModuleAndBuildPaths(projectDep, a, modelBuilder, depBuilder);
396377
}
378+
} else {
379+
initProjectModuleAndBuildPaths(projectDep, a, modelBuilder, depBuilder);
397380
}
398381
}
399382

400-
depBuilder.setResolvedPaths(paths == null ? PathList.of(a.getFile().toPath()) : paths)
401-
.setWorkspaceModule(projectModule);
383+
depBuilder.setResolvedPaths(paths == null ? PathList.of(a.getFile().toPath()) : paths);
402384
if (processQuarkusDependency(depBuilder, modelBuilder)) {
403385
if (isFlagOn(flags, COLLECT_TOP_EXTENSION_RUNTIME_NODES)) {
404386
depBuilder.setFlags(DependencyFlags.TOP_LEVEL_RUNTIME_EXTENSION_ARTIFACT);
@@ -410,6 +392,9 @@ private void collectDependencies(org.gradle.api.artifacts.ResolvedDependency res
410392
depBuilder.clearFlag(DependencyFlags.RELOADABLE);
411393
}
412394
modelBuilder.addDependency(depBuilder);
395+
if (projectModule == null && depBuilder.getWorkspaceModule() != null) {
396+
projectModule = depBuilder.getWorkspaceModule().mutable();
397+
}
413398

414399
if (artifactFiles != null) {
415400
artifactFiles.add(a.getFile());
@@ -429,30 +414,23 @@ private static String toNonNullClassifier(String resolvedClassifier) {
429414
return resolvedClassifier == null ? ArtifactCoords.DEFAULT_CLASSIFIER : resolvedClassifier;
430415
}
431416

432-
private WorkspaceModule.Mutable initProjectModuleAndBuildPaths(final Project project,
433-
ResolvedArtifact resolvedArtifact, ApplicationModelBuilder appModel, final ResolvedDependencyBuilder appDep,
434-
PathList.Builder buildPaths, String sourceName, boolean test) {
417+
private void initProjectModuleAndBuildPaths(final Project project,
418+
ResolvedArtifact resolvedArtifact, ApplicationModelBuilder appModel, final ResolvedDependencyBuilder appDep) {
435419

436420
appDep.setWorkspaceModule().setReloadable();
437421

438-
final WorkspaceModule.Mutable projectModule = appModel.getOrCreateProjectModule(
439-
new GAV(resolvedArtifact.getModuleVersion().getId().getGroup(), resolvedArtifact.getName(),
440-
resolvedArtifact.getModuleVersion().getId().getVersion()),
441-
project.getProjectDir(),
442-
project.getBuildDir())
443-
.setBuildFile(project.getBuildFile().toPath());
444-
445-
final String classifier = toNonNullClassifier(resolvedArtifact.getClassifier());
446-
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
447-
initProjectModule(project, projectModule, sourceSets.findByName(sourceName), classifier);
448-
449-
collectDestinationDirs(projectModule.getSources(classifier).getSourceDirs(), buildPaths);
450-
collectDestinationDirs(projectModule.getSources(classifier).getResourceDirs(), buildPaths);
422+
if (appDep.getWorkspaceModule() == null) {
423+
final WorkspaceModule.Mutable projectModule = appModel.getOrCreateProjectModule(
424+
WorkspaceModuleId.of(resolvedArtifact.getModuleVersion().getId().getGroup(), resolvedArtifact.getName(),
425+
resolvedArtifact.getModuleVersion().getId().getVersion()),
426+
project.getProjectDir(),
427+
project.getLayout().getBuildDirectory().get().getAsFile())
428+
.setBuildFile(project.getBuildFile().toPath());
429+
ProjectDescriptorBuilder.initSourceDirs(project, projectModule);
430+
appDep.setWorkspaceModule(projectModule);
431+
}
451432

452-
appModel.addReloadableWorkspaceModule(
453-
ArtifactKey.of(resolvedArtifact.getModuleVersion().getId().getGroup(), resolvedArtifact.getName(), classifier,
454-
ArtifactCoords.TYPE_JAR));
455-
return projectModule;
433+
appModel.addReloadableWorkspaceModule(appDep.getKey());
456434
}
457435

458436
private boolean processQuarkusDependency(ResolvedDependencyBuilder artifactBuilder, ApplicationModelBuilder modelBuilder) {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.quarkus.gradle.workspace.descriptors;
1+
package io.quarkus.gradle.tooling;
22

33
import io.quarkus.bootstrap.workspace.WorkspaceModule;
44
import io.quarkus.bootstrap.workspace.WorkspaceModuleId;
Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.quarkus.gradle.workspace.descriptors;
1+
package io.quarkus.gradle.tooling;
22

33
import java.io.File;
44
import java.util.ArrayList;
@@ -22,44 +22,45 @@ public class ProjectDescriptorBuilder {
2222

2323
public static Provider<DefaultProjectDescriptor> buildForApp(Project project) {
2424
final ProjectDescriptorBuilder builder = new ProjectDescriptorBuilder(project);
25-
project.afterEvaluate(evaluated -> {
26-
final SourceSetContainer srcSets = evaluated.getExtensions().getByType(SourceSetContainer.class);
27-
// Here we are checking JARs will be produced, which directories they will use as the source of content
28-
// and figure out which source directories are processed to produce the content of the JARs.
29-
// It has to be configureEach instead of forEach, apparently to avoid concurrent collection modification in some cases.
30-
evaluated.getTasks().withType(Jar.class).configureEach(jarTask -> {
31-
final String classifier = jarTask.getArchiveClassifier().get();
25+
project.afterEvaluate(evaluated -> ProjectDescriptorBuilder.initSourceDirs(evaluated, builder.moduleBuilder));
26+
return project.getProviders().provider(() -> new DefaultProjectDescriptor(builder.moduleBuilder));
27+
}
3228

33-
final List<File> classesDirs = new ArrayList<>(2);
34-
final List<File> resourcesOutputDirs = new ArrayList<>(2);
35-
collectSourceSetOutput(((DefaultCopySpec) jarTask.getRootSpec()), classesDirs, resourcesOutputDirs);
29+
public static void initSourceDirs(Project project, WorkspaceModule.Mutable result) {
30+
final SourceSetContainer srcSets = project.getExtensions().getByType(SourceSetContainer.class);
31+
// Here we are checking JARs will be produced, which directories they will use as the source of content
32+
// and figure out which source directories are processed to produce the content of the JARs.
33+
// It has to be configureEach instead of forEach, apparently to avoid concurrent collection modification in some cases.
34+
project.getTasks().withType(Jar.class).configureEach(jarTask -> {
35+
final String classifier = jarTask.getArchiveClassifier().get();
3636

37-
final List<SourceDir> sourceDirs = new ArrayList<>(2);
38-
final List<SourceDir> resourceDirs = new ArrayList<>(2);
39-
for (SourceSet srcSet : srcSets) {
40-
for (var classesDir : srcSet.getOutput().getClassesDirs().getFiles()) {
41-
if (classesDirs.contains(classesDir)) {
42-
for (var srcDir : srcSet.getAllJava().getSrcDirs()) {
43-
sourceDirs.add(new LazySourceDir(srcDir.toPath(), classesDir.toPath())); // TODO findGeneratedSourceDir(destDir, sourceSet));
44-
}
45-
}
46-
}
37+
final List<File> classesDirs = new ArrayList<>(2);
38+
final List<File> resourcesOutputDirs = new ArrayList<>(2);
39+
collectSourceSetOutput(((DefaultCopySpec) jarTask.getRootSpec()), classesDirs, resourcesOutputDirs);
4740

48-
final File resourcesOutputDir = srcSet.getOutput().getResourcesDir();
49-
if (resourcesOutputDirs.contains(resourcesOutputDir)) {
50-
for (var dir : srcSet.getResources().getSrcDirs()) {
51-
resourceDirs.add(new LazySourceDir(dir.toPath(), resourcesOutputDir.toPath()));
41+
final List<SourceDir> sourceDirs = new ArrayList<>(2);
42+
final List<SourceDir> resourceDirs = new ArrayList<>(2);
43+
for (SourceSet srcSet : srcSets) {
44+
for (var classesDir : srcSet.getOutput().getClassesDirs().getFiles()) {
45+
if (classesDirs.contains(classesDir)) {
46+
for (var srcDir : srcSet.getAllJava().getSrcDirs()) {
47+
sourceDirs.add(new LazySourceDir(srcDir.toPath(), classesDir.toPath())); // TODO findGeneratedSourceDir(destDir, sourceSet));
5248
}
5349
}
5450
}
5551

56-
if (!sourceDirs.isEmpty() || !resourceDirs.isEmpty()) {
57-
builder.moduleBuilder.addArtifactSources(new DefaultArtifactSources(classifier, sourceDirs, resourceDirs));
52+
final File resourcesOutputDir = srcSet.getOutput().getResourcesDir();
53+
if (resourcesOutputDirs.contains(resourcesOutputDir)) {
54+
for (var dir : srcSet.getResources().getSrcDirs()) {
55+
resourceDirs.add(new LazySourceDir(dir.toPath(), resourcesOutputDir.toPath()));
56+
}
5857
}
59-
});
60-
});
58+
}
6159

62-
return project.getProviders().provider(() -> new DefaultProjectDescriptor(builder.moduleBuilder));
60+
if (!sourceDirs.isEmpty() || !resourceDirs.isEmpty()) {
61+
result.addArtifactSources(new DefaultArtifactSources(classifier, sourceDirs, resourceDirs));
62+
}
63+
});
6364
}
6465

6566
private static void collectSourceSetOutput(DefaultCopySpec spec, List<File> classesDir, List<File> resourcesDir) {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
quarkusPluginId=io.quarkus
2+
quarkusPlatformGroupId=io.quarkus
3+
quarkusPlatformArtifactId=quarkus-bom
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
plugins {
2+
id 'java'
3+
}
4+
5+
group 'io.example'
6+
version '1.0-SNAPSHOT'
7+
8+
dependencies {
9+
implementation project(':project-b')
10+
}
11+
12+
jar {
13+
archiveClassifier = "something"
14+
archiveBaseName = "project-a"
15+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package io.blob;
2+
3+
import io.leaf.SomeCLass;
4+
5+
public class Intermediate {
6+
7+
public void someMethod() {
8+
SomeCLass someClass = new SomeCLass();
9+
someClass.doWork();
10+
}
11+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
plugins {
2+
id 'java'
3+
}
4+
5+
group 'io.example'
6+
version '1.0-SNAPSHOT'

0 commit comments

Comments
 (0)