import org.gradle.util.VersionNumber buildscript { repositories { maven { url 'https://plugins.gradle.org/m2/' } } dependencies { classpath 'org.owasp:dependency-check-gradle:9.0.9' } } apply plugin: org.owasp.dependencycheck.gradle.DependencyCheckPlugin apply plugin: "distribution" apply plugin: "java-library" ext { localInterlokRepo = project.findProperty('localInterlokRepo') ?: 'unknown' nexusBaseUrl = 'https://nexus.adaptris.net' log4j2Version='2.22.1' slf4jVersion='2.0.11' interlokVersion = project.findProperty('interlokVersion') ?: '3.12.0-RELEASE' // interlok-core is patched to 3.12.0.4-RELEASE // Check the if statement in the dependencies block. interlokCorePatchVersion = project.findProperty('interlokCorePatchVersion') ?: '3.12.0.4-RELEASE' requiresCorePatchVersion = "3.12.0-RELEASE" verifyReportConfigCheckAvailable = '3.12-SNAPSHOT' // We use the UI patch version (3.12.0.1-RELEASE) as default if Interlok version is 3.12.0-RELEASE interlokUiVersion = project.findProperty('interlokUiVersion') ?: (interlokVersion == '3.12.0-RELEASE' ? '3.12.0.1-RELEASE' : interlokVersion) interlokSourceConfig = "${projectDir}/src/main/interlok/config" interlokTmpConfigDirectory = "${buildDir}/tmp/config" interlokTmpLibDirectory = "${buildDir}/tmp/lib" interlokTmpWarDirectory = "${buildDir}/tmp/war" interlokTmpDocsDirectory = "${buildDir}/tmp/docs" interlokTmpServiceTestLog4j = "${buildDir}/tmp/serviceTestLog4j/log4j2.xml" interlokDistDirectory = project.findProperty('interlokDistDirectory') ?: "${buildDir}/distribution" buildEnv = project.findProperty('buildEnv') ?: 'NoBuildEnv' includeWar = project.findProperty('includeWar') ?: 'false' additionalTemplatedConfiguration = project.findProperty('additionalTemplatedConfiguration') ?: [] additionalTemplatedProperties = project.findProperty('additionalTemplatedProperties') ?: [] interlokParentBaseUrl = project.findProperty('interlokParentBaseUrl') ?: 'https://raw.githubusercontent.com/adaptris/interlok-build-parent/main' verifyLog4j = "${interlokParentBaseUrl}/verifyLog4j2.xml" serviceTestLog4j = "${interlokParentBaseUrl}/serviceTestLog4j2.xml" verifyMode = project.hasProperty('verifyMode') ? VerifyModes.valueOf(project.getProperty('verifyMode')) : VerifyModes.WARN interlokVerifyTextReport = "${buildDir}/reports/interlok/verify/report.txt" interlokVerifyTextReportFile = new File(interlokVerifyTextReport) interlokVerifySonarReport = "${buildDir}/reports/interlok/verify/report.json" interlokVerifyEnvironmentPropertiesFile = project.findProperty('interlokVerifyEnvironmentPropertiesFile') ?: "${projectDir}/.env" interlokVerifyLicenseProperties = System.env.containsKey("INTERLOK_LICENSE_KEY") ? [ "interlok.license.key": "$System.env.INTERLOK_LICENSE_KEY" ] : [:] interlokVerifyCategory = project.findProperty('interlokVerifyCategory') ?: "CODE_SMELL" interlokVerifyLevel = project.findProperty('interlokVerifyLevel') ?: "INFO" interlokVerifyPrefix = "$interlokVerifyCategory,$interlokVerifyLevel," } enum VerifyModes { STRICT, WARN } defaultTasks 'clean', 'check' ext.buildDetails = [ isDevMode: { -> return buildEnv.equals("dev") }, isIncludeWar: { -> return includeWar.equals("true") || buildEnv.equals("dev") }, requiresCorePatch: { -> return VersionNumber.parse( interlokVersion ) == VersionNumber.parse( requiresCorePatchVersion ) } ] ext.verifyReport = [ verifyViaConfigCheck: { -> return VersionNumber.parse( interlokVersion ) >= VersionNumber.parse( verifyReportConfigCheckAvailable ) }, verifyReportFile: { -> if (interlokVerifyTextReportFile.exists()) { def content = java.nio.file.Files.readAllLines(interlokVerifyTextReportFile.toPath()) def warningsCount = content.size() // Has the sad effect of printing out CODE_SMELL, but that's acceptable. if (warningsCount > 0) { println "\nConfiguration warnings [$warningsCount]:" content.each { println it.replaceAll(interlokVerifyPrefix, "") } if(verifyMode == VerifyModes.STRICT) { throw new GradleException("Interlok Verify contains warnings [$warningsCount]") } } } }, init: { -> delete interlokVerifyTextReportFile mkdir(interlokVerifyTextReportFile.getParentFile()) } ] def loadPropertiesFromFile(filepath) { Properties properties = new Properties() File propertiesFile = new File(filepath) if(propertiesFile.exists()){ propertiesFile.withInputStream { properties.load(it) } } return properties } def asFileUrl(filepath) { return "file:///" + new java.net.URI(null, filepath, null).toASCIIString(); } def overwriteWithPropertiesTemplate(file, dir){ if(new File("${dir}/${file}-${buildEnv}.properties").exists()){ ant.copy(file: "${dir}/${file}-${buildEnv}.properties", tofile: "${dir}/${file}.properties", overwrite: 'true') } delete fileTree(dir) { include "${file}-*.properties" } } def overwriteWithTemplate(file, dir){ if(new File("${dir}/${file}.${buildEnv}").exists()){ ant.copy(file: "${dir}/${file}.${buildEnv}", tofile: "${dir}/${file}", overwrite: 'true') } delete fileTree(dir) { include "${file}.*" } } distTar.enabled=false distZip.enabled=false configurations { interlokRuntime{} interlokTestRuntime{} interlokJavadocs{} interlokVerify{} interlokVerifyReport{} interlokWar{} antJunit{} all*.exclude group: 'c3p0' all*.exclude group: 'commons-logging' all*.exclude group: 'javamail' all*.exclude group: 'javax.mail', module: 'mail' all*.exclude group: 'org.glassfish.hk2.external' all*.exclude group: 'xalan', module: 'xalan' all*.exclude group: 'net.sf.saxon', module: 'saxon' // Exclude because com.fasterxml.woodstox:woodstox-core should take precedence // however, stax2-api still lives on in the org.codehaus.woodstox group all*.exclude group: 'org.codehaus.woodstox', module: 'woodstox-core-asl' all*.exclude group: 'org.eclipse.jetty.orbit', module: 'javax.mail.glassfish' all*.exclude group: 'javax.el', module: 'javax.el-api' all*.exclude group: 'org.hibernate', module: 'hibernate-validator' // INTERLOK-3197 exclude old javax.mail all*.exclude group: 'com.sun.mail', module: 'javax.mail' all*.exclude group: 'javax.validation', module: 'validation-api' all*.exclude group: 'javax.activation', module: 'activation' all*.exclude group: 'javax.activation', module: 'javax.activation-api' } if (interlokVersion.endsWith("SNAPSHOT") || interlokUiVersion.endsWith("SNAPSHOT")) { allprojects { configurations.all { resolutionStrategy.cacheChangingModulesFor 15, "minutes" } } } repositories { mavenCentral() { content { excludeGroupByRegex "com\\.adaptris.*" } } if (localInterlokRepo != "unknown") { maven { url "$localInterlokRepo" allowInsecureProtocol true } } maven { url "${nexusBaseUrl}/nexus/content/groups/public" } maven { url "${nexusBaseUrl}/nexus/content/groups/interlok" } } dependencies { // If our interlokVersion is set to anything other than 3.12.0-RELEASE then use that // If it is set to 3.12.0-RELEASE then use 3.12.0.4-RELEASE version of Interlokv3. if (interlokVersion.endsWith("SNAPSHOT") || !buildDetails.requiresCorePatch()) { interlokRuntime ("com.adaptris:interlok-core:$interlokVersion") { changing= true} interlokRuntime ("com.adaptris:interlok-common:$interlokVersion") { changing= true} interlokRuntime ("com.adaptris:interlok-boot:$interlokVersion") { changing=true } interlokRuntime ("com.adaptris:interlok-logging:$interlokVersion") { changing=true } } else { interlokRuntime ("com.adaptris:interlok-core:$interlokCorePatchVersion") { changing= true} interlokRuntime ("com.adaptris:interlok-common:$interlokCorePatchVersion") { changing= true} interlokRuntime ("com.adaptris:interlok-boot:$interlokCorePatchVersion") { changing=true } interlokRuntime ("com.adaptris:interlok-logging:$interlokCorePatchVersion") { changing=true } } interlokRuntime ("com.adaptris:interlok-varsub:$interlokVersion") { changing=true } interlokRuntime ("org.slf4j:slf4j-api:$slf4jVersion") interlokRuntime ("org.slf4j:jcl-over-slf4j:$slf4jVersion") interlokRuntime ("org.slf4j:jul-to-slf4j:$slf4jVersion"); interlokRuntime (platform("org.apache.logging.log4j:log4j-bom:$log4j2Version")) interlokRuntime ("org.apache.logging.log4j:log4j-core") interlokRuntime ("org.apache.logging.log4j:log4j-1.2-api") interlokRuntime ("org.apache.logging.log4j:log4j-slf4j2-impl") interlokRuntime ("org.apache.logging.log4j:log4j-api") interlokRuntime ("com.sun.mail:jakarta.mail:1.6.7") interlokRuntime ("com.sun.activation:jakarta.activation:1.2.2") interlokRuntime ("jakarta.validation:jakarta.validation-api:2.0.2") interlokRuntime ("org.eclipse.jetty.aggregate:jetty-all:9.4.53.v20231009") interlokRuntime ("com.thoughtworks.xstream:xstream:1.4.20") interlokRuntime ("org.apache.activemq:activemq-client:5.16.4") { exclude group: "org.apache.geronimo.specs", module: "geronimo-jms_1.1_spec" } interlokTestRuntime ("com.adaptris:interlok-service-tester:$interlokVersion") { changing=true } interlokWar ("com.adaptris.ui:interlok:$interlokUiVersion@war") {changing=true} interlokVerify files("$interlokTmpConfigDirectory"){ builtBy 'localizeConfig' } // Javadocs aren't affected by interlokCorePatchVersion since they should just be bugfixes. interlokJavadocs group: "com.adaptris", name: "interlok-core", version: "$interlokVersion", classifier: "javadoc", changing: true, transitive: false interlokJavadocs group: "com.adaptris", name: "interlok-common", version: "$interlokVersion", classifier: "javadoc", changing: true, transitive: false interlokVerifyReport("com.adaptris:interlok-verify-report:2.2.0") antJunit ("org.apache.ant:ant-junit:1.10.14") } task localizeConfig(type: Copy) { from "${interlokSourceConfig}" into "${interlokTmpConfigDirectory}" doLast { overwriteWithTemplate("log4j2.xml", "${interlokTmpConfigDirectory}") additionalTemplatedConfiguration.each { overwriteWithTemplate("${it}", "${interlokTmpConfigDirectory}") } overwriteWithPropertiesTemplate("variables-local", "${interlokTmpConfigDirectory}") additionalTemplatedProperties.each { overwriteWithPropertiesTemplate("${it}", "${interlokTmpConfigDirectory}") } ant.propertyfile( file: "${interlokTmpConfigDirectory}/version.properties") { entry( key: "build.version", value: "${version}") entry( key: "interlok.core.version", value: "${interlokVersion}") entry( key: "interlok.war.version", value: "${interlokUiVersion}") } } } task getServiceTestLog4j2 (){ outputs.file new File(interlokTmpServiceTestLog4j) doLast { mkdir(new File(interlokTmpServiceTestLog4j).getParentFile()) ant.get(src: serviceTestLog4j, dest: interlokTmpServiceTestLog4j, usetimestamp: 'true', quiet: 'true') } } tasks.register("verifyLauncherJar", Jar) { ext.verifyLauncherClasspath = { -> def verifyLibs = [configurations.interlokRuntime.collect { asFileUrl(it.getCanonicalPath()) }.join(' '), configurations.interlokVerify.collect { asFileUrl(it.getCanonicalPath()) + "/" }.join(' ')] return verifyLibs.join(' ') } appendix = "verify-launcher" manifest { attributes ("Class-Path": verifyLauncherClasspath()) } } def interlokVersionReport = tasks.register("interlokVersionReport", JavaExec) { group = 'Verification' description = 'Show Interlok versions using -version' workingDir = new File("${buildDir}/tmp") classpath = files(verifyLauncherJar.archivePath) mainClass = 'com.adaptris.core.management.SimpleBootstrap' args "-version" } interlokVersionReport.configure { dependsOn localizeConfig, verifyLauncherJar } def interlokVerifyLog4j= tasks.register("interlokVerifyLog4j", JavaExec) { group = 'Verification' description = 'Interlok config test using -configtest reporting by parsing console output (pre 3.12)' onlyIf{ !verifyReport.verifyViaConfigCheck() } doFirst { if(new File("$interlokTmpConfigDirectory/log4j2.xml").exists()) { ant.move file: "$interlokTmpConfigDirectory/log4j2.xml", tofile: "$interlokTmpConfigDirectory/log4j2.xml.bk" } verifyReport.init() } workingDir = new File("${buildDir}/tmp") classpath = files(verifyLauncherJar.archivePath) mainClass = 'com.adaptris.core.management.SimpleBootstrap' args "-configtest" environment loadPropertiesFromFile(interlokVerifyEnvironmentPropertiesFile) environment project.hasProperty('interlokVerifyEnvironmentProperties') ? project.getProperty('interlokVerifyEnvironmentProperties') : [:] systemProperties project.hasProperty('interlokVerifySystemProperties') ? project.getProperty('interlokVerifySystemProperties') : [:] systemProperties interlokVerifyLicenseProperties systemProperty "interlok.logging.url", verifyLog4j standardOutput = new ByteArrayOutputStream() doLast { def verifyOutput = standardOutput.toString() interlokVerifyTextReportFile.createNewFile() verifyOutput.eachLine { interlokVerifyTextReportFile.append(interlokVerifyPrefix + it + "\n") } if(new File("$interlokTmpConfigDirectory/log4j2.xml.bk").exists()) { ant.move file: "$interlokTmpConfigDirectory/log4j2.xml.bk", tofile: "$interlokTmpConfigDirectory/log4j2.xml" } } } def interlokVerifyConfigCheck= tasks.register("interlokVerifyConfigCheck", JavaExec) { group = 'Verification' description = 'Interlok config test using -configtest reporting via a ConfigurationChecker implementation' onlyIf{ verifyReport.verifyViaConfigCheck() } doFirst { verifyReport.init() } workingDir = new File("${buildDir}/tmp") classpath = files(verifyLauncherJar.archivePath) mainClass = 'com.adaptris.core.management.SimpleBootstrap' args "-configtest" environment loadPropertiesFromFile(interlokVerifyEnvironmentPropertiesFile) environment project.hasProperty('interlokVerifyEnvironmentProperties') ? project.getProperty('interlokVerifyEnvironmentProperties') : [:] systemProperties project.hasProperty('interlokVerifySystemProperties') ? project.getProperty('interlokVerifySystemProperties') : [:] systemProperties interlokVerifyLicenseProperties systemProperty "interlok.verify.warning.filename", interlokVerifyTextReport systemProperty "interlok.verify.warning.category", interlokVerifyCategory systemProperty "interlok.verify.warning.level", interlokVerifyLevel } def interlokVerify = tasks.register("interlokVerify") { group = 'Verification' description = 'Wrapper around interlokVerifyConfigCheck / interlokVerifyLog4j' doLast { verifyReport.verifyReportFile() } } def interlokVerifyReport = tasks.register("interlokVerifyReport", JavaExec) { group = 'Verification' description = 'Create Interlok Sonarqube reports from config verification' onlyIf{ // technicaly interlokVerify won't do work so interlokVerify.get().didWork won't be true... // (interlokVerifyConfigCheck.get().didWork || interlokVerifyLog4j.get().didWork) && new File(interlokVerifyTextReport).exists() interlokVerify.get().didWork && new File(interlokVerifyTextReport).exists() } mainClass = 'com.adaptris.verify.CreateVerifyReport' classpath = configurations.interlokVerifyReport args "--reportFile" args interlokVerifyTextReport args "--outputFile" args interlokVerifySonarReport } interlokVerify.configure { dependsOn interlokVerifyConfigCheck, interlokVerifyLog4j finalizedBy interlokVerifyReport } interlokVerifyConfigCheck.configure { dependsOn localizeConfig, verifyLauncherJar } interlokVerifyLog4j.configure { dependsOn localizeConfig, verifyLauncherJar } tasks.register("serviceTesterLauncherJar", Jar) { appendix = "service-tester-launcher" ext.serviceTesterClasspath = { -> def testerLibs = [configurations.interlokRuntime.collect { asFileUrl(it.getCanonicalPath()) }.join(' '), configurations.interlokTestRuntime.collect { asFileUrl(it.getCanonicalPath()) }.join(' '), asFileUrl(new File(interlokTmpServiceTestLog4j).getParentFile().getCanonicalPath()) + "/"] return testerLibs.join(' ') } manifest { attributes ("Class-Path": serviceTesterClasspath()) } } def interlokServiceTest = tasks.register("interlokServiceTest", JavaExec) { group = 'Test' description = 'Execute Interlok service tests' onlyIf { new File("$projectDir/src/test/interlok/service-test.xml").exists() } mainClass = 'com.adaptris.tester.runners.TestExecutor' classpath = files(serviceTesterLauncherJar.archivePath) args "-serviceTest" args "$projectDir/src/test/interlok/service-test.xml" args "-serviceTestOutput" args "$buildDir/reports/unit/" } interlokServiceTest.configure { dependsOn getServiceTestLog4j2, serviceTesterLauncherJar finalizedBy interlokServiceTestReport } task interlokServiceTestReport { group = 'Test' description = 'Create Interlok service test reports' onlyIf{ interlokServiceTest.get().didWork && new File("$buildDir/reports/html").exists() } doLast { mkdir "$buildDir/reports/html" ant.taskdef( name: 'junitreport', classname: 'org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator', classpath: configurations.antJunit.asPath ) ant.junitreport(todir: "$buildDir/reports/html") { fileset(dir: "$buildDir/reports/unit", includes: 'TEST-*.xml') report(todir: "$buildDir/reports/html", format: "frames") } logger.lifecycle("Service tester report available at [$buildDir/reports/html]") } } task serviceTesterDist(type: Copy) { onlyIf { buildDetails.isDevMode() } from project.configurations.interlokTestRuntime into interlokTmpLibDirectory } task interlokWarDist(type: Copy) { onlyIf { buildDetails.isIncludeWar() } from project.configurations.interlokWar into interlokTmpWarDirectory } task interlokJavadocsDist(type: Copy) { onlyIf { buildDetails.isIncludeWar() } from project.configurations.interlokJavadocs into interlokTmpDocsDirectory } distributions { main { contents { def usedFileNames = new HashSet() into('') { from ("src/main/interlok") exclude "config" } into('config') { from(localizeConfig) } into('lib') { def libs = new HashSet() from(project.configurations.interlokRuntime) from(serviceTesterDist) eachFile { // In dev mode, dependencies from serviceTesterDist may conflict // with interlokRuntime dependencies. This stops the same JAR being included with the suffix _1 if (!libs.add(it.sourceName)) { it.exclude() } } } into('webapps') { from(interlokWarDist) } into('docs/javadocs') { from(interlokJavadocsDist) } // Doing: rename '(.*)-[0-9\\.AB]+\\..*.jar', '$1.jar' // AB is for Alpha or Beta versions // but also add an index if a file name already exists rename { filename -> return renameJarFile(filename, usedFileNames) } rename '(.*)-[0-9\\.AB]+\\..*.war', '$1.war' duplicatesStrategy = DuplicatesStrategy.EXCLUDE } } } def renameJarFile(filename, usedFileNames) { def ignorableClassifiers = [ "RELEASE-javadoc", "SNAPSHOT-javadoc", "javadoc", "RELEASE", "SNAPSHOT", // hibernate-validator-6.1.7.Final.jar (and netty) "Final", // Jetty has jetty-continuation-9.4.45.v20220203.jar 'v[0-9]+', // opendmk_jmxremote_optional_jar-1.0-b01-ea.jar // javax.el-3.0.1-b12.jar '^[ab][0-9]+.*', // org.apache.servicemix.bundles.jzlib-1.0.7_2.jar '_[0-9]+', //scalaz-stream_2.11-0.7.3a.jar '^[ab]$' ] if (filename ==~ '(.*)\\.jar') { // AB is for Alpha or Beta versions def jarNamePattern = '(.*)-[0-9\\.AB]+(.*).jar' def basename=filename.replaceFirst('(.*)\\.jar', '$1') if (filename ==~ jarNamePattern) { basename=filename.replaceFirst(jarNamePattern, '$1') def classifier=filename.replaceFirst(jarNamePattern, '$2').replaceFirst('-', "") ignorableClassifiers.each { classifier=classifier.replaceFirst(it, ""); } if (classifier?.trim()) { basename=basename + "-" + classifier } } def isJavadoc = filename ==~ '(.*)-javadoc\\.jar' filename = "${basename}.jar" def index = 1 // At this point jars and javadoc jars can have the same name // so we differentiate them with the boolean 'isJavadoc' while (!usedFileNames.add("$filename $isJavadoc")) { filename = "${basename}_${index}.jar" index++ } } return filename } installDist { destinationDir = new File(interlokDistDirectory) } // dependencyCheckAnalyze { // onlyIf { // !buildDetails.isDevMode() // } // } dependencyCheck { suppressionFiles= [ "https://raw.githubusercontent.com/adaptris/interlok/develop/gradle/owasp-exclude.xml" ] scanConfigurations = buildDetails.isIncludeWar() ? [ "interlokWar", "interlokRuntime" ] : [ "interlokRuntime" ] failBuildOnCVSS = 7 formats = [ "HTML", "JUNIT" ] analyzers { assemblyEnabled=false } } task checkInterlokVersion { doLast { if (interlokVersion.startsWith("4")) { throw new GradleException("Interlok 4+; Switch to using 'https://raw.githubusercontent.com/adaptris/interlok-build-parent/main/v4/build.gradle' instead") } } } // check.dependsOn dependencyCheckAnalyze,interlokVerify,interlokServiceTest,interlokVersionReport check.dependsOn checkInterlokVersion,interlokVerify,interlokServiceTest,interlokVersionReport assemble.dependsOn installDist