diff --git a/integrationTests/src/test/java/org/sonarqube/gradle/AbstractGradleIT.java b/integrationTests/src/test/java/org/sonarqube/gradle/AbstractGradleIT.java index 192a6a0d..b784b948 100644 --- a/integrationTests/src/test/java/org/sonarqube/gradle/AbstractGradleIT.java +++ b/integrationTests/src/test/java/org/sonarqube/gradle/AbstractGradleIT.java @@ -345,7 +345,7 @@ static void assertThatPluginDoesNotCreateGradleDeprecationWarnings(String text) } static boolean isUnexpectedWarning(String line){ - if(line.contains("SonarResolverTask.java:143") || line.contains("SonarResolverTask.java:146")){ + if(line.contains("SonarResolverTask.java:108") || line.contains("SonarResolverTask.java:111")){ // These warnings are expected until we properly support Gradle 9 return false; } diff --git a/src/main/java/org/sonarqube/gradle/BuildFeaturesEnabledResolverTask.java b/src/main/java/org/sonarqube/gradle/BuildFeaturesEnabledResolverTask.java deleted file mode 100644 index 416839d4..00000000 --- a/src/main/java/org/sonarqube/gradle/BuildFeaturesEnabledResolverTask.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * SonarQube Scanner for Gradle - * Copyright (C) 2015-2025 SonarSource - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonarqube.gradle; - -import javax.inject.Inject; -import org.gradle.api.configuration.BuildFeatures; - -public abstract class BuildFeaturesEnabledResolverTask extends SonarResolverTask { - @Inject - public abstract BuildFeatures getBuildFeatures(); - - @Override - public boolean configurationCacheIsDisabled() { - return !getBuildFeatures().getConfigurationCache().getActive().get(); - } - -} diff --git a/src/main/java/org/sonarqube/gradle/SonarQubePlugin.java b/src/main/java/org/sonarqube/gradle/SonarQubePlugin.java index 0c1cedc9..124450a7 100644 --- a/src/main/java/org/sonarqube/gradle/SonarQubePlugin.java +++ b/src/main/java/org/sonarqube/gradle/SonarQubePlugin.java @@ -42,14 +42,13 @@ import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.provider.MapProperty; import org.gradle.api.provider.Provider; +import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.TaskContainer; import org.gradle.testing.jacoco.plugins.JacocoPlugin; import org.gradle.testing.jacoco.tasks.JacocoReport; import org.gradle.util.GradleVersion; import static org.sonarqube.gradle.SonarUtils.capitalize; -import static org.sonarqube.gradle.SonarUtils.getMainClassPath; -import static org.sonarqube.gradle.SonarUtils.getTestClassPath; import static org.sonarqube.gradle.SonarUtils.isAndroidProject; /** @@ -108,7 +107,7 @@ public void apply(Project project) { private static List registerAndConfigureResolverTasks(Project topLevelProject) { List resolverFiles = new ArrayList<>(); topLevelProject.getAllprojects().forEach(target -> - target.getTasks().register(SonarResolverTask.TASK_NAME, getCompatibleTaskType(GradleVersion.current()), task -> { + target.getTasks().register(SonarResolverTask.TASK_NAME, SonarResolverTask.class, task -> { Provider skipProject = target.provider(() -> isSkipped(target)); task.setDescription(SonarResolverTask.TASK_DESCRIPTION); @@ -119,10 +118,10 @@ private static List registerAndConfigureResolverTasks(Project topLevelProj } task.setProjectName(SonarUtils.constructPrefixedProjectName(target.getPath())); - FileCollection mainClassPath = getMainClassPath(target); - task.setCompileClasspath(mainClassPath); - FileCollection testClassPath = getTestClassPath(target); - task.setTestCompileClasspath(testClassPath); + Provider compile = target.provider(() -> querySourceSet(target, SourceSet.MAIN_SOURCE_SET_NAME)); + Provider test = target.provider(() -> querySourceSet(target, SourceSet.TEST_SOURCE_SET_NAME)); + task.setCompileClasspath(compile); + task.setTestCompileClasspath(test); if (isAndroidProject(target)) { setAndroidLibrariesProperties(target, task); @@ -140,6 +139,16 @@ private static List registerAndConfigureResolverTasks(Project topLevelProj return resolverFiles; } + @Nullable + private static FileCollection querySourceSet(Project project, String sourceSetName) { + var sourceSets = SonarUtils.getSourceSets(project); + if (sourceSets == null) { + return null; + } + var set = sourceSets.findByName(sourceSetName); + return set == null ? null : set.getCompileClasspath(); + } + private static void setAndroidLibrariesProperties(Project target, SonarResolverTask task) { AndroidUtils.LibrariesAndTestLibraries libraries = AndroidUtils.LibrariesAndTestLibraries.ofProject(target); task.setMainLibraries(libraries.getMainLibraries()); @@ -153,15 +162,6 @@ private static void setJavaLibrariesProperties(Project target, SonarResolverTask task.setTestLibraries(libraries); } - private static Class getCompatibleTaskType(GradleVersion version) { - if (version.compareTo(GradleVersion.version("8.5.0")) >= 0) { - return BuildFeaturesEnabledResolverTask.class; - } else if (version.compareTo(GradleVersion.version("7.6.1")) >= 0) { - return StartParameterBasedTask.class; - } - return SonarResolverTask.class; - } - private static void addExtensions(Project project, String name, Map> actionBroadcastMap) { project.getAllprojects().forEach(p -> { LOGGER.debug("Adding " + name + " extension to " + p); diff --git a/src/main/java/org/sonarqube/gradle/SonarResolverTask.java b/src/main/java/org/sonarqube/gradle/SonarResolverTask.java index 3610bae3..84c14575 100644 --- a/src/main/java/org/sonarqube/gradle/SonarResolverTask.java +++ b/src/main/java/org/sonarqube/gradle/SonarResolverTask.java @@ -44,10 +44,10 @@ public abstract class SonarResolverTask extends DefaultTask { private String projectName; private boolean isTopLevelProject; - private FileCollection compileClasspath; - private FileCollection testCompileClasspath; private FileCollection mainLibraries; private FileCollection testLibraries; + private Provider compileClasspath; + private Provider testCompileClasspath; private File outputDirectory; private Provider skipProject; @@ -71,19 +71,19 @@ public void setTopLevelProject(boolean topLevelProject) { @Internal FileCollection getCompileClasspath() { - return this.compileClasspath; + return this.compileClasspath.get(); } - public void setCompileClasspath(FileCollection compileClasspath) { + public void setCompileClasspath(Provider compileClasspath) { this.compileClasspath = compileClasspath; } @Internal - FileCollection getTestCompileClasspath() { + Provider getTestCompileClasspath() { return this.testCompileClasspath; } - public void setTestCompileClasspath(FileCollection testCompileClasspath) { + public void setTestCompileClasspath(Provider testCompileClasspath) { this.testCompileClasspath = testCompileClasspath; } @@ -137,23 +137,18 @@ void run() throws IOException { LOGGER.info("Resolving properties for " + displayName + "."); } - // If we failed to initialize class paths at configuration time AND the configuration cache is not active/requested, - // we attempt to rebuild them using the source sets. - if (compileClasspath == null && configurationCacheIsDisabled()) { - compileClasspath = SonarUtils.getMainClassPath(getProject()); - } - if (testCompileClasspath == null && configurationCacheIsDisabled()) { - testCompileClasspath = SonarUtils.getTestClassPath(getProject()); - } + var mainClasspath = this.compileClasspath.getOrNull(); + var testClasspath = testCompileClasspath.getOrNull(); - List compileClasspathFilenames = SonarUtils.exists(compileClasspath == null ? Collections.emptyList() : compileClasspath) + List compileClasspathFilenames = SonarUtils.exists(mainClasspath == null ? Collections.emptyList() : mainClasspath) .stream() .map(File::getAbsolutePath) .collect(Collectors.toList()); - List testCompileClasspathFilenames = SonarUtils.exists(testCompileClasspath == null ? Collections.emptyList() : testCompileClasspath) + List testCompileClasspathFilenames = SonarUtils.exists(testClasspath == null ? Collections.emptyList() : testClasspath) .stream() .map(File::getAbsolutePath) .collect(Collectors.toList()); + List mainLibrariesFilenames = SonarUtils.exists(getMainLibraries() == null ? Collections.emptyList() : getMainLibraries()) .stream() .map(File::getAbsolutePath) @@ -162,6 +157,7 @@ void run() throws IOException { .stream() .map(File::getAbsolutePath) .collect(Collectors.toList()); + ProjectProperties projectProperties = new ProjectProperties( getProjectName(), isTopLevelProject(), @@ -179,9 +175,4 @@ void run() throws IOException { LOGGER.info("Resolved properties for " + displayName + " and wrote them to " + getOutputFile() + "."); } } - - public boolean configurationCacheIsDisabled() { - return true; - } - } diff --git a/src/main/java/org/sonarqube/gradle/SonarUtils.java b/src/main/java/org/sonarqube/gradle/SonarUtils.java index 88800469..9c5a2d75 100644 --- a/src/main/java/org/sonarqube/gradle/SonarUtils.java +++ b/src/main/java/org/sonarqube/gradle/SonarUtils.java @@ -39,11 +39,9 @@ import java.util.stream.StreamSupport; import javax.annotation.Nullable; import org.gradle.api.Project; -import org.gradle.api.file.FileCollection; import org.gradle.api.internal.plugins.DslObject; import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.plugins.JavaPluginExtension; -import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.SourceSetContainer; import org.gradle.util.GradleVersion; @@ -96,6 +94,7 @@ static boolean isAndroidProject(Project project) { * @param project The (sub-)project under analysis * @return A container with the "main" and "test" source sets */ + @Nullable static SourceSetContainer getSourceSets(Project project) { GradleVersion gradleVersion = GradleVersion.version(project.getGradle().getGradleVersion()); if (isCompatibleWithJavaPluginExtension(gradleVersion)) { @@ -123,37 +122,6 @@ private static SourceSetContainer getSourceSetsGradleLegacy(Project project) { return javaPluginConvention.getSourceSets(); } - @Nullable - public static FileCollection getMainClassPath(Project project) { - return getClassPath(project, "main"); - } - - @Nullable - public static FileCollection getTestClassPath(Project project) { - return getClassPath(project, "test"); - } - - @Nullable - public static FileCollection getClassPath(Project project, String sourceSetName) { - SourceSetContainer sourceSets = SonarUtils.getSourceSets(project); - return getClassPathFromSourceSets(sourceSetName, sourceSets); - } - - public static @Nullable FileCollection getClassPathFromSourceSets(String sourceSetName, @Nullable SourceSetContainer sourceSets) { - if (sourceSets == null) { - return null; - } - SourceSet sourceSet = sourceSets.findByName(sourceSetName); - if (sourceSet == null) { - return null; - } - FileCollection compileClasspath = sourceSet.getCompileClasspath(); - if (compileClasspath == null) { - return null; - } - return compileClasspath; - } - static boolean isCompatibleWithJavaPluginExtension(GradleVersion version) { return version.getBaseVersion().compareTo(GradleVersion.version("7.0")) >= 0; } diff --git a/src/main/java/org/sonarqube/gradle/StartParameterBasedTask.java b/src/main/java/org/sonarqube/gradle/StartParameterBasedTask.java deleted file mode 100644 index d0ddb673..00000000 --- a/src/main/java/org/sonarqube/gradle/StartParameterBasedTask.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * SonarQube Scanner for Gradle - * Copyright (C) 2015-2025 SonarSource - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonarqube.gradle; - -import org.gradle.StartParameter; - -public class StartParameterBasedTask extends SonarResolverTask { - @Override - @SuppressWarnings("java:S1874") - public boolean configurationCacheIsDisabled() { - StartParameter startParameter = getProject().getGradle().getStartParameter(); - return startParameter.isConfigurationCacheRequested(); - } -} diff --git a/src/test/java/org/sonarqube/gradle/SonarUtilsTest.java b/src/test/java/org/sonarqube/gradle/SonarUtilsTest.java index 5cbf62da..bd9bce7a 100644 --- a/src/test/java/org/sonarqube/gradle/SonarUtilsTest.java +++ b/src/test/java/org/sonarqube/gradle/SonarUtilsTest.java @@ -24,10 +24,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.gradle.api.tasks.SourceSet; -import org.gradle.api.tasks.SourceSetContainer; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -35,19 +32,6 @@ class SonarUtilsTest { - @Test - void test_get_class_path_from_sourcesets(){ - SourceSetContainer sourceSetsMissingMain = Mockito.mock(SourceSetContainer.class); - when(sourceSetsMissingMain.findByName("main")).thenReturn(null); - assertThat(SonarUtils.getClassPathFromSourceSets("main", sourceSetsMissingMain)).isNull(); - - SourceSetContainer sourceSets = Mockito.mock(SourceSetContainer.class); - SourceSet sourceSet = Mockito.mock(SourceSet.class); - when(sourceSets.findByName("main")).thenReturn(sourceSet); - when(sourceSet.getCompileClasspath()).thenReturn(null); - assertThat(SonarUtils.getClassPathFromSourceSets("main", sourceSets)).isNull(); - } - @Test void test_construct_prefixed_project_name() { assertThat(SonarUtils.constructPrefixedProjectName(":module:submodule")).isEqualTo(":module.:module:submodule");