From faee67270043eb1c75ebeab691a504b2827420a8 Mon Sep 17 00:00:00 2001 From: Vincent Potucek Date: Tue, 5 Aug 2025 09:53:35 +0200 Subject: [PATCH] OPE-930: apply `SOC` on `build.gradle` dedicating `allprojects.gradle` and `subprojects.gradle` --- build.gradle | 830 +------------------------------------- gradle/allprojects.gradle | 174 ++++++++ gradle/subprojects.gradle | 637 +++++++++++++++++++++++++++++ 3 files changed, 820 insertions(+), 821 deletions(-) create mode 100644 gradle/allprojects.gradle create mode 100644 gradle/subprojects.gradle diff --git a/build.gradle b/build.gradle index 99cadc2ec9c8..c5a67278895d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,19 +1,15 @@ -import groovy.text.SimpleTemplateEngine -import org.sonar.build.BlackBoxTest - import static org.gradle.api.JavaVersion.VERSION_17 +// Ordered alphabetically plugins { - // Ordered alphabetically id 'com.github.hierynomus.license' version '0.16.1' - id "com.github.hierynomus.license-report" version "0.16.1" apply false - id 'com.gradleup.shadow' version '8.3.6' apply false + id 'com.github.hierynomus.license-report' version '0.16.1' apply false id 'com.google.protobuf' version '0.8.19' apply false - // dont update com.jfrog.artifactory, new version contains a bug - id 'com.jfrog.artifactory' version '5.2.5' - id "de.undercouch.download" version "5.6.0" apply false + id 'com.gradleup.shadow' version '8.3.6' apply false + id 'com.jfrog.artifactory' version '5.2.5' // dont update new version contains a bug + id 'de.undercouch.download' version '5.6.0' apply false id 'io.spring.dependency-management' version '1.1.7' - id "org.cyclonedx.bom" version "2.3.1" apply false + id 'org.cyclonedx.bom' version '2.3.1' apply false id 'org.sonarqube' version '6.2.0.5505' } @@ -21,182 +17,6 @@ if (!JavaVersion.current().isCompatibleWith(VERSION_17)) { throw new GradleException("JDK 17+ is required to perform this build. It's currently " + System.getProperty("java.home") + ".") } -/** - * The BOM related tasks are disabled by default, activated by: - * - running in the CI and being on a main branch or a nightly build, - * - or using '-Dbom' project property - * - or by explicit call to 'cyclonedxBom' Gradle task - */ -def bomTasks = "cyclonedxBom" -def ghBranch = System.getenv()["GITHUB_BRANCH"] -def isMainBranch = ghBranch in ['master'] || ghBranch ==~ 'branch-[\\d.]+' - -boolean enableBom = System.getenv('CI') == "true" && (isMainBranch) || - System.getProperty("bom") != null || - gradle.startParameter.taskNames.findAll({ it.matches(".*:($bomTasks)") }) - -allprojects { - apply plugin: 'com.jfrog.artifactory' - apply plugin: 'maven-publish' - - ext.versionInSources = version - ext.buildNumber = System.getProperty("buildNumber") - // when no buildNumber is provided, then project version must end with '-SNAPSHOT' - if (ext.buildNumber == null) { - version = "${version}-SNAPSHOT".toString() - ext.versionWithoutBuildNumber = version - } else { - ext.versionWithoutBuildNumber = version - version = (version.toString().count('.') == 1 ? "${version}.0.${ext.buildNumber}" : "${version}.${ext.buildNumber}").toString() - } - - task cacheDependencies { - doLast { - configurations.each { conf -> - if (conf.isCanBeResolved()) { - if (conf.getName() != 'appZip') - conf.resolve() - } - } - } - } - - ext { - release = project.hasProperty('release') && project.getProperty('release') - deployCommunity = project.hasProperty('deployCommunity') && (project.getProperty('deployCommunity') == 'true') - official = project.hasProperty('official') && project.getProperty('official') - } - - ext.enableBom = enableBom - if (!enableBom) { - tasks.matching { it.name.matches(bomTasks) }.all({ - logger.info("{} disabled", it.name); - it.enabled = false - }) - } - - repositories { - // The environment variables ARTIFACTORY_PRIVATE_USERNAME and ARTIFACTORY_PRIVATE_PASSWORD are used on QA env (Jenkins) - // On local box, please add artifactoryUsername and artifactoryPassword to ~/.gradle/gradle.properties - def artifactoryUsername = System.env.'ARTIFACTORY_PRIVATE_USERNAME' ?: (project.hasProperty('artifactoryUsername') ? project.getProperty('artifactoryUsername') : '') - def artifactoryPassword = System.env.'ARTIFACTORY_PRIVATE_PASSWORD' ?: (project.hasProperty('artifactoryPassword') ? project.getProperty('artifactoryPassword') : '') - def artifactoryUrl = System.getenv('ARTIFACTORY_URL') ?: (project.hasProperty('artifactoryUrl') ? project.getProperty('artifactoryUrl') : '') - - if (artifactoryPassword) { - if (artifactoryUrl == '') { - throw new GradleException('Invalid artifactoryUrl') - } - maven { - authentication { - header(HttpHeaderAuthentication) - } - credentials(HttpHeaderCredentials) { - name = "Authorization" - value = "Bearer $artifactoryPassword" - } - url "${artifactoryUrl}/sonarsource" - } - maven { - authentication { - header(HttpHeaderAuthentication) - } - credentials(HttpHeaderCredentials) { - name = "Authorization" - value = "Bearer $artifactoryPassword" - } - url "${artifactoryUrl}/sonarsource-qa" - } - } else { - mavenCentral() - maven { - url 'https://jitpack.io' - } - maven { - url 'https://maven.codelibs.org/' - } - maven { - url 'https://build.shibboleth.net/nexus/content/repositories/releases/' - } - } - ivy { - if (artifactoryUsername && artifactoryPassword) { - url "${artifactoryUrl}/sonarsource-bucket" - authentication { - header(HttpHeaderAuthentication) - } - credentials(HttpHeaderCredentials) { - name = "Authorization" - value = "Bearer $artifactoryPassword" - } - - patternLayout { - artifact '/[organisation]/[module]/[module]-[revision].[ext]' - } - } else { - // For public build - url "https://artifacts.elastic.co/downloads/" - - patternLayout { - artifact '/[organisation]/[module]-[revision].[ext]' - } - } - - metadataSources { artifact() } - } - } - - task allDependencies { - dependsOn 'dependencies' - } - - artifactory { - clientConfig.setIncludeEnvVars(true) - clientConfig.setEnvVarsExcludePatterns('*pass*,*psw*,*secret*,*MAVEN_CMD_LINE_ARGS*,sun.java.command,*token*,*login*,*key*,*signing*,*auth*,*pwd*') - clientConfig.publisher.setFilterExcludedArtifactsFromBuild(true) - contextUrl = System.getenv('ARTIFACTORY_URL') - - //if property deployCommunity is true set the value to sonar-enterprise-sqcb - //otherwise set it to sqs - if (deployCommunity) { - clientConfig.info.setBuildName('sonar-enterprise-sqcb') - clientConfig.info.addEnvironmentProperty('ARTIFACTS_TO_PUBLISH', - "${project.group}:sonar-application:zip") - } else { - clientConfig.info.setBuildName('sonar-enterprise-sqs') - clientConfig.info.addEnvironmentProperty('ARTIFACTS_TO_PUBLISH', - "com.sonarsource.sonarqube:sonarqube-developer:zip," + - "com.sonarsource.sonarqube:sonarqube-datacenter:zip," + - "com.sonarsource.sonarqube:sonarqube-enterprise:zip") - } - - publish { - repository { - repoKey = System.getenv('ARTIFACTORY_DEPLOY_REPO') - username = System.getenv('ARTIFACTORY_DEPLOY_USERNAME') ?: project.properties.artifactoryUsername - password = System.getenv('ARTIFACTORY_DEPLOY_PASSWORD') ?: project.properties.artifactoryPaswword - } - defaults { - properties = [ - 'build.name' : 'sonar-enterprise-sqcb', - 'build.number' : System.getenv('BUILD_NUMBER'), - 'pr.branch.target': System.getenv('GITHUB_BASE_BRANCH'), - 'pr.number' : System.getenv('PULL_REQUEST'), - 'vcs.branch' : ghBranch, - 'vcs.revision' : System.getenv('GIT_SHA1'), - 'version' : version - ] - publications('mavenJava') - publishPom = true - publishIvy = false - } - } - clientConfig.info.setBuildNumber(System.getenv('BUILD_NUMBER')) - // The name of this variable is important because it's used by the delivery process when extracting version from Artifactory build info. - clientConfig.info.addEnvironmentProperty('PROJECT_VERSION', "${version}") - } -} - -apply plugin: 'org.sonarqube' sonar { properties { property 'sonar.projectName', projectTitle @@ -209,641 +29,6 @@ tasks.named('wrapper') { distributionType = Wrapper.DistributionType.ALL } -subprojects { - apply plugin: 'com.github.hierynomus.license' - apply plugin: 'io.spring.dependency-management' - apply plugin: 'jacoco' - apply plugin: 'java-library' - apply plugin: 'idea' - apply plugin: 'signing' - - // do not deploy to Artifactory by default - artifactoryPublish.skip = true - - compileJava.options.encoding = "UTF-8" - compileTestJava.options.encoding = "UTF-8" - - def testFixtureSrc = 'src/testFixtures' - if (file(testFixtureSrc).exists()) { - apply plugin: 'java-test-fixtures' - } - - ext { - protobufVersion = '4.31.1' - springSecurityVersion = '6.5.1' - elasticSearchClientVersion = '7.17.28' - } - - sonar { - properties { - property 'sonar.moduleKey', project.group + ':' + project.name - } - } - - sourceSets { - test { - resources { - srcDirs += ['src/it/resources'] - } - java { - srcDirs += ['src/it/java'] - } - } - - bbt { - resources { - srcDirs = ['src/bbt/resources'] - } - java { - srcDirs = ['src/bbt/java'] - } - } - } - - configurations { - bbtCompile.extendsFrom testCompile - bbtRuntime.extendsFrom testRuntime - bbtImplementation.extendsFrom testImplementation - - webapp { - transitive = false - } - - // global exclusions and resolution strategies - all { - // do not conflict with com.sun.mail:javax.mail - exclude group: 'javax.mail', module: 'mail' - resolutionStrategy { - force 'net.java.dev.jna:jna:5.14.0' - } - } - } - - // Central place for definition dependency versions and exclusions. - dependencyManagement { - dependencies { - // bundled plugin list -- keep it alphabetically ordered - dependency 'com.sonarsource.abap:sonar-abap-plugin:3.15.1.6010' - dependency 'com.sonarsource.armor:sonar-jasmin-plugin:1.3.0.6541' - dependency 'com.sonarsource.cobol:sonar-cobol-plugin:5.8.1.8428' - dependency 'com.sonarsource.cpp:sonar-cfamily-dependencies-plugin:6.70.0.87073' - dependency 'com.sonarsource.cpp:sonar-cfamily-plugin:6.70.0.87073' - dependency 'com.sonarsource.dart:sonar-dart-plugin:1.3.0.2614' - dependency 'com.sonarsource.dbd:sonar-dbd-plugin:2.2.0.16530' - dependency 'com.sonarsource.dbd:sonar-dbd-java-frontend-plugin:2.2.0.16530' - dependency 'com.sonarsource.dbd:sonar-dbd-python-frontend-plugin:2.2.0.16530' - dependency 'com.sonarsource.dotnet:sonar-csharp-enterprise-plugin:10.15.0.120848' - dependency 'com.sonarsource.dotnet:sonar-vbnet-enterprise-plugin:10.15.0.120848' - dependency 'com.sonarsource.go:sonar-go-enterprise-plugin:1.26.0.3421' - dependency 'com.sonarsource.pli:sonar-pli-plugin:1.16.0.5325' - dependency 'com.sonarsource.plsql:sonar-plsql-plugin:3.17.0.7448' - dependency 'com.sonarsource.plugins.vb:sonar-vb-plugin:2.14.1.5552' - dependency 'com.sonarsource.rpg:sonar-rpg-plugin:3.10.0.5337' - dependency 'com.sonarsource.security:sonar-security-csharp-frontend-plugin:11.6.0.39346' - dependency 'com.sonarsource.security:sonar-security-go-frontend-plugin:11.6.0.39346' - dependency 'com.sonarsource.security:sonar-security-java-frontend-plugin:11.6.0.39346' - dependency 'com.sonarsource.security:sonar-security-js-frontend-plugin:11.6.0.39346' - dependency 'com.sonarsource.security:sonar-security-kotlin-frontend-plugin:11.6.0.39346' - dependency 'com.sonarsource.security:sonar-security-php-frontend-plugin:11.6.0.39346' - dependency 'com.sonarsource.security:sonar-security-plugin:11.6.0.39346' - dependency 'com.sonarsource.security:sonar-security-python-frontend-plugin:11.6.0.39346' - dependency 'com.sonarsource.security:sonar-security-vbnet-frontend-plugin:11.6.0.39346' - dependency 'com.sonarsource.slang:sonar-apex-plugin:1.20.0.552' - dependency 'org.sonarsource.slang:sonar-ruby-plugin:1.19.0.471' - dependency 'org.sonarsource.slang:sonar-scala-plugin:1.19.0.484' - dependency 'com.sonarsource.swift:sonar-swift-plugin:4.14.0.8764' - dependency 'com.sonarsource.tsql:sonar-tsql-plugin:1.15.0.7898' - dependency 'org.sonarsource.dotnet:sonar-csharp-plugin:10.15.0.120848' - dependency 'org.sonarsource.dotnet:sonar-vbnet-plugin:10.15.0.120848' - dependency 'org.sonarsource.flex:sonar-flex-plugin:2.14.0.5032' - dependency 'org.sonarsource.go:sonar-go-plugin:1.26.0.3421' - dependency 'org.sonarsource.html:sonar-html-plugin:3.19.0.5695' - dependency 'org.sonarsource.jacoco:sonar-jacoco-plugin:1.3.0.1538' - dependency 'org.sonarsource.java:sonar-java-plugin:8.18.0.40025' - dependency 'org.sonarsource.java:sonar-java-symbolic-execution-plugin:8.16.0.131' - dependency 'org.sonarsource.javascript:sonar-javascript-plugin:10.25.0.33900' - dependency 'org.sonarsource.php:sonar-php-plugin:3.46.0.13151' - dependency 'org.sonarsource.plugins.cayc:sonar-cayc-plugin:2.4.0.2018' - dependency 'org.sonarsource.python:sonar-python-plugin:5.7.0.24163' - dependency 'org.sonarsource.rust:sonar-rust-plugin:1.0.3.786' - dependency 'com.sonarsource.python:sonar-python-enterprise-plugin:5.7.0.24163' - dependency 'org.sonarsource.kotlin:sonar-kotlin-plugin:3.3.0.7402' - dependency "org.sonarsource.api.plugin:sonar-plugin-api:$pluginApiVersion" - dependency "org.sonarsource.api.plugin:sonar-plugin-api-test-fixtures:$pluginApiVersion" - dependency 'org.sonarsource.xml:sonar-xml-plugin:2.13.0.5938' - dependency 'org.sonarsource.iac:sonar-iac-plugin:1.48.0.15768' - dependency 'com.sonarsource.iac:sonar-iac-enterprise-plugin:1.48.0.15768' - dependency 'org.sonarsource.text:sonar-text-plugin:2.26.0.7517' - dependency 'com.sonarsource.text:sonar-text-developer-plugin:2.26.0.7517' - dependency 'com.sonarsource.text:sonar-text-enterprise-plugin:2.26.0.7517' - dependency 'com.sonarsource.jcl:sonar-jcl-plugin:1.4.1.1493' - dependency 'com.sonarsource.architecture:sonar-architecture-plugin:2.0.0.6303' - dependency 'com.sonarsource.architecture:sonar-architecture-java-frontend-plugin:2.0.0.6303' - dependency 'com.sonarsource.architecture:sonar-architecture-javascript-frontend-plugin:2.0.0.6303' - - // Webapp - dependency "org.sonarsource.sonarqube:webapp-assets:$webappVersion" - - // please keep this list alphabetically ordered - dependencySet(group: 'ch.qos.logback', version: '1.5.18') { - entry 'logback-classic' - entry 'logback-core' - } - - // https://mvnrepository.com/artifact/ch.qos.logback.access/common - dependency('ch.qos.logback.access:common:2.0.3') - dependency('ch.qos.logback.access:logback-access-tomcat:2.0.6') - dependency 'commons-codec:commons-codec:1.18.0' - dependency 'commons-dbutils:commons-dbutils:1.8.1' - dependency 'commons-io:commons-io:2.19.0' - imports { mavenBom 'com.fasterxml.jackson:jackson-bom:2.19.0' } - dependency 'com.eclipsesource.minimal-json:minimal-json:0.9.5' - dependencySet(group: 'com.github.scribejava', version: '8.3.3') { - entry 'scribejava-apis' - entry 'scribejava-core' - } - dependency('com.github.erosb:json-sKema:0.23.0') { - // this version of json-sKema does not make use of commons-collections, so we can exclude it safely - exclude 'commons-collections:commons-collections' - } - // This project is no longer maintained and was forked - // by https://github.com/java-diff-utils/java-diff-utils - // (io.github.java-diff-utils:java-diff-utils). - dependency 'com.googlecode.java-diff-utils:diffutils:1.3.0' - dependency('com.googlecode.json-simple:json-simple:1.1.1') { - exclude 'junit:junit' - } - dependency 'io.github.hakky54:sslcontext-kickstart:9.1.0' - dependency 'io.prometheus:simpleclient:0.16.0' - dependency 'io.prometheus:simpleclient_common:0.16.0' - dependency 'io.prometheus:simpleclient_servlet:0.16.0' - dependency 'com.github.spotbugs:spotbugs-annotations:4.9.3' - dependency 'com.google.code.gson:gson:2.13.1' - dependency('com.google.guava:guava:33.4.8-jre') { - exclude 'com.google.errorprone:error_prone_annotations' - exclude 'com.google.guava:listenablefuture' - exclude 'com.google.j2objc:j2objc-annotations' - exclude 'org.checkerframework:checker-qual' - exclude 'org.codehaus.mojo:animal-sniffer-annotations' - } - dependency "com.google.protobuf:protobuf-java:${protobufVersion}" - dependency 'com.h2database:h2:2.3.232' - dependencySet(group: 'com.hazelcast', version: '5.5.0') { - entry 'hazelcast' - } - // Documentation must be updated if mssql-jdbc is updated: https://github.com/SonarSource/sonarqube/commit/03e4773ebf6cba854cdcf57a600095f65f4f53e7 - dependency('com.microsoft.sqlserver:mssql-jdbc:12.10.0.jre11') { - exclude 'com.fasterxml.jackson.core:jackson-databind' - } - dependency 'com.microsoft.azure:msal4j:1.22.0' - dependency 'com.oracle.database.jdbc:ojdbc11:23.8.0.25.04' - dependency 'com.datadoghq:dd-java-agent:1.49.0' - dependency 'org.aspectj:aspectjtools:1.9.24' - dependencySet(group: 'com.squareup.okhttp3', version: '4.12.0') { - entry 'okhttp' - entry 'mockwebserver' - entry 'okhttp-tls' - entry 'logging-interceptor' - } - dependency 'commons-logging:commons-logging:1.3.5' - dependency 'org.json:json:20250517' - // To be removed after migration to JUnit5 is finished - dependency 'com.tngtech.java:junit-dataprovider:1.13.1' - dependency 'com.tngtech.junit.dataprovider:junit-jupiter-params-dataprovider:2.10' - dependencySet(group: 'io.jsonwebtoken', version: '0.12.6') { - entry 'jjwt-api' - entry 'jjwt-impl' - entry 'jjwt-jackson' - } - dependency 'com.auth0:java-jwt:4.5.0' - dependency 'io.netty:netty-all:4.2.1.Final' - dependency 'jakarta.mail:jakarta.mail-api:2.1.3' - dependency 'jakarta.annotation:jakarta.annotation-api:3.0.0' - dependency 'jakarta.inject:jakarta.inject-api:2.0.1' - dependency 'jakarta.servlet:jakarta.servlet-api:6.1.0' - dependency 'junit:junit:4.13.2' - dependencySet(group: 'org.xmlunit', version: '2.10.2') { - entry 'xmlunit-core' - entry 'xmlunit-matchers' - } - dependency 'org.lz4:lz4-java:1.8.0' - dependency 'org.littleshoot:littleproxy:1.1.2' - dependency 'net.sf.trove4j:core:3.1.0' - dependency 'org.awaitility:awaitility:4.3.0' - dependency 'org.apache.commons:commons-collections4:4.5.0' - dependency 'org.apache.commons:commons-csv:1.14.0' - dependency 'org.apache.commons:commons-lang3:3.17.0' - dependency 'org.apache.commons:commons-email2-jakarta:2.0.0-M1' - dependency 'org.apache.commons:commons-exec:1.5.0' - dependency 'org.apache.commons:commons-text:1.13.1' - dependency 'org.apache.mina:mina-core:2.2.4' - dependency 'org.apache.kerby:kerb-simplekdc:2.1.0' - dependency 'org.apache.kerby:ldap-backend:2.1.0' - dependency 'com.zaxxer:HikariCP:6.3.0' - dependency('org.apache.directory.server:apacheds-server-integ:2.0.0.AM27') { - exclude 'log4j:log4j' - } - // Be aware that Log4j is used by Elasticsearch client - dependencySet(group: 'org.apache.logging.log4j', version: '2.24.3') { - entry 'log4j-core' - entry 'log4j-api' - entry 'log4j-to-slf4j' - } - dependencySet(group: 'org.apache.tomcat.embed', version: '11.0.8') { - entry 'tomcat-embed-core' - entry('tomcat-embed-jasper') { - exclude 'org.eclipse.jdt.core.compiler:ecj' - } - } - //transitive dependency of SVNKit, to be re-assessed when updating SVNKit - dependency 'org.apache.sshd:sshd-core:2.15.0' - dependencySet(group: 'org.assertj', version: '3.27.3') { - entry 'assertj-core' - entry 'assertj-guava' - } - dependencySet(group: 'org.bouncycastle', version: '1.80') { - entry 'bcpkix-jdk18on' - entry 'bcprov-jdk18on' - } - dependency('org.codehaus.sonar:sonar-channel:4.2') { - exclude 'org.slf4j:slf4j-api' - } - dependency 'org.cyclonedx:cyclonedx-core-java:10.2.1' - dependency 'com.fasterxml.staxmate:staxmate:2.4.1' - dependency("org.elasticsearch.client:elasticsearch-rest-high-level-client:${elasticSearchClientVersion}") { - exclude 'org.apache.logging.log4j:log4j-core' - } - dependency "org.elasticsearch.plugin:transport-netty4-client:${elasticSearchClientVersion}" - dependency 'org.elasticsearch:mocksocket:1.2' - dependency 'org.eclipse.jgit:org.eclipse.jgit:7.3.0.202506031305-r' - dependency "org.codelibs.elasticsearch.module:analysis-common:7.17.22" - dependency "org.codelibs.elasticsearch.module:reindex:7.17.22" - dependency('org.tmatesoft.svnkit:svnkit:1.10.11') { - exclude 'net.i2p.crypto:eddsa' - } - dependency 'org.hamcrest:hamcrest:3.0' - dependency 'org.jsoup:jsoup:1.20.1' - // JUnit 5 - imports { mavenBom 'org.junit:junit-bom:5.11.4' } - dependency 'org.junit-pioneer:junit-pioneer:2.3.0' - dependencySet(group: 'org.mockito', version: '5.18.0') { - entry 'mockito-core' - entry('mockito-junit-jupiter') { - exclude 'org.junit.jupiter:junit-jupiter-api' - } - } - dependency 'org.spdx:java-spdx-library:2.0.0' - dependency 'org.spdx:spdx-jackson-store:2.0.2' - dependencySet(group: 'org.springframework', version: '6.2.8') { - entry 'spring-test' - entry('spring-context') { - exclude 'commons-logging:commons-logging' - } - entry('spring-webmvc') { - exclude 'commons-logging:commons-logging' - } - } - dependency "org.springframework.security:spring-security-saml2-service-provider:${springSecurityVersion}" - dependency 'org.mybatis:mybatis:3.5.19' - dependencySet(group: 'org.slf4j', version: '2.0.17') { - entry 'jcl-over-slf4j' - entry 'jul-to-slf4j' - entry 'log4j-over-slf4j' - entry 'slf4j-api' - } - dependency 'org.postgresql:postgresql:42.7.7' - dependency 'org.reflections:reflections:0.10.2' - dependency 'org.simpleframework:simple:5.1.6' - dependency 'org.sonarsource.git.blame:git-files-blame:2.0.0.2053' - dependency('org.sonarsource.orchestrator:sonar-orchestrator-junit4:5.6.2.2625') { - exclude 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml' - } - dependency('org.sonarsource.orchestrator:sonar-orchestrator-junit5:5.6.2.2625') { - exclude 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml' - } - dependency "com.sonarsource.pdfreport:regulatory-report-pdf-generation:${pdfreportVersion}" - dependency "com.sonarsource.pdfreport:security-report-pdf-generation:${pdfreportVersion}" - dependency 'com.sonarsource.fixsuggestions:ai-suggestions-shared:1.0.0.1312' - dependency 'org.sonarsource.update-center:sonar-update-center-common:1.35.0.2835' - dependency 'org.sonarsource.classloader:sonar-classloader:1.1.0.1059' - dependency 'org.springdoc:springdoc-openapi-starter-webmvc-api:2.8.6' - dependencySet(group: 'com.icegreen', version: '2.1.3') { - entry 'greenmail' - entry 'greenmail-junit4' - entry 'greenmail-junit5' - } - dependency 'org.yaml:snakeyaml:2.4' - dependency 'org.hibernate.validator:hibernate-validator:9.0.0.Final' - dependency 'org.kohsuke:github-api:1.327' - dependency 'org.wiremock:wiremock-standalone:3.13.0' - dependency 'org.skyscreamer:jsonassert:1.5.3' - // to be used only in sonar-ws-generator - dependency("org.apache.velocity:velocity:1.7") { - dependency 'commons-collections:commons-collections:3.2.2' - } - dependency 'com.google.code.findbugs:jsr305:3.0.2' - // please keep this list alphabetically ordered - } - } - - tasks.withType(Javadoc) { - options.addStringOption('Xdoclint:none', '-quiet') - options.encoding = 'UTF-8' - title = project.name + ' ' + versionWithoutBuildNumber - } - - tasks.withType(Test) { - if (System.getenv().containsKey("CIRRUS_CI")) { - develocity.testRetry { - maxRetries = 3 - maxFailures = 30 - failOnPassedAfterRetry = System.getenv("CIRRUS_PR") != null - } - } - } - - task sourcesJar(type: Jar, dependsOn: classes) { - archiveClassifier = 'sources' - from sourceSets.main.allSource - } - - task javadocJar(type: Jar, dependsOn: javadoc) { - archiveClassifier = 'javadoc' - from javadoc.destinationDir - } - - // generate code before opening project in IDE (Eclipse or Intellij) - task ide() { - // empty by default. Dependencies are added to the task - // when needed (see protobuf modules for example) - } - - task generatePackageInfo { - doLast { - def allPathsContainingJavaFiles = [] as Set - - fileTree('src/main/java/').matching() { - include "*/**/*.java" - exclude "*/**/package-info.java" - }.forEach { - allPathsContainingJavaFiles << it.toPath().toFile().getParent(); - } - - allPathsContainingJavaFiles.each { - String packageInfoPath = it + "/package-info.java" - File packageInfoFile = new File(packageInfoPath) - if (!packageInfoFile.exists()) { - logger.info("Creating file: " + packageInfoPath) - def packageName = packageInfoFile.getParent().replaceAll("[\\\\ /]", ".").takeAfter("src.main.java."); - String packageInfoContent = applyPackageInfoTemplate(packageName) - packageInfoFile << packageInfoContent - } - } - - def allPackageInfoFiles = [] as Set - - fileTree('src/main/java/').matching() { - include "*/**/package-info.java" - }.forEach { - allPackageInfoFiles << it.toPath().toFile(); - } - - allPackageInfoFiles.forEach { - File packageInfoFile = it; - if (!allPathsContainingJavaFiles.contains(packageInfoFile.getParent())) { - logger.warn("Deleting package info file: " + packageInfoFile) - packageInfoFile.delete(); - } - } - - } - } - build.dependsOn(generatePackageInfo) - generatePackageInfo.finalizedBy(licenseFormat) - - jacocoTestReport { - reports { - xml.required = true - csv.required = false - html.required = false - } - } - - normalization { - runtimeClasspath { - // Following classpath resources contain volatile data that changes in each CI build (build number, commit id, time), - // so we exclude them from calculation of build cache key of test tasks: - ignore 'META-INF/MANIFEST.MF' - ignore 'sonar-api-version.txt' - ignore 'sq-version.txt' - } - } - - - ext.failedTests = [] - test { - jvmArgs '-Dfile.encoding=UTF8' - maxHeapSize = '1500m' - systemProperty 'java.awt.headless', true - // Some tests are asserting on localized messages or dates - systemProperty 'user.language', 'en' - systemProperty 'user.country', 'US' - environment 'LANGUAGE', 'en_US' - testLogging { - events "skipped", "failed" // verbose log for failed and skipped tests (by default the name of the tests are not logged) - exceptionFormat 'full' // log the full stack trace (default is the 1st line of the stack trace) - } - jacoco { - enabled = true // do not disable recording of code coverage, so that remote Gradle cache entry can be used locally - includes = ['com.sonar.*', 'com.sonarsource.*', 'org.sonar.*', 'org.sonarqube.*', 'org.sonarsource.*'] - } - if (project.hasProperty('maxParallelTests')) { - maxParallelForks = project.maxParallelTests as int - } - if (project.hasProperty('parallelTests')) { - // See https://guides.gradle.org/performance/#parallel_test_execution - maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 - } - - afterTest { descriptor, result -> - if (result.resultType == TestResult.ResultType.FAILURE) { - String failedTest = " ${descriptor.className} > ${descriptor.name}" - failedTests << failedTest - } - } - } - - gradle.buildFinished { - if (!failedTests.empty) { - println "\nFailed tests:" - failedTests.each { failedTest -> - println failedTest - } - println "" - } - } - - def protoMainSrc = 'src/main/protobuf' - def protoTestSrc = 'src/test/protobuf' - if (file(protoMainSrc).exists() || file(protoTestSrc).exists()) { - // protobuf must be applied after java - apply plugin: 'com.google.protobuf' - - sourceSets.main.proto.srcDir protoMainSrc // in addition to the default 'src/main/proto' - sourceSets.test.proto.srcDir protoTestSrc // in addition to the default 'src/test/proto' - protobuf { - protoc { - artifact = "com.google.protobuf:protoc:${protobufVersion}" - } - } - jar { - exclude('**/*.proto') - } - idea { - module { - sourceDirs += file("${protobuf.generatedFilesBaseDir}/main/java") - testSourceDirs += file("${protobuf.generatedFilesBaseDir}/test/java") - generatedSourceDirs += file("${protobuf.generatedFilesBaseDir}/main/java") - generatedSourceDirs += file("${protobuf.generatedFilesBaseDir}/test/java") - } - } - ide.dependsOn(['generateProto', 'generateTestProto']) - } - - if (official) { - jar { - // do not break incremental build on non official versions - manifest { - attributes( - 'Version': "${version}", - 'Implementation-Build': System.getenv('GIT_SHA1'), - 'Build-Time': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") - ) - } - } - } - - license { - header = rootProject.file('HEADER') - ignoreFailures = project.hasProperty('ignoreLicenseFailures') ? project.getProperty('ignoreLicenseFailures').toBoolean() : true - strictCheck true - encoding = 'UTF-8' - mapping { - java = 'SLASHSTAR_STYLE' - js = 'SLASHSTAR_STYLE' - ts = 'SLASHSTAR_STYLE' - tsx = 'SLASHSTAR_STYLE' - css = 'SLASHSTAR_STYLE' - } - includes(['**/*.java', '**/*.js', '**/*.ts', '**/*.tsx', '**/*.css']) - } - - tasks.withType(GenerateModuleMetadata) { - enabled = false - } - - publishing { - publications { - mavenJava(MavenPublication) { - pom { - name = 'SonarQube' - description = project.description - url = 'https://www.sonarsource.com/products/sonarqube' - organization { - name = 'SonarSource' - url = 'https://www.sonarsource.com' - } - licenses { - license { - name = 'GNU LGPL 3' - url = 'http://www.gnu.org/licenses/lgpl.txt' - distribution = 'repo' - } - } - scm { - url = 'https://github.com/SonarSource/sonarqube' - } - developers { - developer { - id = 'sonarsource-team' - name = 'SonarSource Team' - } - } - } - } - } - } - - tasks.withType(Test) { - configurations { - ddAgent - } - - dependencies { - ddAgent 'com.datadoghq:dd-java-agent' - } - - if (System.getenv('CI') == "true") { - doFirst { - ext { - ddJavaAgent = configurations.ddAgent.resolvedConfiguration.resolvedArtifacts.find { it.name == 'dd-java-agent' } - } - jvmArgs "-javaagent:${ddJavaAgent.file}" - jvmArgs "-Ddatadog.slf4j.simpleLogger.logFile=${project.projectDir}/build/datadog.log" - } - } - } - - tasks.withType(BlackBoxTest) { - jacoco.enabled = false - testClassesDirs = sourceSets.bbt.output.classesDirs - classpath = sourceSets.bbt.runtimeClasspath - - configurations { - includeInTestResources - } - - dependencies { - bbtRuntimeOnly 'com.microsoft.sqlserver:mssql-jdbc' - bbtRuntimeOnly 'com.oracle.database.jdbc:ojdbc11' - bbtRuntimeOnly 'org.postgresql:postgresql' - bbtRuntimeOnly project(':plugins:sonar-xoo-plugin') - - bbtImplementation 'org.sonarsource.orchestrator:sonar-orchestrator-junit4' - bbtImplementation project(":sonar-testing-harness") - bbtImplementation project(":private:it-common") - bbtImplementation testFixtures(project(":sonar-ws")) - } - } - - signing { - def signingKeyId = findProperty("signingKeyId") - def signingKey = findProperty("signingKey") - def signingPassword = findProperty("signingPassword") - useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword) - required { - return isMainBranch && gradle.taskGraph.hasTask(":artifactoryPublish") - } - sign publishing.publications - } - - tasks.withType(Sign) { - onlyIf { - return !artifactoryPublish.skip && isMainBranch && gradle.taskGraph.hasTask(":artifactoryPublish") - } - } -} - -static def applyPackageInfoTemplate(packageName) { - def engine = new SimpleTemplateEngine() - def templateText = "@ParametersAreNonnullByDefault\n" + - "package $packageName;\n" + - "\n" + - "import javax.annotation.ParametersAreNonnullByDefault;\n" - def templateParams = ["packageName": packageName] - engine.createTemplate(templateText).make(templateParams).toString() -} - gradle.projectsEvaluated { gradle -> // yarn_run tasks can't all run in parallel without random issues // this script ensure all yarn_run tasks run sequentially @@ -862,3 +47,6 @@ ext.osAdaptiveCommand = { commands -> return newCommands } + +apply from: "$rootDir/gradle/allprojects.gradle" +apply from: "$rootDir/gradle/subprojects.gradle" diff --git a/gradle/allprojects.gradle b/gradle/allprojects.gradle new file mode 100644 index 000000000000..ef2bf762e1d5 --- /dev/null +++ b/gradle/allprojects.gradle @@ -0,0 +1,174 @@ +/** + * The BOM related tasks are disabled by default, activated by: + * - running in the CI and being on a main branch or a nightly build, + * - or using '-Dbom' project property + * - or by explicit call to 'cyclonedxBom' Gradle task + */ +def bomTasks = "cyclonedxBom" +def ghBranch = System.getenv()["GITHUB_BRANCH"] +def isMainBranch = ghBranch in ['master'] || ghBranch ==~ 'branch-[\\d.]+' + +boolean enableBom = System.getenv('CI') == "true" && (isMainBranch) || + System.getProperty("bom") != null || + gradle.startParameter.taskNames.findAll({ it.matches(".*:($bomTasks)") }) + +allprojects { + apply plugin: 'com.jfrog.artifactory' + apply plugin: 'maven-publish' + + ext.versionInSources = version + ext.buildNumber = System.getProperty("buildNumber") + // when no buildNumber is provided, then project version must end with '-SNAPSHOT' + if (ext.buildNumber == null) { + version = "${version}-SNAPSHOT".toString() + ext.versionWithoutBuildNumber = version + } else { + ext.versionWithoutBuildNumber = version + version = (version.toString().count('.') == 1 ? "${version}.0.${ext.buildNumber}" : "${version}.${ext.buildNumber}").toString() + } + + task cacheDependencies { + doLast { + configurations.each { conf -> + if (conf.isCanBeResolved()) { + if (conf.getName() != 'appZip') + conf.resolve() + } + } + } + } + + ext { + release = project.hasProperty('release') && project.getProperty('release') + deployCommunity = project.hasProperty('deployCommunity') && (project.getProperty('deployCommunity') == 'true') + official = project.hasProperty('official') && project.getProperty('official') + } + + ext.enableBom = enableBom + if (!enableBom) { + tasks.matching { it.name.matches(bomTasks) }.all({ + logger.info("{} disabled", it.name); + it.enabled = false + }) + } + + repositories { + // The environment variables ARTIFACTORY_PRIVATE_USERNAME and ARTIFACTORY_PRIVATE_PASSWORD are used on QA env (Jenkins) + // On local box, please add artifactoryUsername and artifactoryPassword to ~/.gradle/gradle.properties + def artifactoryUsername = System.env.'ARTIFACTORY_PRIVATE_USERNAME' ?: (project.hasProperty('artifactoryUsername') ? project.getProperty('artifactoryUsername') : '') + def artifactoryPassword = System.env.'ARTIFACTORY_PRIVATE_PASSWORD' ?: (project.hasProperty('artifactoryPassword') ? project.getProperty('artifactoryPassword') : '') + def artifactoryUrl = System.getenv('ARTIFACTORY_URL') ?: (project.hasProperty('artifactoryUrl') ? project.getProperty('artifactoryUrl') : '') + + if (artifactoryPassword) { + if (artifactoryUrl == '') { + throw new GradleException('Invalid artifactoryUrl') + } + maven { + authentication { + header(HttpHeaderAuthentication) + } + credentials(HttpHeaderCredentials) { + name = "Authorization" + value = "Bearer $artifactoryPassword" + } + url "${artifactoryUrl}/sonarsource" + } + maven { + authentication { + header(HttpHeaderAuthentication) + } + credentials(HttpHeaderCredentials) { + name = "Authorization" + value = "Bearer $artifactoryPassword" + } + url "${artifactoryUrl}/sonarsource-qa" + } + } else { + mavenCentral() + maven { + url 'https://jitpack.io' + } + maven { + url 'https://maven.codelibs.org/' + } + maven { + url 'https://build.shibboleth.net/nexus/content/repositories/releases/' + } + } + ivy { + if (artifactoryUsername && artifactoryPassword) { + url "${artifactoryUrl}/sonarsource-bucket" + authentication { + header(HttpHeaderAuthentication) + } + credentials(HttpHeaderCredentials) { + name = "Authorization" + value = "Bearer $artifactoryPassword" + } + + patternLayout { + artifact '/[organisation]/[module]/[module]-[revision].[ext]' + } + } else { + // For public build + url "https://artifacts.elastic.co/downloads/" + + patternLayout { + artifact '/[organisation]/[module]-[revision].[ext]' + } + } + + metadataSources { artifact() } + } + } + + task allDependencies { + dependsOn 'dependencies' + } + + artifactory { + clientConfig.setIncludeEnvVars(true) + clientConfig.setEnvVarsExcludePatterns('*pass*,*psw*,*secret*,*MAVEN_CMD_LINE_ARGS*,sun.java.command,*token*,*login*,*key*,*signing*,*auth*,*pwd*') + clientConfig.publisher.setFilterExcludedArtifactsFromBuild(true) + contextUrl = System.getenv('ARTIFACTORY_URL') + + //if property deployCommunity is true set the value to sonar-enterprise-sqcb + //otherwise set it to sqs + if (deployCommunity) { + clientConfig.info.setBuildName('sonar-enterprise-sqcb') + clientConfig.info.addEnvironmentProperty('ARTIFACTS_TO_PUBLISH', + "${project.group}:sonar-application:zip") + } else { + clientConfig.info.setBuildName('sonar-enterprise-sqs') + clientConfig.info.addEnvironmentProperty('ARTIFACTS_TO_PUBLISH', + "com.sonarsource.sonarqube:sonarqube-developer:zip," + + "com.sonarsource.sonarqube:sonarqube-datacenter:zip," + + "com.sonarsource.sonarqube:sonarqube-enterprise:zip") + } + + publish { + repository { + repoKey = System.getenv('ARTIFACTORY_DEPLOY_REPO') + username = System.getenv('ARTIFACTORY_DEPLOY_USERNAME') ?: project.properties.artifactoryUsername + password = System.getenv('ARTIFACTORY_DEPLOY_PASSWORD') ?: project.properties.artifactoryPaswword + } + defaults { + properties = [ + 'build.name' : 'sonar-enterprise-sqcb', + 'build.number' : System.getenv('BUILD_NUMBER'), + 'pr.branch.target': System.getenv('GITHUB_BASE_BRANCH'), + 'pr.number' : System.getenv('PULL_REQUEST'), + 'vcs.branch' : ghBranch, + 'vcs.revision' : System.getenv('GIT_SHA1'), + 'version' : version + ] + publications('mavenJava') + publishPom = true + publishIvy = false + } + } + clientConfig.info.setBuildNumber(System.getenv('BUILD_NUMBER')) + // The name of this variable is important because it's used by the delivery process when extracting version from Artifactory build info. + clientConfig.info.addEnvironmentProperty('PROJECT_VERSION', "${version}") + } +} diff --git a/gradle/subprojects.gradle b/gradle/subprojects.gradle new file mode 100644 index 000000000000..553235e03557 --- /dev/null +++ b/gradle/subprojects.gradle @@ -0,0 +1,637 @@ +import groovy.text.SimpleTemplateEngine +import org.sonar.build.BlackBoxTest + +static def applyPackageInfoTemplate(packageName) { + def engine = new SimpleTemplateEngine() + def templateText = "@ParametersAreNonnullByDefault\n" + + "package $packageName;\n" + + "\n" + + "import javax.annotation.ParametersAreNonnullByDefault;\n" + def templateParams = ["packageName": packageName] + engine.createTemplate(templateText).make(templateParams).toString() +} + +subprojects { + apply plugin: 'com.github.hierynomus.license' + apply plugin: 'io.spring.dependency-management' + apply plugin: 'jacoco' + apply plugin: 'java-library' + apply plugin: 'idea' + apply plugin: 'signing' + + // do not deploy to Artifactory by default + artifactoryPublish.skip = true + + compileJava.options.encoding = "UTF-8" + compileTestJava.options.encoding = "UTF-8" + + def testFixtureSrc = 'src/testFixtures' + if (file(testFixtureSrc).exists()) { + apply plugin: 'java-test-fixtures' + } + + ext { + protobufVersion = '4.31.1' + springSecurityVersion = '6.5.1' + elasticSearchClientVersion = '7.17.28' + } + + sonar { + properties { + property 'sonar.moduleKey', project.group + ':' + project.name + } + } + + sourceSets { + test { + resources { + srcDirs += ['src/it/resources'] + } + java { + srcDirs += ['src/it/java'] + } + } + + bbt { + resources { + srcDirs = ['src/bbt/resources'] + } + java { + srcDirs = ['src/bbt/java'] + } + } + } + + configurations { + bbtCompile.extendsFrom testCompile + bbtRuntime.extendsFrom testRuntime + bbtImplementation.extendsFrom testImplementation + + webapp { + transitive = false + } + + // global exclusions and resolution strategies + all { + // do not conflict with com.sun.mail:javax.mail + exclude group: 'javax.mail', module: 'mail' + resolutionStrategy { + force 'net.java.dev.jna:jna:5.14.0' + } + } + } + + // Central place for definition dependency versions and exclusions. + dependencyManagement { + dependencies { + // bundled plugin list -- keep it alphabetically ordered + dependency 'com.sonarsource.abap:sonar-abap-plugin:3.15.1.6010' + dependency 'com.sonarsource.armor:sonar-jasmin-plugin:1.3.0.6541' + dependency 'com.sonarsource.cobol:sonar-cobol-plugin:5.8.1.8428' + dependency 'com.sonarsource.cpp:sonar-cfamily-dependencies-plugin:6.70.0.87073' + dependency 'com.sonarsource.cpp:sonar-cfamily-plugin:6.70.0.87073' + dependency 'com.sonarsource.dart:sonar-dart-plugin:1.3.0.2614' + dependency 'com.sonarsource.dbd:sonar-dbd-plugin:2.2.0.16530' + dependency 'com.sonarsource.dbd:sonar-dbd-java-frontend-plugin:2.2.0.16530' + dependency 'com.sonarsource.dbd:sonar-dbd-python-frontend-plugin:2.2.0.16530' + dependency 'com.sonarsource.dotnet:sonar-csharp-enterprise-plugin:10.15.0.120848' + dependency 'com.sonarsource.dotnet:sonar-vbnet-enterprise-plugin:10.15.0.120848' + dependency 'com.sonarsource.go:sonar-go-enterprise-plugin:1.26.0.3421' + dependency 'com.sonarsource.pli:sonar-pli-plugin:1.16.0.5325' + dependency 'com.sonarsource.plsql:sonar-plsql-plugin:3.17.0.7448' + dependency 'com.sonarsource.plugins.vb:sonar-vb-plugin:2.14.1.5552' + dependency 'com.sonarsource.rpg:sonar-rpg-plugin:3.10.0.5337' + dependency 'com.sonarsource.security:sonar-security-csharp-frontend-plugin:11.6.0.39346' + dependency 'com.sonarsource.security:sonar-security-go-frontend-plugin:11.6.0.39346' + dependency 'com.sonarsource.security:sonar-security-java-frontend-plugin:11.6.0.39346' + dependency 'com.sonarsource.security:sonar-security-js-frontend-plugin:11.6.0.39346' + dependency 'com.sonarsource.security:sonar-security-kotlin-frontend-plugin:11.6.0.39346' + dependency 'com.sonarsource.security:sonar-security-php-frontend-plugin:11.6.0.39346' + dependency 'com.sonarsource.security:sonar-security-plugin:11.6.0.39346' + dependency 'com.sonarsource.security:sonar-security-python-frontend-plugin:11.6.0.39346' + dependency 'com.sonarsource.security:sonar-security-vbnet-frontend-plugin:11.6.0.39346' + dependency 'com.sonarsource.slang:sonar-apex-plugin:1.20.0.552' + dependency 'org.sonarsource.slang:sonar-ruby-plugin:1.19.0.471' + dependency 'org.sonarsource.slang:sonar-scala-plugin:1.19.0.484' + dependency 'com.sonarsource.swift:sonar-swift-plugin:4.14.0.8764' + dependency 'com.sonarsource.tsql:sonar-tsql-plugin:1.15.0.7898' + dependency 'org.sonarsource.dotnet:sonar-csharp-plugin:10.15.0.120848' + dependency 'org.sonarsource.dotnet:sonar-vbnet-plugin:10.15.0.120848' + dependency 'org.sonarsource.flex:sonar-flex-plugin:2.14.0.5032' + dependency 'org.sonarsource.go:sonar-go-plugin:1.26.0.3421' + dependency 'org.sonarsource.html:sonar-html-plugin:3.19.0.5695' + dependency 'org.sonarsource.jacoco:sonar-jacoco-plugin:1.3.0.1538' + dependency 'org.sonarsource.java:sonar-java-plugin:8.18.0.40025' + dependency 'org.sonarsource.java:sonar-java-symbolic-execution-plugin:8.16.0.131' + dependency 'org.sonarsource.javascript:sonar-javascript-plugin:10.25.0.33900' + dependency 'org.sonarsource.php:sonar-php-plugin:3.46.0.13151' + dependency 'org.sonarsource.plugins.cayc:sonar-cayc-plugin:2.4.0.2018' + dependency 'org.sonarsource.python:sonar-python-plugin:5.7.0.24163' + dependency 'org.sonarsource.rust:sonar-rust-plugin:1.0.3.786' + dependency 'com.sonarsource.python:sonar-python-enterprise-plugin:5.7.0.24163' + dependency 'org.sonarsource.kotlin:sonar-kotlin-plugin:3.3.0.7402' + dependency "org.sonarsource.api.plugin:sonar-plugin-api:$pluginApiVersion" + dependency "org.sonarsource.api.plugin:sonar-plugin-api-test-fixtures:$pluginApiVersion" + dependency 'org.sonarsource.xml:sonar-xml-plugin:2.13.0.5938' + dependency 'org.sonarsource.iac:sonar-iac-plugin:1.48.0.15768' + dependency 'com.sonarsource.iac:sonar-iac-enterprise-plugin:1.48.0.15768' + dependency 'org.sonarsource.text:sonar-text-plugin:2.26.0.7517' + dependency 'com.sonarsource.text:sonar-text-developer-plugin:2.26.0.7517' + dependency 'com.sonarsource.text:sonar-text-enterprise-plugin:2.26.0.7517' + dependency 'com.sonarsource.jcl:sonar-jcl-plugin:1.4.1.1493' + dependency 'com.sonarsource.architecture:sonar-architecture-plugin:2.0.0.6303' + dependency 'com.sonarsource.architecture:sonar-architecture-java-frontend-plugin:2.0.0.6303' + dependency 'com.sonarsource.architecture:sonar-architecture-javascript-frontend-plugin:2.0.0.6303' + + // Webapp + dependency "org.sonarsource.sonarqube:webapp-assets:$webappVersion" + + // please keep this list alphabetically ordered + dependencySet(group: 'ch.qos.logback', version: '1.5.18') { + entry 'logback-classic' + entry 'logback-core' + } + + // https://mvnrepository.com/artifact/ch.qos.logback.access/common + dependency('ch.qos.logback.access:common:2.0.3') + dependency('ch.qos.logback.access:logback-access-tomcat:2.0.6') + dependency 'commons-codec:commons-codec:1.18.0' + dependency 'commons-dbutils:commons-dbutils:1.8.1' + dependency 'commons-io:commons-io:2.19.0' + imports { mavenBom 'com.fasterxml.jackson:jackson-bom:2.19.0' } + dependency 'com.eclipsesource.minimal-json:minimal-json:0.9.5' + dependencySet(group: 'com.github.scribejava', version: '8.3.3') { + entry 'scribejava-apis' + entry 'scribejava-core' + } + dependency('com.github.erosb:json-sKema:0.23.0') { + // this version of json-sKema does not make use of commons-collections, so we can exclude it safely + exclude 'commons-collections:commons-collections' + } + // This project is no longer maintained and was forked + // by https://github.com/java-diff-utils/java-diff-utils + // (io.github.java-diff-utils:java-diff-utils). + dependency 'com.googlecode.java-diff-utils:diffutils:1.3.0' + dependency('com.googlecode.json-simple:json-simple:1.1.1') { + exclude 'junit:junit' + } + dependency 'io.github.hakky54:sslcontext-kickstart:9.1.0' + dependency 'io.prometheus:simpleclient:0.16.0' + dependency 'io.prometheus:simpleclient_common:0.16.0' + dependency 'io.prometheus:simpleclient_servlet:0.16.0' + dependency 'com.github.spotbugs:spotbugs-annotations:4.9.3' + dependency 'com.google.code.gson:gson:2.13.1' + dependency('com.google.guava:guava:33.4.8-jre') { + exclude 'com.google.errorprone:error_prone_annotations' + exclude 'com.google.guava:listenablefuture' + exclude 'com.google.j2objc:j2objc-annotations' + exclude 'org.checkerframework:checker-qual' + exclude 'org.codehaus.mojo:animal-sniffer-annotations' + } + dependency "com.google.protobuf:protobuf-java:${protobufVersion}" + dependency 'com.h2database:h2:2.3.232' + dependencySet(group: 'com.hazelcast', version: '5.5.0') { + entry 'hazelcast' + } + // Documentation must be updated if mssql-jdbc is updated: https://github.com/SonarSource/sonarqube/commit/03e4773ebf6cba854cdcf57a600095f65f4f53e7 + dependency('com.microsoft.sqlserver:mssql-jdbc:12.10.0.jre11') { + exclude 'com.fasterxml.jackson.core:jackson-databind' + } + dependency 'com.microsoft.azure:msal4j:1.22.0' + dependency 'com.oracle.database.jdbc:ojdbc11:23.8.0.25.04' + dependency 'com.datadoghq:dd-java-agent:1.49.0' + dependency 'org.aspectj:aspectjtools:1.9.24' + dependencySet(group: 'com.squareup.okhttp3', version: '4.12.0') { + entry 'okhttp' + entry 'mockwebserver' + entry 'okhttp-tls' + entry 'logging-interceptor' + } + dependency 'commons-logging:commons-logging:1.3.5' + dependency 'org.json:json:20250517' + // To be removed after migration to JUnit5 is finished + dependency 'com.tngtech.java:junit-dataprovider:1.13.1' + dependency 'com.tngtech.junit.dataprovider:junit-jupiter-params-dataprovider:2.10' + dependencySet(group: 'io.jsonwebtoken', version: '0.12.6') { + entry 'jjwt-api' + entry 'jjwt-impl' + entry 'jjwt-jackson' + } + dependency 'com.auth0:java-jwt:4.5.0' + dependency 'io.netty:netty-all:4.2.1.Final' + dependency 'jakarta.mail:jakarta.mail-api:2.1.3' + dependency 'jakarta.annotation:jakarta.annotation-api:3.0.0' + dependency 'jakarta.inject:jakarta.inject-api:2.0.1' + dependency 'jakarta.servlet:jakarta.servlet-api:6.1.0' + dependency 'junit:junit:4.13.2' + dependencySet(group: 'org.xmlunit', version: '2.10.2') { + entry 'xmlunit-core' + entry 'xmlunit-matchers' + } + dependency 'org.lz4:lz4-java:1.8.0' + dependency 'org.littleshoot:littleproxy:1.1.2' + dependency 'net.sf.trove4j:core:3.1.0' + dependency 'org.awaitility:awaitility:4.3.0' + dependency 'org.apache.commons:commons-collections4:4.5.0' + dependency 'org.apache.commons:commons-csv:1.14.0' + dependency 'org.apache.commons:commons-lang3:3.17.0' + dependency 'org.apache.commons:commons-email2-jakarta:2.0.0-M1' + dependency 'org.apache.commons:commons-exec:1.5.0' + dependency 'org.apache.commons:commons-text:1.13.1' + dependency 'org.apache.mina:mina-core:2.2.4' + dependency 'org.apache.kerby:kerb-simplekdc:2.1.0' + dependency 'org.apache.kerby:ldap-backend:2.1.0' + dependency 'com.zaxxer:HikariCP:6.3.0' + dependency('org.apache.directory.server:apacheds-server-integ:2.0.0.AM27') { + exclude 'log4j:log4j' + } + // Be aware that Log4j is used by Elasticsearch client + dependencySet(group: 'org.apache.logging.log4j', version: '2.24.3') { + entry 'log4j-core' + entry 'log4j-api' + entry 'log4j-to-slf4j' + } + dependencySet(group: 'org.apache.tomcat.embed', version: '11.0.8') { + entry 'tomcat-embed-core' + entry('tomcat-embed-jasper') { + exclude 'org.eclipse.jdt.core.compiler:ecj' + } + } + //transitive dependency of SVNKit, to be re-assessed when updating SVNKit + dependency 'org.apache.sshd:sshd-core:2.15.0' + dependencySet(group: 'org.assertj', version: '3.27.3') { + entry 'assertj-core' + entry 'assertj-guava' + } + dependencySet(group: 'org.bouncycastle', version: '1.80') { + entry 'bcpkix-jdk18on' + entry 'bcprov-jdk18on' + } + dependency('org.codehaus.sonar:sonar-channel:4.2') { + exclude 'org.slf4j:slf4j-api' + } + dependency 'org.cyclonedx:cyclonedx-core-java:10.2.1' + dependency 'com.fasterxml.staxmate:staxmate:2.4.1' + dependency("org.elasticsearch.client:elasticsearch-rest-high-level-client:${elasticSearchClientVersion}") { + exclude 'org.apache.logging.log4j:log4j-core' + } + dependency "org.elasticsearch.plugin:transport-netty4-client:${elasticSearchClientVersion}" + dependency 'org.elasticsearch:mocksocket:1.2' + dependency 'org.eclipse.jgit:org.eclipse.jgit:7.3.0.202506031305-r' + dependency "org.codelibs.elasticsearch.module:analysis-common:7.17.22" + dependency "org.codelibs.elasticsearch.module:reindex:7.17.22" + dependency('org.tmatesoft.svnkit:svnkit:1.10.11') { + exclude 'net.i2p.crypto:eddsa' + } + dependency 'org.hamcrest:hamcrest:3.0' + dependency 'org.jsoup:jsoup:1.20.1' + // JUnit 5 + imports { mavenBom 'org.junit:junit-bom:5.11.4' } + dependency 'org.junit-pioneer:junit-pioneer:2.3.0' + dependencySet(group: 'org.mockito', version: '5.18.0') { + entry 'mockito-core' + entry('mockito-junit-jupiter') { + exclude 'org.junit.jupiter:junit-jupiter-api' + } + } + dependency 'org.spdx:java-spdx-library:2.0.0' + dependency 'org.spdx:spdx-jackson-store:2.0.2' + dependencySet(group: 'org.springframework', version: '6.2.8') { + entry 'spring-test' + entry('spring-context') { + exclude 'commons-logging:commons-logging' + } + entry('spring-webmvc') { + exclude 'commons-logging:commons-logging' + } + } + dependency "org.springframework.security:spring-security-saml2-service-provider:${springSecurityVersion}" + dependency 'org.mybatis:mybatis:3.5.19' + dependencySet(group: 'org.slf4j', version: '2.0.17') { + entry 'jcl-over-slf4j' + entry 'jul-to-slf4j' + entry 'log4j-over-slf4j' + entry 'slf4j-api' + } + dependency 'org.postgresql:postgresql:42.7.7' + dependency 'org.reflections:reflections:0.10.2' + dependency 'org.simpleframework:simple:5.1.6' + dependency 'org.sonarsource.git.blame:git-files-blame:2.0.0.2053' + dependency('org.sonarsource.orchestrator:sonar-orchestrator-junit4:5.6.2.2625') { + exclude 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml' + } + dependency('org.sonarsource.orchestrator:sonar-orchestrator-junit5:5.6.2.2625') { + exclude 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml' + } + dependency "com.sonarsource.pdfreport:regulatory-report-pdf-generation:${pdfreportVersion}" + dependency "com.sonarsource.pdfreport:security-report-pdf-generation:${pdfreportVersion}" + dependency 'com.sonarsource.fixsuggestions:ai-suggestions-shared:1.0.0.1312' + dependency 'org.sonarsource.update-center:sonar-update-center-common:1.35.0.2835' + dependency 'org.sonarsource.classloader:sonar-classloader:1.1.0.1059' + dependency 'org.springdoc:springdoc-openapi-starter-webmvc-api:2.8.6' + dependencySet(group: 'com.icegreen', version: '2.1.3') { + entry 'greenmail' + entry 'greenmail-junit4' + entry 'greenmail-junit5' + } + dependency 'org.yaml:snakeyaml:2.4' + dependency 'org.hibernate.validator:hibernate-validator:9.0.0.Final' + dependency 'org.kohsuke:github-api:1.327' + dependency 'org.wiremock:wiremock-standalone:3.13.0' + dependency 'org.skyscreamer:jsonassert:1.5.3' + // to be used only in sonar-ws-generator + dependency("org.apache.velocity:velocity:1.7") { + dependency 'commons-collections:commons-collections:3.2.2' + } + dependency 'com.google.code.findbugs:jsr305:3.0.2' + // please keep this list alphabetically ordered + } + } + + tasks.withType(Javadoc) { + options.addStringOption('Xdoclint:none', '-quiet') + options.encoding = 'UTF-8' + title = project.name + ' ' + versionWithoutBuildNumber + } + + tasks.withType(Test) { + if (System.getenv().containsKey("CIRRUS_CI")) { + develocity.testRetry { + maxRetries = 3 + maxFailures = 30 + failOnPassedAfterRetry = System.getenv("CIRRUS_PR") != null + } + } + } + + task sourcesJar(type: Jar, dependsOn: classes) { + archiveClassifier = 'sources' + from sourceSets.main.allSource + } + + task javadocJar(type: Jar, dependsOn: javadoc) { + archiveClassifier = 'javadoc' + from javadoc.destinationDir + } + + // generate code before opening project in IDE (Eclipse or Intellij) + task ide() { + // empty by default. Dependencies are added to the task + // when needed (see protobuf modules for example) + } + + task generatePackageInfo { + doLast { + def allPathsContainingJavaFiles = [] as Set + + fileTree('src/main/java/').matching() { + include "*/**/*.java" + exclude "*/**/package-info.java" + }.forEach { + allPathsContainingJavaFiles << it.toPath().toFile().getParent(); + } + + allPathsContainingJavaFiles.each { + String packageInfoPath = it + "/package-info.java" + File packageInfoFile = new File(packageInfoPath) + if (!packageInfoFile.exists()) { + logger.info("Creating file: " + packageInfoPath) + def packageName = packageInfoFile.getParent().replaceAll("[\\\\ /]", ".").takeAfter("src.main.java."); + String packageInfoContent = applyPackageInfoTemplate(packageName) + packageInfoFile << packageInfoContent + } + } + + def allPackageInfoFiles = [] as Set + + fileTree('src/main/java/').matching() { + include "*/**/package-info.java" + }.forEach { + allPackageInfoFiles << it.toPath().toFile(); + } + + allPackageInfoFiles.forEach { + File packageInfoFile = it; + if (!allPathsContainingJavaFiles.contains(packageInfoFile.getParent())) { + logger.warn("Deleting package info file: " + packageInfoFile) + packageInfoFile.delete(); + } + } + + } + } + build.dependsOn(generatePackageInfo) + generatePackageInfo.finalizedBy(licenseFormat) + + jacocoTestReport { + reports { + xml.required = true + csv.required = false + html.required = false + } + } + + normalization { + runtimeClasspath { + // Following classpath resources contain volatile data that changes in each CI build (build number, commit id, time), + // so we exclude them from calculation of build cache key of test tasks: + ignore 'META-INF/MANIFEST.MF' + ignore 'sonar-api-version.txt' + ignore 'sq-version.txt' + } + } + + + ext.failedTests = [] + test { + jvmArgs '-Dfile.encoding=UTF8' + maxHeapSize = '1500m' + systemProperty 'java.awt.headless', true + // Some tests are asserting on localized messages or dates + systemProperty 'user.language', 'en' + systemProperty 'user.country', 'US' + environment 'LANGUAGE', 'en_US' + testLogging { + events "skipped", "failed" // verbose log for failed and skipped tests (by default the name of the tests are not logged) + exceptionFormat 'full' // log the full stack trace (default is the 1st line of the stack trace) + } + jacoco { + enabled = true // do not disable recording of code coverage, so that remote Gradle cache entry can be used locally + includes = ['com.sonar.*', 'com.sonarsource.*', 'org.sonar.*', 'org.sonarqube.*', 'org.sonarsource.*'] + } + if (project.hasProperty('maxParallelTests')) { + maxParallelForks = project.maxParallelTests as int + } + if (project.hasProperty('parallelTests')) { + // See https://guides.gradle.org/performance/#parallel_test_execution + maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 + } + + afterTest { descriptor, result -> + if (result.resultType == TestResult.ResultType.FAILURE) { + String failedTest = " ${descriptor.className} > ${descriptor.name}" + failedTests << failedTest + } + } + } + + gradle.buildFinished { + if (!failedTests.empty) { + println "\nFailed tests:" + failedTests.each { failedTest -> + println failedTest + } + println "" + } + } + + def protoMainSrc = 'src/main/protobuf' + def protoTestSrc = 'src/test/protobuf' + if (file(protoMainSrc).exists() || file(protoTestSrc).exists()) { + // protobuf must be applied after java + apply plugin: 'com.google.protobuf' + + sourceSets.main.proto.srcDir protoMainSrc // in addition to the default 'src/main/proto' + sourceSets.test.proto.srcDir protoTestSrc // in addition to the default 'src/test/proto' + protobuf { + protoc { + artifact = "com.google.protobuf:protoc:${protobufVersion}" + } + } + jar { + exclude('**/*.proto') + } + idea { + module { + sourceDirs += file("${protobuf.generatedFilesBaseDir}/main/java") + testSourceDirs += file("${protobuf.generatedFilesBaseDir}/test/java") + generatedSourceDirs += file("${protobuf.generatedFilesBaseDir}/main/java") + generatedSourceDirs += file("${protobuf.generatedFilesBaseDir}/test/java") + } + } + ide.dependsOn(['generateProto', 'generateTestProto']) + } + + if (official) { + jar { + // do not break incremental build on non official versions + manifest { + attributes( + 'Version': "${version}", + 'Implementation-Build': System.getenv('GIT_SHA1'), + 'Build-Time': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + ) + } + } + } + + license { + header = rootProject.file('HEADER') + ignoreFailures = project.hasProperty('ignoreLicenseFailures') ? project.getProperty('ignoreLicenseFailures').toBoolean() : true + strictCheck true + encoding = 'UTF-8' + mapping { + java = 'SLASHSTAR_STYLE' + js = 'SLASHSTAR_STYLE' + ts = 'SLASHSTAR_STYLE' + tsx = 'SLASHSTAR_STYLE' + css = 'SLASHSTAR_STYLE' + } + includes(['**/*.java', '**/*.js', '**/*.ts', '**/*.tsx', '**/*.css']) + } + + tasks.withType(GenerateModuleMetadata) { + enabled = false + } + + publishing { + publications { + mavenJava(MavenPublication) { + pom { + name = 'SonarQube' + description = project.description + url = 'https://www.sonarsource.com/products/sonarqube' + organization { + name = 'SonarSource' + url = 'https://www.sonarsource.com' + } + licenses { + license { + name = 'GNU LGPL 3' + url = 'http://www.gnu.org/licenses/lgpl.txt' + distribution = 'repo' + } + } + scm { + url = 'https://github.com/SonarSource/sonarqube' + } + developers { + developer { + id = 'sonarsource-team' + name = 'SonarSource Team' + } + } + } + } + } + } + + tasks.withType(Test) { + configurations { + ddAgent + } + + dependencies { + ddAgent 'com.datadoghq:dd-java-agent' + } + + if (System.getenv('CI') == "true") { + doFirst { + ext { + ddJavaAgent = configurations.ddAgent.resolvedConfiguration.resolvedArtifacts.find { it.name == 'dd-java-agent' } + } + jvmArgs "-javaagent:${ddJavaAgent.file}" + jvmArgs "-Ddatadog.slf4j.simpleLogger.logFile=${project.projectDir}/build/datadog.log" + } + } + } + + tasks.withType(BlackBoxTest) { + jacoco.enabled = false + testClassesDirs = sourceSets.bbt.output.classesDirs + classpath = sourceSets.bbt.runtimeClasspath + + configurations { + includeInTestResources + } + + dependencies { + bbtRuntimeOnly 'com.microsoft.sqlserver:mssql-jdbc' + bbtRuntimeOnly 'com.oracle.database.jdbc:ojdbc11' + bbtRuntimeOnly 'org.postgresql:postgresql' + bbtRuntimeOnly project(':plugins:sonar-xoo-plugin') + + bbtImplementation 'org.sonarsource.orchestrator:sonar-orchestrator-junit4' + bbtImplementation project(":sonar-testing-harness") + bbtImplementation project(":private:it-common") + bbtImplementation testFixtures(project(":sonar-ws")) + } + } + + signing { + def signingKeyId = findProperty("signingKeyId") + def signingKey = findProperty("signingKey") + def signingPassword = findProperty("signingPassword") + useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword) + required { + return isMainBranch && gradle.taskGraph.hasTask(":artifactoryPublish") + } + sign publishing.publications + } + + tasks.withType(Sign) { + onlyIf { + return !artifactoryPublish.skip && isMainBranch && gradle.taskGraph.hasTask(":artifactoryPublish") + } + } +} \ No newline at end of file