1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/ofbiz_ynh.git synced 2024-09-03 19:46:33 +02:00
ofbiz_ynh/conf/build.gradle
2022-03-02 04:02:38 +01:00

1200 lines
47 KiB
Groovy
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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 at.bxm.gradleplugins.svntools.tasks.SvnCheckout
import org.apache.tools.ant.filters.ReplaceTokens
import org.asciidoctor.gradle.AsciidoctorTask
/* ========================================================
* Project setup
* ======================================================== */
buildscript {
repositories {
mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath 'at.bxm.gradleplugins:gradle-svntools-plugin:2.2.1'
classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.8.1' // Rather than using 1.5.9.2 see OFBIZ-10693
classpath 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.16'
}
}
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'eclipse'
apply plugin: 'maven-publish'
apply plugin: "at.bxm.svntools"
apply plugin: 'org.asciidoctor.convert'
apply plugin: 'checkstyle'
apply from: 'common.gradle'
// global properties
ext.os = System.getProperty('os.name').toLowerCase()
ext.pluginsDir = "${rootDir}/plugins"
// java settings
List jvmArguments = ['-Xms128M', '-Xmx1024M']
if (project.hasProperty('jvmArgs')) {
jvmArguments = jvmArgs.tokenize()
}
ext.ofbizMainClass = 'org.apache.ofbiz.base.start.Start'
javadoc {
title='OFBiz R18.12 API'
failOnError = true
options {
source '8'
encoding "UTF-8"
charSet "UTF-8"
// Those external Javadoc links should correspond to the actual
// versions declared in the "dependencies" block.
links(
"https://docs.oracle.com/javase/8/docs/api",
"https://docs.oracle.com/javaee/7/api",
"http://docs.groovy-lang.org/docs/groovy-2.4.13/html/api",
"https://commons.apache.org/proper/commons-cli/apidocs"
)
}
}
// Checks OFBiz Java coding conventions.
checkstyle {
// Defining a maximum number of “tolerated” errors ensures that
// this number cannot increase in the future. It corresponds to
// the sum of errors that were present before introducing the
// checkstyle tool present in the framework and in the official
// plugins.
// Because of Windows EOL difference with *nix, despite the number
// for maxErrors being more around 39600+ we temporarily put 50000
// here to avoid issue when releasing.
// Just increasing the number of lines is the problem.
maxErrors = 50000
// Currently there are a lot of errors so we need to temporarily
// hide them to avoid polluting the terminal output.
showViolations = false
}
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
// Java compile options, syntax gradlew -PXlint:none build
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
if (!project.hasProperty('Xlint:none')) {
options.compilerArgs << "-Xlint:all"
// Exclude varargs warnings which are not silenced by @SafeVarargs.
options.compilerArgs << "-Xlint:-varargs"
}
}
// defines the footer files for svn and git info
def File gitFooterFile = file("${rootDir}/runtime/GitInfo.ftl")
def File svnFooterFile = file("${rootDir}/runtime/SvnInfo.ftl")
// root and subproject settings
defaultTasks 'build'
allprojects {
repositories{
mavenCentral()
// the switch from jCenter to mavenCentral needs some additional repositories to be configured here
// this should be checked frequently to remove obsolete configurations if the artifacts are available
// on mavenCentral directly
maven {
// org.restlet and org.restlet.ext.servlet
url "https://maven.restlet.talend.com"
}
maven {
// apache-xerces:xercesImpl:2.9.1
url "https://maven.repository.redhat.com/ga/"
}
maven {
// net.fortuna.ical4j:ical4j:1.0-rc4-atlassian-12
url "https://packages.atlassian.com/maven-3rdparty"
}
maven {
// org/milyn/flute/1.3/flute-1.3.jar
// need artifact only because of wrong pom metadata in maven central
url "https://repo1.maven.org/maven2"
metadataSources {
artifact()
}
}
}
}
subprojects {
configurations {
// compile-time plugin libraries
pluginLibsCompile
// runtime plugin libraries
pluginLibsRuntime
//compile-only libraries
pluginLibsCompileOnly
}
}
configurations {
junitReport {
description = 'libraries needed to run junitreport for OFBiz unit tests'
}
ofbizPlugins {
description = 'ofbiz plugin dependencies configuration'
transitive = true
}
}
dependencies {
// ofbiz compile libs
compile 'apache-xerces:xercesImpl:2.9.1'
compile 'com.google.zxing:core:3.3.3'
compile 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2'
compile 'com.googlecode.ez-vcard:ez-vcard:0.9.10'
compile 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20180219.1'
compile 'com.googlecode.libphonenumber:libphonenumber:8.9.16'
compile 'com.ibm.icu:icu4j:63.1'
compile 'com.lowagie:itext:2.1.7' // Don't update due to license change in newer versions, see OFBIZ-10455
compile 'com.sun.mail:javax.mail:1.6.2'
compile 'com.rometools:rome:1.16.0'
compile 'com.thoughtworks.xstream:xstream:1.4.11.1'
compile 'commons-cli:commons-cli:1.4'
compile 'commons-net:commons-net:3.6'
compile 'commons-validator:commons-validator:1.6'
compile 'commons-fileupload:commons-fileupload:1.3.3'
compile 'de.odysseus.juel:juel-impl:2.2.7'
compile 'javax.el:javax.el-api:3.0.1-b06'
compile 'javax.servlet:javax.servlet-api:4.0.1'
compile 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.3'
compile 'junit:junit-dep:4.11'
compile 'net.fortuna.ical4j:ical4j:1.0-rc4-atlassian-12'
compile 'org.apache.ant:ant-junit:1.10.5'
compile 'org.apache.axis2:axis2-kernel:1.7.8'
compile 'org.apache.commons:commons-collections4:4.2'
compile 'org.apache.commons:commons-csv:1.6'
compile 'org.apache.commons:commons-dbcp2:2.5.0'
compile 'org.apache.commons:commons-text:1.6'
compile 'org.apache.geronimo.components:geronimo-transaction:3.1.4'
compile 'org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1.1'
compile 'org.apache.httpcomponents:httpclient-cache:4.5.6'
compile 'org.apache.logging.log4j:log4j-api:2.17.1' // the API of log4j 2
compile 'org.apache.logging.log4j:log4j-web:2.17.1' //???
compile 'org.apache.poi:poi:3.17'
compile 'org.apache.pdfbox:pdfbox:2.0.24'
compile 'org.apache.shiro:shiro-core:1.4.0'
compile 'org.apache.sshd:sshd-core:1.7.0'
compile 'org.apache.tika:tika-core:1.28'
compile 'org.apache.tika:tika-parsers:1.28'
compile 'org.apache.tomcat:tomcat-catalina-ha:9.0.54'
compile 'org.apache.tomcat:tomcat-catalina:9.0.54'
compile 'org.apache.tomcat:tomcat-jasper:9.0.54'
compile 'org.apache.tomcat:tomcat-tribes:9.0.54'
compile 'org.apache.xmlgraphics:fop:2.3'
compile 'org.apache.xmlrpc:xmlrpc-client:3.1.3'
compile 'org.apache.xmlrpc:xmlrpc-server:3.1.3'
compile 'org.codehaus.groovy:groovy-all:2.4.13' // Remember to change the version number in javadoc.options block
compile 'org.freemarker:freemarker:2.3.31' // Remember to change the version number in FreeMarkerWorker class when upgrading
compile 'org.hamcrest:hamcrest-all:1.3'
compile 'org.owasp.esapi:esapi:2.1.0.1'
compile 'org.springframework:spring-test:5.1.2.RELEASE'
compile 'org.zapodot:jackson-databind-java-optional:2.6.1'
compile 'oro:oro:2.0.8'
compile 'wsdl4j:wsdl4j:1.6.3'
compile 'org.jsoup:jsoup:1.11.3'
compile 'com.auth0:java-jwt:3.8.2'
compile 'org.jdom:jdom:1.1.3' // don't upgrade above 1.1.3, makes a lot of not obvious and useless complications, see last commits of OFBIZ-12092 for more
compile 'net.lingala.zip4j:zip4j:2.6.4'
compile 'org.apache.commons:commons-imaging:1.0-alpha2' // Alpha but OK, "Imaging was working and was used by a number of projects in production even before reaching its initial release as an Apache Commons component."
compile 'batik:batik-svg-dom:1.6-1'
compile 'org.postgresql:postgresql:42.3.3'
// ofbiz unit-test compile libs
testCompile 'org.mockito:mockito-core:2.23.0'
// ofbiz runtime libs
runtime 'javax.xml.soap:javax.xml.soap-api:1.4.0'
runtime 'de.odysseus.juel:juel-spi:2.2.7'
runtime 'net.sf.barcode4j:barcode4j-fop-ext:2.1'
runtime 'net.sf.barcode4j:barcode4j:2.1'
runtime 'org.apache.axis2:axis2-transport-http:1.7.8'
runtime 'org.apache.axis2:axis2-transport-local:1.7.8'
runtime 'org.apache.derby:derby:10.14.2.0'
runtime 'org.apache.geronimo.specs:geronimo-jaxrpc_1.1_spec:1.1'
runtime 'org.apache.logging.log4j:log4j-1.2-api:2.17.1' // for external jars using the old log4j1.2: routes logging to log4j 2
runtime 'org.apache.logging.log4j:log4j-core:2.17.1' // the implementation of the log4j 2 API
runtime 'org.apache.logging.log4j:log4j-jul:2.17.1' // for external jars using the java.util.logging: routes logging to log4j 2
runtime 'org.apache.logging.log4j:log4j-slf4j-impl:2.17.1' // for external jars using slf4j: routes logging to log4j 2
runtime 'org.apache.logging.log4j:log4j-jcl:2.17.1' // need to constrain to version to avoid classpath conflict (ReflectionUtil)
runtime 'org.codeartisans.thirdparties.swing:batik-all:1.8pre-r1084380'
// plugin libs
subprojects.each { subProject ->
compile project(path: subProject.path, configuration: 'pluginLibsCompile')
runtime project(path: subProject.path, configuration: 'pluginLibsRuntime')
compileOnly project(path: subProject.path, configuration: 'pluginLibsCompileOnly')
}
// libs needed for junitreport
junitReport 'junit:junit:4.12'
junitReport 'org.apache.ant:ant-junit:1.10.5'
// bug workaround - see OFBIZ-9873
asciidoctor 'org.jruby:jruby-complete:9.2.4.0'
// local libs
getDirectoryInActiveComponentsIfExists('lib').each { libDir ->
compile fileTree(dir: libDir, include: '**/*.jar')
}
compile fileTree(dir: file("${rootDir}/lib"), include: '**/*.jar')
}
def excludedJavaSources = [
'org/apache/ofbiz/accounting/thirdparty/cybersource/IcsPaymentServices.java',
'org/apache/ofbiz/accounting/thirdparty/orbital/OrbitalPaymentServices.java',
'org/apache/ofbiz/accounting/thirdparty/paypal/PayPalServices.java',
'org/apache/ofbiz/accounting/thirdparty/securepay/SecurePayPaymentServices.java',
'org/apache/ofbiz/accounting/thirdparty/securepay/SecurePayServiceTest.java',
'org/apache/ofbiz/accounting/thirdparty/verisign/PayflowPro.java',
'org/apache/ofbiz/order/thirdparty/taxware/TaxwareException.java',
'org/apache/ofbiz/order/thirdparty/taxware/TaxwareServices.java',
'org/apache/ofbiz/order/thirdparty/taxware/TaxwareUTL.java'
]
// Files and directories present in config directories that should not be included in ofbiz.jar (see OFBIZ-8321).
def excludedConfigFiles = [
'README',
'APACHE2_HEADER_FOR_XML',
'*.txt',
'*.jks',
'fop.xconf',
'MiniLang.xslt',
'AutoImportTemplate.ftl',
'axis2',
'barcode'
]
sourceSets {
main {
java {
srcDirs = getDirectoryInActiveComponentsIfExists('src/main/java')
exclude excludedJavaSources
}
groovy {
srcDirs = getDirectoryInActiveComponentsIfExists('src/main/groovy')
}
resources {
srcDirs = getDirectoryInActiveComponentsIfExists('src/main/java')
srcDirs += getDirectoryInActiveComponentsIfExists('config')
srcDirs += getDirectoryInActiveComponentsIfExists('dtd')
exclude excludedJavaSources
exclude excludedConfigFiles
// Below are necessary for unit tests run by Gradle and integration tests
exclude { FileTreeElement elem -> elem.getName().contains('Labels.xml') }
exclude { FileTreeElement elem -> elem.getName().contains('.properties') &&
!elem.getName().contains('start.properties') &&
!elem.getName().contains('load-data.properties') &&
!elem.getName().contains('debug.properties') &&
!elem.getName().contains('cache.properties') &&
!elem.getName().contains('test.properties') &&
!elem.getName().contains('rmi.properties')
}
}
}
test {
java {
srcDirs = getDirectoryInActiveComponentsIfExists('src/test/java')
}
groovy {
srcDirs = getDirectoryInActiveComponentsIfExists('src/test/groovy')
}
resources {
srcDirs = getDirectoryInActiveComponentsIfExists('src/test/java')
}
}
}
jar {
manifest {
attributes(
"Implementation-Title": project.name,
"Main-Class": ofbizMainClass,
"Class-Path": getJarManifestClasspathForCurrentOs()
)
}
}
// Eclipse plugin settings
eclipse.classpath.file.whenMerged { classpath ->
/* The code inside this block removes unnecessary entries
* in the .classpath file which are generated automatically
* due to the settings in the sourceSets block
*/
def fileSep = System.getProperty("file.separator")
iterateOverActiveComponents { component ->
def componentName = component.toString() - rootDir.toString() - fileSep
def eclipseEntry = os.contains('windows') ? componentName.replaceAll("\\\\", "/") : componentName
classpath.entries.removeAll { entry ->
// remove any "src" entries in .classpath of the form /componentName
entry.kind == 'src' && !(entry.path ==~ 'framework/base/config' || entry.path ==~ 'framework/base/dtd') && (
entry.path ==~ '.*/+(' + componentName.tokenize(fileSep).last() + ')$' ||
entry.path ==~ /(\/+framework)$/ ||
entry.path ==~ /(\/+applications)$/ ||
entry.path ==~ /(\/+plugins)$/ ||
entry.path ==~ /(\/+themes)$/ ||
entry.path ==~ eclipseEntry + '/config' ||
entry.path ==~ eclipseEntry + '/dtd')
}
}
}
tasks.eclipse.dependsOn(cleanEclipse)
/* OWASP plugin
*
* If project property "enableOwasp" is flagged then
* gradle will download required dependencies and
* activate Gradle's OWASP plugin and its related tasks.
*
* Syntax: gradlew -PenableOwasp dependencyCheckAnalyze
*/
buildscript {
if (project.hasProperty('enableOwasp')) {
dependencies {
classpath 'org.owasp:dependency-check-gradle:3.0.2'
}
}
}
if (project.hasProperty('enableOwasp')) {
apply plugin: 'org.owasp.dependencycheck'
}
/* ========================================================
* Tasks
* ======================================================== */
// ========== Task group labels ==========
def cleanupGroup = 'Cleaning'
def docsGroup = 'Documentation'
def ofbizServer = 'OFBiz Server'
def ofbizPlugin = 'OFBiz Plugin'
def sysadminGroup = 'System Administration'
// ========== OFBiz Server tasks ==========
task loadAll(group: ofbizServer) {
dependsOn 'ofbiz --load-data'
description 'Load default data; meant for OFBiz development, testing, and demo purposes'
}
task testIntegration(group: ofbizServer) {
dependsOn 'ofbiz --test'
description 'Run OFBiz integration tests; You must run loadAll before running this task'
}
task terminateOfbiz(group: ofbizServer,
description: 'Force termination of any running OFBiz servers, only use if \"--shutdown\" command fails') {
doLast {
if (os.contains('windows')) {
Runtime.getRuntime().exec("wmic process where \"CommandLine Like \'%org.apache.ofbiz.base.start.Start%\'\" Call Terminate")
} else {
def processOutput = new ByteArrayOutputStream()
exec {
commandLine 'ps', 'ax'
standardOutput = processOutput
}
processOutput.toString().split(System.lineSeparator()).each { line ->
if (line ==~ /.*org\.apache\.ofbiz\.base\.start\.Start.*/) {
exec { commandLine 'kill', '-9', line.tokenize().first() }
}
}
}
}
}
task loadAdminUserLogin(group: ofbizServer) {
description 'Create admin user with temporary password equal to ofbiz. You must provide userLoginId'
createOfbizCommandTask('executeLoadAdminUser',
['--load-data', 'file=/runtime/tmp/AdminUserLoginData.xml'],
jvmArguments, false)
executeLoadAdminUser.doFirst {
copy {
from ("${rootDir}/framework/resources/templates/AdminUserLoginData.xml") {
filter(ReplaceTokens, tokens: [userLoginId: userLoginId])
}
into "${rootDir}/runtime/tmp/"
}
}
dependsOn executeLoadAdminUser
doLast {
delete("${rootDir}/runtime/tmp/AdminUserLoginData.xml")
}
}
task loadTenant(group: ofbizServer, description: 'Load data using tenantId') {
createOfbizCommandTask('executeLoadTenant', [], jvmArguments, false)
if (project.hasProperty('tenantId')) {
executeLoadTenant.args '--load-data'
executeLoadTenant.args "delegator=default#${tenantId}"
}
if (project.hasProperty('tenantReaders')) {
executeLoadTenant.args '--load-data'
executeLoadTenant.args "readers=${tenantReaders}"
}
if (project.hasProperty('tenantComponent')) {
executeLoadTenant.args '--load-data'
executeLoadTenant.args "component=${tenantComponent}"
}
executeLoadTenant.doFirst {
if (!project.hasProperty('tenantId')) {
throw new GradleException('Missing project property tenantId')
}
}
dependsOn executeLoadTenant
}
task createTenant(group: ofbizServer, description: 'Create a new tenant in your environment') {
def databaseTemplateFile = "${rootDir}/framework/resources/templates/AdminNewTenantData-Derby.xml"
task prepareAndValidateTenantArguments {
doLast {
if (!project.hasProperty('tenantId')) {
throw new GradleException('Project property tenantId is missing')
}
// dbPlatform values: D(Derby), M(MySQL), O(Oracle), P(PostgreSQL) (default D)
if (project.hasProperty('dbPlatform')) {
if (dbPlatform == 'D') {
databaseTemplateFile = "${rootDir}/framework/resources/templates/AdminNewTenantData-Derby.xml"
} else if (dbPlatform == 'M') {
databaseTemplateFile = "${rootDir}/framework/resources/templates/AdminNewTenantData-MySQL.xml"
} else if (dbPlatform == 'O') {
databaseTemplateFile = "${rootDir}/framework/resources/templates/AdminNewTenantData-Oracle.xml"
} else if (dbPlatform == 'P') {
databaseTemplateFile = "${rootDir}/framework/resources/templates/AdminNewTenantData-PostgreSQL.xml"
} else {
throw new GradleException('Invalid value for property dbPlatform: ' + "${dbPlatform}")
}
}
}
}
task generateDatabaseTemplateFile(dependsOn: prepareAndValidateTenantArguments) {
doLast {
def filterTokens = ['tenantId': tenantId,
'tenantName': project.hasProperty('tenantName')? tenantName : tenantId,
'domainName': project.hasProperty('domainName')? domainName : 'org.apache.ofbiz',
'db-IP': project.hasProperty('dbIp')? dbIp : '',
'db-User': project.hasProperty('dbUser')? dbUser : '',
'db-Password': project.hasProperty('dbPassword')? dbPassword : '']
generateFileFromTemplate(databaseTemplateFile, 'runtime/tmp',
filterTokens, 'tmpFilteredTenantData.xml')
}
}
task generateAdminUserTemplateFile(dependsOn: prepareAndValidateTenantArguments) {
doLast {
generateFileFromTemplate(
"${rootDir}/framework/resources/templates/AdminUserLoginData.xml",
'runtime/tmp',
['userLoginId': "${tenantId}-admin".toString()],
'tmpFilteredUserLogin.xml')
}
}
// Load the tenants master database
createOfbizCommandTask('loadTenantOnMasterTenantDb',
['--load-data', 'file=/runtime/tmp/tmpFilteredTenantData.xml',
'--load-data', 'readers=tenant'],
jvmArguments, false)
loadTenantOnMasterTenantDb.dependsOn(generateDatabaseTemplateFile, generateAdminUserTemplateFile)
// Load the actual tenant data
createOfbizCommandTask('loadTenantData', [], jvmArguments, false)
loadTenantData.dependsOn(loadTenantOnMasterTenantDb)
// Load the tenant admin user account
createOfbizCommandTask('loadTenantAdminUserLogin', [], jvmArguments, false)
loadTenantAdminUserLogin.dependsOn(loadTenantData)
/* pass arguments to tasks, must be done this way
* because we are in the configuration phase. We cannot
* set the parameters at the execution phase. */
if (project.hasProperty('tenantId')) {
loadTenantData.args '--load-data'
loadTenantData.args "delegator=default#${tenantId}"
loadTenantAdminUserLogin.args '--load-data'
loadTenantAdminUserLogin.args "delegator=default#${tenantId}"
loadTenantAdminUserLogin.args '--load-data'
loadTenantAdminUserLogin.args "file=${rootDir}/runtime/tmp/tmpFilteredUserLogin.xml"
}
if (project.hasProperty('tenantReaders')) {
loadTenantData.args '--load-data'
loadTenantData.args "readers=${tenantReaders}"
}
dependsOn(loadTenantAdminUserLogin)
// cleanup
doLast {
delete("${rootDir}/runtime/tmp/tmpFilteredTenantData.xml")
delete("${rootDir}/runtime/tmp/tmpFilteredUserLogin.xml")
}
}
// ========== Documentation tasks ==========
tasks.withType(AsciidoctorTask) { task ->
backends 'html5', 'pdf'
attributes \
'doctype': 'book',
'experimental': '',
'icons': 'font',
'sectnums': '',
'chapter-label': '',
'toc': 'left@',
'toclevels': '3'
}
task deleteOfbizDocumentation {
doFirst { delete "${buildDir}/asciidoc/ofbiz" }
}
task deletePluginDocumentation {
def activeComponents = []
iterateOverActiveComponents { component ->
activeComponents.add(component.name)
}
doFirst {
if (!project.hasProperty('pluginId')) {
throw new GradleException('Missing property \"pluginId\"')
}
if(!activeComponents.contains(pluginId)) {
throw new GradleException("Could not find plugin with id ${pluginId}")
}
delete "${buildDir}/asciidoc/plugins/${pluginId}"
}
}
task deleteAllPluginsDocumentation {
doFirst { delete "${buildDir}/asciidoc/plugins" }
}
task generateReadmeFiles(group: docsGroup, type: AsciidoctorTask) {
doFirst { delete "${buildDir}/asciidoc/readme" }
description 'Generate OFBiz README files'
sourceDir "${rootDir}"
sources {
include 'README.adoc', 'CHANGELOG.adoc', 'CONTRIBUTING.adoc'
}
outputDir file("${buildDir}/asciidoc/readme/")
}
task generateOfbizDocumentation(group: docsGroup, type: AsciidoctorTask) {
dependsOn deleteOfbizDocumentation
description 'Generate OFBiz documentation manuals'
sourceDir "${rootDir}/docs/asciidoc"
outputDir file("${buildDir}/asciidoc/ofbiz")
}
task generatePluginDocumentation(group: docsGroup) {
dependsOn deletePluginDocumentation
description 'Generate plugin documentation. Expects pluginId flag'
iterateOverActiveComponents { component ->
if (project.hasProperty('pluginId') && component.name == pluginId) {
def pluginAsciidoc = task "${component.name}Documentation" (type: AsciidoctorTask) {
def asciidocFolder = new File("${component}/src/docs/asciidoc")
if (asciidocFolder.exists()) {
copy {
from "${rootDir}/docs/asciidoc/images/OFBiz-Logo.svg"
into "${component}/src/docs/asciidoc/images"
}
sourceDir file("${component}/src/docs/asciidoc")
outputDir file("${buildDir}/asciidoc/plugins/${component.name}")
doLast { println "Documentation generated for plugin ${component.name}" }
} else {
println "No documentation found for plugin ${component.name}"
}
doLast { delete "${component}/src/docs/asciidoc/images/OFBiz-Logo.svg" }
mustRunAfter deletePluginDocumentation
}
dependsOn pluginAsciidoc
doLast { delete "${component}/src/docs/asciidoc/images/OFBiz-Logo.svg" }
}
}
}
task generateAllPluginsDocumentation(group: docsGroup,
description: 'Generate all plugins documentation.') {
dependsOn deleteAllPluginsDocumentation
file("${pluginsDir}").eachDir { plugin ->
iterateOverActiveComponents { component ->
if (component.name == plugin.name) {
if (subprojectExists(":plugins:${plugin.name}")) {
// Note: the "-" between "component.name" and "Documentation" allows to differentiate from
// the other inner task temporary created by the generatePluginDocumentation task
def pluginAsciidoc = task "${component.name}-Documentation" (type: AsciidoctorTask) {
def asciidocFolder = new File("${component}/src/docs/asciidoc")
doFirst {
if (asciidocFolder.exists()) {
copy {
from "${rootDir}/docs/asciidoc/images/OFBiz-Logo.svg"
into "${component}/src/docs/asciidoc/images"
}
}
}
if (asciidocFolder.exists()) {
sourceDir file("${component}/src/docs/asciidoc")
outputDir file("${buildDir}/asciidoc/plugins/${component.name}")
doLast { println "Documentation generated for plugin ${component.name}" }
}
mustRunAfter deleteAllPluginsDocumentation
doLast { delete "${component}/src/docs/asciidoc/images/OFBiz-Logo.svg" }
}
dependsOn pluginAsciidoc
}
}
}
}
}
// ========== System Administration tasks ==========
task createTestReports(group: sysadminGroup, description: 'Generate HTML reports from junit XML output') {
doLast {
ant.taskdef(name: 'junitreport',
classname: 'org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator',
classpath: configurations.junitReport.asPath)
ant.junitreport(todir: './runtime/logs/test-results') {
fileset(dir: './runtime/logs/test-results') {
include(name: '*.xml')
}
report(format:'frames', todir:'./runtime/logs/test-results/html')
}
}
}
task gitInfoFooter(group: sysadminGroup, description: 'Update the Git Branch-revision info in the footer if Git is used') {
doLast {
def branch
def revision
def timestamp = new Date().format 'yyyy-MM-dd HH:mm:ss'
def gitFolder = new File('.git')
if (!gitFolder.exists()) {
println ("Git is not used")
return
}
def branchOutput = new ByteArrayOutputStream()
exec{
commandLine 'git', 'rev-parse', '--abbrev-ref', 'HEAD'
standardOutput = branchOutput
}
branch = branchOutput.toString()
def revisionOutput = new ByteArrayOutputStream()
exec{
commandLine 'git', 'rev-parse', 'HEAD'
standardOutput = revisionOutput
}
revision = revisionOutput.toString()
gitFooterFile.delete()
gitFooterFile.createNewFile()
gitFooterFile << System.lineSeparator()
gitFooterFile << '${uiLabelMap.CommonBranch} : ' + "${branch}" + System.lineSeparator()
gitFooterFile << '${uiLabelMap.CommonRevision} : ' + "${revision}" + System.lineSeparator()
gitFooterFile << '${uiLabelMap.CommonBuiltOn} : ' + "${timestamp}" + System.lineSeparator()
gitFooterFile << '${uiLabelMap.CommonJavaVersion} : ' + "${org.gradle.internal.jvm.Jvm.current()}"
}
}
task svnInfoFooter(group: sysadminGroup, description: 'Update the Subversion revision info in the footer if Subversion is used') {
doLast {
def timestamp = new Date().format 'yyyy-MM-dd HH:mm:ss'
def svnOutput = new ByteArrayOutputStream()
def svnFolder = new File('.svn')
if (!svnFolder.exists()) {
println ("Subversion is not used")
return
}
exec{
commandLine 'svn', 'info', '--xml'
standardOutput = svnOutput
}
def info = new XmlParser().parseText(svnOutput.toString())
svnFooterFile.delete()
svnFooterFile.createNewFile()
svnFooterFile << System.lineSeparator()
svnFooterFile << '${uiLabelMap.CommonBranch} : ' + "${info.entry.url.text()}" + System.lineSeparator()
svnFooterFile << '${uiLabelMap.CommonRevision} : ' + "${info.entry.commit.@revision}" + System.lineSeparator()
svnFooterFile << '${uiLabelMap.CommonBuiltOn} : ' + "${timestamp}" + System.lineSeparator()
svnFooterFile << '${uiLabelMap.CommonJavaVersion} : ' + "${org.gradle.internal.jvm.Jvm.current()}"
}
}
// ========== OFBiz Plugin Management ==========
task createPlugin(group: ofbizPlugin, description: 'create a new plugin component based on specified templates') {
doLast {
if (!project.hasProperty('pluginResourceName')) {
ext.pluginResourceName = pluginId.capitalize()
}
if (!project.hasProperty('webappName')) {
ext.webappName = pluginId
}
if (!project.hasProperty('basePermission')) {
ext.basePermission = pluginId.toUpperCase()
}
def filterTokens = ['component-name': pluginId,
'component-resource-name': pluginResourceName,
'webapp-name': webappName,
'base-permission': basePermission]
def templateDir = "${rootDir}/framework/resources/templates"
def pluginDir = "${pluginsDir}/${pluginId}"
['config', 'data/helpdata', 'dtd', 'documents', 'entitydef', 'lib', 'patches/test', 'patches/qa',
'patches/production', 'groovyScripts', 'minilang', 'servicedef', 'src/main/java', 'src/test/java', 'testdef',
'widget', "webapp/${webappName}/error", "webapp/${webappName}/WEB-INF"].each {
mkdir pluginDir+'/'+it
}
[ [tempName:'ofbiz-component.xml', newName:'ofbiz-component.xml', location:''],
[tempName:'build.gradle', newName:'build.gradle', location:''],
[tempName:'TypeData.xml', newName:"${pluginResourceName}TypeData.xml", location:'data'],
[tempName:'SecurityPermissionSeedData.xml', newName:"${pluginResourceName}SecurityPermissionSeedData.xml", location:'data'],
[tempName:'SecurityGroupDemoData.xml', newName:"${pluginResourceName}SecurityGroupDemoData.xml", location:'data'],
[tempName:'DemoData.xml', newName:"${pluginResourceName}DemoData.xml", location:'data'],
[tempName:'HELP.xml', newName:"HELP_${pluginResourceName}.xml", location:'data/helpdata'],
[tempName:'document.xml', newName:"${pluginResourceName}.xml", location:'documents'],
[tempName:'entitymodel.xml', newName:'entitymodel.xml', location:'entitydef'],
[tempName:'services.xml', newName:'services.xml', location:'servicedef'],
[tempName:'Tests.xml', newName:"${pluginResourceName}Tests.xml", location:'testdef'],
[tempName:'UiLabels.xml', newName:"${pluginResourceName}UiLabels.xml", location:'config'],
[tempName:'index.jsp', newName:'index.jsp', location:"webapp/${webappName}"],
[tempName:'error.jsp', newName:'error.jsp', location:"webapp/${webappName}/error"],
[tempName:'controller.xml', newName:'controller.xml', location:"webapp/${webappName}/WEB-INF"],
[tempName:'web.xml', newName:'web.xml', location:"webapp/${webappName}/WEB-INF"],
[tempName:'CommonScreens.xml', newName:'CommonScreens.xml', location:'widget'],
[tempName:'Screens.xml', newName:"${pluginResourceName}Screens.xml", location:'widget'],
[tempName:'Menus.xml', newName:"${pluginResourceName}Menus.xml", location:'widget'],
[tempName:'Forms.xml', newName:"${pluginResourceName}Forms.xml", location:'widget']
].each { tmpl ->
generateFileFromTemplate(templateDir + '/' + tmpl.tempName,
pluginDir + '/' + tmpl.location, filterTokens, tmpl.newName)
}
println "plugin successfully created in directory ${pluginsDir}/${pluginId}."
}
}
task installPlugin(group: ofbizPlugin, description: 'executes plugin install task if it exists') {
doFirst {
if (!project.hasProperty('pluginId')) {
throw new GradleException('Missing property \"pluginId\"')
}
}
if (project.hasProperty('pluginId')) {
iterateOverActiveComponents { component ->
if (component.name == pluginId) {
if (subprojectExists(":plugins:${pluginId}")) {
if (taskExistsInproject(":plugins:${pluginId}", 'install')) {
dependsOn ":plugins:${pluginId}:install"
doLast { println "installed plugin ${pluginId}" }
} else {
doLast { println "No install task defined for plugin ${pluginId}, nothing to do" }
}
}
}
}
}
}
task uninstallPlugin(group: ofbizPlugin, description: 'executes plugin uninstall task if it exists') {
doFirst {
if (!project.hasProperty('pluginId')) {
throw new GradleException('Missing property \"pluginId\"')
}
if (!subprojectExists(":plugins:${pluginId}")) {
throw new GradleException("Plugin \"${pluginId}\" does not exist")
}
}
if (project.hasProperty('pluginId') && taskExistsInproject(":plugins:${pluginId}", 'uninstall')) {
dependsOn ":plugins:${pluginId}:uninstall"
doLast { println "uninstalled plugin ${pluginId}" }
} else {
doLast { println "No uninstall task defined for plugin ${pluginId}" }
}
}
task removePlugin(group: ofbizPlugin, description: 'Uninstall a plugin and delete its files') {
if (project.hasProperty('pluginId') && subprojectExists(":plugins:${pluginId}")) {
dependsOn uninstallPlugin
}
doLast {
if (file("${pluginsDir}/${pluginId}").exists()) {
delete "${pluginsDir}/${pluginId}"
} else {
throw new GradleException("Directory not found: ${pluginsDir}/${pluginId}")
}
}
}
task pushPlugin(group: ofbizPlugin, description: 'push an existing plugin to local maven repository') {
if (project.hasProperty('pluginId')) {
doFirst {
if (!subprojectExists(":plugins:${pluginId}")) {
throw new GradleException("Plugin ${pluginId} does not exist, cannot publish")
}
}
task createPluginArchive(type: Zip) {
from "${pluginsDir}/${pluginId}"
}
publishing {
publications {
ofbizPluginPublication(MavenPublication) {
artifactId pluginId
groupId project.hasProperty('pluginGroup')? pluginGroup :'org.apache.ofbiz.plugin'
version project.hasProperty('pluginVersion')? pluginVersion :'0.1.0-SNAPSHOT'
artifact createPluginArchive
pom.withXml {
if (project.hasProperty('pluginDescription')) {
asNode().appendNode('description', pluginDescription)
} else {
asNode().appendNode('description', "Publication of OFBiz plugin ${pluginId}")
}
}
}
}
}
if (subprojectExists(":plugins:${pluginId}")) {
dependsOn publishToMavenLocal
}
} else {
doFirst { throw new GradleException('Missing property \"pluginId\"') }
}
}
task pullPlugin(group: ofbizPlugin, description: 'Download and install a plugin with all dependencies') {
doLast {
if (!project.hasProperty('dependencyId')) {
throw new GradleException('You must pass the dependencyId of the plugin')
}
// Connect to a remote maven repository if defined
if (project.hasProperty('repoUrl')) {
repositories {
maven {
url repoUrl
if (project.hasProperty('repoUser') && project.hasProperty('repoPassword')) {
credentials {
username repoUser
password repoPassword
}
}
}
}
}
// download plugin and dependencies
dependencies {
ofbizPlugins dependencyId
}
// reverse the order of dependencies to install them before the plugin
def ofbizPluginArchives = new ArrayList(configurations.ofbizPlugins.files)
Collections.reverse(ofbizPluginArchives)
// Extract and install plugin and dependencies
ofbizPluginArchives.each { pluginArchive ->
ext.pluginId = dependencyId.tokenize(':').get(1)
println "installing plugin: ${pluginId}"
copy {
from zipTree(pluginArchive)
into "${pluginsDir}/${pluginId}"
}
gradlewSubprocess(['installPlugin', "-PpluginId=${pluginId}"])
}
}
}
task pullPluginSource(group: ofbizPlugin, description: 'Download and install a plugin from source control') {
if (project.hasProperty('pluginId')) {
task pullPluginFromSvn(type: SvnCheckout) {
svnUrl = "https://github.com/apache/ofbiz-plugins/branches/release18.12/${pluginId}"
workspaceDir = "${pluginsDir}/${pluginId}"
}
dependsOn pullPluginFromSvn
}
doLast {
gradlewSubprocess(['installPlugin', "-PpluginId=${pluginId}"])
}
}
task pullAllPluginsSource(group: ofbizPlugin,
description: 'Download and install all plugins from source control. Warning! deletes existing plugins') {
task deleteBeforePulling {
doLast { delete "${pluginsDir}" }
}
task pullPluginsFromSvn(type: SvnCheckout, dependsOn: deleteBeforePulling) {
svnUrl = "https://github.com/apache/ofbiz-plugins/branches/release18.12"
workspaceDir = "${pluginsDir}"
}
dependsOn pullPluginsFromSvn
task installAllPlugins {
file("${pluginsDir}").eachDir { plugin ->
iterateOverActiveComponents { component ->
if (component.name == plugin.name) {
if (subprojectExists(":plugins:${plugin.name}")) {
if (taskExistsInproject(":plugins:${plugin.name}", 'install')) {
dependsOn ":plugins:${plugin.name}:install"
doLast { println "installed plugin ${plugin.name}" }
}
}
}
}
}
}
doLast {
gradlewSubprocess(['installAllPlugins'])
}
}
// ========== Clean up tasks ==========
task cleanCatalina(group: cleanupGroup, description: 'Clean Catalina data in runtime/catalina/work') {
doLast { delete "${rootDir}/runtime/catalina/work" }
}
task cleanData(group: cleanupGroup, description: 'Clean all DB data (Derby) under runtime/data') {
doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/data/", ['README', 'derby.properties']) }
}
task cleanDownloads(group: cleanupGroup, description: 'Clean all downloaded files') {
doLast {
delete fileTree(dir: "${rootDir}/framework/base/lib", includes: ['activemq-*.jar'])
delete fileTree(dir: "${rootDir}/framework/entity/lib/jdbc", includes: ['postgresql-*.jar'])
delete fileTree(dir: "${rootDir}/framework/entity/lib/jdbc", includes: ['mysql-*.jar'])
}
}
task cleanLogs(group: cleanupGroup, description: 'Clean all logs in runtime/logs') {
doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/logs/", ['README']) }
}
task cleanOutput(group: cleanupGroup, description: 'Clean runtime/output directory') {
doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/output/", ['README']) }
}
task cleanIndexes(group: cleanupGroup, description: 'Remove search indexes (e.g. Lucene) from runtime/indexes') {
doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/indexes/", ['README', 'index.properties']) }
}
task cleanTempfiles(group: cleanupGroup, description: 'Remove file in runtime/tempfiles') {
doLast {
deleteAllInDirWithExclusions("${rootDir}/runtime/tempfiles/", ['README'])
deleteAllInDirWithExclusions("${rootDir}/runtime/tmp/", ['README'])
}
}
task cleanUploads(group: cleanupGroup, description: 'Remove uploaded files.') {
doLast { deleteAllInDirWithExclusions("${rootDir}/runtime/uploads/", []) }
}
task cleanXtra(group: cleanupGroup, description: 'Clean extra generated files like .rej, .DS_Store, etc.') {
doLast {
delete fileTree(dir: "${rootDir}",
includes: ['**/.nbattrs', '**/*~','**/.#*', '**/.DS_Store', '**/*.rej', '**/*.orig'])
}
}
task cleanFooterFiles(group: cleanupGroup, description: 'clean generated footer files') {
doLast {
delete gitFooterFile
delete svnFooterFile
}
}
/*
* Keep this task below all other clean tasks The location of
* declaration is important because it means that it will automatically
* run whenever the task cleanAll executes (dependency matched by regex)
*/
def cleanTasks = tasks.findAll { it.name ==~ /^clean.+/ }
task cleanAll(group: cleanupGroup, dependsOn: [cleanTasks, clean]) {
description 'Execute all cleaning tasks.'
}
/* ========================================================
* Rules-based OFBiz server commands
* ======================================================== */
tasks.addRule('Pattern: ofbiz <Commands>: Execute OFBiz startup commands') { String taskName ->
if (taskName ==~ /^ofbiz\s.*/ || taskName == 'ofbiz') {
def arguments = (taskName - 'ofbiz').tokenize(' ')
createOfbizCommandTask(taskName, arguments, jvmArguments, false)
}
}
tasks.addRule('Pattern: ofbizDebug <Commands>: Execute OFBiz startup commands in remote debug mode') { String taskName ->
if (taskName ==~ /^ofbizDebug\s.*/ || taskName == 'ofbizDebug') {
def arguments = (taskName - 'ofbizDebug').tokenize(' ')
createOfbizCommandTask(taskName, arguments, jvmArguments, true)
}
}
tasks.addRule('Pattern: ofbizBackground <Commands>: Execute OFBiz startup commands in background and output to console.log') { String taskName ->
if (taskName ==~ /^ofbizBackground\s.*/ || taskName == 'ofbizBackground') {
createOfbizBackgroundCommandTask(taskName)
}
}
/* ========================================================
* Helper Functions
* ======================================================== */
def createOfbizCommandTask(taskName, arguments, jvmArguments, isDebugMode) {
def ofbizJarName = buildDir.toString()+'/libs/'+project.name+'.jar'
task(type: JavaExec, dependsOn: build, taskName) {
jvmArgs(jvmArguments)
debug = isDebugMode
classpath = files(ofbizJarName)
main = ofbizMainClass
arguments.each { argument ->
args argument
}
if (taskName ==~ /^ofbiz.*--test.*/
|| taskName ==~ /^ofbiz.*-t.*/) {
finalizedBy(createTestReports)
}
}
}
def createOfbizBackgroundCommandTask(taskName) {
def sourceTask = taskName.tokenize().first()
def arguments = (taskName - sourceTask)
def serverCommand = "ofbiz ${arguments}".toString()
def gradleRunner = os.contains('windows') ? 'gradlew.bat' : './gradlew'
task (taskName) {
doLast {
spawnProcess([gradleRunner, "--no-daemon", serverCommand])
}
}
}
def spawnProcess(command) {
ProcessBuilder pb = new ProcessBuilder(command)
File consoleLog = file("${rootDir}/runtime/logs/console.log");
pb.directory(file("${rootDir}"))
pb.redirectErrorStream(true)
pb.redirectOutput(ProcessBuilder.Redirect.appendTo(consoleLog))
pb.start()
}
def getDirectoryInActiveComponentsIfExists(String dirName) {
def dirInComponents = []
iterateOverActiveComponents { component ->
def subDir = file(component.toString() + '/' + dirName)
if (subDir.exists()) {
dirInComponents.add subDir
}
}
return dirInComponents
}
def deleteAllInDirWithExclusions(dirName, exclusions) {
ant.delete (includeEmptyDirs: 'true', verbose: 'on') {
fileset(dir: dirName, includes: '**/*', erroronmissingdir: "false") {
exclusions.each { exclusion ->
exclude name: exclusion
}
}
}
}
def generateFileFromTemplate(templateFileInFullPath, targetDirectory, filterTokens, newFileName) {
copy {
from (templateFileInFullPath) {
filter ReplaceTokens, tokens: filterTokens
rename templateFileInFullPath.tokenize('/').last(), newFileName
}
into targetDirectory
}
}
def getJarManifestClasspathForCurrentOs() {
def osClassPath = ''
if (os.contains('windows')) {
configurations.runtime.files.each { cpEntry ->
osClassPath += '\\' + cpEntry.toString() + ' '
}
} else {
osClassPath = configurations.runtime.files.collect { "$it" }.join(' ')
}
return osClassPath
}
def subprojectExists(fullyQualifiedProject) {
subprojects.stream()
.filter { it.path == fullyQualifiedProject.toString() }
.findAny()
.isPresent()
}
def taskExistsInproject(fullyQualifiedProject, taskName) {
subprojects.stream()
.filter { it.path == fullyQualifiedProject.toString() }
.flatMap { it.tasks.stream() }
.anyMatch { it.name == taskName }
}
def gradlewSubprocess(commandList) {
def gradlew = os.contains('windows') ? 'gradlew.bat' : './gradlew'
exec { commandLine(gradlew, "--no-daemon", *commandList) }
}
def gradle = project.getGradle()
new File("${gradle.getGradleUserHomeDir().getAbsolutePath()}/daemon/${gradle.getGradleVersion()}").listFiles().each {
if (it.getName().endsWith('.out.log')) {
logger.debug("Cleaning up daemon log file $it")
it.delete()
}
}