All Downloads are FREE. Search and download functionalities are using the official Maven repository.

name.remal.gradle_plugins.plugins.code_quality.sonar.SonarLintPlugin.kt Maven / Gradle / Ivy

There is a newer version: 1.9.2
Show newest version
package name.remal.gradle_plugins.plugins.code_quality.sonar

import name.remal.gradle_plugins.api.BuildTimeConstants.getStringProperties
import name.remal.gradle_plugins.api.BuildTimeConstants.getStringProperty
import name.remal.gradle_plugins.dsl.Plugin
import name.remal.gradle_plugins.dsl.PluginAction
import name.remal.gradle_plugins.dsl.SimpleTestAdditionalGradleScript
import name.remal.gradle_plugins.dsl.WithPlugins
import name.remal.gradle_plugins.dsl.extensions.*
import name.remal.gradle_plugins.plugins.code_quality.BaseCodeQualityReflectiveProjectPlugin
import name.remal.gradle_plugins.plugins.java.JavaAnyPluginId
import name.remal.gradle_plugins.plugins.kotlin.KotlinAnyPluginId
import name.remal.nullIfEmpty
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.TaskContainer
import java.io.File

@Plugin(
    id = "name.remal.sonarlint",
    description = "Plugin that executes SonarLint checks without SonarQube server.",
    tags = ["sonar", "sonarlint"]
)
@SimpleTestAdditionalGradleScript("""
    sonarlint {
        ignoreFailures = false
        excludes {
            message 'squid:S2094'
        }
    }
""")
class SonarLintPlugin : BaseCodeQualityReflectiveProjectPlugin() {

    companion object {
        private val SONARSOURCE_REPOSITORY = getStringProperty("sonarsource.repository")
        private val SONAR_PLUGIN_PROPERTIES = getStringProperties("sonar-*-plugin.*")
    }


    override val toolVersion: String get() = getStringProperty("sonarlint-core.latest-version")
    override val isToolPluginsConfigurationEnabled: Boolean get() = true


    @PluginAction
    fun RepositoryHandler.`Add SonarSource repository`() {
        maven {
            it.name = "SonarSource"
            it.setUrl(SONARSOURCE_REPOSITORY)
            it.includeGroupByRegex("org\\.sonarsource(\\..+)?")
        }

        jcenterIfNotAdded("SonarLint dependencies") {
            it.includeModule("commons-lang", "commons-lang")
            it.includeModule("com.google.code.findbugs", "jsr305")
        }
    }


    override fun Configuration.configureConfiguration(extension: SonarLintExtension, dependencyHandler: DependencyHandler) {
        defaultDependencies { dependencies ->
            val toolVersion = extension.toolVersion
            dependencies.add(dependencyHandler.createToolDependency("org.sonarsource.sonarlint.core:sonarlint-core:$toolVersion"))
            dependencies.add(dependencyHandler.create("commons-lang:commons-lang:2.6"))
            dependencies.add(dependencyHandler.create("com.google.code.findbugs:jsr305:3.0.2"))
        }
    }


    @PluginAction(order = -90)
    @WithPlugins(JavaAnyPluginId::class)
    fun ConfigurationContainer.`Add java Sonar plugin dependency`(project: Project, dependencyHandler: DependencyHandler) {
        addSonarPluginDependency(project, dependencyHandler, "java")
    }

    @PluginAction(order = -90)
    @WithPlugins(KotlinAnyPluginId::class)
    fun ConfigurationContainer.`Add kotlin Sonar plugin dependency`(project: Project, dependencyHandler: DependencyHandler) {
        addSonarPluginDependency(project, dependencyHandler, "kotlin")
    }

    @PluginAction(order = -90)
    fun ConfigurationContainer.`Add html, javascript, xml Sonar plugin dependencies`(project: Project, dependencyHandler: DependencyHandler) {
        addSonarPluginDependency(project, dependencyHandler, "html", "javascript", "xml")
    }


    @PluginAction
    fun TaskContainer.`Configure SonarLint tasks' Sonar classpath`(configurations: ConfigurationContainer) {
        all(SonarLint::class.java) { task ->
            task.sonarClasspath = configurations.toolConfiguration
            task.sonarPluginsClasspath = configurations.toolPluginsConfiguration
        }
    }

    override fun SonarLint.configureTaskForSourceSet(sourceSet: SourceSet, isTest: Boolean) {
        source(project.provider { sourceSet.allSource })

        if (isTest) {
            isTestSources = true
        }

        val sourceSets = project.java.sourceSets
        doSetup(Int.MIN_VALUE) {
            sourceSet.output.files.filter(File::exists).map(File::getAbsoluteFile).joinToString(",").nullIfEmpty()?.also { sonarProperty("sonar.java.binaries", it) }
            sourceSet.compileClasspath.files.filter(File::exists).map(File::getAbsoluteFile).joinToString(",").nullIfEmpty()?.also { sonarProperty("sonar.java.libraries", it) }

            if (isTest) {
                isTestSources = true
                sonarProperty("sonar.java.test.binaries", sonarProperties["sonar.java.binaries"])
                sonarProperty("sonar.java.test.libraries", sonarProperties["sonar.java.libraries"])

            } else {
                val allBinaries = mutableSetOf()
                val allLibraries = mutableSetOf()
                sourceSets.filter { it.isTest }.forEach {
                    it.output.files.filter(File::exists).mapTo(allBinaries, File::getAbsoluteFile)
                    it.compileClasspath.files.filter(File::exists).mapTo(allLibraries, File::getAbsoluteFile)
                }
                allBinaries.joinToString(",").nullIfEmpty()?.also { sonarProperty("sonar.java.test.binaries", it) }
                allLibraries.joinToString(",").nullIfEmpty()?.also { sonarProperty("sonar.java.test.libraries", it) }
            }
        }

        dependsOn {
            sourceSets.asSequence()
                .filter { it.isTest }
                .mapNotNull(SourceSet::getClassesTaskName)
                .toList()
        }
    }


    private fun ConfigurationContainer.addSonarPluginDependency(project: Project, dependencyHandler: DependencyHandler, vararg sonarPlugins: String) {
        sonarPlugins.forEach { sonarPlugin ->
            val latestVersion = SONAR_PLUGIN_PROPERTIES["sonar-$sonarPlugin-plugin.latest-version"] ?: throw IllegalStateException("Last version isn't defined for '$sonarPlugin' Sonar plugin")
            val version = project.findProperty("sonar-$sonarPlugin-plugin.version").unwrapProviders()?.toString() ?: latestVersion
            val notation = (SONAR_PLUGIN_PROPERTIES["sonar-$sonarPlugin-plugin.dependency-notation"] ?: throw IllegalStateException("Notation isn't defined for '$sonarPlugin' Sonar plugin"))
                .let {
                    val tokens = it.split(':').toMutableList()
                    if (tokens.size <= 2) {
                        tokens.add(version)
                    } else {
                        tokens[2] = version
                    }
                    return@let tokens.joinToString(":")
                }
            val dependency = dependencyHandler.create(notation)
            toolPluginsConfiguration.dependencies.add(dependency)
        }
    }

}


val SourceSet.sonarlintTaskName: String get() = getTaskName("sonarlint", null)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy