Skip to content

Commit 29d5d8d

Browse files
authored
Merge pull request #99 from beryx/groovy
issue #98: Add support for Groovy projects
2 parents 44a76f6 + 44c18e5 commit 29d5d8d

Some content is hidden

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

52 files changed

+703
-18
lines changed

src/main/java/org/javamodularity/moduleplugin/JavaProjectHelper.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77
import org.gradle.api.tasks.SourceSetContainer;
88
import org.gradle.api.tasks.compile.JavaCompile;
99

10+
import java.io.File;
1011
import java.util.Optional;
1112

1213
/**
1314
* Generic helper for Gradle {@link Project} API that is modular and has {@link JavaPlugin} applied.
1415
*/
1516
public final class JavaProjectHelper {
17+
public static final String MERGE_CLASSES_TASK_NAME = "mergeClasses";
1618

1719
private final Project project;
1820

@@ -76,4 +78,13 @@ public JavaCompile compileJavaTask(String taskName) {
7678
}
7779
//endregion
7880

81+
//region DIRECTORIES
82+
public File getMergedDir() {
83+
return new File(project.getBuildDir().getPath() +"/classes/merged");
84+
}
85+
86+
public File getModuleInfoDir() {
87+
return new File(project.getBuildDir().getPath() +"/classes/module-info");
88+
}
89+
//endregion
7990
}

src/main/java/org/javamodularity/moduleplugin/ModuleSystemPlugin.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ private void configureModularity(Project project, String moduleName) {
2424

2525
new CompileTask(project).configureCompileJava();
2626
new CompileModuleInfoTask(project).configureCompileModuleInfoJava();
27+
new MergeClassesTask(project).configureMergeClasses();
2728
new CompileTestTask(project).configureCompileTestJava();
2829
new TestTask(project).configureTestJava();
2930
new RunTask(project).configureRun();

src/main/java/org/javamodularity/moduleplugin/extensions/CompileModuleOptions.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
package org.javamodularity.moduleplugin.extensions;
22

33
import org.gradle.api.Project;
4+
import org.gradle.api.tasks.compile.AbstractCompile;
45
import org.gradle.api.tasks.compile.JavaCompile;
6+
import org.javamodularity.moduleplugin.internal.TaskOption;
57
import org.javamodularity.moduleplugin.tasks.ModuleOptions;
68

9+
import java.io.File;
10+
import java.util.List;
11+
import java.util.stream.Collectors;
12+
713
public class CompileModuleOptions extends ModuleOptions {
814

915
/**
@@ -32,4 +38,21 @@ public void setCompileModuleInfoSeparately(boolean compileModuleInfoSeparately)
3238
this.compileModuleInfoSeparately = compileModuleInfoSeparately;
3339
}
3440

41+
@Override
42+
public void mutateArgs(List<String> args) {
43+
super.mutateArgs(args);
44+
45+
List<File> otherDirs = mergeClassesHelper().otherCompileTaskStream()
46+
.map(AbstractCompile::getDestinationDir)
47+
.collect(Collectors.toList());
48+
if(!otherDirs.isEmpty()) {
49+
new TaskOption(
50+
"--patch-module",
51+
helper().moduleName() + "=" +
52+
otherDirs.stream()
53+
.map(File::getAbsolutePath)
54+
.collect(Collectors.joining(File.pathSeparator))
55+
).mutateArgs(args);
56+
}
57+
}
3558
}

src/main/java/org/javamodularity/moduleplugin/tasks/AbstractExecutionMutator.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,8 @@ protected final String getMainClassName() {
3232
protected final JavaProjectHelper helper() {
3333
return new JavaProjectHelper(project);
3434
}
35+
36+
protected final MergeClassesHelper mergeClassesHelper() {
37+
return new MergeClassesHelper(project);
38+
}
3539
}

src/main/java/org/javamodularity/moduleplugin/tasks/AbstractModulePluginTask.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@ abstract class AbstractModulePluginTask {
1414
protected final JavaProjectHelper helper() {
1515
return new JavaProjectHelper(project);
1616
}
17+
18+
protected final MergeClassesHelper mergeClassesHelper() {
19+
return new MergeClassesHelper(project);
20+
}
1721
}

src/main/java/org/javamodularity/moduleplugin/tasks/CompileJavaTaskMutator.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,17 @@
22

33
import org.gradle.api.Project;
44
import org.gradle.api.file.FileCollection;
5-
import org.gradle.api.tasks.compile.AbstractCompile;
65
import org.gradle.api.tasks.compile.JavaCompile;
76
import org.javamodularity.moduleplugin.JavaProjectHelper;
87
import org.javamodularity.moduleplugin.extensions.CompileModuleOptions;
98

9+
import java.nio.file.Files;
1010
import java.util.ArrayList;
1111
import java.util.List;
12+
import java.util.Optional;
1213

1314
class CompileJavaTaskMutator {
1415

15-
private static final String COMPILE_KOTLIN_TASK_NAME = "compileKotlin";
16-
1716
private final Project project;
1817
/**
1918
* {@linkplain JavaCompile#getClasspath() Classpath} of {@code compileJava} task.
@@ -40,10 +39,16 @@ void modularizeJavaCompileTask(JavaCompile javaCompile) {
4039
List<String> compilerArgs = buildCompilerArgs(javaCompile);
4140
javaCompile.getOptions().setCompilerArgs(compilerArgs);
4241
javaCompile.setClasspath(project.files());
42+
configureSourcepath(javaCompile);
43+
}
4344

44-
// https://github.com/java9-modularity/gradle-modules-plugin/issues/45
45-
helper().findTask(COMPILE_KOTLIN_TASK_NAME, AbstractCompile.class)
46-
.ifPresent(compileKotlin -> javaCompile.setDestinationDir(compileKotlin.getDestinationDir()));
45+
// Setting the sourcepath is necessary when using forked compilation for module-info.java
46+
private void configureSourcepath(JavaCompile javaCompile) {
47+
helper().mainSourceSet().getJava().getSrcDirs().stream()
48+
.map(srcDir -> srcDir.toPath().resolve("module-info.java"))
49+
.filter(Files::exists)
50+
.findFirst()
51+
.ifPresent(path -> javaCompile.getOptions().setSourcepath(project.files(path.getParent())));
4752
}
4853

4954
private List<String> buildCompilerArgs(JavaCompile javaCompile) {

src/main/java/org/javamodularity/moduleplugin/tasks/CompileModuleInfoTask.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.gradle.api.Project;
55
import org.gradle.api.Task;
66
import org.gradle.api.plugins.JavaPlugin;
7+
import org.gradle.api.tasks.bundling.Jar;
78
import org.gradle.api.tasks.compile.JavaCompile;
89
import org.javamodularity.moduleplugin.extensions.CompileModuleOptions;
910

@@ -48,6 +49,13 @@ public void execute(Task task) {
4849
mutator.modularizeJavaCompileTask(compileModuleInfoJava);
4950
}
5051
});
52+
53+
project.getTasks().withType(Jar.class).configureEach(new Action<Jar>() {
54+
@Override
55+
public void execute(Jar jar) {
56+
jar.from(helper().getModuleInfoDir());
57+
}
58+
});
5159
}
5260

5361
/**
@@ -59,7 +67,9 @@ private JavaCompile preconfigureCompileModuleInfoJava(JavaCompile compileJava) {
5967

6068
compileModuleInfoJava.setClasspath(project.files()); // empty
6169
compileModuleInfoJava.setSource(pathToModuleInfoJava());
62-
compileModuleInfoJava.setDestinationDir(compileJava.getDestinationDir());
70+
compileModuleInfoJava.getOptions().setSourcepath(project.files(pathToModuleInfoJava().getParent()));
71+
72+
compileModuleInfoJava.setDestinationDir(helper().getModuleInfoDir());
6373

6474
// we need all the compiled classes before compiling module-info.java
6575
compileModuleInfoJava.dependsOn(compileJava);

src/main/java/org/javamodularity/moduleplugin/tasks/CompileTask.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
import org.gradle.api.Project;
55
import org.gradle.api.Task;
66
import org.gradle.api.plugins.JavaPlugin;
7+
import org.gradle.api.tasks.compile.AbstractCompile;
78
import org.gradle.api.tasks.compile.JavaCompile;
89
import org.javamodularity.moduleplugin.extensions.CompileModuleOptions;
910

10-
public class CompileTask extends AbstractCompileTask {
11+
import java.util.Optional;
1112

13+
public class CompileTask extends AbstractCompileTask {
1214
public CompileTask(Project project) {
1315
super(project);
1416
}
@@ -24,6 +26,13 @@ public void configureCompileJava() {
2426
private void configureCompileJava(JavaCompile compileJava) {
2527
var moduleOptions = compileJava.getExtensions().create("moduleOptions", CompileModuleOptions.class, project);
2628
project.afterEvaluate(p -> {
29+
MergeClassesHelper.POST_JAVA_COMPILE_TASK_NAMES.stream()
30+
.map(name -> helper().findTask(name, AbstractCompile.class))
31+
.flatMap(Optional::stream)
32+
.filter(task -> !task.getSource().isEmpty())
33+
.findAny()
34+
.ifPresent(task -> moduleOptions.setCompileModuleInfoSeparately(true));
35+
2736
if (moduleOptions.getCompileModuleInfoSeparately()) {
2837
compileJava.exclude("module-info.java");
2938
} else {

src/main/java/org/javamodularity/moduleplugin/tasks/CompileTestTask.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ private List<String> buildCompilerArgs(JavaCompile compileTestJava, ModuleOption
4242

4343
String moduleName = helper().moduleName();
4444
var patchModuleExtension = helper().extension(PatchModuleExtension.class);
45-
FileCollection classpath = compileTestJava.getClasspath();
45+
FileCollection classpath = mergeClassesHelper().getMergeAdjustedClasspath(compileTestJava.getClasspath());
4646

4747
patchModuleExtension.buildModulePathOption(classpath).ifPresent(option -> option.mutateArgs(compilerArgs));
4848

src/main/java/org/javamodularity/moduleplugin/tasks/JavadocTask.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public void execute(Task task) {
3636
private void addJavadocOptions(Javadoc javadoc, ModuleOptions moduleOptions) {
3737
var options = (CoreJavadocOptions) javadoc.getOptions();
3838
var patchModuleExtension = helper().extension(PatchModuleExtension.class);
39-
FileCollection classpath = javadoc.getClasspath();
39+
FileCollection classpath = mergeClassesHelper().getMergeAdjustedClasspath(javadoc.getClasspath());
4040

4141
StreamHelper.concat(
4242
patchModuleExtension.buildModulePathOption(classpath).stream(),
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package org.javamodularity.moduleplugin.tasks;
2+
3+
import org.gradle.api.Project;
4+
import org.gradle.api.file.FileCollection;
5+
import org.gradle.api.plugins.JavaPlugin;
6+
import org.gradle.api.tasks.Sync;
7+
import org.gradle.api.tasks.compile.AbstractCompile;
8+
import org.gradle.api.tasks.compile.JavaCompile;
9+
import org.javamodularity.moduleplugin.JavaProjectHelper;
10+
import org.javamodularity.moduleplugin.extensions.CompileModuleOptions;
11+
12+
import java.io.File;
13+
import java.util.HashSet;
14+
import java.util.List;
15+
import java.util.Optional;
16+
import java.util.Set;
17+
import java.util.stream.Stream;
18+
19+
public class MergeClassesHelper {
20+
public static final String MERGE_CLASSES_TASK_NAME = "mergeClasses";
21+
public static List<String> PRE_JAVA_COMPILE_TASK_NAMES = List.of("compileKotlin");
22+
public static List<String> POST_JAVA_COMPILE_TASK_NAMES = List.of("compileGroovy");
23+
24+
private final Project project;
25+
26+
public MergeClassesHelper(Project project) {
27+
this.project = project;
28+
}
29+
30+
public Project project() {
31+
return project;
32+
}
33+
34+
public Stream<AbstractCompile> otherCompileTaskStream() {
35+
return otherCompileTaskNameStream()
36+
.map(name -> helper().findTask(name, AbstractCompile.class))
37+
.flatMap(Optional::stream);
38+
}
39+
40+
private Stream<String> otherCompileTaskNameStream() {
41+
return Stream.concat(
42+
Stream.concat(PRE_JAVA_COMPILE_TASK_NAMES.stream(), POST_JAVA_COMPILE_TASK_NAMES.stream()),
43+
Stream.of(CompileModuleOptions.COMPILE_MODULE_INFO_TASK_NAME)
44+
);
45+
}
46+
47+
public JavaCompile javaCompileTask() {
48+
return helper().task(JavaPlugin.COMPILE_JAVA_TASK_NAME, JavaCompile.class);
49+
}
50+
51+
public Stream<AbstractCompile> allCompileTaskStream() {
52+
return Stream.concat(Stream.of(javaCompileTask()), otherCompileTaskStream());
53+
}
54+
55+
public boolean isMergeRequired() {
56+
return otherCompileTaskStream().filter(task -> !task.getSource().isEmpty()).findAny().isPresent();
57+
}
58+
59+
public Sync createMergeClassesTask() {
60+
return project.getTasks().create(MERGE_CLASSES_TASK_NAME, Sync.class);
61+
}
62+
63+
public FileCollection getMergeAdjustedClasspath(FileCollection classpath) {
64+
if (!isMergeRequired()) {
65+
return classpath;
66+
}
67+
68+
Set<File> files = new HashSet<>(classpath.getFiles());
69+
allCompileTaskStream().map(AbstractCompile::getDestinationDir).forEach(files::remove);
70+
files.add(helper().getMergedDir());
71+
return project.files(files.toArray());
72+
}
73+
74+
private JavaProjectHelper helper() {
75+
return new JavaProjectHelper(project);
76+
}
77+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package org.javamodularity.moduleplugin.tasks;
2+
3+
import org.gradle.api.Project;
4+
import org.gradle.api.plugins.ApplicationPlugin;
5+
import org.gradle.api.plugins.JavaPlugin;
6+
7+
import java.util.Optional;
8+
import java.util.stream.Stream;
9+
10+
public class MergeClassesTask extends AbstractModulePluginTask {
11+
public MergeClassesTask(Project project) {
12+
super(project);
13+
}
14+
15+
public void configureMergeClasses() {
16+
project.afterEvaluate(p -> configureMergeClassesAfterEvaluate());
17+
}
18+
19+
public void configureMergeClassesAfterEvaluate() {
20+
if (!mergeClassesHelper().isMergeRequired()) {
21+
return;
22+
}
23+
24+
var mergeClasses = mergeClassesHelper().createMergeClassesTask();
25+
26+
mergeClassesHelper().allCompileTaskStream().forEach(task -> {
27+
mergeClasses.from(task.getDestinationDir());
28+
mergeClasses.dependsOn(task);
29+
});
30+
mergeClasses.into(helper().getMergedDir());
31+
32+
Stream.of(ApplicationPlugin.TASK_RUN_NAME, JavaPlugin.TEST_TASK_NAME)
33+
.map(helper()::findTask)
34+
.flatMap(Optional::stream)
35+
.forEach(task -> task.dependsOn(mergeClasses));
36+
}
37+
}

src/main/java/org/javamodularity/moduleplugin/tasks/ModuleOptions.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,11 @@ private Stream<TaskOption> buildOptionStream(String flag, Map<String, String> ma
101101
}
102102
//endregion
103103

104-
private JavaProjectHelper helper() {
104+
protected JavaProjectHelper helper() {
105105
return new JavaProjectHelper(project);
106106
}
107+
108+
protected final MergeClassesHelper mergeClassesHelper() {
109+
return new MergeClassesHelper(project);
110+
}
107111
}

src/main/java/org/javamodularity/moduleplugin/tasks/RunTaskMutator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ private List<String> buildJavaExecJvmArgs() {
3939
String moduleName = helper().moduleName();
4040
var patchModuleExtension = helper().extension(PatchModuleExtension.class);
4141
var moduleOptions = execTask.getExtensions().getByType(ModuleOptions.class);
42-
FileCollection classpath = execTask.getClasspath();
4342

4443
moduleOptions.mutateArgs(jvmArgs);
4544

45+
FileCollection classpath = mergeClassesHelper().getMergeAdjustedClasspath(execTask.getClasspath());
4646
patchModuleExtension.buildModulePathOption(classpath).ifPresent(option -> option.mutateArgs(jvmArgs));
4747
patchModuleExtension.resolvePatched(classpath).mutateArgs(jvmArgs);
4848

src/main/java/org/javamodularity/moduleplugin/tasks/TestTask.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,10 @@ private List<String> buildJvmArgs(Test testJava, TestModuleOptions testModuleOpt
6262
var jvmArgs = new ArrayList<>(testJava.getJvmArgs());
6363

6464
var patchModuleExtension = helper().extension(PatchModuleExtension.class);
65-
FileCollection classpath = testJava.getClasspath();
6665

66+
FileCollection classpath = mergeClassesHelper().getMergeAdjustedClasspath(testJava.getClasspath());
6767
patchModuleExtension.buildModulePathOption(classpath).ifPresent(option -> option.mutateArgs(jvmArgs));
68+
6869
patchModuleExtension.resolvePatched(classpath).mutateArgs(jvmArgs);
6970

7071
new TaskOption("--patch-module", buildPatchModuleOptionValue()).mutateArgs(jvmArgs);

0 commit comments

Comments
 (0)