blob: 3a3219e8a712fe0c83cd6574dacc5a1bcb731f58 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.tools.ant.filters.ReplaceTokens
import org.codehaus.groovy.gradle.JarJarTask
apply plugin: 'osgi'
group = 'org.codehaus.groovy'
archivesBaseName = 'groovy'
ext.srcSpec = copySpec {
from(projectDir) {
exclude 'target',
'build',
'benchmark',
'subprojects/*/target',
'buildSrc/target',
buildDir.path,
'classes/**',
'cruise/**',
'src/install/**', // CI file
'.travis.yml', // CI file
'appveyor.yml', // CI file
'jitpack.yml', // CI file
'security/groovykeys',
'.clover/*',
'local.build.properties',
'gradle/wrapper',
'gradlew',
'gradlew.bat',
'cobertura.ser',
'junitvmwatcher*.properties',
'out',
'artifactory.properties', // generated by the CI server
'gradle.properties.gz', // generated by the CI server
'**/*.iml', // used by Intellij IDEA
'**/*.ipr', // used by Intellij IDEA
'**/*.iws', // used by Intellij IDEA
'.settings', // used by Eclipse
'.gradle', // used by Gradle
'buildSrc/.gradle' // used by Gradle
}
}
ext.docSpec = copySpec {
into('html/api') {
from javadocAll.destinationDir
}
into('html/gapi') {
from groovydocAll.destinationDir
}
into('html/documentation') {
from "$buildDir/asciidocAll/html5"
}
into('html/groovy-jdk') {
from docGDK.destinationDir
}
into('licenses') {
from 'licenses'
include 'asciidoc-style-license.txt'
include 'jquery-js-license.txt'
include 'normalize-stylesheet-license.txt'
}
from "$projectDir/licenses/LICENSE-DOC"
from "$projectDir/notices/NOTICE-BASE"
rename 'LICENSE-DOC', 'LICENSE'
rename 'NOTICE-BASE', 'NOTICE'
}
task copy(type: Copy) {
into "$buildDir/meta"
}
// unnecessary entries which in addition may trigger unnecessary rebuilds
def excludedFromManifest = [
'Ant-Version',
'Originally-Created-By',
'Bnd-LastModified',
'Created-By'
]
ext.allManifest = manifest {
attributes(
'Extension-Name': 'groovy',
'Specification-Title': 'Groovy: a powerful, dynamic language for the JVM',
'Specification-Version': groovyBundleVersion,
'Specification-Vendor': 'The Apache Software Foundation',
'Implementation-Title': 'Groovy: a powerful, dynamic language for the JVM',
'Implementation-Version': groovyBundleVersion,
'Implementation-Vendor': 'The Apache Software Foundation',
'Bundle-ManifestVersion': '2',
'Bundle-Name': 'Groovy Runtime',
'Bundle-Description': 'Groovy Runtime',
'Bundle-Version': groovyBundleVersion,
'Bundle-Vendor': 'The Apache Software Foundation',
'Bundle-ClassPath': '.',
'Eclipse-BuddyPolicy': 'dependent',
'DynamicImport-Package': '*',
'Main-Class': 'groovy.ui.GroovyMain')
}
ext.groovyOsgiManifest = {
// Exclude the Bnd-LastModified attribute as it always triggers a rebuild without being really needed.
from(allManifest) {
eachEntry { details ->
if (excludedFromManifest.any { it == details.key }) {
details.exclude()
}
}
}
version = groovyBundleVersion
instruction '-nouses', 'true'
instruction 'Export-Package', "*;version=${groovyBundleVersion}"
instruction 'Eclipse-ExtensibleAPI', 'true'
classpath = sourceSets.main.runtimeClasspath
}
ext.subprojectOsgiManifest = {
// Exclude attributes not needed for subprojects.
from(allManifest) {
eachEntry { details ->
if (details.key in [*excludedFromManifest, 'Bnd-LastModified', 'Extension-Name', 'Bundle-Name', 'Bundle-Description', 'Main-Class']) {
details.exclude()
}
}
}
version = groovyBundleVersion
instruction '-nouses', 'true'
instruction 'Export-Package', "*;version=${groovyBundleVersion}"
def folder = new File( "${projectDir}/subprojects/${symbolicName}/src/main/resources/META-INF/services" )
if( folder.exists() ) {
if (folder.listFiles().count { it.name ==~ /^(?!(org.codehaus.groovy.transform.ASTTransformation)$).*$/ } > 0) {
instruction 'Require-Capability', 'osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)"'
instruction 'Require-Capability', 'osgi.extender;filter:="(osgi.extender=osgi.serviceloader.processor)"'
folder.eachFileMatch(~/^(?!(org.codehaus.groovy.transform.ASTTransformation)$).*$/) {
instruction 'Require-Capability', "osgi.serviceloader;filter:=\"(osgi.serviceloader=${it.name})\";cardinality:=multiple"
instruction 'Provide-Capability', "osgi.serviceloader;osgi.serviceloader=\"${it.name}\""
}
}
}
classpath = sourceSets.main.runtimeClasspath
}
allprojects {
boolean isRoot = project == rootProject
def producedJars = [jar]
jar {
appendix = 'raw'
manifest {
from(allManifest) {
eachEntry { details ->
if (excludedFromManifest.any { it == details.key }) {
details.exclude()
}
}
}
}
}
if (rootProject.indyCapable()) {
task jarWithIndy(type: Jar) {
dependsOn compileGroovyWithIndy
classifier = 'indy'
appendix = 'raw'
from sourceSets.main.java.outputDir
from sourceSets.main.groovy.outputDir
from compileGroovyWithIndy.destinationDir
from "${project.buildDir}/resources/main"
}
producedJars << jarWithIndy
}
producedJars.each { arch ->
arch.metaInf {
from("$projectDir/licenses/LICENSE-JARJAR")
from("$projectDir/licenses") {
into('licenses')
include('asm-license.txt')
include('antlr2-license.txt')
include('antlr4-license.txt')
}
from("$projectDir/notices/NOTICE-JARJAR")
from(generateReleaseInfo)
rename '^([A-Z]+)-([^.]*)', '$1'
}
arch.exclude '**/package-info.class'
task "jar${arch.name}"(type: JarJarTask) {
dependsOn arch
from = file(arch.archivePath)
if (project == rootProject) {
repackagedLibraries = files(configurations.runtime.incoming.artifactView {
componentFilter { component ->
if (component instanceof ModuleComponentIdentifier) {
return component.module in [
'antlr', 'antlr-runtime', 'antlr4', 'antlr4-runtime', 'antlr4-annotations',
'asm', 'asm-commons', 'asm-tree', 'asm-util', 'picocli']
}
return false
}
}.files)
} else {
repackagedLibraries = files()
}
jarjarToolClasspath = rootProject.configurations.tools
untouchedFiles = [
'groovy/cli/picocli/CliBuilder*.class',
'groovy/cli/picocli/OptionAccessor*.class'
]
patterns = [
'antlr.**': 'groovyjarjarantlr.@1', // antlr2
'org.antlr.**': 'groovyjarjarantlr4.@1', // antlr4
'org.objectweb.**': 'groovyjarjarasm.@1',
'picocli.**': 'groovyjarjarpicocli.@1'
]
excludesPerLibrary = [
'*': ['META-INF/maven/**', 'META-INF/*', 'META-INF/services/javax.annotation.processing.Processor', '**/module-info.class']
]
includesPerLibrary = [
'asm-util': ['org/objectweb/asm/util/Printer.class',
'org/objectweb/asm/util/Textifier*',
'org/objectweb/asm/util/ASMifier.class',
'org/objectweb/asm/util/Trace*']
]
outputFile = file("$buildDir/libs/${arch.baseName}-${arch.version}${arch.classifier ? '-' + arch.classifier : ''}.jar")
withManifest {
def moduleName = "org.codehaus.${project.name.replace('-', '.')}"
attributes('Automatic-Module-Name': moduleName)
from(allManifest) {
eachEntry { details ->
if (excludedFromManifest.any { it == details.key }) {
details.exclude()
}
}
}
}
withManifest(isRoot ? groovyOsgiManifest : subprojectOsgiManifest)
}
}
if (project.name in ['groovy', 'groovy-test']) {
task grooidjar(type: JarJarTask) {
dependsOn jarjar
from = file(jarjar.outputFile)
if (isRoot) {
repackagedLibraries = files(configurations.runtime.incoming.artifactView {
componentFilter { component ->
if (component instanceof ModuleComponentIdentifier) {
return component.module in ['openbeans']
}
return false
}
}.files)
} else {
repackagedLibraries = files()
}
jarjarToolClasspath = rootProject.configurations.tools
patterns = [
'com.googlecode.openbeans.**': 'groovyjarjaropenbeans.@1',
'org.apache.harmony.beans.**': 'groovyjarjarharmonybeans.@1',
'java.beans.**': 'groovyjarjaropenbeans.@1'
]
excludesPerLibrary = [
'*': ['META-INF/NOTICE']
]
excludes = ['META-INF/NOTICE', 'META-INF/INDEX.LIST']
createManifest = false
includedResources = [
("$rootProject.projectDir/notices/${isRoot ? 'NOTICE-GROOIDJARJAR' : 'NOTICE-GROOID'}".toString()): 'META-INF/NOTICE'
]
outputFile = file("$buildDir/libs/${jar.baseName}-${jar.version}-grooid.jar")
}
}
}
def producedJars = [jar]
if (rootProject.indyCapable()) {
producedJars << jarWithIndy
}
producedJars.each {
it.dependsOn('dgmConverter')
it.from files(dgmConverter.outputDir)
}
subprojects { sp ->
jar {
metaInf {
if (file("${projectDir}/LICENSE").exists()) {
from "${projectDir}/LICENSE"
} else {
from "${rootProject.projectDir}/licenses/LICENSE-BASE"
}
if (file("${projectDir}/NOTICE").exists()) {
from "${projectDir}/NOTICE"
} else {
from "${rootProject.projectDir}/notices/NOTICE-BASE"
}
rename '^([A-Z]+)-([^.]*)', '$1'
}
exclude '**/package-info.class'
}
}
task sourceAllJar(type: Jar, dependsOn: { modules()*.sourceJar + rootProject.sourceJar }) {
with sourceJar.rootSpec
modules()*.sourceJar.each {
with it.rootSpec
}
baseName = 'groovy-all'
classifier = 'sources'
}
allprojects {
task javadocJar(type: Jar, dependsOn: javadoc) {
from javadoc.destinationDir
classifier = 'javadoc'
}
task groovydocJar(type: Jar, dependsOn: groovydoc) {
from groovydoc.destinationDir
classifier = 'groovydoc'
}
}
task javadocAllJar(type: Jar, dependsOn: javadocAll) {
baseName = 'groovy-all'
from javadocAll.destinationDir
classifier = 'javadoc'
}
task groovydocAllJar(type: Jar, dependsOn: groovydocAll) {
baseName = 'groovy-all'
from groovydocAll.destinationDir
classifier = 'groovydoc'
}
evaluationDependsOn('groovy-jaxb')
ext.distSpec = copySpec {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from("$projectDir/licenses/LICENSE-BINZIP")
from("$projectDir/notices/NOTICE-BINZIP")
rename '^([A-Z]+)-([^.]*)', '$1'
exclude { it.file.name =~ /-raw/ }
into('lib') {
from jarjar
from modules()*.jarjar
from(configurations.runtime) {
exclude {
it.file.name.startsWith('openbeans-') ||
it.file.name.startsWith('asm-') ||
it.file.name.startsWith('antlr-') ||
it.file.name.startsWith('antlr4-') ||
it.file.name.startsWith('picocli-')
}
}
from('src/bin/groovy.icns')
}
modules().configurations.runtime.each { conf ->
into('lib') {
from(conf) {
exclude {
it.file.name.contains('livetribe-jsr223') ||
it.file.name.matches(/groovy-\d.*/) ||
it.file.name.startsWith('asm-') ||
it.file.name.startsWith('antlr-') ||
it.file.name.startsWith('antlr4-') ||
it.file.name.startsWith('openbeans-') ||
it.file.name.startsWith('picocli-')
}
}
}
}
into('lib/extras-jaxb') {
from project(':groovy-jaxb').configurations.jaxb
from project(':groovy-jaxb').configurations.jaxbRuntime
}
if (!rootProject.hasProperty('skipIndy')) {
into('indy') {
from jarjarWithIndy
from modules()*.jarjarWithIndy
}
}
if (!rootProject.hasProperty('skipGrooid')) {
into('grooid') {
from { new File(jar.archivePath.parent, "${jar.baseName}-${jar.version}-grooid.jar") }
from {
modules()*.jar.collect { j ->
new File(j.archivePath.parent, "${j.baseName}-${j.version}-grooid.jar")
}
}
}
}
into('conf') {
from 'src/conf'
}
into('bin') {
from('src/bin') {
filter(ReplaceTokens, tokens: [GROOVYJAR: jarjar.archiveName])
fileMode = 0755
exclude 'groovy.icns'
}
from('subprojects/groovy-docgenerator/src/main/resources/org/apache/groovy/docgenerator/groovy.ico')
}
into('licenses') {
from 'licenses'
include 'antlr2-license.txt'
include 'antlr4-license.txt'
include 'asm-license.txt'
include 'hamcrest-license.txt'
include 'jline2-license.txt'
include 'jsr166y-license.txt'
include 'jsr223-license.txt'
include 'junit4-license.txt'
include 'junit5-license.txt'
include 'xstream-license.txt'
}
}
task distBin(type: Zip) {
baseName = 'apache-groovy'
appendix = 'binary'
into("groovy-$version") {
with distSpec
}
allprojects {
if (project.name in ['groovy', 'groovy-test']) {
distBin.dependsOn(grooidjar)
}
}
}
task distDoc(type: Zip, dependsOn: doc) {
baseName = 'apache-groovy'
appendix = 'docs'
into("groovy-$version") {
with docSpec
}
}
task syncDoc(type: Copy, dependsOn: doc) {
inputs.files javadoc.outputs.files
inputs.files groovydoc.outputs.files
destinationDir(file("$buildDir/html"))
into('api') {
from javadoc.destinationDir
}
into('gapi') {
from groovydoc.destinationDir
}
// groovy-jdk already at the correct place
}
task distSrc(type: Zip) {
baseName = 'apache-groovy'
appendix = 'src'
into("groovy-$version")
with srcSpec
}
def installDir = {
project.hasProperty('groovy_installPath') ? project.groovy_installPath :
System.properties.installDirectory ?: "$buildDir/install"
}
task installGroovy(type: Sync, dependsOn: [checkCompatibility, distBin]) {
description 'Generates a groovy distribution into an install directory'
doLast {
logger.lifecycle "Groovy installed under ${installDir()}"
}
with distSpec
into installDir
}
task checkNoSnapshotVersions {
doLast {
if (project.isReleaseVersion) {
// TODO use modules() and exclusions as per distSpec
allprojects {
project.configurations.runtime.resolvedConfiguration.resolvedArtifacts.each {
if (it.moduleVersion.id.version.endsWith("-SNAPSHOT")) {
throw new GradleException("Found snapshot dependency for non-snapshot Groovy: " + it.moduleVersion)
}
}
}
}
}
}
distBin.dependsOn checkNoSnapshotVersions
task dist(type: Zip, dependsOn: [checkCompatibility, distBin, distSrc, distDoc, syncDoc]) {
description = 'Generates the binary, sources, documentation and full distributions'
baseName = 'apache-groovy'
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
appendix 'sdk'
into "groovy-$version"
from("$projectDir/licenses/LICENSE-SDK")
from("$projectDir/notices/NOTICE-SDK")
rename '^([A-Z]+)-([^.]*)', '$1'
with distSpec
into('doc') {
with docSpec
}
into('src') {
with srcSpec
}
if ((version.endsWith('SNAPSHOT') && !groovyBundleVersion.endsWith('SNAPSHOT'))
|| (!version.endsWith('SNAPSHOT') && groovyBundleVersion.endsWith('SNAPSHOT'))) {
throw new GradleException("Incoherent versions. Found groovyVersion=$version and groovyBundleVersion=$groovyBundleVersion")
}
}
task updateLicenses {
description = 'Updates the various LICENSE files'
ext.licensesDir = "${projectDir}/licenses"
ext.licenseBaseFile = "${licensesDir}/LICENSE-BASE"
ext.licenseSrcFile = "${projectDir}/LICENSE"
ext.licenseDocGeneratorFile = "${projectDir}/subprojects/groovy-docgenerator/LICENSE"
ext.licenseGroovyDocFile = "${projectDir}/subprojects/groovy-groovydoc/LICENSE"
ext.licenseJsr223File = "${projectDir}/subprojects/groovy-jsr223/LICENSE"
ext.licenseBinZipFile = "${licensesDir}/LICENSE-BINZIP"
ext.licenseDocFile = "${licensesDir}/LICENSE-DOC"
ext.licenseJarJarFile = "${licensesDir}/LICENSE-JARJAR"
ext.licenseSdkFile = "${licensesDir}/LICENSE-SDK"
inputs.files(licenseBaseFile, fileTree(licensesDir).include('*.txt'))
outputs.files(licenseBinZipFile, licenseDocFile, licenseJarJarFile, licenseSrcFile,
licenseDocGeneratorFile, licenseGroovyDocFile, licenseJsr223File, licenseSdkFile)
doLast {
def srcFiles = fileTree(licensesDir).include('*-SRC*.txt').sort { it.name }
def docFiles = fileTree(licensesDir).include('*-DOC*.txt').sort { it.name }
def jarjarFiles = fileTree(licensesDir).include('*-JARJAR*.txt').sort { it.name }
def binzipFiles = fileTree(licensesDir) {
include '*-JARJAR*.txt'
include '*-BINZIP*.txt'
}.sort { it.name }
def docgeneratorFiles = fileTree(licensesDir).include('normalize-stylesheet-groovy-docgenerator.txt')
def groovydocFiles = fileTree(licensesDir).include('normalize-stylesheet-groovy-groovydoc.txt')
def jsr223Files = fileTree(licensesDir).include('jsr223-BINZIP-SRC.txt')
def licenseHdr = '\n\n------------------------------------------------------------------------\n\n'
[
(licenseBinZipFile): binzipFiles,
(licenseDocFile): docFiles,
(licenseJarJarFile): jarjarFiles,
(licenseSrcFile): srcFiles,
(licenseDocGeneratorFile): docgeneratorFiles,
(licenseGroovyDocFile): groovydocFiles,
(licenseJsr223File): jsr223Files,
].each { outFile, inFiles ->
file(outFile).withWriter('utf-8') { writer ->
writer << ([file(licenseBaseFile)] + inFiles).collect {
it.text.replaceAll(/[\n\r]*$/, '')
}.join(licenseHdr) + '\n'
}
}
file(licenseSdkFile).withWriter { writer ->
writer << [
file(licenseBinZipFile).text,
"This convenience zip embeds Groovy's src and doc zips.\nSee also src/LICENSE " +
"and doc/LICENSE files for additional license information."
].join(licenseHdr) + '\n'
}
}
}
task updateNotices {
description = 'Updates the various NOTICE files'
ext.noticesDir = "${projectDir}/notices"
ext.noticeBaseFile = "${noticesDir}/NOTICE-BASE"
ext.noticeSrcFile = "${projectDir}/NOTICE"
ext.noticeGroovyConsoleFile = "${projectDir}/subprojects/groovy-console/NOTICE"
ext.noticeBinZipFile = "${noticesDir}/NOTICE-BINZIP"
ext.noticeGrooidFile = "${noticesDir}/NOTICE-GROOID"
ext.noticeGrooidJarJarFile = "${noticesDir}/NOTICE-GROOIDJARJAR"
ext.noticeJarJarFile = "${noticesDir}/NOTICE-JARJAR"
ext.noticeSdkFile = "${noticesDir}/NOTICE-SDK"
inputs.files(noticeBaseFile, fileTree(noticesDir).include('*.txt'))
outputs.files(noticeBinZipFile, noticeGrooidFile, noticeGrooidJarJarFile,
noticeJarJarFile, noticeSrcFile, noticeGroovyConsoleFile, noticeSdkFile)
doLast {
def srcFiles = fileTree(noticesDir).include('*-SRC*.txt').sort { it.name }
def grooidFiles = fileTree(noticesDir).include('*-GROOID*.txt').sort { it.name }
def jarjarFiles = fileTree(noticesDir).include('*-JARJAR*.txt').sort { it.name }
def grooidJarjarFiles = fileTree(noticesDir) {
include '*-JARJAR*.txt'
include '*-GROOID*.txt'
}.sort { it.name }
def binzipFiles = fileTree(noticesDir) {
include '*-JARJAR*.txt'
include '*-GROOID*.txt'
include '*-BINZIP*.txt'
}.sort { it.name }
def groovyconsoleFiles = fileTree(noticesDir).include('silkicons-BINZIP-SRC.txt')
[
(noticeBinZipFile): binzipFiles,
(noticeGrooidFile): grooidFiles,
(noticeGrooidJarJarFile): grooidJarjarFiles,
(noticeJarJarFile): jarjarFiles,
(noticeSrcFile): srcFiles,
(noticeGroovyConsoleFile): groovyconsoleFiles,
].each { outFile, inFiles ->
file(outFile).withWriter('utf-8') { writer ->
writer << ([file(noticeBaseFile)] + inFiles).collect {
it.text.replaceAll(/[\n\r]*$/, '')
}.join('\n\n')
}
}
file(noticeSdkFile).withWriter { writer ->
writer << [
file(noticeBinZipFile).text,
"This convenience zip embeds Groovy's src and doc zips.\nSee also src/NOTICE " +
"and doc/NOTICE files for additional notice information."
].join('\n\n')
}
}
}