From a263c3365ee6246e770930f25f487059d800519e Mon Sep 17 00:00:00 2001 From: Arthur McGibbon Date: Tue, 26 Mar 2024 20:22:24 +0000 Subject: [PATCH 01/11] Handle composite builds --- .../bs/gradle/model/GradleIncludedBuild.java | 23 ++++++ .../bs/gradle/model/GradleSourceSets.java | 2 + .../impl/DefaultGradleIncludedBuild.java | 75 +++++++++++++++++++ .../model/impl/DefaultGradleSourceSets.java | 28 +++++-- .../gradle/plugin/SourceSetsModelBuilder.java | 19 ++++- .../internal/gradle/GradleApiConnector.java | 28 +++++++ .../gradle/GradleApiConnectorTest.java | 14 ++++ testProjects/composite-build/build.gradle | 0 .../composite-build/projectA/build.gradle | 3 + .../composite-build/projectA/settings.gradle | 1 + .../composite-build/projectB/build.gradle | 3 + .../composite-build/projectB/settings.gradle | 1 + testProjects/composite-build/settings.gradle | 4 + 13 files changed, 194 insertions(+), 7 deletions(-) create mode 100644 model/src/main/java/com/microsoft/java/bs/gradle/model/GradleIncludedBuild.java create mode 100644 model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleIncludedBuild.java create mode 100644 testProjects/composite-build/build.gradle create mode 100644 testProjects/composite-build/projectA/build.gradle create mode 100644 testProjects/composite-build/projectA/settings.gradle create mode 100644 testProjects/composite-build/projectB/build.gradle create mode 100644 testProjects/composite-build/projectB/settings.gradle create mode 100644 testProjects/composite-build/settings.gradle diff --git a/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleIncludedBuild.java b/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleIncludedBuild.java new file mode 100644 index 00000000..1e0a22cd --- /dev/null +++ b/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleIncludedBuild.java @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +package com.microsoft.java.bs.gradle.model; + +import java.io.File; +import java.io.Serializable; + +/** + * Represents a source set in a Gradle project. + */ +public interface GradleIncludedBuild extends Serializable { + + /** + * Equivalent to {@code org.gradle.api.initialization.IncludedBuild.getName()}. + */ + public String getName(); + + /** + * Equivalent to {@code org.gradle.api.initialization.IncludedBuild.getProjectDir()}. + */ + public File getProjectDir(); +} diff --git a/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSets.java b/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSets.java index b6ad63bd..ff126181 100644 --- a/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSets.java +++ b/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSets.java @@ -10,5 +10,7 @@ * List of all Gradle source set instances. */ public interface GradleSourceSets extends Serializable { + public List getGradleIncludedBuilds(); + public List getGradleSourceSets(); } diff --git a/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleIncludedBuild.java b/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleIncludedBuild.java new file mode 100644 index 00000000..97774625 --- /dev/null +++ b/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleIncludedBuild.java @@ -0,0 +1,75 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +package com.microsoft.java.bs.gradle.model.impl; + +import java.io.File; +import java.util.Objects; + +import com.microsoft.java.bs.gradle.model.GradleIncludedBuild; + +/** + * Default implementation of {@link GradleIncludedBuild}. + */ +public class DefaultGradleIncludedBuild implements GradleIncludedBuild { + private static final long serialVersionUID = 1L; + + private String name; + + private File projectDir; + + public DefaultGradleIncludedBuild() {} + + public DefaultGradleIncludedBuild(String name, File projectDir) { + this.name = name; + this.projectDir = projectDir; + } + + /** + * Copy constructor. + * + * @param gradleIncludedBuild the included build set to copy from. + */ + public DefaultGradleIncludedBuild(GradleIncludedBuild gradleIncludedBuild) { + this(gradleIncludedBuild.getName(), gradleIncludedBuild.getProjectDir()); + } + + @Override + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public File getProjectDir() { + return projectDir; + } + + public void setProjectDir(File projectDir) { + this.projectDir = projectDir; + } + + @Override + public int hashCode() { + return Objects.hash(name, projectDir); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + DefaultGradleIncludedBuild other = (DefaultGradleIncludedBuild) obj; + return Objects.equals(name, other.name) + && Objects.equals(projectDir, other.projectDir); + } +} diff --git a/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSets.java b/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSets.java index 31771c8d..b4cab465 100644 --- a/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSets.java +++ b/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSets.java @@ -7,6 +7,7 @@ import java.util.Objects; import java.util.stream.Collectors; +import com.microsoft.java.bs.gradle.model.GradleIncludedBuild; import com.microsoft.java.bs.gradle.model.GradleSourceSet; import com.microsoft.java.bs.gradle.model.GradleSourceSets; @@ -16,9 +17,13 @@ public class DefaultGradleSourceSets implements GradleSourceSets { private static final long serialVersionUID = 1L; + private List gradleIncludedBuilds; + private List gradleSourceSets; - public DefaultGradleSourceSets(List gradleSourceSets) { + public DefaultGradleSourceSets(List gradleIncludedBuilds, + List gradleSourceSets) { + this.gradleIncludedBuilds = gradleIncludedBuilds; this.gradleSourceSets = gradleSourceSets; } @@ -26,10 +31,22 @@ public DefaultGradleSourceSets(List gradleSourceSets) { * Copy constructor. */ public DefaultGradleSourceSets(GradleSourceSets sourceSets) { - this.gradleSourceSets = sourceSets.getGradleSourceSets().stream() - .map(DefaultGradleSourceSet::new).collect(Collectors.toList()); + this(sourceSets.getGradleIncludedBuilds().stream() + .map(DefaultGradleIncludedBuild::new).collect(Collectors.toList()), + sourceSets.getGradleSourceSets().stream() + .map(DefaultGradleSourceSet::new).collect(Collectors.toList())); + } + + @Override + public List getGradleIncludedBuilds() { + return gradleIncludedBuilds; } + public void setGradleIncludedBuilds(List gradleIncludedBuilds) { + this.gradleIncludedBuilds = gradleIncludedBuilds; + } + + @Override public List getGradleSourceSets() { return gradleSourceSets; } @@ -40,7 +57,7 @@ public void setGradleSourceSets(List gradleSourceSets) { @Override public int hashCode() { - return Objects.hash(gradleSourceSets); + return Objects.hash(gradleIncludedBuilds, gradleSourceSets); } @Override @@ -55,6 +72,7 @@ public boolean equals(Object obj) { return false; } DefaultGradleSourceSets other = (DefaultGradleSourceSets) obj; - return Objects.equals(gradleSourceSets, other.gradleSourceSets); + return Objects.equals(gradleIncludedBuilds, other.gradleIncludedBuilds) + && Objects.equals(gradleSourceSets, other.gradleSourceSets); } } diff --git a/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/SourceSetsModelBuilder.java b/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/SourceSetsModelBuilder.java index a7037120..26b5d316 100644 --- a/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/SourceSetsModelBuilder.java +++ b/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/SourceSetsModelBuilder.java @@ -6,12 +6,14 @@ import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import org.gradle.api.Project; import org.gradle.api.Task; @@ -19,6 +21,7 @@ import org.gradle.api.file.Directory; import org.gradle.api.file.FileCollection; import org.gradle.api.file.SourceDirectorySet; +import org.gradle.api.invocation.Gradle; import org.gradle.api.internal.file.copy.DefaultCopySpec; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.SourceSetContainer; @@ -29,12 +32,14 @@ import org.gradle.tooling.provider.model.ToolingModelBuilder; import org.gradle.util.GradleVersion; +import com.microsoft.java.bs.gradle.model.GradleIncludedBuild; import com.microsoft.java.bs.gradle.model.BuildTargetDependency; import com.microsoft.java.bs.gradle.model.GradleSourceSets; -import com.microsoft.java.bs.gradle.model.LanguageExtension; +import com.microsoft.java.bs.gradle.model.impl.DefaultGradleIncludedBuild; import com.microsoft.java.bs.gradle.model.impl.DefaultBuildTargetDependency; import com.microsoft.java.bs.gradle.model.impl.DefaultGradleSourceSet; import com.microsoft.java.bs.gradle.model.impl.DefaultGradleSourceSets; +import com.microsoft.java.bs.gradle.model.LanguageExtension; import com.microsoft.java.bs.gradle.plugin.dependency.DependencyCollector; /** @@ -49,12 +54,21 @@ public boolean canBuild(String modelName) { @Override public Object buildAll(String modelName, Project rootProject) { Set allProject = rootProject.getAllprojects(); + List includedBuilds = new ArrayList<>(); SourceSetCache cache = new SourceSetCache(); // this set is used to eliminate the source, resource and output // directories from the module dependencies. Set exclusionFromDependencies = new HashSet<>(); // mapping Gradle source set to our customized model. for (Project project : allProject) { + // lookup included builds regardless of sourcesets existing + Gradle gradle = project.getGradle(); + includedBuilds.addAll( + gradle.getIncludedBuilds() + .stream().map(includedBuild -> + new DefaultGradleIncludedBuild(includedBuild.getName(), includedBuild.getProjectDir())) + .collect(Collectors.toList())); + SourceSetContainer sourceSets = getSourceSetContainer(project); if (sourceSets == null || sourceSets.isEmpty()) { continue; @@ -185,7 +199,8 @@ public Object buildAll(String modelName, Project rootProject) { } - return new DefaultGradleSourceSets(new LinkedList<>(cache.getAllGradleSourceSets())); + return new DefaultGradleSourceSets(includedBuilds, + new LinkedList<>(cache.getAllGradleSourceSets())); } private void setModuleDependencies(SourceSetCache cache, Set exclusionFromDependencies) { diff --git a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java index 1e4e5a01..a7ef55c5 100644 --- a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java +++ b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java @@ -9,6 +9,8 @@ import java.io.File; import java.io.IOException; import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -31,6 +33,8 @@ import com.microsoft.java.bs.core.internal.reporter.DefaultProgressReporter; import com.microsoft.java.bs.core.internal.reporter.ProgressReporter; import com.microsoft.java.bs.core.internal.reporter.TestReportReporter; +import com.microsoft.java.bs.gradle.model.GradleIncludedBuild; +import com.microsoft.java.bs.gradle.model.GradleSourceSet; import com.microsoft.java.bs.gradle.model.GradleSourceSets; import com.microsoft.java.bs.gradle.model.impl.DefaultGradleSourceSets; @@ -70,6 +74,19 @@ private String getGradleVersion(ProjectConnection connection) { return model.getGradle().getGradleVersion(); } + private List getIncludedBuildGradleSourceSets(File initScript, URI projectUri) { + // add source sets for this project + List allSourceSets = new ArrayList<>(); + GradleSourceSets gradleSourceSets = getGradleSourceSets(initScript, projectUri); + allSourceSets.addAll(gradleSourceSets.getGradleSourceSets()); + // check included builds for more source sets to add + for (GradleIncludedBuild includedBuild : gradleSourceSets.getGradleIncludedBuilds()) { + URI includedProjectUri = includedBuild.getProjectDir().toURI(); + allSourceSets.addAll(getIncludedBuildGradleSourceSets(initScript, includedProjectUri)); + } + return allSourceSets; + } + /** * Get the source sets of the Gradle project. * @@ -82,6 +99,17 @@ public GradleSourceSets getGradleSourceSets(URI projectUri, BuildClient client) if (!initScript.exists()) { throw new IllegalStateException("Failed to get init script file."); } + List allSourceSets = getIncludedBuildGradleSourceSets(initScript, projectUri); + + return new DefaultGradleSourceSets(Collections.emptyList(), allSourceSets); + } + + private GradleSourceSets getGradleSourceSets(File initScript, URI projectUri) { + TaskProgressReporter reporter = new TaskProgressReporter(new DefaultProgressReporter()); + String summary = ""; + StatusCode statusCode = StatusCode.OK; + try (ProjectConnection connection = getGradleConnector(projectUri).connect()) { + reporter.taskStarted("Connect to Gradle Daemon"); ProgressReporter reporter = new DefaultProgressReporter(client); ByteArrayOutputStream errorOut = new ByteArrayOutputStream(); try (ProjectConnection connection = getGradleConnector(projectUri).connect(); diff --git a/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java b/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java index 15cf94f3..c8591116 100644 --- a/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java +++ b/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java @@ -137,6 +137,20 @@ void testGetGradleHasTests() { assertFalse(findSourceSet(gradleSourceSets, "test-tag [testFixtures]").hasTests()); } + @Test + void testCompositeBuild() { + File projectDir = projectPath.resolve("composite-build").toFile(); + PreferenceManager preferenceManager = new PreferenceManager(); + preferenceManager.setPreferences(new Preferences()); + GradleApiConnector connector = new GradleApiConnector(preferenceManager); + GradleSourceSets gradleSourceSets = connector.getGradleSourceSets(projectDir.toURI()); + assertEquals(4, gradleSourceSets.getGradleSourceSets().size()); + findSourceSet(gradleSourceSets, "projectA [main]"); + findSourceSet(gradleSourceSets, "projectA [test]"); + findSourceSet(gradleSourceSets, "projectB [main]"); + findSourceSet(gradleSourceSets, "projectB [test]"); + } + private void assertHasBuildTargetDependency(GradleSourceSet sourceSet, GradleSourceSet dependency) { boolean exists = sourceSet.getBuildTargetDependencies().stream() diff --git a/testProjects/composite-build/build.gradle b/testProjects/composite-build/build.gradle new file mode 100644 index 00000000..e69de29b diff --git a/testProjects/composite-build/projectA/build.gradle b/testProjects/composite-build/projectA/build.gradle new file mode 100644 index 00000000..bde068fc --- /dev/null +++ b/testProjects/composite-build/projectA/build.gradle @@ -0,0 +1,3 @@ +plugins { + id 'java' +} diff --git a/testProjects/composite-build/projectA/settings.gradle b/testProjects/composite-build/projectA/settings.gradle new file mode 100644 index 00000000..91314219 --- /dev/null +++ b/testProjects/composite-build/projectA/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'projectA' \ No newline at end of file diff --git a/testProjects/composite-build/projectB/build.gradle b/testProjects/composite-build/projectB/build.gradle new file mode 100644 index 00000000..bde068fc --- /dev/null +++ b/testProjects/composite-build/projectB/build.gradle @@ -0,0 +1,3 @@ +plugins { + id 'java' +} diff --git a/testProjects/composite-build/projectB/settings.gradle b/testProjects/composite-build/projectB/settings.gradle new file mode 100644 index 00000000..36447f1f --- /dev/null +++ b/testProjects/composite-build/projectB/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'projectB' \ No newline at end of file diff --git a/testProjects/composite-build/settings.gradle b/testProjects/composite-build/settings.gradle new file mode 100644 index 00000000..e44da015 --- /dev/null +++ b/testProjects/composite-build/settings.gradle @@ -0,0 +1,4 @@ +rootProject.name = 'composite-build' + +includeBuild 'projectA' +includeBuild 'projectB' \ No newline at end of file From a2884349a26e8d7f64b2565e21348548829a18b3 Mon Sep 17 00:00:00 2001 From: Tanish-Ranjan Date: Fri, 31 May 2024 23:27:28 +0530 Subject: [PATCH 02/11] Synchronize branch composite-builds with main branch This commit updates this branch to reflect the latest changes in the main branch. This ensures the branch stays aligned with the current development state. --- .../core/internal/gradle/GradleApiConnector.java | 15 +++++---------- .../internal/gradle/GradleApiConnectorTest.java | 2 +- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java index a7ef55c5..6e28fcc7 100644 --- a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java +++ b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java @@ -74,15 +74,15 @@ private String getGradleVersion(ProjectConnection connection) { return model.getGradle().getGradleVersion(); } - private List getIncludedBuildGradleSourceSets(File initScript, URI projectUri) { + private List getIncludedBuildGradleSourceSets(File initScript, URI projectUri, BuildClient client) { // add source sets for this project List allSourceSets = new ArrayList<>(); - GradleSourceSets gradleSourceSets = getGradleSourceSets(initScript, projectUri); + GradleSourceSets gradleSourceSets = getGradleSourceSets(initScript, projectUri, client); allSourceSets.addAll(gradleSourceSets.getGradleSourceSets()); // check included builds for more source sets to add for (GradleIncludedBuild includedBuild : gradleSourceSets.getGradleIncludedBuilds()) { URI includedProjectUri = includedBuild.getProjectDir().toURI(); - allSourceSets.addAll(getIncludedBuildGradleSourceSets(initScript, includedProjectUri)); + allSourceSets.addAll(getIncludedBuildGradleSourceSets(initScript, includedProjectUri, client)); } return allSourceSets; } @@ -99,17 +99,12 @@ public GradleSourceSets getGradleSourceSets(URI projectUri, BuildClient client) if (!initScript.exists()) { throw new IllegalStateException("Failed to get init script file."); } - List allSourceSets = getIncludedBuildGradleSourceSets(initScript, projectUri); + List allSourceSets = getIncludedBuildGradleSourceSets(initScript, projectUri, client); return new DefaultGradleSourceSets(Collections.emptyList(), allSourceSets); } - private GradleSourceSets getGradleSourceSets(File initScript, URI projectUri) { - TaskProgressReporter reporter = new TaskProgressReporter(new DefaultProgressReporter()); - String summary = ""; - StatusCode statusCode = StatusCode.OK; - try (ProjectConnection connection = getGradleConnector(projectUri).connect()) { - reporter.taskStarted("Connect to Gradle Daemon"); + private GradleSourceSets getGradleSourceSets(File initScript, URI projectUri, BuildClient client) { ProgressReporter reporter = new DefaultProgressReporter(client); ByteArrayOutputStream errorOut = new ByteArrayOutputStream(); try (ProjectConnection connection = getGradleConnector(projectUri).connect(); diff --git a/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java b/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java index c8591116..250e1f8b 100644 --- a/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java +++ b/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java @@ -143,7 +143,7 @@ void testCompositeBuild() { PreferenceManager preferenceManager = new PreferenceManager(); preferenceManager.setPreferences(new Preferences()); GradleApiConnector connector = new GradleApiConnector(preferenceManager); - GradleSourceSets gradleSourceSets = connector.getGradleSourceSets(projectDir.toURI()); + GradleSourceSets gradleSourceSets = connector.getGradleSourceSets(projectDir.toURI(), null); assertEquals(4, gradleSourceSets.getGradleSourceSets().size()); findSourceSet(gradleSourceSets, "projectA [main]"); findSourceSet(gradleSourceSets, "projectA [test]"); From 1d0f36d7c5a789be7c6b7a7e09ac305ff59d3690 Mon Sep 17 00:00:00 2001 From: Tanish-Ranjan Date: Sat, 1 Jun 2024 01:47:50 +0530 Subject: [PATCH 03/11] Address checkstyle warnings in GradleApiConnector.java This commit addresses checkstyle warnings identified in the GradleApiConnector.java --- .../internal/gradle/GradleApiConnector.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java index 6e28fcc7..109aef5b 100644 --- a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java +++ b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java @@ -74,7 +74,11 @@ private String getGradleVersion(ProjectConnection connection) { return model.getGradle().getGradleVersion(); } - private List getIncludedBuildGradleSourceSets(File initScript, URI projectUri, BuildClient client) { + private List getIncludedBuildGradleSourceSets( + File initScript, + URI projectUri, + BuildClient client + ) { // add source sets for this project List allSourceSets = new ArrayList<>(); GradleSourceSets gradleSourceSets = getGradleSourceSets(initScript, projectUri, client); @@ -82,7 +86,9 @@ private List getIncludedBuildGradleSourceSets(File initScript, // check included builds for more source sets to add for (GradleIncludedBuild includedBuild : gradleSourceSets.getGradleIncludedBuilds()) { URI includedProjectUri = includedBuild.getProjectDir().toURI(); - allSourceSets.addAll(getIncludedBuildGradleSourceSets(initScript, includedProjectUri, client)); + allSourceSets.addAll( + getIncludedBuildGradleSourceSets(initScript, includedProjectUri, client) + ); } return allSourceSets; } @@ -99,12 +105,17 @@ public GradleSourceSets getGradleSourceSets(URI projectUri, BuildClient client) if (!initScript.exists()) { throw new IllegalStateException("Failed to get init script file."); } - List allSourceSets = getIncludedBuildGradleSourceSets(initScript, projectUri, client); + List allSourceSets = + getIncludedBuildGradleSourceSets(initScript, projectUri, client); return new DefaultGradleSourceSets(Collections.emptyList(), allSourceSets); } - private GradleSourceSets getGradleSourceSets(File initScript, URI projectUri, BuildClient client) { + private GradleSourceSets getGradleSourceSets( + File initScript, + URI projectUri, + BuildClient client + ) { ProgressReporter reporter = new DefaultProgressReporter(client); ByteArrayOutputStream errorOut = new ByteArrayOutputStream(); try (ProjectConnection connection = getGradleConnector(projectUri).connect(); From 54f0f59341ee8a934e8a3e384d9d9a5c2a16aaad Mon Sep 17 00:00:00 2001 From: Tanish-Ranjan Date: Thu, 13 Jun 2024 11:25:02 +0530 Subject: [PATCH 04/11] Refactor CompositeBuild Tests This commit refactors the CompositeBuild tests for better organization and clarity. Changes: - Moved the existing composite-build test to a new test named "composite-build-1" - Added a new test named "composite-build-2" to verify dependency substitution functionality. --- .../gradle/GradleApiConnectorTest.java | 18 ++++++++++++++++-- .../build.gradle | 0 .../projectA/build.gradle | 0 .../projectA/settings.gradle | 0 .../projectB/build.gradle | 0 .../projectB/settings.gradle | 0 .../settings.gradle | 2 +- testProjects/composite-build-2/build.gradle | 11 +++++++++++ .../composite-build-2/my-app/app/build.gradle | 19 +++++++++++++++++++ .../src/main/java/org/sample/myapp/Main.java | 16 ++++++++++++++++ .../composite-build-2/my-app/settings.gradle | 3 +++ .../my-utils/number-utils/build.gradle | 10 ++++++++++ .../java/org/sample/numberutils/Numbers.java | 5 +++++ .../my-utils/settings.gradle | 3 +++ .../my-utils/string-utils/build.gradle | 14 ++++++++++++++ .../java/org/sample/stringutils/Strings.java | 13 +++++++++++++ .../composite-build-2/settings.gradle | 4 ++++ 17 files changed, 115 insertions(+), 3 deletions(-) rename testProjects/{composite-build => composite-build-1}/build.gradle (100%) rename testProjects/{composite-build => composite-build-1}/projectA/build.gradle (100%) rename testProjects/{composite-build => composite-build-1}/projectA/settings.gradle (100%) rename testProjects/{composite-build => composite-build-1}/projectB/build.gradle (100%) rename testProjects/{composite-build => composite-build-1}/projectB/settings.gradle (100%) rename testProjects/{composite-build => composite-build-1}/settings.gradle (55%) create mode 100644 testProjects/composite-build-2/build.gradle create mode 100644 testProjects/composite-build-2/my-app/app/build.gradle create mode 100644 testProjects/composite-build-2/my-app/app/src/main/java/org/sample/myapp/Main.java create mode 100644 testProjects/composite-build-2/my-app/settings.gradle create mode 100644 testProjects/composite-build-2/my-utils/number-utils/build.gradle create mode 100644 testProjects/composite-build-2/my-utils/number-utils/src/main/java/org/sample/numberutils/Numbers.java create mode 100644 testProjects/composite-build-2/my-utils/settings.gradle create mode 100644 testProjects/composite-build-2/my-utils/string-utils/build.gradle create mode 100644 testProjects/composite-build-2/my-utils/string-utils/src/main/java/org/sample/stringutils/Strings.java create mode 100644 testProjects/composite-build-2/settings.gradle diff --git a/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java b/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java index 250e1f8b..a70b9c93 100644 --- a/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java +++ b/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java @@ -138,8 +138,8 @@ void testGetGradleHasTests() { } @Test - void testCompositeBuild() { - File projectDir = projectPath.resolve("composite-build").toFile(); + void testCompositeBuild1() { + File projectDir = projectPath.resolve("composite-build-1").toFile(); PreferenceManager preferenceManager = new PreferenceManager(); preferenceManager.setPreferences(new Preferences()); GradleApiConnector connector = new GradleApiConnector(preferenceManager); @@ -151,6 +151,20 @@ void testCompositeBuild() { findSourceSet(gradleSourceSets, "projectB [test]"); } + @Test + void testCompositeBuild2() { + File projectDir = projectPath.resolve("composite-build-2").toFile(); + PreferenceManager preferenceManager = new PreferenceManager(); + preferenceManager.setPreferences(new Preferences()); + GradleApiConnector connector = new GradleApiConnector(preferenceManager); + GradleSourceSets gradleSourceSets = connector.getGradleSourceSets(projectDir.toURI(), null); + assertEquals(4, gradleSourceSets.getGradleSourceSets().size()); + /*findSourceSet(gradleSourceSets, "projectA [main]"); + findSourceSet(gradleSourceSets, "projectA [test]"); + findSourceSet(gradleSourceSets, "projectB [main]"); + findSourceSet(gradleSourceSets, "projectB [test]");*/ + } + private void assertHasBuildTargetDependency(GradleSourceSet sourceSet, GradleSourceSet dependency) { boolean exists = sourceSet.getBuildTargetDependencies().stream() diff --git a/testProjects/composite-build/build.gradle b/testProjects/composite-build-1/build.gradle similarity index 100% rename from testProjects/composite-build/build.gradle rename to testProjects/composite-build-1/build.gradle diff --git a/testProjects/composite-build/projectA/build.gradle b/testProjects/composite-build-1/projectA/build.gradle similarity index 100% rename from testProjects/composite-build/projectA/build.gradle rename to testProjects/composite-build-1/projectA/build.gradle diff --git a/testProjects/composite-build/projectA/settings.gradle b/testProjects/composite-build-1/projectA/settings.gradle similarity index 100% rename from testProjects/composite-build/projectA/settings.gradle rename to testProjects/composite-build-1/projectA/settings.gradle diff --git a/testProjects/composite-build/projectB/build.gradle b/testProjects/composite-build-1/projectB/build.gradle similarity index 100% rename from testProjects/composite-build/projectB/build.gradle rename to testProjects/composite-build-1/projectB/build.gradle diff --git a/testProjects/composite-build/projectB/settings.gradle b/testProjects/composite-build-1/projectB/settings.gradle similarity index 100% rename from testProjects/composite-build/projectB/settings.gradle rename to testProjects/composite-build-1/projectB/settings.gradle diff --git a/testProjects/composite-build/settings.gradle b/testProjects/composite-build-1/settings.gradle similarity index 55% rename from testProjects/composite-build/settings.gradle rename to testProjects/composite-build-1/settings.gradle index e44da015..6a7980da 100644 --- a/testProjects/composite-build/settings.gradle +++ b/testProjects/composite-build-1/settings.gradle @@ -1,4 +1,4 @@ -rootProject.name = 'composite-build' +rootProject.name = 'composite-build-1' includeBuild 'projectA' includeBuild 'projectB' \ No newline at end of file diff --git a/testProjects/composite-build-2/build.gradle b/testProjects/composite-build-2/build.gradle new file mode 100644 index 00000000..ba39c38f --- /dev/null +++ b/testProjects/composite-build-2/build.gradle @@ -0,0 +1,11 @@ +defaultTasks 'run' + +tasks.register('run') { + dependsOn gradle.includedBuild('my-app').task(':app:run') +} + +task checkAll { + dependsOn gradle.includedBuild('my-app').task(':app:check') + dependsOn gradle.includedBuild('my-utils').task(':number-utils:check') + dependsOn gradle.includedBuild('my-utils').task(':string-utils:check') +} diff --git a/testProjects/composite-build-2/my-app/app/build.gradle b/testProjects/composite-build-2/my-app/app/build.gradle new file mode 100644 index 00000000..0bf1f45f --- /dev/null +++ b/testProjects/composite-build-2/my-app/app/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'application' +} + +application { + mainClass = 'org.sample.myapp.Main' +} + +dependencies { + implementation 'org.sample:number-utils:1.0' + implementation 'org.sample:string-utils:1.0' +} + +group 'org.sample' +version '1.0' + +repositories { + mavenCentral() +} \ No newline at end of file diff --git a/testProjects/composite-build-2/my-app/app/src/main/java/org/sample/myapp/Main.java b/testProjects/composite-build-2/my-app/app/src/main/java/org/sample/myapp/Main.java new file mode 100644 index 00000000..062d8bf0 --- /dev/null +++ b/testProjects/composite-build-2/my-app/app/src/main/java/org/sample/myapp/Main.java @@ -0,0 +1,16 @@ +package org.sample.myapp; + +import org.sample.numberutils.Numbers; +import org.sample.stringutils.Strings; + +public class Main { + + public static void main(String... args) { + new Main().printAnswer(); + } + + public void printAnswer() { + String output = Strings.concat(" The answer is ", Numbers.add(19, 23)); + System.out.println(output); + } +} diff --git a/testProjects/composite-build-2/my-app/settings.gradle b/testProjects/composite-build-2/my-app/settings.gradle new file mode 100644 index 00000000..553a0170 --- /dev/null +++ b/testProjects/composite-build-2/my-app/settings.gradle @@ -0,0 +1,3 @@ +rootProject.name = 'my-app' + +include 'app' diff --git a/testProjects/composite-build-2/my-utils/number-utils/build.gradle b/testProjects/composite-build-2/my-utils/number-utils/build.gradle new file mode 100644 index 00000000..acc7834d --- /dev/null +++ b/testProjects/composite-build-2/my-utils/number-utils/build.gradle @@ -0,0 +1,10 @@ +plugins { + id 'java-library' +} + +group 'org.sample' +version '1.0' + +repositories { + mavenCentral() +} diff --git a/testProjects/composite-build-2/my-utils/number-utils/src/main/java/org/sample/numberutils/Numbers.java b/testProjects/composite-build-2/my-utils/number-utils/src/main/java/org/sample/numberutils/Numbers.java new file mode 100644 index 00000000..d36210c3 --- /dev/null +++ b/testProjects/composite-build-2/my-utils/number-utils/src/main/java/org/sample/numberutils/Numbers.java @@ -0,0 +1,5 @@ +package org.sample.numberutils; + +public class Numbers { + public static int add(int left, int right) { return left + right; } +} diff --git a/testProjects/composite-build-2/my-utils/settings.gradle b/testProjects/composite-build-2/my-utils/settings.gradle new file mode 100644 index 00000000..50e0f268 --- /dev/null +++ b/testProjects/composite-build-2/my-utils/settings.gradle @@ -0,0 +1,3 @@ +rootProject.name = 'my-utils' + +include 'number-utils', 'string-utils' diff --git a/testProjects/composite-build-2/my-utils/string-utils/build.gradle b/testProjects/composite-build-2/my-utils/string-utils/build.gradle new file mode 100644 index 00000000..0e797e3b --- /dev/null +++ b/testProjects/composite-build-2/my-utils/string-utils/build.gradle @@ -0,0 +1,14 @@ +plugins { + id 'java-library' +} + +group 'org.sample' +version '1.0' + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.apache.commons:commons-lang3:3.4' +} diff --git a/testProjects/composite-build-2/my-utils/string-utils/src/main/java/org/sample/stringutils/Strings.java b/testProjects/composite-build-2/my-utils/string-utils/src/main/java/org/sample/stringutils/Strings.java new file mode 100644 index 00000000..db81d7e8 --- /dev/null +++ b/testProjects/composite-build-2/my-utils/string-utils/src/main/java/org/sample/stringutils/Strings.java @@ -0,0 +1,13 @@ +package org.sample.stringutils; + +import org.apache.commons.lang3.StringUtils; + +public class Strings { + public static String concat(Object left, Object right) { + return strip(left) + " " + strip(right); + } + + private static String strip(Object val) { + return StringUtils.strip(String.valueOf(val)); + } +} diff --git a/testProjects/composite-build-2/settings.gradle b/testProjects/composite-build-2/settings.gradle new file mode 100644 index 00000000..b3fd0a94 --- /dev/null +++ b/testProjects/composite-build-2/settings.gradle @@ -0,0 +1,4 @@ +rootProject.name = 'my-composite-2' + +includeBuild 'my-app' +includeBuild 'my-utils' From 17b3f464ad001a9dafce74d25c01e6f54a956092 Mon Sep 17 00:00:00 2001 From: Tanish-Ranjan Date: Fri, 21 Jun 2024 16:14:29 +0530 Subject: [PATCH 05/11] Retrieve source sets using dedicated build action (GetSourceSetsAction) This commit improves the code by delegating the logic for retrieving source sets to a dedicated build action named `GetSourceSetsAction`. This enhances code organization and separation of concerns. Additionally, the test case `testCompositeBuild2` has been updated to verify if the new approach correctly retrieves the expected source sets. --- .../bs/gradle/model/GradleSourceSets.java | 2 - .../model/impl/DefaultGradleSourceSets.java | 17 +---- .../gradle/plugin/SourceSetsModelBuilder.java | 12 +--- .../internal/gradle/GradleApiConnector.java | 65 ++++--------------- .../gradle/actions/GetSourceSetsAction.java | 65 +++++++++++++++++++ .../gradle/GradleApiConnectorTest.java | 12 ++-- 6 files changed, 89 insertions(+), 84 deletions(-) create mode 100644 server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java diff --git a/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSets.java b/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSets.java index ff126181..b6ad63bd 100644 --- a/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSets.java +++ b/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSets.java @@ -10,7 +10,5 @@ * List of all Gradle source set instances. */ public interface GradleSourceSets extends Serializable { - public List getGradleIncludedBuilds(); - public List getGradleSourceSets(); } diff --git a/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSets.java b/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSets.java index b4cab465..5441d7aa 100644 --- a/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSets.java +++ b/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSets.java @@ -21,9 +21,7 @@ public class DefaultGradleSourceSets implements GradleSourceSets { private List gradleSourceSets; - public DefaultGradleSourceSets(List gradleIncludedBuilds, - List gradleSourceSets) { - this.gradleIncludedBuilds = gradleIncludedBuilds; + public DefaultGradleSourceSets(List gradleSourceSets) { this.gradleSourceSets = gradleSourceSets; } @@ -31,21 +29,10 @@ public DefaultGradleSourceSets(List gradleIncludedBuilds, * Copy constructor. */ public DefaultGradleSourceSets(GradleSourceSets sourceSets) { - this(sourceSets.getGradleIncludedBuilds().stream() - .map(DefaultGradleIncludedBuild::new).collect(Collectors.toList()), - sourceSets.getGradleSourceSets().stream() + this(sourceSets.getGradleSourceSets().stream() .map(DefaultGradleSourceSet::new).collect(Collectors.toList())); } - @Override - public List getGradleIncludedBuilds() { - return gradleIncludedBuilds; - } - - public void setGradleIncludedBuilds(List gradleIncludedBuilds) { - this.gradleIncludedBuilds = gradleIncludedBuilds; - } - @Override public List getGradleSourceSets() { return gradleSourceSets; diff --git a/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/SourceSetsModelBuilder.java b/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/SourceSetsModelBuilder.java index 26b5d316..90187fe1 100644 --- a/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/SourceSetsModelBuilder.java +++ b/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/SourceSetsModelBuilder.java @@ -54,21 +54,12 @@ public boolean canBuild(String modelName) { @Override public Object buildAll(String modelName, Project rootProject) { Set allProject = rootProject.getAllprojects(); - List includedBuilds = new ArrayList<>(); SourceSetCache cache = new SourceSetCache(); // this set is used to eliminate the source, resource and output // directories from the module dependencies. Set exclusionFromDependencies = new HashSet<>(); // mapping Gradle source set to our customized model. for (Project project : allProject) { - // lookup included builds regardless of sourcesets existing - Gradle gradle = project.getGradle(); - includedBuilds.addAll( - gradle.getIncludedBuilds() - .stream().map(includedBuild -> - new DefaultGradleIncludedBuild(includedBuild.getName(), includedBuild.getProjectDir())) - .collect(Collectors.toList())); - SourceSetContainer sourceSets = getSourceSetContainer(project); if (sourceSets == null || sourceSets.isEmpty()) { continue; @@ -199,8 +190,7 @@ public Object buildAll(String modelName, Project rootProject) { } - return new DefaultGradleSourceSets(includedBuilds, - new LinkedList<>(cache.getAllGradleSourceSets())); + return new DefaultGradleSourceSets(new LinkedList<>(cache.getAllGradleSourceSets())); } private void setModuleDependencies(SourceSetCache cache, Set exclusionFromDependencies) { diff --git a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java index 109aef5b..ebb5dc24 100644 --- a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java +++ b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java @@ -9,19 +9,17 @@ import java.io.File; import java.io.IOException; import java.net.URI; -import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang3.exception.ExceptionUtils; +import com.microsoft.java.bs.core.internal.gradle.actions.GetSourceSetsAction; +import org.gradle.tooling.BuildActionExecuter; import org.gradle.tooling.BuildException; import org.gradle.tooling.BuildLauncher; import org.gradle.tooling.GradleConnectionException; import org.gradle.tooling.GradleConnector; -import org.gradle.tooling.ModelBuilder; import org.gradle.tooling.ProjectConnection; import org.gradle.tooling.TestLauncher; import org.gradle.tooling.events.OperationType; @@ -33,8 +31,6 @@ import com.microsoft.java.bs.core.internal.reporter.DefaultProgressReporter; import com.microsoft.java.bs.core.internal.reporter.ProgressReporter; import com.microsoft.java.bs.core.internal.reporter.TestReportReporter; -import com.microsoft.java.bs.gradle.model.GradleIncludedBuild; -import com.microsoft.java.bs.gradle.model.GradleSourceSet; import com.microsoft.java.bs.gradle.model.GradleSourceSets; import com.microsoft.java.bs.gradle.model.impl.DefaultGradleSourceSets; @@ -74,30 +70,11 @@ private String getGradleVersion(ProjectConnection connection) { return model.getGradle().getGradleVersion(); } - private List getIncludedBuildGradleSourceSets( - File initScript, - URI projectUri, - BuildClient client - ) { - // add source sets for this project - List allSourceSets = new ArrayList<>(); - GradleSourceSets gradleSourceSets = getGradleSourceSets(initScript, projectUri, client); - allSourceSets.addAll(gradleSourceSets.getGradleSourceSets()); - // check included builds for more source sets to add - for (GradleIncludedBuild includedBuild : gradleSourceSets.getGradleIncludedBuilds()) { - URI includedProjectUri = includedBuild.getProjectDir().toURI(); - allSourceSets.addAll( - getIncludedBuildGradleSourceSets(initScript, includedProjectUri, client) - ); - } - return allSourceSets; - } - /** * Get the source sets of the Gradle project. * * @param projectUri uri of the project - * @param client connection to BSP client + * @param client connection to BSP client * @return an instance of {@link GradleSourceSets} */ public GradleSourceSets getGradleSourceSets(URI projectUri, BuildClient client) { @@ -105,39 +82,25 @@ public GradleSourceSets getGradleSourceSets(URI projectUri, BuildClient client) if (!initScript.exists()) { throw new IllegalStateException("Failed to get init script file."); } - List allSourceSets = - getIncludedBuildGradleSourceSets(initScript, projectUri, client); - - return new DefaultGradleSourceSets(Collections.emptyList(), allSourceSets); - } - - private GradleSourceSets getGradleSourceSets( - File initScript, - URI projectUri, - BuildClient client - ) { ProgressReporter reporter = new DefaultProgressReporter(client); ByteArrayOutputStream errorOut = new ByteArrayOutputStream(); try (ProjectConnection connection = getGradleConnector(projectUri).connect(); - errorOut) { - ModelBuilder customModelBuilder = Utils.getModelBuilder( - connection, - preferenceManager.getPreferences(), - GradleSourceSets.class - ); - customModelBuilder.addProgressListener(reporter, - OperationType.FILE_DOWNLOAD, OperationType.PROJECT_CONFIGURATION) + errorOut) { + BuildActionExecuter buildExecutor + = connection.action(new GetSourceSetsAction()); + buildExecutor.addProgressListener(reporter, + OperationType.FILE_DOWNLOAD, OperationType.PROJECT_CONFIGURATION) .setStandardError(errorOut) .addArguments("--init-script", initScript.getAbsolutePath()); if (Boolean.getBoolean("bsp.plugin.debug.enabled")) { - customModelBuilder.addJvmArguments( + buildExecutor.addJvmArguments( "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"); } - customModelBuilder.addJvmArguments("-Dbsp.gradle.supportedLanguages=" + buildExecutor.addJvmArguments("-Dbsp.gradle.supportedLanguages=" + String.join(",", preferenceManager.getClientSupportedLanguages())); // since the model returned from Gradle TAPI is a wrapped object, here we re-construct it // via a copy constructor and return as a POJO. - return new DefaultGradleSourceSets(customModelBuilder.get()); + return new DefaultGradleSourceSets(buildExecutor.run()); } catch (GradleConnectionException | IllegalStateException | IOException e) { String summary = e.getMessage(); if (errorOut.size() > 0) { @@ -152,15 +115,15 @@ private GradleSourceSets getGradleSourceSets( * Request Gradle daemon to run the tasks. * * @param projectUri uri of the project - * @param reporter reporter on feedback from Gradle - * @param tasks tasks to run + * @param reporter reporter on feedback from Gradle + * @param tasks tasks to run */ public StatusCode runTasks(URI projectUri, ProgressReporter reporter, String... tasks) { // Don't issue a start progress update - the listener will pick that up automatically final ByteArrayOutputStream errorOut = new ByteArrayOutputStream(); StatusCode statusCode = StatusCode.OK; try (ProjectConnection connection = getGradleConnector(projectUri).connect(); - errorOut + errorOut ) { BuildLauncher launcher = Utils.getBuildLauncher(connection, preferenceManager.getPreferences()); diff --git a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java new file mode 100644 index 00000000..1f01703a --- /dev/null +++ b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java @@ -0,0 +1,65 @@ +package com.microsoft.java.bs.core.internal.gradle.actions; + +import com.microsoft.java.bs.gradle.model.GradleSourceSet; +import com.microsoft.java.bs.gradle.model.GradleSourceSets; +import com.microsoft.java.bs.gradle.model.impl.DefaultGradleSourceSets; +import org.gradle.tooling.BuildAction; +import org.gradle.tooling.BuildController; +import org.gradle.tooling.model.gradle.GradleBuild; + +import java.util.List; +import java.util.Map; +import java.util.HashMap; +import java.util.stream.Collectors; + +/** + * {@link BuildAction} that retrieves {@link GradleSourceSets} from a Gradle build, + * handling both normal and composite builds. + */ +public class GetSourceSetsAction implements BuildAction { + + /** + * Executes the build action and retrieves source sets from the Gradle build. + * + * @return A {@link DefaultGradleSourceSets} object containing all retrieved source sets. + */ + @Override + public GradleSourceSets execute(BuildController buildController) { + Map> sourceSets = new HashMap<>(); + GradleBuild buildModel = buildController.getBuildModel(); + String rootProjectName = buildModel.getRootProject().getName(); + fetchModels(buildController, buildModel, sourceSets, rootProjectName); + return new DefaultGradleSourceSets(sourceSets.values().stream().flatMap(List::stream) + .collect(Collectors.toList())); + } + + /** + * Fetches source sets from the provided Gradle build model and stores them in a map categorized by project name. + * + * @param buildController The Gradle build controller used to interact with the build. + * @param build The Gradle build model representing the current build. + * @param sourceSets A map to store the retrieved source sets categorized by project name. + * @param buildName The name of the root project in the build. + */ + private void fetchModels( + BuildController buildController, + GradleBuild build, + Map> sourceSets, + String buildName + ) { + if (sourceSets.containsKey(buildName)) { + return; + } + sourceSets.put( + buildName, + buildController + .findModel(build.getRootProject(), GradleSourceSets.class) + .getGradleSourceSets() + ); + for (GradleBuild includedBuild : build.getIncludedBuilds()) { + String includedBuildName = includedBuild.getRootProject().getName(); + fetchModels(buildController, includedBuild, sourceSets, includedBuildName); + } + } + +} diff --git a/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java b/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java index a70b9c93..c6be57dd 100644 --- a/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java +++ b/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java @@ -158,11 +158,13 @@ void testCompositeBuild2() { preferenceManager.setPreferences(new Preferences()); GradleApiConnector connector = new GradleApiConnector(preferenceManager); GradleSourceSets gradleSourceSets = connector.getGradleSourceSets(projectDir.toURI(), null); - assertEquals(4, gradleSourceSets.getGradleSourceSets().size()); - /*findSourceSet(gradleSourceSets, "projectA [main]"); - findSourceSet(gradleSourceSets, "projectA [test]"); - findSourceSet(gradleSourceSets, "projectB [main]"); - findSourceSet(gradleSourceSets, "projectB [test]");*/ + assertEquals(6, gradleSourceSets.getGradleSourceSets().size()); + findSourceSet(gradleSourceSets, "app [main]"); + findSourceSet(gradleSourceSets, "app [test]"); + findSourceSet(gradleSourceSets, "string-utils [main]"); + findSourceSet(gradleSourceSets, "string-utils [test]"); + findSourceSet(gradleSourceSets, "number-utils [test]"); + findSourceSet(gradleSourceSets, "number-utils [test]"); } private void assertHasBuildTargetDependency(GradleSourceSet sourceSet, From 8217878cedb091b8c698695c3149f261861194f5 Mon Sep 17 00:00:00 2001 From: Tanish-Ranjan Date: Thu, 27 Jun 2024 12:06:40 +0530 Subject: [PATCH 06/11] Refactored source sets handling and dependency mapping logic. Changes: - Removed unused files: DefaultGradleIncludedBuild.java and GradleIncludedBuild.java - Removed leftover implementations from DefaultGradleSourceSets.java - Moved dependency mapping logic from SourceSetsModelBuilder.java to GetSourceSetsBuildAction.java - Introduced GradleSourceSetsMetadata.java for passing information between SourceSetsModelBuilder and GetSourceSetsBuildAction for dependency mapping - Updated GradleApiConnectorTest.java#testCompositeBuild2 to verify proper dependency mapping - Updated GradleBuildServerPluginTest.java#getGradleSourceSets to receive GradleSourceSetsMetadata and return expected GradleSourceSets --- .../bs/gradle/model/GradleIncludedBuild.java | 23 ---- .../bs/gradle/model/GradleSourceSets.java | 2 +- .../model/GradleSourceSetsMetadata.java | 15 +++ .../impl/DefaultGradleIncludedBuild.java | 75 ----------- .../model/impl/DefaultGradleSourceSets.java | 17 ++- .../impl/DefaultGradleSourceSetsMetadata.java | 69 +++++++++++ .../gradle/plugin/SourceSetsModelBuilder.java | 117 +++++++----------- .../plugin/GradleBuildServerPluginTest.java | 16 ++- .../internal/gradle/GradleApiConnector.java | 2 +- .../gradle/actions/GetSourceSetsAction.java | 74 +++++++---- .../gradle/GradleApiConnectorTest.java | 8 +- 11 files changed, 202 insertions(+), 216 deletions(-) delete mode 100644 model/src/main/java/com/microsoft/java/bs/gradle/model/GradleIncludedBuild.java create mode 100644 model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSetsMetadata.java delete mode 100644 model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleIncludedBuild.java create mode 100644 model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSetsMetadata.java diff --git a/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleIncludedBuild.java b/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleIncludedBuild.java deleted file mode 100644 index 1e0a22cd..00000000 --- a/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleIncludedBuild.java +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - -package com.microsoft.java.bs.gradle.model; - -import java.io.File; -import java.io.Serializable; - -/** - * Represents a source set in a Gradle project. - */ -public interface GradleIncludedBuild extends Serializable { - - /** - * Equivalent to {@code org.gradle.api.initialization.IncludedBuild.getName()}. - */ - public String getName(); - - /** - * Equivalent to {@code org.gradle.api.initialization.IncludedBuild.getProjectDir()}. - */ - public File getProjectDir(); -} diff --git a/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSets.java b/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSets.java index b6ad63bd..af1dec73 100644 --- a/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSets.java +++ b/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSets.java @@ -10,5 +10,5 @@ * List of all Gradle source set instances. */ public interface GradleSourceSets extends Serializable { - public List getGradleSourceSets(); + List getGradleSourceSets(); } diff --git a/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSetsMetadata.java b/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSetsMetadata.java new file mode 100644 index 00000000..1e07b5a6 --- /dev/null +++ b/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSetsMetadata.java @@ -0,0 +1,15 @@ +package com.microsoft.java.bs.gradle.model; + +import java.io.File; +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * Provides necessary information to build SourceSets. + */ +public interface GradleSourceSetsMetadata extends Serializable { + Map> getGradleSourceSets(); + + Map getOutputsToSourceSet(); +} diff --git a/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleIncludedBuild.java b/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleIncludedBuild.java deleted file mode 100644 index 97774625..00000000 --- a/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleIncludedBuild.java +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. - -package com.microsoft.java.bs.gradle.model.impl; - -import java.io.File; -import java.util.Objects; - -import com.microsoft.java.bs.gradle.model.GradleIncludedBuild; - -/** - * Default implementation of {@link GradleIncludedBuild}. - */ -public class DefaultGradleIncludedBuild implements GradleIncludedBuild { - private static final long serialVersionUID = 1L; - - private String name; - - private File projectDir; - - public DefaultGradleIncludedBuild() {} - - public DefaultGradleIncludedBuild(String name, File projectDir) { - this.name = name; - this.projectDir = projectDir; - } - - /** - * Copy constructor. - * - * @param gradleIncludedBuild the included build set to copy from. - */ - public DefaultGradleIncludedBuild(GradleIncludedBuild gradleIncludedBuild) { - this(gradleIncludedBuild.getName(), gradleIncludedBuild.getProjectDir()); - } - - @Override - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public File getProjectDir() { - return projectDir; - } - - public void setProjectDir(File projectDir) { - this.projectDir = projectDir; - } - - @Override - public int hashCode() { - return Objects.hash(name, projectDir); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - DefaultGradleIncludedBuild other = (DefaultGradleIncludedBuild) obj; - return Objects.equals(name, other.name) - && Objects.equals(projectDir, other.projectDir); - } -} diff --git a/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSets.java b/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSets.java index 5441d7aa..93f00431 100644 --- a/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSets.java +++ b/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSets.java @@ -3,22 +3,19 @@ package com.microsoft.java.bs.gradle.model.impl; +import com.microsoft.java.bs.gradle.model.GradleSourceSet; +import com.microsoft.java.bs.gradle.model.GradleSourceSets; + import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -import com.microsoft.java.bs.gradle.model.GradleIncludedBuild; -import com.microsoft.java.bs.gradle.model.GradleSourceSet; -import com.microsoft.java.bs.gradle.model.GradleSourceSets; - /** * Default implementation of {@link GradleSourceSets}. */ public class DefaultGradleSourceSets implements GradleSourceSets { private static final long serialVersionUID = 1L; - private List gradleIncludedBuilds; - private List gradleSourceSets; public DefaultGradleSourceSets(List gradleSourceSets) { @@ -30,7 +27,8 @@ public DefaultGradleSourceSets(List gradleSourceSets) { */ public DefaultGradleSourceSets(GradleSourceSets sourceSets) { this(sourceSets.getGradleSourceSets().stream() - .map(DefaultGradleSourceSet::new).collect(Collectors.toList())); + .map(DefaultGradleSourceSet::new) + .collect(Collectors.toList())); } @Override @@ -44,7 +42,7 @@ public void setGradleSourceSets(List gradleSourceSets) { @Override public int hashCode() { - return Objects.hash(gradleIncludedBuilds, gradleSourceSets); + return Objects.hash(gradleSourceSets); } @Override @@ -59,7 +57,6 @@ public boolean equals(Object obj) { return false; } DefaultGradleSourceSets other = (DefaultGradleSourceSets) obj; - return Objects.equals(gradleIncludedBuilds, other.gradleIncludedBuilds) - && Objects.equals(gradleSourceSets, other.gradleSourceSets); + return Objects.equals(gradleSourceSets, other.gradleSourceSets); } } diff --git a/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSetsMetadata.java b/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSetsMetadata.java new file mode 100644 index 00000000..b776dd96 --- /dev/null +++ b/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSetsMetadata.java @@ -0,0 +1,69 @@ +package com.microsoft.java.bs.gradle.model.impl; + +import com.microsoft.java.bs.gradle.model.GradleSourceSet; +import com.microsoft.java.bs.gradle.model.GradleSourceSetsMetadata; + +import java.io.File; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * Default implementation of {@link DefaultGradleSourceSetsMetadata}. + */ +public class DefaultGradleSourceSetsMetadata implements GradleSourceSetsMetadata { + + private Map> gradleSourceSets; + private Map outputsToSourceSet; + + public DefaultGradleSourceSetsMetadata( + Map> gradleSourceSets, + Map outputsToSourceSet + ) { + this.gradleSourceSets = gradleSourceSets; + this.outputsToSourceSet = outputsToSourceSet; + } + + // TODO: Copy constructor + + public DefaultGradleSourceSetsMetadata(GradleSourceSetsMetadata gradleSourceSetsMetadata) { + this(gradleSourceSetsMetadata.getGradleSourceSets(), + gradleSourceSetsMetadata.getOutputsToSourceSet()); + } + + @Override + public Map> getGradleSourceSets() { + return gradleSourceSets; + } + + public void setGradleSourceSets(Map> gradleSourceSets) { + this.gradleSourceSets = gradleSourceSets; + } + + @Override + public Map getOutputsToSourceSet() { + return outputsToSourceSet; + } + + public void setOutputsToSourceSet(Map outputsToSourceSet) { + this.outputsToSourceSet = outputsToSourceSet; + } + + @Override + public int hashCode() { + return Objects.hash(gradleSourceSets, outputsToSourceSet); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + DefaultGradleSourceSetsMetadata that = (DefaultGradleSourceSetsMetadata) obj; + return Objects.equals(gradleSourceSets, that.gradleSourceSets) + && Objects.equals(outputsToSourceSet, that.outputsToSourceSet); + } +} diff --git a/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/SourceSetsModelBuilder.java b/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/SourceSetsModelBuilder.java index 90187fe1..c4342b1b 100644 --- a/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/SourceSetsModelBuilder.java +++ b/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/SourceSetsModelBuilder.java @@ -6,22 +6,21 @@ import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.stream.Collectors; +import com.microsoft.java.bs.gradle.model.GradleSourceSet; +import com.microsoft.java.bs.gradle.model.GradleSourceSetsMetadata; import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.file.CopySpec; import org.gradle.api.file.Directory; import org.gradle.api.file.FileCollection; import org.gradle.api.file.SourceDirectorySet; -import org.gradle.api.invocation.Gradle; import org.gradle.api.internal.file.copy.DefaultCopySpec; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.SourceSetContainer; @@ -32,13 +31,8 @@ import org.gradle.tooling.provider.model.ToolingModelBuilder; import org.gradle.util.GradleVersion; -import com.microsoft.java.bs.gradle.model.GradleIncludedBuild; -import com.microsoft.java.bs.gradle.model.BuildTargetDependency; -import com.microsoft.java.bs.gradle.model.GradleSourceSets; -import com.microsoft.java.bs.gradle.model.impl.DefaultGradleIncludedBuild; -import com.microsoft.java.bs.gradle.model.impl.DefaultBuildTargetDependency; import com.microsoft.java.bs.gradle.model.impl.DefaultGradleSourceSet; -import com.microsoft.java.bs.gradle.model.impl.DefaultGradleSourceSets; +import com.microsoft.java.bs.gradle.model.impl.DefaultGradleSourceSetsMetadata; import com.microsoft.java.bs.gradle.model.LanguageExtension; import com.microsoft.java.bs.gradle.plugin.dependency.DependencyCollector; @@ -48,11 +42,15 @@ public class SourceSetsModelBuilder implements ToolingModelBuilder { @Override public boolean canBuild(String modelName) { - return modelName.equals(GradleSourceSets.class.getName()); + return modelName.equals(GradleSourceSetsMetadata.class.getName()); } @Override public Object buildAll(String modelName, Project rootProject) { + + Map> gradleSourceSets = new HashMap<>(); + Map outputsToSourceSet = new HashMap<>(); + Set allProject = rootProject.getAllprojects(); SourceSetCache cache = new SourceSetCache(); // this set is used to eliminate the source, resource and output @@ -68,6 +66,7 @@ public Object buildAll(String modelName, Project rootProject) { DefaultGradleSourceSet gradleSourceSet = new DefaultGradleSourceSet(); cache.addGradleSourceSet(sourceSet, gradleSourceSet); cache.addProject(sourceSet, project); + gradleSourceSet.setBuildTargetDependencies(new HashSet<>()); gradleSourceSet.setGradleVersion(project.getGradle().getGradleVersion()); gradleSourceSet.setProjectName(project.getName()); String projectPath = project.getPath(); @@ -113,10 +112,13 @@ public Object buildAll(String modelName, Project rootProject) { List compileClasspath = new LinkedList<>(sourceSet.getCompileClasspath().getFiles()); gradleSourceSet.setCompileClasspath(compileClasspath); + gradleSourceSets.put(gradleSourceSet, compileClasspath); + // source output dir File sourceOutputDir = getSourceOutputDir(sourceSet); if (sourceOutputDir != null) { gradleSourceSet.setSourceOutputDir(sourceOutputDir); + outputsToSourceSet.put(sourceOutputDir, gradleSourceSet); exclusionFromDependencies.add(sourceOutputDir); } @@ -129,6 +131,7 @@ public Object buildAll(String modelName, Project rootProject) { File resourceOutputDir = sourceSet.getOutput().getResourcesDir(); if (resourceOutputDir != null) { gradleSourceSet.setResourceOutputDir(resourceOutputDir); + outputsToSourceSet.put(resourceOutputDir, gradleSourceSet); exclusionFromDependencies.add(resourceOutputDir); } @@ -158,9 +161,35 @@ public Object buildAll(String modelName, Project rootProject) { } } }); + + if (!sourceSets.isEmpty()) { + // get all archive tasks for this project and find the dirs that are included in the archive + TaskCollection archiveTasks = + project.getTasks().withType(AbstractArchiveTask.class); + for (AbstractArchiveTask archiveTask : archiveTasks) { + Set archiveSourcePaths = getArchiveSourcePaths(archiveTask.getRootSpec()); + for (Object sourcePath : archiveSourcePaths) { + sourceSets.forEach(sourceSet -> { + DefaultGradleSourceSet gradleSourceSet = cache.getGradleSourceSet(sourceSet); + if (gradleSourceSet == null) { + return; + } + + if (sourceSet.getOutput().equals(sourcePath)) { + File archiveFile; + if (GradleVersion.current().compareTo(GradleVersion.version("5.1")) >= 0) { + archiveFile = archiveTask.getArchiveFile().get().getAsFile(); + } else { + archiveFile = archiveTask.getArchivePath(); + } + outputsToSourceSet.put(archiveFile, gradleSourceSet); + } + }); + } + } + } } - setSourceSetDependencies(cache); setModuleDependencies(cache, exclusionFromDependencies); for (SourceSet sourceSet : cache.getAllSourceSets()) { @@ -177,7 +206,6 @@ public Object buildAll(String modelName, Project rootProject) { Map extensions = new HashMap<>(); for (LanguageModelBuilder languageModelBuilder : GradleBuildServerPlugin.SUPPORTED_LANGUAGE_BUILDERS) { - if (languageModelBuilder.appliesFor(project, sourceSet)) { LanguageExtension extension = languageModelBuilder.getExtensionsFor(project, sourceSet, gradleSourceSet.getModuleDependencies()); @@ -187,10 +215,9 @@ public Object buildAll(String modelName, Project rootProject) { } } gradleSourceSet.setExtensions(extensions); - } - return new DefaultGradleSourceSets(new LinkedList<>(cache.getAllGradleSourceSets())); + return new DefaultGradleSourceSetsMetadata(gradleSourceSets, outputsToSourceSet); } private void setModuleDependencies(SourceSetCache cache, Set exclusionFromDependencies) { @@ -206,64 +233,6 @@ private void setModuleDependencies(SourceSetCache cache, Set exclusionFrom } } - private void setSourceSetDependencies(SourceSetCache cache) { - // map all output dirs to their source sets - Map outputsToSourceSet = new HashMap<>(); - for (DefaultGradleSourceSet sourceSet : cache.getAllGradleSourceSets()) { - if (sourceSet.getSourceOutputDir() != null) { - outputsToSourceSet.put(sourceSet.getSourceOutputDir(), sourceSet); - } - if (sourceSet.getResourceOutputDir() != null) { - outputsToSourceSet.put(sourceSet.getResourceOutputDir(), sourceSet); - } - } - - // map all output jars to their source sets - for (Project project : cache.getAllProjects()) { - SourceSetContainer sourceSets = getSourceSetContainer(project); - if (sourceSets == null || sourceSets.isEmpty()) { - continue; - } - - // get all archive tasks for this project and find the dirs that are included in the archive - TaskCollection archiveTasks = - project.getTasks().withType(AbstractArchiveTask.class); - for (AbstractArchiveTask archiveTask : archiveTasks) { - Set archiveSourcePaths = getArchiveSourcePaths(archiveTask.getRootSpec()); - for (Object sourcePath : archiveSourcePaths) { - sourceSets.forEach(sourceSet -> { - DefaultGradleSourceSet gradleSourceSet = cache.getGradleSourceSet(sourceSet); - if (gradleSourceSet == null) { - return; - } - - if (sourceSet.getOutput().equals(sourcePath)) { - File archiveFile; - if (GradleVersion.current().compareTo(GradleVersion.version("5.1")) >= 0) { - archiveFile = archiveTask.getArchiveFile().get().getAsFile(); - } else { - archiveFile = archiveTask.getArchivePath(); - } - outputsToSourceSet.put(archiveFile, gradleSourceSet); - } - }); - } - } - } - - // match any classpath entries to other project's output dirs/jars to create dependencies - for (SourceSet sourceSet : cache.getAllSourceSets()) { - Set dependencies = new HashSet<>(); - for (File file : sourceSet.getCompileClasspath()) { - DefaultGradleSourceSet otherSourceSet = outputsToSourceSet.get(file); - if (otherSourceSet != null) { - dependencies.add(new DefaultBuildTargetDependency(otherSourceSet)); - } - } - cache.getGradleSourceSet(sourceSet).setBuildTargetDependencies(dependencies); - } - } - private SourceSetContainer getSourceSetContainer(Project project) { if (GradleVersion.current().compareTo(GradleVersion.version("5.0")) >= 0) { SourceSetContainer sourceSetContainer = project.getExtensions() @@ -331,7 +300,7 @@ private File getSourceOutputDir(SourceSet sourceSet) { Method getOutputDirMethod = SourceDirectorySet.class.getMethod("getOutputDir"); return (File) getOutputDirMethod.invoke(sourceSet.getJava()); } catch (NoSuchMethodException | SecurityException | IllegalAccessException - | IllegalArgumentException | InvocationTargetException e) { + | IllegalArgumentException | InvocationTargetException e) { // ignore } } else { @@ -370,7 +339,7 @@ private Set getArchiveSourcePaths(CopySpec copySpec) { } } } catch (NoSuchMethodException | IllegalAccessException - | IllegalArgumentException | InvocationTargetException e) { + | IllegalArgumentException | InvocationTargetException e) { // cannot get archive information } } diff --git a/plugin/src/test/java/com/microsoft/java/bs/gradle/plugin/GradleBuildServerPluginTest.java b/plugin/src/test/java/com/microsoft/java/bs/gradle/plugin/GradleBuildServerPluginTest.java index 80f07c15..a366f643 100644 --- a/plugin/src/test/java/com/microsoft/java/bs/gradle/plugin/GradleBuildServerPluginTest.java +++ b/plugin/src/test/java/com/microsoft/java/bs/gradle/plugin/GradleBuildServerPluginTest.java @@ -16,9 +16,14 @@ import java.util.List; import java.util.function.Consumer; import java.util.stream.Stream; +import java.util.ArrayList; +import com.microsoft.java.bs.gradle.model.GradleSourceSet; +import com.microsoft.java.bs.gradle.model.GradleSourceSets; +import com.microsoft.java.bs.gradle.model.GradleSourceSetsMetadata; import com.microsoft.java.bs.gradle.model.JavaExtension; import com.microsoft.java.bs.gradle.model.ScalaExtension; +import com.microsoft.java.bs.gradle.model.SupportedLanguages; import com.microsoft.java.bs.gradle.model.impl.DefaultGradleSourceSets; import org.gradle.tooling.GradleConnector; import org.gradle.tooling.ModelBuilder; @@ -28,10 +33,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import com.microsoft.java.bs.gradle.model.GradleSourceSet; -import com.microsoft.java.bs.gradle.model.GradleSourceSets; -import com.microsoft.java.bs.gradle.model.SupportedLanguages; - class GradleBuildServerPluginTest { private static Path projectPath; @@ -46,7 +47,8 @@ static void beforeClass() { } private GradleSourceSets getGradleSourceSets(ProjectConnection connect) throws IOException { - ModelBuilder modelBuilder = connect.model(GradleSourceSets.class); + ModelBuilder modelBuilder = + connect.model(GradleSourceSetsMetadata.class); File initScript = PluginHelper.getInitScript(); modelBuilder .addArguments("--init-script", initScript.getAbsolutePath()) @@ -55,7 +57,9 @@ private GradleSourceSets getGradleSourceSets(ProjectConnection connect) throws I .addArguments("-Dorg.gradle.logging.level=quiet") .addJvmArguments("-Dbsp.gradle.supportedLanguages=" + String.join(",", SupportedLanguages.allBspNames)); - return new DefaultGradleSourceSets(modelBuilder.get()); + GradleSourceSetsMetadata sourceSetsMetadata = modelBuilder.get(); + return new DefaultGradleSourceSets( + new ArrayList<>(sourceSetsMetadata.getGradleSourceSets().keySet())); } private interface ConnectionConsumer { diff --git a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java index ebb5dc24..8088f7ea 100644 --- a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java +++ b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java @@ -15,6 +15,7 @@ import org.apache.commons.lang3.exception.ExceptionUtils; import com.microsoft.java.bs.core.internal.gradle.actions.GetSourceSetsAction; +import com.microsoft.java.bs.gradle.model.impl.DefaultGradleSourceSets; import org.gradle.tooling.BuildActionExecuter; import org.gradle.tooling.BuildException; import org.gradle.tooling.BuildLauncher; @@ -32,7 +33,6 @@ import com.microsoft.java.bs.core.internal.reporter.ProgressReporter; import com.microsoft.java.bs.core.internal.reporter.TestReportReporter; import com.microsoft.java.bs.gradle.model.GradleSourceSets; -import com.microsoft.java.bs.gradle.model.impl.DefaultGradleSourceSets; import ch.epfl.scala.bsp4j.BuildClient; import ch.epfl.scala.bsp4j.BuildTargetIdentifier; diff --git a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java index 1f01703a..6372a613 100644 --- a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java +++ b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java @@ -1,19 +1,21 @@ package com.microsoft.java.bs.core.internal.gradle.actions; +import com.microsoft.java.bs.gradle.model.BuildTargetDependency; import com.microsoft.java.bs.gradle.model.GradleSourceSet; import com.microsoft.java.bs.gradle.model.GradleSourceSets; +import com.microsoft.java.bs.gradle.model.GradleSourceSetsMetadata; +import com.microsoft.java.bs.gradle.model.impl.DefaultBuildTargetDependency; +import com.microsoft.java.bs.gradle.model.impl.DefaultGradleSourceSet; import com.microsoft.java.bs.gradle.model.impl.DefaultGradleSourceSets; import org.gradle.tooling.BuildAction; import org.gradle.tooling.BuildController; import org.gradle.tooling.model.gradle.GradleBuild; -import java.util.List; -import java.util.Map; -import java.util.HashMap; -import java.util.stream.Collectors; +import java.io.File; +import java.util.*; /** - * {@link BuildAction} that retrieves {@link GradleSourceSets} from a Gradle build, + * {@link BuildAction} that retrieves {@link DefaultGradleSourceSet} from a Gradle build, * handling both normal and composite builds. */ public class GetSourceSetsAction implements BuildAction { @@ -25,40 +27,66 @@ public class GetSourceSetsAction implements BuildAction { */ @Override public GradleSourceSets execute(BuildController buildController) { - Map> sourceSets = new HashMap<>(); + List traversedProjects = new ArrayList<>(); + Map> sourceSetToClasspath = new HashMap<>(); + Map outputsToSourceSet = new HashMap<>(); + GradleBuild buildModel = buildController.getBuildModel(); String rootProjectName = buildModel.getRootProject().getName(); - fetchModels(buildController, buildModel, sourceSets, rootProjectName); - return new DefaultGradleSourceSets(sourceSets.values().stream().flatMap(List::stream) - .collect(Collectors.toList())); + fetchModels(buildController, buildModel, traversedProjects, sourceSetToClasspath, outputsToSourceSet, rootProjectName); + + // Add dependencies + List sourceSets = new ArrayList<>(); + for (Map.Entry> entry : sourceSetToClasspath.entrySet()) { + + Set dependencies = new HashSet<>(); + for (File file : entry.getValue()) { + GradleSourceSet otherSourceSet = outputsToSourceSet.get(file); + if (otherSourceSet != null) { + dependencies.add(new DefaultBuildTargetDependency(otherSourceSet)); + } + } + + DefaultGradleSourceSet sourceSet = new DefaultGradleSourceSet(entry.getKey()); + sourceSet.setBuildTargetDependencies(dependencies); + sourceSets.add(sourceSet); + + } + + return new DefaultGradleSourceSets(sourceSets); } /** - * Fetches source sets from the provided Gradle build model and stores them in a map categorized by project name. + * Fetches source sets from the provided Gradle build model and + * stores them in a map categorized by project name. * - * @param buildController The Gradle build controller used to interact with the build. - * @param build The Gradle build model representing the current build. - * @param sourceSets A map to store the retrieved source sets categorized by project name. - * @param buildName The name of the root project in the build. + * @param buildController The Gradle build controller used to interact with the build. + * @param build The Gradle build model representing the current build. + * @param sourceSetToClasspath A map to store the retrieved source sets categorized + * by project name. + * @param buildName The name of the root project in the build. */ private void fetchModels( BuildController buildController, GradleBuild build, - Map> sourceSets, + List traversedProjects, + Map> sourceSetToClasspath, + Map outputsToSourceSet, String buildName ) { - if (sourceSets.containsKey(buildName)) { + if (traversedProjects.contains(buildName)) { return; } - sourceSets.put( - buildName, - buildController - .findModel(build.getRootProject(), GradleSourceSets.class) - .getGradleSourceSets() - ); + GradleSourceSetsMetadata sourceSets = buildController + .findModel(build.getRootProject(), GradleSourceSetsMetadata.class); + + traversedProjects.add(buildName); + sourceSetToClasspath.putAll(sourceSets.getGradleSourceSets()); + outputsToSourceSet.putAll(sourceSets.getOutputsToSourceSet()); + for (GradleBuild includedBuild : build.getIncludedBuilds()) { String includedBuildName = includedBuild.getRootProject().getName(); - fetchModels(buildController, includedBuild, sourceSets, includedBuildName); + fetchModels(buildController, includedBuild, traversedProjects, sourceSetToClasspath, outputsToSourceSet, includedBuildName); } } diff --git a/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java b/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java index c6be57dd..760bcc56 100644 --- a/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java +++ b/server/src/test/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnectorTest.java @@ -159,12 +159,14 @@ void testCompositeBuild2() { GradleApiConnector connector = new GradleApiConnector(preferenceManager); GradleSourceSets gradleSourceSets = connector.getGradleSourceSets(projectDir.toURI(), null); assertEquals(6, gradleSourceSets.getGradleSourceSets().size()); - findSourceSet(gradleSourceSets, "app [main]"); findSourceSet(gradleSourceSets, "app [test]"); - findSourceSet(gradleSourceSets, "string-utils [main]"); findSourceSet(gradleSourceSets, "string-utils [test]"); findSourceSet(gradleSourceSets, "number-utils [test]"); - findSourceSet(gradleSourceSets, "number-utils [test]"); + GradleSourceSet mainApp = findSourceSet(gradleSourceSets, "app [main]"); + GradleSourceSet mainStringUtils = findSourceSet(gradleSourceSets, "string-utils [main]"); + GradleSourceSet mainNumberUtils = findSourceSet(gradleSourceSets, "number-utils [main]"); + assertHasBuildTargetDependency(mainApp, mainStringUtils); + assertHasBuildTargetDependency(mainApp, mainNumberUtils); } private void assertHasBuildTargetDependency(GradleSourceSet sourceSet, From e8e3d0f4e33c676ed28f327186d1c75e1ccfd6fe Mon Sep 17 00:00:00 2001 From: Tanish-Ranjan Date: Wed, 3 Jul 2024 11:44:20 +0530 Subject: [PATCH 07/11] Code cleanup: imports, Java 17 features, checkstyle Changes: - Added missing import statements for improved readability. - Utilized Java 17 features for concise code (var type inference). - Addressed checkstyle warnings to maintain code consistency. --- .../impl/DefaultGradleSourceSetsMetadata.java | 7 ---- .../internal/gradle/GradleApiConnector.java | 1 + .../gradle/actions/GetSourceSetsAction.java | 32 +++++++++++++------ 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSetsMetadata.java b/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSetsMetadata.java index b776dd96..2e4de988 100644 --- a/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSetsMetadata.java +++ b/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSetsMetadata.java @@ -24,13 +24,6 @@ public DefaultGradleSourceSetsMetadata( this.outputsToSourceSet = outputsToSourceSet; } - // TODO: Copy constructor - - public DefaultGradleSourceSetsMetadata(GradleSourceSetsMetadata gradleSourceSetsMetadata) { - this(gradleSourceSetsMetadata.getGradleSourceSets(), - gradleSourceSetsMetadata.getOutputsToSourceSet()); - } - @Override public Map> getGradleSourceSets() { return gradleSourceSets; diff --git a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java index 8088f7ea..7487a348 100644 --- a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java +++ b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/GradleApiConnector.java @@ -10,6 +10,7 @@ import java.io.IOException; import java.net.URI; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; diff --git a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java index 6372a613..7fd6b319 100644 --- a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java +++ b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java @@ -12,7 +12,11 @@ import org.gradle.tooling.model.gradle.GradleBuild; import java.io.File; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; /** * {@link BuildAction} that retrieves {@link DefaultGradleSourceSet} from a Gradle build, @@ -27,19 +31,24 @@ public class GetSourceSetsAction implements BuildAction { */ @Override public GradleSourceSets execute(BuildController buildController) { - List traversedProjects = new ArrayList<>(); - Map> sourceSetToClasspath = new HashMap<>(); - Map outputsToSourceSet = new HashMap<>(); + var traversedProjects = new ArrayList(); + var sourceSetToClasspath = new HashMap>(); + var outputsToSourceSet = new HashMap(); GradleBuild buildModel = buildController.getBuildModel(); String rootProjectName = buildModel.getRootProject().getName(); - fetchModels(buildController, buildModel, traversedProjects, sourceSetToClasspath, outputsToSourceSet, rootProjectName); + fetchModels(buildController, + buildModel, + traversedProjects, + sourceSetToClasspath, + outputsToSourceSet, + rootProjectName); // Add dependencies - List sourceSets = new ArrayList<>(); - for (Map.Entry> entry : sourceSetToClasspath.entrySet()) { + var sourceSets = new ArrayList(); + for (var entry : sourceSetToClasspath.entrySet()) { - Set dependencies = new HashSet<>(); + var dependencies = new HashSet(); for (File file : entry.getValue()) { GradleSourceSet otherSourceSet = outputsToSourceSet.get(file); if (otherSourceSet != null) { @@ -86,7 +95,12 @@ private void fetchModels( for (GradleBuild includedBuild : build.getIncludedBuilds()) { String includedBuildName = includedBuild.getRootProject().getName(); - fetchModels(buildController, includedBuild, traversedProjects, sourceSetToClasspath, outputsToSourceSet, includedBuildName); + fetchModels(buildController, + includedBuild, + traversedProjects, + sourceSetToClasspath, + outputsToSourceSet, + includedBuildName); } } From 63deea11a11bf1df52655959afa2ce69005ebe2d Mon Sep 17 00:00:00 2001 From: Tanish-Ranjan Date: Wed, 3 Jul 2024 12:19:35 +0530 Subject: [PATCH 08/11] Updated JavaDocs for GetSourceSetsAction.java --- .../core/internal/gradle/actions/GetSourceSetsAction.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java index 7fd6b319..7148a77a 100644 --- a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java +++ b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java @@ -71,8 +71,11 @@ public GradleSourceSets execute(BuildController buildController) { * * @param buildController The Gradle build controller used to interact with the build. * @param build The Gradle build model representing the current build. - * @param sourceSetToClasspath A map to store the retrieved source sets categorized - * by project name. + * @param traversedProjects A list of traversed project names to avoid cyclic dependencies. + * @param sourceSetToClasspath A map that associates GradleSourceSet objects with their + * corresponding classpath files. + * @param outputsToSourceSet A map that associates output files with the GradleSourceSet + * they belong to. * @param buildName The name of the root project in the build. */ private void fetchModels( From 7a63d9a56e517465ec77a6c4694171800967a970 Mon Sep 17 00:00:00 2001 From: Tanish-Ranjan Date: Thu, 4 Jul 2024 16:30:20 +0530 Subject: [PATCH 09/11] Addressing comments --- .../core/internal/gradle/actions/GetSourceSetsAction.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java index 7148a77a..4dde0d3b 100644 --- a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java +++ b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java @@ -31,7 +31,7 @@ public class GetSourceSetsAction implements BuildAction { */ @Override public GradleSourceSets execute(BuildController buildController) { - var traversedProjects = new ArrayList(); + var traversedProjects = new HashSet(); var sourceSetToClasspath = new HashMap>(); var outputsToSourceSet = new HashMap(); @@ -51,7 +51,7 @@ public GradleSourceSets execute(BuildController buildController) { var dependencies = new HashSet(); for (File file : entry.getValue()) { GradleSourceSet otherSourceSet = outputsToSourceSet.get(file); - if (otherSourceSet != null) { + if (otherSourceSet != null && entry.getKey() != otherSourceSet) { dependencies.add(new DefaultBuildTargetDependency(otherSourceSet)); } } @@ -71,7 +71,7 @@ public GradleSourceSets execute(BuildController buildController) { * * @param buildController The Gradle build controller used to interact with the build. * @param build The Gradle build model representing the current build. - * @param traversedProjects A list of traversed project names to avoid cyclic dependencies. + * @param traversedProjects A set of traversed project names to avoid cyclic dependencies. * @param sourceSetToClasspath A map that associates GradleSourceSet objects with their * corresponding classpath files. * @param outputsToSourceSet A map that associates output files with the GradleSourceSet @@ -81,7 +81,7 @@ public GradleSourceSets execute(BuildController buildController) { private void fetchModels( BuildController buildController, GradleBuild build, - List traversedProjects, + HashSet traversedProjects, Map> sourceSetToClasspath, Map outputsToSourceSet, String buildName From aa3a23b1aa31b051a8ad65ba26a0bbb02fab9287 Mon Sep 17 00:00:00 2001 From: Tanish-Ranjan Date: Fri, 5 Jul 2024 09:20:15 +0530 Subject: [PATCH 10/11] Improved readability and clarity of GradleSourceSetsMetadata Changes: - Refactored variable and method names to reflect their purpose clearly. - Updated JavaDoc comments for better explanation. --- .../model/GradleSourceSetsMetadata.java | 34 +++++++++++++++++-- .../impl/DefaultGradleSourceSetsMetadata.java | 18 +++++----- .../gradle/plugin/SourceSetsModelBuilder.java | 6 ++-- .../plugin/GradleBuildServerPluginTest.java | 2 +- .../gradle/actions/GetSourceSetsAction.java | 5 +-- 5 files changed, 48 insertions(+), 17 deletions(-) diff --git a/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSetsMetadata.java b/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSetsMetadata.java index 1e07b5a6..00435b27 100644 --- a/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSetsMetadata.java +++ b/model/src/main/java/com/microsoft/java/bs/gradle/model/GradleSourceSetsMetadata.java @@ -6,10 +6,40 @@ import java.util.Map; /** - * Provides necessary information to build SourceSets. + * Provides necessary information about Gradle source sets, + * enabling mapping of dependencies between them. */ public interface GradleSourceSetsMetadata extends Serializable { - Map> getGradleSourceSets(); + /** + * Returns a map that associates each Gradle source set with its corresponding + * classpath files in a gradle project. This typically includes any libraries + * or dependencies required for compilation within that source set. + * + *

+ * The keys of the map represent instances of the {@link GradleSourceSet} class, + * identifying all the source sets within the project. + *

+ *

+ * The values of the map are lists of {@link File} objects, representing the + * classpath files associated with the corresponding source set. + *

+ */ + Map> getGradleSourceSetsToClasspath(); + + /** + * Returns a map that associates output files with the Gradle source sets that + * generated them. This is useful for understanding the origin of generated artifacts. + * + *

+ * The keys of the map are {@link File} objects, representing individual + * output files produced during the build process. + *

+ *

+ * The values of the map are instances of the {@link GradleSourceSet} class, + * indicating the source set that generated the corresponding output file. + *

+ */ Map getOutputsToSourceSet(); + } diff --git a/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSetsMetadata.java b/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSetsMetadata.java index 2e4de988..21459e6f 100644 --- a/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSetsMetadata.java +++ b/model/src/main/java/com/microsoft/java/bs/gradle/model/impl/DefaultGradleSourceSetsMetadata.java @@ -13,24 +13,24 @@ */ public class DefaultGradleSourceSetsMetadata implements GradleSourceSetsMetadata { - private Map> gradleSourceSets; + private Map> sourceSetsToClasspath; private Map outputsToSourceSet; public DefaultGradleSourceSetsMetadata( - Map> gradleSourceSets, + Map> sourceSetsToClasspath, Map outputsToSourceSet ) { - this.gradleSourceSets = gradleSourceSets; + this.sourceSetsToClasspath = sourceSetsToClasspath; this.outputsToSourceSet = outputsToSourceSet; } @Override - public Map> getGradleSourceSets() { - return gradleSourceSets; + public Map> getGradleSourceSetsToClasspath() { + return sourceSetsToClasspath; } - public void setGradleSourceSets(Map> gradleSourceSets) { - this.gradleSourceSets = gradleSourceSets; + public void setSourceSetsToClasspath(Map> sourceSetsToClasspath) { + this.sourceSetsToClasspath = sourceSetsToClasspath; } @Override @@ -44,7 +44,7 @@ public void setOutputsToSourceSet(Map outputsToSourceSet) @Override public int hashCode() { - return Objects.hash(gradleSourceSets, outputsToSourceSet); + return Objects.hash(sourceSetsToClasspath, outputsToSourceSet); } @Override @@ -56,7 +56,7 @@ public boolean equals(Object obj) { return false; } DefaultGradleSourceSetsMetadata that = (DefaultGradleSourceSetsMetadata) obj; - return Objects.equals(gradleSourceSets, that.gradleSourceSets) + return Objects.equals(sourceSetsToClasspath, that.sourceSetsToClasspath) && Objects.equals(outputsToSourceSet, that.outputsToSourceSet); } } diff --git a/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/SourceSetsModelBuilder.java b/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/SourceSetsModelBuilder.java index c4342b1b..bf458e16 100644 --- a/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/SourceSetsModelBuilder.java +++ b/plugin/src/main/java/com/microsoft/java/bs/gradle/plugin/SourceSetsModelBuilder.java @@ -48,7 +48,7 @@ public boolean canBuild(String modelName) { @Override public Object buildAll(String modelName, Project rootProject) { - Map> gradleSourceSets = new HashMap<>(); + Map> sourceSetsToClasspath = new HashMap<>(); Map outputsToSourceSet = new HashMap<>(); Set allProject = rootProject.getAllprojects(); @@ -112,7 +112,7 @@ public Object buildAll(String modelName, Project rootProject) { List compileClasspath = new LinkedList<>(sourceSet.getCompileClasspath().getFiles()); gradleSourceSet.setCompileClasspath(compileClasspath); - gradleSourceSets.put(gradleSourceSet, compileClasspath); + sourceSetsToClasspath.put(gradleSourceSet, compileClasspath); // source output dir File sourceOutputDir = getSourceOutputDir(sourceSet); @@ -217,7 +217,7 @@ public Object buildAll(String modelName, Project rootProject) { gradleSourceSet.setExtensions(extensions); } - return new DefaultGradleSourceSetsMetadata(gradleSourceSets, outputsToSourceSet); + return new DefaultGradleSourceSetsMetadata(sourceSetsToClasspath, outputsToSourceSet); } private void setModuleDependencies(SourceSetCache cache, Set exclusionFromDependencies) { diff --git a/plugin/src/test/java/com/microsoft/java/bs/gradle/plugin/GradleBuildServerPluginTest.java b/plugin/src/test/java/com/microsoft/java/bs/gradle/plugin/GradleBuildServerPluginTest.java index a366f643..171063c1 100644 --- a/plugin/src/test/java/com/microsoft/java/bs/gradle/plugin/GradleBuildServerPluginTest.java +++ b/plugin/src/test/java/com/microsoft/java/bs/gradle/plugin/GradleBuildServerPluginTest.java @@ -59,7 +59,7 @@ private GradleSourceSets getGradleSourceSets(ProjectConnection connect) throws I + String.join(",", SupportedLanguages.allBspNames)); GradleSourceSetsMetadata sourceSetsMetadata = modelBuilder.get(); return new DefaultGradleSourceSets( - new ArrayList<>(sourceSetsMetadata.getGradleSourceSets().keySet())); + new ArrayList<>(sourceSetsMetadata.getGradleSourceSetsToClasspath().keySet())); } private interface ConnectionConsumer { diff --git a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java index 4dde0d3b..5b087c4c 100644 --- a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java +++ b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java @@ -17,6 +17,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; /** * {@link BuildAction} that retrieves {@link DefaultGradleSourceSet} from a Gradle build, @@ -51,7 +52,7 @@ public GradleSourceSets execute(BuildController buildController) { var dependencies = new HashSet(); for (File file : entry.getValue()) { GradleSourceSet otherSourceSet = outputsToSourceSet.get(file); - if (otherSourceSet != null && entry.getKey() != otherSourceSet) { + if (otherSourceSet != null && !Objects.equals(entry.getKey(), otherSourceSet)) { dependencies.add(new DefaultBuildTargetDependency(otherSourceSet)); } } @@ -93,7 +94,7 @@ private void fetchModels( .findModel(build.getRootProject(), GradleSourceSetsMetadata.class); traversedProjects.add(buildName); - sourceSetToClasspath.putAll(sourceSets.getGradleSourceSets()); + sourceSetToClasspath.putAll(sourceSets.getGradleSourceSetsToClasspath()); outputsToSourceSet.putAll(sourceSets.getOutputsToSourceSet()); for (GradleBuild includedBuild : build.getIncludedBuilds()) { From 4eb77368eb8f660d804c401c9402dbaf8231f6c3 Mon Sep 17 00:00:00 2001 From: Tanish-Ranjan Date: Fri, 5 Jul 2024 11:49:59 +0530 Subject: [PATCH 11/11] Updated GetSourceSetsAction#fetchModels parameter type for consistency --- .../bs/core/internal/gradle/actions/GetSourceSetsAction.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java index 5b087c4c..cf6403ce 100644 --- a/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java +++ b/server/src/main/java/com/microsoft/java/bs/core/internal/gradle/actions/GetSourceSetsAction.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; /** * {@link BuildAction} that retrieves {@link DefaultGradleSourceSet} from a Gradle build, @@ -82,7 +83,7 @@ public GradleSourceSets execute(BuildController buildController) { private void fetchModels( BuildController buildController, GradleBuild build, - HashSet traversedProjects, + Set traversedProjects, Map> sourceSetToClasspath, Map outputsToSourceSet, String buildName