The main feature, one of them, of Groovy’s Gradle build framework is that plug-ins will add task to the life-cycle. Life-cycle in this case is the build life-cycle. Since mobile java builds are different than enterprise java I have had to come up with my own build life cycle definition, which looks like this in Gradle:
gradle.taskGraph.whenReady {taskGraph ->
if (taskGraph.hasTask(':debug')) {
debug.doFirst(dependsOn: 'clean') {
}
debug.doFirst(dependsOn: 'generateJavaClassesFromTemplates') {
}
debug.doFirst(dependsOn: 'processJavaPreprocess') {
}
debug.doFirst(dependsOn: 'processSrcResources') {
}
debug.doFirst(dependsOn: 'compileAidlJavaClasses') {
}
debug.doFirst(dependsOn: 'processPreCompileReports') {
}
debug.doFirst(dependsOn: 'compile') {
}
debug.doFirst(dependsOn: 'processPostCompileReports') {
}
debubg.doFirst(dependsOn: 'processAssetsResources') {
}
debug.doFirst(dependsOn: 'processPackageResources') {
}
debug.doFirst(dependsOn: 'processDex'){
}
debug.doLast(dependsOn: 'appInstall') {
}
} else {
}
if (taskGraph.hasTask(':release')) {
debug.doFirst(dependsOn: 'clean') {
}
debug.doFirst(dependsOn: 'generateJavaClassesFromTemplates') {
}
debug.doFirst(dependsOn: 'processJavaPreprocess') {
}
debug.doFirst(dependsOn: 'processSrcResources') {
}
debug.doFirst(dependsOn: 'compileAidlJavaClasses') {
}
debug.doFirst(dependsOn: 'processPreCompileReports') {
}
debug.doFirst(dependsOn: 'compile') {
}
debug.doFirst(dependsOn: 'obfuscate') {
}
debug.doFirst(dependsOn: 'processPostCompileReports') {
}
debubg.doFirst(dependsOn: 'processAssetsResources') {
}
debug.doFirst(dependsOn: 'processPackageResources') {
}
debug.doFirst(dependsOn: 'processDex'){
}
debug.doLast(dependsOn; 'appProductionSigned') {
}
} else {
}
/**
* mockTestsSomething tasks are defined under the project tag
*/
if (taskGraph.hasTask(':tests:mockAll')) {
debug.doFirst(dependsOn: 'clean') {
}
debug.doFirst(dependsOn: 'generateJavaClassesFromTemplates') {
}
debug.doFirst(dependsOn: 'processJavaPreprocess') {
}
debug.doFirst(dependsOn: 'processSrcResources') {
}
debug.doFirst(dependsOn: 'compileAidlJavaClasses') {
}
debug.doFirst(dependsOn: 'processPreCompileReports') {
}
debug.doFirst(dependsOn: 'compile') {
}
debug.doFirst(dependsOn: 'processPostCompileReports') {
}
debubg.doFirst(dependsOn: 'processAssetsResources') {
}
debug.doFirst(dependsOn: 'processPackageResources') {
}
debug.doFirst(dependsOn: 'processDex'){
}
debug.doFirst(dependsOn: 'appReinstall')) {
}
} else {
}
if (taskGraph.hasTask(':tests:mockFunctional')) {
debug.doFirst(dependsOn: 'clean') {
}
debug.doFirst(dependsOn: 'generateJavaClassesFromTemplates') {
}
debug.doFirst(dependsOn: 'processJavaPreprocess') {
}
debug.doFirst(dependsOn: 'processSrcResources') {
}
debug.doFirst(dependsOn: 'compileAidlJavaClasses') {
}
debug.doFirst(dependsOn: 'processPreCompileReports') {
}
debug.doFirst(dependsOn: 'compile') {
}
debug.doFirst(dependsOn: 'processPostCompileReports') {
}
debubg.doFirst(dependsOn: 'processAssetsResources') {
}
debug.doFirst(dependsOn: 'processPackageResources') {
}
debug.doFirst(dependsOn: 'processDex'){
}
debug.doFirst(dependsOn: 'appReinstall')) {
}
} else {
}
if (taskGraph.hasTask(':tests:mockUnit')) {
debug.doFirst(dependsOn: 'clean') {
}
debug.doFirst(dependsOn: 'generateJavaClassesFromTemplates') {
}
debug.doFirst(dependsOn: 'processJavaPreprocess') {
}
debug.doFirst(dependsOn: 'processSrcResources') {
}
debug.doFirst(dependsOn: 'compileAidlJavaClasses') {
}
debug.doFirst(dependsOn: 'processPreCompileReports') {
}
debug.doFirst(dependsOn: 'compile') {
}
debug.doFirst(dependsOn: 'processPostCompileReports') {
}
debubg.doFirst(dependsOn: 'processAssetsResources') {
}
debug.doFirst(dependsOn: 'processPackageResources') {
}
debug.doFirst(dependsOn: 'processDex'){
}
debug.doFirst(dependsOn: 'appReinstall')) {
}
} else {
}
/**
* Have to disallow individual task exuciton that is not from
* the debug, release, and :tests:mockSomething entry points
*
* we hack it by setting tasks to false and
* printing an error message
*/
if (taskGraph.hasTask(':clean')) {
clean.enabled = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskgraph.hasTask(':generateJavaClassesFromTemplates')) {
generateJavaClassesFromTemplates.enabled = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask(':processJavaPreprocess')) {
processJavaPreprocess.enabled = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('processSrcResources') {
processSrcResources.enabled = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('compileAidlJavaClasses') {
compileAidlJavaClasses.enabled = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('processPreCompileReports') {
processPreCompileReports.enabled = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('compile') {
compile.enabled = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('processPostCompileReports') {
processPostCompileReports.enable = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('processAssetsResources') {
processAssetsResources.enable = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('processPackageResources') {
processPackageResources.enable = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('processDex') {
processDex.enable = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('appReinstall') {
appReinstall.enable = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('appInstall') {
appInstall.enable = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
if (taskGraph.hasTask('obfuscate') {
obfuscate.enable = false
logging.info('sorry please use debug, release, or :tests:MockSomething')
} else {
}
Basically, the only entry points are debug, release, and mockSomething tasks. I kept the dependencies group in the order of execution thus the build is both readable and understandable and functional. Now it is add in the details of all tasks and start testing each task one by one. With the Gradle 0.8 project feature I was able to eliminate the need for a separate build script to be in the tests/src folder and remotely execute that script.
I should optimize my Life-cycle definition by using Goovy switch statements. Than switch to switch statements for the if-else blocks in my configurations block and I should be down to a compact 300 lines and with the other task details filled in about 800 lines. The ANT build script with the same feature set was turning out ot be 300 lines of mind-numbing not easy to read and understand mess.