Skip to content

Commit

Permalink
Allow multiple source and class directories for upstream projects (#295)
Browse files Browse the repository at this point in the history
  • Loading branch information
DreierF committed Jan 25, 2025
1 parent 00c6470 commit 8e6dfc4
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,11 @@

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -137,18 +140,18 @@ private static List<UpstreamProjectDescriptor> extractUpstreamProjects(Project p
String group = project.getGroup().toString();
String version = project.getVersion().toString();

Map<GAV, File> classDirectoriesByGAV = getDependencyProjectClassesDirectoriesMappedByGav(compileClasspath, group, version);
Map<GAV, File> sourcesDirectoriesByGAV = getDependencyProjectSourceDirectoriesMappedByGav(project, compileClasspath, group, version);
Map<GAV, Set<File>> classDirectoriesByGAV = getDependencyProjectClassesDirectoriesMappedByGav(compileClasspath, group, version);
Map<GAV, Set<File>> sourcesDirectoriesByGAV = getDependencyProjectSourceDirectoriesMappedByGav(project, compileClasspath, group, version);

return classDirectoriesByGAV.entrySet().stream()
.collect(associateClassesDirectoriesToSourcesDirectories(sourcesDirectoriesByGAV));
}

private static Map<GAV, File> getDependencyProjectClassesDirectoriesMappedByGav(Configuration compileClasspath, String group, String version) {
private static Map<GAV, Set<File>> getDependencyProjectClassesDirectoriesMappedByGav(Configuration compileClasspath, String group, String version) {
return compileClasspath.getIncoming()
.artifactView(projects())
.getArtifacts().getArtifacts().stream()
.collect(collectToClassDirectoriesMappedByGav(group, version));
.collect(collectToDirectoriesMappedByGav(group, version));
}

private static Action<ArtifactView.ViewConfiguration> projects() {
Expand All @@ -157,21 +160,26 @@ private static Action<ArtifactView.ViewConfiguration> projects() {
};
}

private static Collector<ResolvedArtifactResult, ?, Map<GAV, File>> collectToClassDirectoriesMappedByGav(String group, String version) {
private static Collector<ResolvedArtifactResult, ?, Map<GAV, Set<File>>> collectToDirectoriesMappedByGav(String group, String version) {
return Collectors.toMap(
a -> {
ProjectComponentIdentifier m = (ProjectComponentIdentifier) a.getId().getComponentIdentifier();
return GAV.of(group, m.getProjectName(), version);
},
ResolvedArtifactResult::getFile
artifact -> Collections.singleton(artifact.getFile()),
(l, r) -> {
Set<File> result = new HashSet<>(l);
result.addAll(r);
return result;
}
);
}

private static Map<GAV, File> getDependencyProjectSourceDirectoriesMappedByGav(Project project, Configuration compileClasspath, String group, String version) {
private static Map<GAV, Set<File>> getDependencyProjectSourceDirectoriesMappedByGav(Project project, Configuration compileClasspath, String group, String version) {
return compileClasspath.getIncoming()
.artifactView(projectSources(project.getObjects()))
.getArtifacts().getArtifacts().stream()
.collect(collectSrcMainJavaMappedByGav(group, version));
.collect(collectToDirectoriesMappedByGav(group, version));
}

private static Action<ArtifactView.ViewConfiguration> projectSources(ObjectFactory objectFactory) {
Expand All @@ -182,16 +190,6 @@ private static Action<ArtifactView.ViewConfiguration> projectSources(ObjectFacto
};
}

private static Collector<ResolvedArtifactResult, ?, Map<GAV, File>> collectSrcMainJavaMappedByGav(String group, String version) {
return Collectors.toMap(
a -> {
ProjectComponentIdentifier m = (ProjectComponentIdentifier) a.getId().getComponentIdentifier();
return GAV.of(group, m.getProjectName(), version);
},
ResolvedArtifactResult::getFile,
(l, r) -> l.getName().equals("java") ? l : r
);
}

private static Spec<ComponentIdentifier> projectDependencies() {
return ci -> ci instanceof ProjectComponentIdentifier;
Expand All @@ -208,7 +206,7 @@ private static Action<AttributeContainer> sourceAttributes(ObjectFactory objectF
};
}

private static Collector<Map.Entry<GAV, File>, ArrayList<UpstreamProjectDescriptor>, ArrayList<UpstreamProjectDescriptor>> associateClassesDirectoriesToSourcesDirectories(Map<GAV, File> sourcesDirectoriesByGav) {
private static Collector<Map.Entry<GAV, Set<File>>, ArrayList<UpstreamProjectDescriptor>, ArrayList<UpstreamProjectDescriptor>> associateClassesDirectoriesToSourcesDirectories(Map<GAV, Set<File>> sourcesDirectoriesByGav) {
return Collector.of(ArrayList::new, (acc, e) -> {
acc.add(new UpstreamProjectDescriptor(
e.getKey(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;

@CacheableTask
public abstract class GenerateMavenPluginDescriptorTask extends AbstractMavenPluginDevelopmentTask {
Expand Down Expand Up @@ -98,14 +99,16 @@ private PluginDescriptor extractPluginDescriptor() {
PluginToolsRequest pluginToolsRequest = createPluginToolsRequest(mavenProject, descriptor);
// process upstream projects in order to scan base classes
getUpstreamProjects().get().forEach(it -> {
File dir = it.getClassesDirs();
Set<File> dirs = it.getClassesDirs();
GAV gav = it.getGav();
DefaultArtifact artifact = new DefaultArtifact(
gav.getGroup(), gav.getArtifactId(), gav.getVersion(), "compile", "jar", null, new DefaultArtifactHandler()
);
artifact.setFile(dir);
pluginToolsRequest.getDependencies().add(artifact);
mavenProject.addProjectReference(mavenProject(gav.getGroup(), gav.getArtifactId(), gav.getVersion(), it.getSourceDirectories(), classesDir));
for (File dir : dirs) {
DefaultArtifact artifact = new DefaultArtifact(
gav.getGroup(), gav.getArtifactId(), gav.getVersion(), "compile", "jar", null, new DefaultArtifactHandler()
);
artifact.setFile(dir);
pluginToolsRequest.getDependencies().add(artifact);
}
mavenProject.addProjectReference(mavenProject(gav.getGroup(), gav.getArtifactId(), gav.getVersion(), it.getSourceDirectories(), classesDir));
});
populatePluginDescriptor(pluginToolsRequest);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,18 @@
import org.gradle.work.NormalizeLineEndings;

import java.io.File;
import java.util.Set;

public final class UpstreamProjectDescriptor {

private final GAV gav;
private final File classesDir;
private final File sourceDirectorie;
private final Set<File> classesDir;
private final Set<File> sourceDirectories;

public UpstreamProjectDescriptor(GAV gav, File classesDir, File sourcesDir) {
public UpstreamProjectDescriptor(GAV gav, Set<File> classesDir, Set<File> sourcesDir) {
this.gav = gav;
this.classesDir = classesDir;
this.sourceDirectorie = sourcesDir;
this.sourceDirectories = sourcesDir;
}

@Nested
Expand All @@ -45,16 +46,16 @@ public GAV getGav() {

@CompileClasspath
@InputFiles
public File getClassesDirs() {
public Set<File> getClassesDirs() {
return classesDir;
}

@InputFiles
@PathSensitive(PathSensitivity.RELATIVE)
@IgnoreEmptyDirectories
@NormalizeLineEndings
public File getSourceDirectories() {
return sourceDirectorie;
public Set<File> getSourceDirectories() {
return sourceDirectories;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,15 @@ class PluginDescriptorGenerationFuncTest extends AbstractPluginFuncTest {
!pluginDescriptor.hasDependency('com.google.guava:guava:28.0-jre')
}

def "supports kotlin project dependency"() {
given:
multiProjectKotlinSetup()

when:
run(":plugin:generateMavenPluginDescriptor")

then:
pluginDescriptor("plugin/").hasDependency('root-project:kotlin-lib:unspecified')
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ trait TestProject {

abstract DescriptorFile getHelpDescriptor()

DescriptorFile pluginDescriptor() {
DescriptorFile.parse(file("build/mavenPlugin/descriptor/META-INF/maven/plugin.xml"))
DescriptorFile pluginDescriptor(dir = "") {
DescriptorFile.parse(file(dir + "build/mavenPlugin/descriptor/META-INF/maven/plugin.xml"))
}

DescriptorFile helpDescriptor(String groupId = "org.example", artifactId = "touch-maven-plugin") {
Expand Down Expand Up @@ -176,4 +176,12 @@ trait TestProject {
}
"""
}

def kotlinClass(String sourceSetName = "main", String className = "Foo") {
file("src/$sourceSetName/java/org/example/${className}.kt") << """
package org.example;
class $className
"""
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,38 @@ class TestRootProject extends ExternalResource implements TestProject {
"""
}
}

def multiProjectKotlinSetup() {
settingsFile.text = "rootProject.name = 'root-project'"
buildFile.text = ""
subproject("kotlin-lib") { project ->
project.buildFile << """
plugins {
id 'org.jetbrains.kotlin.jvm' version '2.1.0'
}
group = "org.example"
version = "1.0.0"
repositories {
mavenCentral()
}
"""
project.kotlinClass()
}
subproject("plugin") { project ->
project.buildFile << """
plugins {
id 'java'
id 'org.gradlex.maven-plugin-development'
}
repositories {
mavenCentral()
}
dependencies {
implementation project(":kotlin-lib")
}
"""
}
}
}

0 comments on commit 8e6dfc4

Please sign in to comment.