Skip to content

Commit 1cda618

Browse files
committed
Add 'allLocalModules' access to extension
1 parent 2bf40fa commit 1cda618

File tree

5 files changed

+140
-16
lines changed

5 files changed

+140
-16
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Java Module Dependencies Gradle Plugin - Changelog
22

3+
## Version 1.10.1
4+
* [#245](https://github.com/gradlex-org/java-module-dependencies/issues/245) Add 'allLocalModules' access to extension
5+
* Update module name mappings
6+
37
## Version 1.10
48
* [#235](https://github.com/gradlex-org/java-module-dependencies/issues/235) Upgrade to Gradle 9.1, address deprecation
59
* [#221](https://github.com/gradlex-org/java-module-dependencies/issues/221) Upgrade to Gradle 9, remove deprecated features

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

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@
5656
import java.util.Collection;
5757
import java.util.Collections;
5858
import java.util.Comparator;
59-
import java.util.HashMap;
6059
import java.util.List;
6160
import java.util.Map;
6261
import java.util.Optional;
@@ -226,15 +225,14 @@ public Provider<Dependency> create(String moduleName, SourceSet sourceSetWithMod
226225

227226
private Provider<Dependency> createPrecise(String moduleName) {
228227
return getProviders().provider(() -> {
229-
String projectPath = getModuleInfoCache().get().getProjectPath(moduleName);
230-
String capability = getModuleInfoCache().get().getCapability(moduleName);
228+
LocalModule localModule = getModuleInfoCache().get().getLocalModule(moduleName);
231229

232-
if (projectPath != null) {
230+
if (localModule != null) {
233231
// local project
234-
ProjectDependency projectDependency = (ProjectDependency) getDependencies().create(getProject().project(projectPath));
232+
ProjectDependency projectDependency = (ProjectDependency) getDependencies().create(getProject().project(localModule.getProjectPath()));
235233
projectDependency.because(moduleName);
236-
if (capability != null) {
237-
projectDependency.capabilities(c -> c.requireCapabilities(capability));
234+
if (localModule.getCapability() != null) {
235+
projectDependency.capabilities(c -> c.requireCapabilities(localModule.getCapability()));
238236
}
239237
return projectDependency;
240238
} else {
@@ -406,6 +404,13 @@ public Provider<String> moduleName(Provider<String> ga) {
406404
});
407405
}
408406

407+
/**
408+
* @return information about all modules defined in module-info.java files in the build
409+
*/
410+
public Collection<LocalModule> allLocalModules() {
411+
return getModuleInfoCache().get().getAllLocalModules();
412+
}
413+
409414
/**
410415
* @deprecated use the 'org.gradlex.jvm-dependency-conflict-resolution' plugin instead.
411416
*/
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright the GradleX team.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.gradlex.javamodule.dependencies;
18+
19+
import org.jspecify.annotations.Nullable;
20+
21+
import java.io.Serializable;
22+
import java.util.Objects;
23+
24+
public class LocalModule implements Serializable {
25+
private final String moduleName;
26+
private final String projectPath;
27+
@Nullable
28+
private final String capability;
29+
30+
public LocalModule(String moduleName, String projectPath, @Nullable String capability) {
31+
this.moduleName = moduleName;
32+
this.projectPath = projectPath;
33+
this.capability = capability;
34+
}
35+
36+
/**
37+
* @return the module name as defined in the module-info.java file, e.g. 'org.example.module-a'
38+
*/
39+
public String getModuleName() {
40+
return moduleName;
41+
}
42+
43+
/**
44+
* @return the full Gradle project path for the subproject defining the module, e.g. ':module-a'
45+
*/
46+
public String getProjectPath() {
47+
return projectPath;
48+
}
49+
50+
/**
51+
* @return the capability to address the module in a dependency if it is not in the 'main' source set, e.g. 'org.example:module-a-test-fixtures'
52+
*/
53+
@Nullable
54+
public String getCapability() {
55+
return capability;
56+
}
57+
58+
@Override
59+
public String toString() {
60+
return "[" +
61+
"moduleName='" + moduleName + '\'' +
62+
", projectPath='" + projectPath + '\'' +
63+
", capability='" + capability + '\'' +
64+
']';
65+
}
66+
67+
@Override
68+
public boolean equals(Object o) {
69+
if (o == null || getClass() != o.getClass()) return false;
70+
LocalModule that = (LocalModule) o;
71+
return Objects.equals(moduleName, that.moduleName) && Objects.equals(projectPath, that.projectPath) && Objects.equals(capability, that.capability);
72+
}
73+
74+
@Override
75+
public int hashCode() {
76+
return Objects.hash(moduleName, projectPath, capability);
77+
}
78+
}

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

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@
2020
import org.gradle.api.provider.Provider;
2121
import org.gradle.api.provider.ProviderFactory;
2222
import org.gradle.api.tasks.SourceSet;
23+
import org.gradlex.javamodule.dependencies.LocalModule;
2324
import org.jspecify.annotations.Nullable;
2425
import org.slf4j.LoggerFactory;
2526

2627
import javax.inject.Inject;
2728
import java.io.File;
2829
import java.nio.file.Path;
2930
import java.nio.file.Paths;
31+
import java.util.Collection;
3032
import java.util.HashMap;
3133
import java.util.Map;
3234

@@ -37,8 +39,7 @@ public abstract class ModuleInfoCache {
3739

3840
private final boolean initializedInSettings;
3941
private final Map<File, ModuleInfo> moduleInfo = new HashMap<>();
40-
private final Map<String, String> moduleNameToProjectPath = new HashMap<>();
41-
private final Map<String, String> moduleNameToCapability = new HashMap<>();
42+
private final Map<String, LocalModule> localModules = new HashMap<>();
4243

4344
@Inject
4445
public ModuleInfoCache(boolean initializedInSettings) {
@@ -82,28 +83,30 @@ public ModuleInfo put(File projectRoot, String moduleInfoPath, String projectPat
8283
File folder = new File(projectRoot, moduleInfoPath);
8384
if (maybePutModuleInfo(folder, providers)) {
8485
ModuleInfo thisModuleInfo = moduleInfo.get(folder);
85-
moduleNameToProjectPath.put(thisModuleInfo.getModuleName(), projectPath);
86+
String moduleName = thisModuleInfo.getModuleName();
87+
String capability = null;
8688
Path parentDirectory = Paths.get(moduleInfoPath).getParent();
8789
String capabilitySuffix = parentDirectory == null ? null : sourceSetToCapabilitySuffix(parentDirectory.getFileName().toString());
8890
if (capabilitySuffix != null) {
8991
if (group.isPresent()) {
90-
moduleNameToCapability.put(thisModuleInfo.getModuleName(), group.get() + ":" + artifact + "-" + capabilitySuffix);
92+
capability = group.get() + ":" + artifact + "-" + capabilitySuffix;
9193
} else {
9294
LOGGER.lifecycle(
93-
"[WARN] [Java Module Dependencies] " + thisModuleInfo.getModuleName() + " - 'group' not defined!");
95+
"[WARN] [Java Module Dependencies] " + moduleName + " - 'group' not defined!");
9496
}
9597
}
98+
localModules.put(moduleName, new LocalModule(moduleName, projectPath, capability));
9699
return thisModuleInfo;
97100
}
98101
return ModuleInfo.EMPTY;
99102
}
100103

101-
public @Nullable String getProjectPath(String moduleName) {
102-
return moduleNameToProjectPath.get(moduleName);
104+
public @Nullable LocalModule getLocalModule(String moduleName) {
105+
return localModules.get(moduleName);
103106
}
104107

105-
public @Nullable String getCapability(String moduleName) {
106-
return moduleNameToCapability.get(moduleName);
108+
public Collection<LocalModule> getAllLocalModules() {
109+
return localModules.values();
107110
}
108111

109112
private boolean maybePutModuleInfo(File folder, ProviderFactory providers) {

src/test/java/org/gradlex/javamodule/dependencies/test/initialization/SettingsPluginTest.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,4 +282,38 @@ void can_have_moduleinfo_in_custom_location() {
282282
assertThat(requireNonNull(result.task(":lib:compileJava")).getOutcome()).isEqualTo(SUCCESS);
283283
}
284284

285+
@Test
286+
void can_access_local_module_information_in_project() {
287+
build.settingsFile.appendText("""
288+
javaModules {
289+
directory(".") {
290+
group = "org.example"
291+
module("aggregation")
292+
}
293+
}""");
294+
build.libModuleInfoFile.writeText("module abc.lib { }");
295+
build.file("lib/src/testFixtures/java/module-info.java").writeText("module abc.lib.test.fixtures { }");
296+
build.appModuleInfoFile.writeText("""
297+
module org.gradlex.test.app {
298+
requires abc.lib;
299+
}""");
300+
301+
build.file("aggregation/build.gradle.kts").writeText("""
302+
plugins { id("org.gradlex.java-module-dependencies") }
303+
tasks.register("info") {
304+
val info = javaModuleDependencies.allLocalModules().joinToString("\\n")
305+
doLast { println(info) }
306+
}""");
307+
308+
var result = build.runner(":aggregation:info").build();
309+
310+
assertThat(result.getOutput()).contains("""
311+
> Task :aggregation:info
312+
[moduleName='abc.lib.test.fixtures', projectPath=':lib', capability='org.example:lib-test-fixtures']
313+
[moduleName='org.gradlex.test.app', projectPath=':app', capability='null']
314+
[moduleName='abc.lib', projectPath=':lib', capability='null']
315+
316+
""");
317+
}
318+
285319
}

0 commit comments

Comments
 (0)