Skip to content

Commit

Permalink
SONARGRADL-120 Add .gradle.kts files to the sonar.sources (#182)
Browse files Browse the repository at this point in the history
  • Loading branch information
leveretka authored Jul 13, 2023
1 parent e4d24ef commit 2a927d3
Show file tree
Hide file tree
Showing 2 changed files with 229 additions and 4 deletions.
31 changes: 27 additions & 4 deletions src/main/java/org/sonarqube/gradle/SonarPropertyComputer.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -225,10 +226,14 @@ private static void configureForJava(final Project project, final Map<String, Ob

private static void configureForKotlin(Project project, Map<String, Object> properties, Object kotlinProjectExtension) {
Collection<File> sourceDirectories = getKotlinSourceFiles(kotlinProjectExtension, MAIN_SOURCE_SET_SUFFIX);
properties.put(SONAR_SOURCES_PROP, sourceDirectories);
if (sourceDirectories != null) {
SonarUtils.appendProps(properties, SONAR_SOURCES_PROP, sourceDirectories);
}

Collection<File> testDirectories = getKotlinSourceFiles(kotlinProjectExtension, TEST_SOURCE_SET_SUFFIX);
properties.put(SONAR_TESTS_PROP, testDirectories);
if (testDirectories != null) {
SonarUtils.appendProps(properties, SONAR_TESTS_PROP, testDirectories);
}

if (sourceDirectories != null || testDirectories != null) {
configureSourceEncoding(project, properties);
Expand Down Expand Up @@ -308,11 +313,15 @@ private static void configureSourceDirsAndJavaClasspath(Project project, Map<Str

SourceSet main = javaPluginConvention.getSourceSets().getAt("main");
Collection<File> sourceDirectories = getJavaSourceFiles(main);
properties.put(SONAR_SOURCES_PROP, sourceDirectories);
if (sourceDirectories != null) {
SonarUtils.appendProps(properties, SONAR_SOURCES_PROP, sourceDirectories);
}

SourceSet test = javaPluginConvention.getSourceSets().getAt("test");
Collection<File> testDirectories = getJavaSourceFiles(test);
properties.put(SONAR_TESTS_PROP, testDirectories);
if (testDirectories != null) {
SonarUtils.appendProps(properties, SONAR_TESTS_PROP, testDirectories);
}

if (sourceDirectories != null || testDirectories != null) {
configureSourceEncoding(project, properties);
Expand Down Expand Up @@ -443,6 +452,8 @@ private void addGradleDefaults(final Project project, final Map<String, Object>
properties.put("sonar.projectBaseDir", project.getProjectDir());
properties.put("sonar.kotlin.gradleProjectRoot", project.getRootProject().getProjectDir().getAbsolutePath());

addKotlinBuildScriptsToSources(project, properties);

if (project.equals(targetProject)) {
// Root project of the analysis
properties.put("sonar.working.directory", new File(project.getBuildDir(), "sonar"));
Expand All @@ -459,6 +470,18 @@ private void addGradleDefaults(final Project project, final Map<String, Object>
}
}

private static void addKotlinBuildScriptsToSources(Project project, Map<String, Object> properties) {
List<File> buildScripts = project.getAllprojects().stream()
.map(Project::getBuildFile)
.filter(file -> file.getAbsolutePath().endsWith("kts"))
.collect(Collectors.toList());

var settingsFile = Path.of(project.getProjectDir().getAbsolutePath(), "settings.gradle.kts").toFile();
if (settingsFile.exists()) buildScripts.add(settingsFile);

if (!buildScripts.isEmpty()) SonarUtils.appendProps(properties, SONAR_SOURCES_PROP, buildScripts);
}

private String computeProjectKey() {
Project rootProject = targetProject.getRootProject();
String rootProjectName = rootProject.getName();
Expand Down
202 changes: 202 additions & 0 deletions src/test/groovy/org/sonarqube/gradle/GradleKtsTests.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/*
* SonarQube Scanner for Gradle
* Copyright (C) 2015-2023 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.assertj.core.api.Assertions
import org.gradle.testkit.runner.GradleRunner
import spock.lang.Specification
import spock.lang.TempDir

import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardCopyOption

class GradleKtsTests extends Specification {
@TempDir
Path testProjectDir
Path settingsFile
Path buildFile
Path outFile

def setup() {
outFile = testProjectDir.resolve('out.properties')
// For JaCoCo coverage, see https://github.com/koral--/jacoco-gradle-testkit-plugin
InputStream is = GradleKtsTests.class.getClassLoader().getResourceAsStream('testkit-gradle.properties')
Files.copy(is, testProjectDir.resolve('gradle.properties'), StandardCopyOption.REPLACE_EXISTING)
}

def "add build and settings gradle files to sources when both are in kotlin dsl"() {
given:
addBuildKts()
addSettingsKts()

when:
def result = GradleRunner.create()
.withProjectDir(testProjectDir.toFile())
.forwardOutput()
.withArguments('sonarqube', '--info', '-Dsonar.scanner.dumpToFile=' + outFile.toAbsolutePath())
.withPluginClasspath()
.build()

def props = new Properties()
props.load(outFile.newDataInputStream())

then:
def sonarSources = props["sonar.sources"].split(",")
Assertions.assertThat(sonarSources)
.containsExactlyInAnyOrder(settingsFile.toRealPath().toString(), buildFile.toRealPath().toString())

}

def "add only build and file to sources when only build is in kotlin dsl"() {
given:
addBuildKts()
addSettings()

when:
def result = GradleRunner.create()
.withProjectDir(testProjectDir.toFile())
.forwardOutput()
.withArguments('sonarqube', '--info', '-Dsonar.scanner.dumpToFile=' + outFile.toAbsolutePath())
.withPluginClasspath()
.build()

def props = new Properties()
props.load(outFile.newDataInputStream())

then:
props["sonar.sources"] == buildFile.toRealPath().toString()

}

def "add only settings file to sources when only settings file is in kotlin dsl"() {
given:
addBuild()
addSettingsKts()

when:
def result = GradleRunner.create()
.withProjectDir(testProjectDir.toFile())
.forwardOutput()
.withArguments('sonarqube', '--info', '-Dsonar.scanner.dumpToFile=' + outFile.toAbsolutePath())
.withPluginClasspath()
.build()

def props = new Properties()
props.load(outFile.newDataInputStream())

then:
props["sonar.sources"] == settingsFile.toRealPath().toString()

}

def "add only build file to sources when no settings found"() {
given:
addBuildKts()

when:
def result = GradleRunner.create()
.withProjectDir(testProjectDir.toFile())
.forwardOutput()
.withArguments('sonarqube', '--info', '-Dsonar.scanner.dumpToFile=' + outFile.toAbsolutePath())
.withPluginClasspath()
.build()

def props = new Properties()
props.load(outFile.newDataInputStream())

then:
props["sonar.sources"] == buildFile.toRealPath().toString()

}

def "add nothing to sources when Groovy dsl is used"() {
given:
addBuild()
addSettings()

when:
def result = GradleRunner.create()
.withProjectDir(testProjectDir.toFile())
.forwardOutput()
.withArguments('sonarqube', '--info', '-Dsonar.scanner.dumpToFile=' + outFile.toAbsolutePath())
.withPluginClasspath()
.build()

def props = new Properties()
props.load(outFile.newDataInputStream())

then:
props["sonar.sources"] == ""

}

def "add nothing to sources when Groovy dsl is used and no settings"() {
given:
addBuild()

when:
def result = GradleRunner.create()
.withProjectDir(testProjectDir.toFile())
.forwardOutput()
.withArguments('sonarqube', '--info', '-Dsonar.scanner.dumpToFile=' + outFile.toAbsolutePath())
.withPluginClasspath()
.build()

def props = new Properties()
props.load(outFile.newDataInputStream())

then:
props["sonar.sources"] == ""

}

private def addSettings() {
settingsFile = testProjectDir.resolve('settings.gradle')
settingsFile << "rootProject.name = 'java-task-toolchains'"
}

private def addSettingsKts() {
settingsFile = testProjectDir.resolve('settings.gradle.kts')
settingsFile << """rootProject.name = "java-task-toolchains"
"""
}

private def addBuild() {
buildFile = testProjectDir.resolve('build.gradle')
buildFile << """
plugins {
id 'java'
id 'org.sonarqube'
}
"""
}

private def addBuildKts() {
buildFile = testProjectDir.resolve('build.gradle.kts')
buildFile << """
plugins {
java
id("org.sonarqube")
}
"""
}
}

0 comments on commit 2a927d3

Please sign in to comment.