Skip to content

Commit e003bc2

Browse files
committed
Multiple source sets and capabilities support
1 parent e6a3cdc commit e003bc2

File tree

6 files changed

+141
-54
lines changed

6 files changed

+141
-54
lines changed

src/main/java/org/gradlex/javamodule/dependencies/JavaModuleDependenciesExtension.java

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -212,13 +212,38 @@ private String toProjectName(String moduleNameSuffix) {
212212
}
213213

214214
public Provider<Dependency> create(String moduleName, SourceSet sourceSetWithModuleInfo) {
215+
if (moduleInfoCache.initializedInSettings()) {
216+
return createPrecise(moduleName, sourceSetWithModuleInfo);
217+
} else {
218+
return createWithGuessing(moduleName, sourceSetWithModuleInfo);
219+
}
220+
}
221+
222+
public Provider<Dependency> createPrecise(String moduleName, SourceSet sourceSetWithModuleInfo) {
223+
return getProviders().provider(() -> {
224+
String projectPath = moduleInfoCache.getProjectPath(moduleName);
225+
String capability = moduleInfoCache.getCapability(moduleName);
226+
227+
if (projectPath != null) {
228+
// local project
229+
ProjectDependency projectDependency = (ProjectDependency) getDependencies().create(getProject().project(projectPath));
230+
projectDependency.because(moduleName);
231+
if (capability != null) {
232+
projectDependency.capabilities(c -> c.requireCapabilities(capability));
233+
}
234+
return projectDependency;
235+
} else {
236+
return createExternalDependency(moduleName);
237+
}
238+
});
239+
}
240+
241+
public Provider<Dependency> createWithGuessing(String moduleName, SourceSet sourceSetWithModuleInfo) {
215242
return getProviders().provider(() -> {
216243
Map<String, String> allProjectNamesAndGroups = getProject().getRootProject().getSubprojects().stream().collect(
217244
Collectors.toMap(Project::getName, p -> (String) p.getGroup(), (a, b) -> a));
218245

219-
Provider<String> coordinates = getModuleNameToGA().getting(moduleName).orElse(mapByPrefix(getProviders().provider(() -> moduleName)));
220-
221-
ModuleInfo moduleInfo = getModuleInfoCache().get(sourceSetWithModuleInfo, getProviders());
246+
ModuleInfo moduleInfo = moduleInfoCache.get(sourceSetWithModuleInfo, getProviders());
222247
String ownModuleNamesPrefix = moduleInfo.moduleNamePrefix(getProject().getName(), sourceSetWithModuleInfo.getName(), getModuleNameCheck().get());
223248

224249
String moduleNameSuffix = ownModuleNamesPrefix == null ? null :
@@ -243,34 +268,41 @@ public Provider<Dependency> create(String moduleName, SourceSet sourceSetWithMod
243268
allProjectNamesAndGroups.get(projectName) + ":" + capabilityName));
244269
projectDependency.because(moduleName);
245270
return projectDependency;
246-
} else if (coordinates.isPresent()) {
247-
Map<String, Object> component;
248-
String capability;
249-
if (coordinates.get().contains("|")) {
250-
String[] split = coordinates.get().split("\\|");
251-
component = findGav(split[0], moduleName);
252-
if (split[1].contains(":")) {
253-
capability = split[1];
254-
} else {
255-
// only classifier was specified
256-
capability = split[0] + "-" + split[1];
257-
}
271+
}
272+
273+
return createExternalDependency(moduleName);
274+
});
275+
}
276+
277+
private ModuleDependency createExternalDependency(String moduleName) {
278+
Provider<String> coordinates = getModuleNameToGA().getting(moduleName).orElse(mapByPrefix(getProviders().provider(() -> moduleName)));
279+
if (coordinates.isPresent()) {
280+
Map<String, Object> component;
281+
String capability;
282+
if (coordinates.get().contains("|")) {
283+
String[] split = coordinates.get().split("\\|");
284+
component = findGav(split[0], moduleName);
285+
if (split[1].contains(":")) {
286+
capability = split[1];
258287
} else {
259-
component = findGav(coordinates.get(), moduleName);
260-
capability = null;
261-
}
262-
ModuleDependency dependency = (ModuleDependency) getDependencies().create(component);
263-
dependency.because(moduleName);
264-
if (capability != null) {
265-
dependency.capabilities(c -> c.requireCapability(capability));
288+
// only classifier was specified
289+
capability = split[0] + "-" + split[1];
266290
}
267-
return dependency;
268291
} else {
269-
getProject().getLogger().lifecycle(
270-
"[WARN] [Java Module Dependencies] " + moduleName + "=group:artifact missing in " + getModulesProperties().get().getAsFile());
271-
return null;
292+
component = findGav(coordinates.get(), moduleName);
293+
capability = null;
272294
}
273-
});
295+
ModuleDependency dependency = (ModuleDependency) getDependencies().create(component);
296+
dependency.because(moduleName);
297+
if (capability != null) {
298+
dependency.capabilities(c -> c.requireCapability(capability));
299+
}
300+
return dependency;
301+
} else {
302+
getProject().getLogger().lifecycle(
303+
"[WARN] [Java Module Dependencies] " + moduleName + "=group:artifact missing in " + getModulesProperties().get().getAsFile());
304+
return null;
305+
}
274306
}
275307

276308
/**

src/main/java/org/gradlex/javamodule/dependencies/initialization/JavaModulesExtension.java

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public void module(String folder) {
6060
}
6161

6262
public void module(String folder, Action<Module> action) {
63-
Module module = getObjects().newInstance(Module.class);
63+
Module module = getObjects().newInstance(Module.class, settings.getRootDir());
6464
module.getFolder().set(folder);
6565
action.execute(module);
6666
includeModule(module, new File(settings.getRootDir(), module.getFolder().get()));
@@ -71,7 +71,7 @@ public void modules(String folder) {
7171
}
7272

7373
public void modules(String folder, Action<Modules> action) {
74-
Modules moduleGroup = getObjects().newInstance(Modules.class);
74+
Modules moduleGroup = getObjects().newInstance(Modules.class, new File(settings.getRootDir(), folder));
7575
action.execute(moduleGroup);
7676

7777
File[] projectFolders = new File(settings.getRootDir(), folder).listFiles();
@@ -100,9 +100,8 @@ public void versions(String folder) {
100100
}
101101

102102
private void includeModule(Module module, File projectDir) {
103-
ModuleInfo moduleInfo = moduleInfoCache.get(projectDir, module.getModuleInfoPath().get(),
104-
module.getArtifact().get(), module.getGroup(), settings.getProviders());
105-
if (moduleInfo == ModuleInfo.EMPTY) {
103+
List<String> modulePaths = module.getModuleInfoPaths().get();
104+
if (modulePaths.isEmpty()) {
106105
return;
107106
}
108107

@@ -111,13 +110,21 @@ private void includeModule(Module module, File projectDir) {
111110
ProjectDescriptor project = settings.project(":" + artifact);
112111
project.setProjectDir(projectDir);
113112

114-
String group = module.getGroup().getOrNull();
113+
String mainModuleName = null;
114+
for (String path : modulePaths) {
115+
ModuleInfo moduleInfo = moduleInfoCache.put(projectDir, path,
116+
module.getArtifact().get(), module.getGroup(), settings.getProviders());
117+
if (path.contains("/main/")) {
118+
mainModuleName = moduleInfo.getModuleName();
119+
}
120+
}
115121

122+
String group = module.getGroup().getOrNull();
116123
List<String> plugins = module.getPlugins().get();
117124
if (SUPPORT_PROJECT_ISOLATION) {
118-
settings.getGradle().getLifecycle().beforeProject(new ApplyPluginsAction(artifact, group, plugins, moduleInfo.getModuleName()));
125+
settings.getGradle().getLifecycle().beforeProject(new ApplyPluginsAction(artifact, group, plugins, mainModuleName));
119126
} else {
120-
settings.getGradle().beforeProject(new ApplyPluginsAction(artifact, group, plugins, moduleInfo.getModuleName()));
127+
settings.getGradle().beforeProject(new ApplyPluginsAction(artifact, group, plugins, mainModuleName));
121128
}
122129
}
123130

@@ -127,13 +134,13 @@ private static class ApplyPluginsAction implements IsolatedAction<Project>, Acti
127134
private final String artifact;
128135
private final String group;
129136
private final List<String> plugins;
130-
private final String modueName;
137+
private final String mainModuleName;
131138

132-
public ApplyPluginsAction(String artifact, @Nullable String group, List<String> plugins, String modueName) {
139+
public ApplyPluginsAction(String artifact, @Nullable String group, List<String> plugins, @Nullable String mainModuleName) {
133140
this.artifact = artifact;
134141
this.group = group;
135142
this.plugins = plugins;
136-
this.modueName = modueName;
143+
this.mainModuleName = mainModuleName;
137144
}
138145

139146
@Override
@@ -142,8 +149,10 @@ public void execute(Project project) {
142149
if (group != null) project.setGroup(group);
143150
project.getPlugins().apply(JavaModuleDependenciesPlugin.class);
144151
plugins.forEach(id -> project.getPlugins().apply(id));
145-
project.getPlugins().withType(ApplicationPlugin.class, p ->
146-
project.getExtensions().getByType(JavaApplication.class).getMainModule().set(modueName));
152+
if (mainModuleName != null) {
153+
project.getPlugins().withType(ApplicationPlugin.class, p ->
154+
project.getExtensions().getByType(JavaApplication.class).getMainModule().set(mainModuleName));
155+
}
147156
}
148157
}
149158
}

src/main/java/org/gradlex/javamodule/dependencies/initialization/Module.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,36 @@
33
import org.gradle.api.provider.ListProperty;
44
import org.gradle.api.provider.Property;
55

6+
import javax.inject.Inject;
7+
import java.io.File;
68
import java.nio.file.Paths;
9+
import java.util.Arrays;
10+
import java.util.stream.Collectors;
11+
import java.util.stream.Stream;
712

813
public abstract class Module {
914
public abstract Property<String> getFolder();
1015
public abstract Property<String> getArtifact();
1116
public abstract Property<String> getGroup();
12-
public abstract Property<String> getModuleInfoPath();
17+
public abstract ListProperty<String> getModuleInfoPaths();
1318
public abstract ListProperty<String> getPlugins();
1419

15-
public Module() {
20+
@Inject
21+
public Module(File root) {
1622
getArtifact().convention(getFolder().map(f -> Paths.get(f).getFileName().toString()));
17-
getModuleInfoPath().convention("src/main/java");
23+
getModuleInfoPaths().convention(getFolder().map(projectDir -> listChildren(root, projectDir + "/src")
24+
.map(srcDir -> new File(srcDir, "java/module-info.java"))
25+
.filter(File::exists)
26+
.map(moduleInfo -> "src/" + moduleInfo.getParentFile().getParentFile().getName() + "/java")
27+
.collect(Collectors.toList())));
28+
}
29+
30+
private Stream<File> listChildren(File root, String projectDir) {
31+
File[] children = new File(root, projectDir).listFiles();
32+
return children == null ? Stream.empty() : Arrays.stream(children);
1833
}
1934

2035
public void plugin(String id) {
2136
getPlugins().add(id);
2237
}
23-
24-
2538
}

src/main/java/org/gradlex/javamodule/dependencies/initialization/Modules.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,24 @@
66
import org.gradle.api.provider.Property;
77

88
import javax.inject.Inject;
9+
import java.io.File;
910
import java.util.LinkedHashMap;
1011
import java.util.Map;
1112

1213
public abstract class Modules {
1314

15+
private final File root;
1416
final Map<String, Module> customizedModules = new LinkedHashMap<>();
1517

1618
public abstract Property<String> getGroup();
17-
public abstract Property<String> getModuleInfoPath();
1819
public abstract ListProperty<String> getPlugins();
1920

2021
@Inject
2122
public abstract ObjectFactory getObjects();
2223

23-
public Modules() {
24-
getModuleInfoPath().convention("src/main/java");
24+
@Inject
25+
public Modules(File root) {
26+
this.root = root;
2527
}
2628

2729
public void plugin(String id) {
@@ -35,11 +37,10 @@ public void module(String moduleFolder, Action<Module> action) {
3537
}
3638

3739
Module addModule(String moduleFolder) {
38-
Module module = getObjects().newInstance(Module.class);
40+
Module module = getObjects().newInstance(Module.class, root);
3941
module.getFolder().convention(moduleFolder);
4042
module.getGroup().convention(getGroup());
4143
module.getPlugins().addAll(getPlugins());
42-
module.getModuleInfoPath().convention(getModuleInfoPath());
4344
return module;
4445
}
4546
}

src/main/java/org/gradlex/javamodule/dependencies/internal/utils/ModuleInfoCache.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,17 @@
2424

2525
import javax.inject.Inject;
2626
import java.io.File;
27+
import java.nio.file.Paths;
2728
import java.util.HashMap;
2829
import java.util.Map;
2930

31+
import static org.gradlex.javamodule.dependencies.internal.utils.ModuleNamingUtil.sourceSetToCapabilitySuffix;
32+
3033
public abstract class ModuleInfoCache {
3134

3235
private final Map<File, ModuleInfo> moduleInfo = new HashMap<>();
3336
private final Map<String, String> moduleNameToProjectPath = new HashMap<>();
34-
private final Map<String, String> moduleNameToGA = new HashMap<>();
37+
private final Map<String, String> moduleNameToCapability = new HashMap<>();
3538

3639
@Inject
3740
public abstract ObjectFactory getObjects();
@@ -56,19 +59,28 @@ public ModuleInfo get(SourceSet sourceSet, ProviderFactory providers) {
5659
* @param projectRoot the project that should hold a Java module
5760
* @return parsed module-info.java for the given project assuming a standard Java project layout
5861
*/
59-
public ModuleInfo get(File projectRoot, String moduleInfoPath, String artifact, Provider<String> group, ProviderFactory providers) {
62+
public ModuleInfo put(File projectRoot, String moduleInfoPath, String artifact, Provider<String> group, ProviderFactory providers) {
6063
File folder = new File(projectRoot, moduleInfoPath);
6164
if (maybePutModuleInfo(folder, providers)) {
6265
ModuleInfo thisModuleInfo = moduleInfo.get(folder);
6366
moduleNameToProjectPath.put(thisModuleInfo.getModuleName(), ":" + artifact);
64-
if (group.isPresent()) {
65-
moduleNameToGA.put(thisModuleInfo.getModuleName(), group.get() + ":" + artifact);
67+
String capabilitySuffix = sourceSetToCapabilitySuffix(Paths.get(moduleInfoPath).getFileName().toString());
68+
if (group.isPresent() && capabilitySuffix != null) {
69+
moduleNameToCapability.put(thisModuleInfo.getModuleName(), group.get() + ":" + artifact + "-" + capabilitySuffix);
6670
}
6771
return thisModuleInfo;
6872
}
6973
return ModuleInfo.EMPTY;
7074
}
7175

76+
public String getProjectPath(String moduleName) {
77+
return moduleNameToProjectPath.get(moduleName);
78+
}
79+
80+
public String getCapability(String moduleName) {
81+
return moduleNameToCapability.get(moduleName);
82+
}
83+
7284
private boolean maybePutModuleInfo(File folder, ProviderFactory providers) {
7385
RegularFileProperty moduleInfoFile = getObjects().fileProperty();
7486
moduleInfoFile.set(new File(folder, "module-info.java"));
@@ -81,4 +93,8 @@ private boolean maybePutModuleInfo(File folder, ProviderFactory providers) {
8193
}
8294
return false;
8395
}
96+
97+
public boolean initializedInSettings() {
98+
return false;
99+
}
84100
}

src/main/java/org/gradlex/javamodule/dependencies/internal/utils/ModuleNamingUtil.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ public static String sourceSetToModuleName(String projectName, String sourceSetN
3030
return toDottedCase(projectName) + "." + toDottedCase(sourceSetName);
3131
}
3232

33+
public static String sourceSetToCapabilitySuffix(String sourceSetName) {
34+
if (sourceSetName.equals(SourceSet.MAIN_SOURCE_SET_NAME)) {
35+
return null;
36+
}
37+
return toKebabCase(sourceSetName);
38+
}
39+
3340
/**
3441
* Converts 'camelCase' and 'kebab-case' to 'dotted.case'.
3542
*/
@@ -38,4 +45,13 @@ private static String toDottedCase(String sourceSetName) {
3845
.split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])"))
3946
.map(String::toLowerCase).collect(Collectors.joining("."));
4047
}
48+
49+
/**
50+
* Converts 'camelCase' to 'kebab-case'.
51+
*/
52+
private static String toKebabCase(String sourceSetName) {
53+
return Arrays.stream(sourceSetName
54+
.split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])"))
55+
.map(String::toLowerCase).collect(Collectors.joining("-"));
56+
}
4157
}

0 commit comments

Comments
 (0)