JAL-3130 make sure testng-results.xml is generated
[jalview.git] / build.gradle
1 import org.apache.tools.ant.filters.ReplaceTokens
2 import org.gradle.internal.os.OperatingSystem
3
4
5 buildscript {
6   dependencies {
7         classpath 'org.openclover:clover:4.3.1'
8   }
9 }
10
11 plugins {
12   id 'java'
13   id 'application'
14   id 'com.github.johnrengelman.shadow' version '4.0.3'
15   id 'com.install4j.gradle' version '7.0.9'
16 }
17
18 repositories {
19   jcenter()
20   mavenCentral()
21   mavenLocal()
22   flatDir {
23     dirs gradlePluginsDir
24   }
25 }
26
27 mainClassName = launcherClass
28 def cloverInstrDir = file("$buildDir/sources-instr")
29
30 sourceSets {
31
32   main {
33     java {
34       srcDirs "$jalviewDir/$sourceDir"
35       outputDir = file("$jalviewDir/$classesDir")
36     }
37
38     resources {
39       srcDirs "$jalviewDir/$resourceDir"
40       srcDirs "$jalviewDir/$libDir"
41     }
42
43     jar.destinationDir = file("$jalviewDir/$packageDir")
44
45     compileClasspath = files(sourceSets.main.java.outputDir)
46     compileClasspath += fileTree(dir: "$jalviewDir/$libDir", include: ["*.jar"])
47     if (JAVA_VERSION.equals("1.8")) {
48       print("ADDING J11LIBS TO CLASSPATH")
49       compileClasspath += fileTree(dir: "$jalviewDir/$j11libDir", include: ["*.jar"])
50     }
51
52     runtimeClasspath = compileClasspath
53   }
54
55   modules {
56     compileClasspath = fileTree(dir: "$jalviewDir/$j11libDir", include: ["*.jar"])
57
58     runtimeClasspath = compileClasspath
59   }
60   
61   clover {
62     java {
63         srcDirs = [ cloverInstrDir ]
64         outputDir = file("${buildDir}/clover-classes")
65     }
66     
67     resources {
68       srcDirs = sourceSets.main.resources.srcDirs
69     }
70     compileClasspath = configurations.cloverRuntime + files( sourceSets.clover.java.outputDir )
71     compileClasspath += fileTree(dir: "$jalviewDir/$utilsDir", include: ["**/*.jar"])
72     compileClasspath += fileTree(dir: "$jalviewDir/$libDir", include: ["*.jar"])
73     if (JAVA_VERSION.equals("1.8")) {
74       print("ADDING J11LIBS TO CLASSPATH")
75       compileClasspath += fileTree(dir: "$jalviewDir/$j11libDir", include: ["*.jar"])
76     }
77
78     runtimeClasspath = compileClasspath
79   }
80   
81   test {
82     java {
83       srcDirs "$jalviewDir/$testSourceDir"
84       outputDir = file("$jalviewDir/$testOutputDir")
85     }
86
87     resources {
88       srcDirs = sourceSets.main.resources.srcDirs
89     }
90
91
92     compileClasspath = configurations.cloverRuntime 
93     compileClasspath += files( sourceSets.test.java.outputDir ) 
94     compileClasspath += files( sourceSets.clover.java.outputDir )
95     compileClasspath += files( sourceSets.main.resources.srcDirs)
96     compileClasspath += fileTree(dir: "$jalviewDir/$utilsDir", include: ["**/*.jar"])
97     compileClasspath += fileTree(dir: "$jalviewDir/$libDir", include: ["*.jar"])
98     if (JAVA_VERSION.equals("1.8")) {
99       print("ADDING J11LIBS TO CLASSPATH")
100       compileClasspath += fileTree(dir: "$jalviewDir/$j11libDir", include: ["*.jar"])
101     }
102
103     runtimeClasspath = compileClasspath
104   }
105 }
106
107 // clover bits
108 dependencies {
109   cloverCompile 'org.openclover:clover:4.3.1'
110   testCompile 'org.openclover:clover:4.3.1'
111 }
112
113 configurations {
114     cloverRuntime
115     cloverRuntime.extendsFrom cloverCompile
116 }
117  
118 task cloverInstr() {
119   // only instrument source, we build test classes as normal
120     inputs.files files (sourceSets.main.allJava) // , fileTree(dir:"$jalviewDir/$testSourceDir", include: ["**/*.java"]))
121     outputs.dir cloverInstrDir
122
123     doFirst {
124         delete cloverInstrDir
125         def argsList = ["--initstring", "${buildDir}/clover/clover.db",
126                         "-d", "${buildDir}/sources-instr"]
127         argsList.addAll(inputs.files.files.collect({ file ->
128             file.absolutePath
129         }))
130         String[] args = argsList.toArray()
131         println("About to instrument "+args.length +" files")
132         com.atlassian.clover.CloverInstr.mainImpl(args)
133     }
134 }
135
136 test.dependsOn cloverInstr
137
138  
139 task cloverReport {
140     inputs.dir "${buildDir}/clover"
141     outputs.dir "${reportsDir}/clover"
142     onlyIf {
143         file("${buildDir}/clover/clover.db").exists()
144     }
145     doFirst {
146         def argsList = ["--initstring", "${buildDir}/clover/clover.db",
147                         "-o", "${reportsDir}/clover"]
148         String[] args = argsList.toArray()
149         com.atlassian.clover.reporters.html.HtmlReporter.runReport(args)
150     }
151 }
152
153 // end clover bits
154
155
156 compileJava {
157
158   doFirst {
159     if (JAVA_VERSION.equals("1.8")) {
160       sourceCompatibility = 1.8
161       targetCompatibility = 1.8
162     } else if (JAVA_VERSION.equals("11")) {
163       sourceCompatibility = 11
164       targetCompatibility = 11
165
166       options.compilerArgs = [
167         '--module-path', sourceSets.modules.compileClasspath.asPath,
168         '--add-modules', j11modules
169       ]
170     }
171     print ("Setting target compatibility to "+targetCompatibility+"\n")
172   }
173
174 }
175
176 compileTestJava {
177   dependsOn compileCloverJava
178   doFirst {
179     if (JAVA_VERSION.equals("1.8")) {
180       sourceCompatibility = 1.8
181       targetCompatibility = 1.8
182     } else if (JAVA_VERSION.equals("11")) {
183       sourceCompatibility = 11
184       targetCompatibility = 11
185
186       options.compilerArgs = [
187         '--module-path', sourceSets.modules.compileClasspath.asPath,
188         '--add-modules', j11modules
189       ]
190     }
191     print ("Setting target compatibility to "+targetCompatibility+"\n")
192   }
193   classpath += configurations.cloverRuntime
194 }
195
196
197 compileCloverJava {
198
199   doFirst {
200     if (JAVA_VERSION.equals("1.8")) {
201       sourceCompatibility = 1.8
202       targetCompatibility = 1.8
203     } else if (JAVA_VERSION.equals("11")) {
204       sourceCompatibility = 11
205       targetCompatibility = 11
206
207       options.compilerArgs += [
208         '--module-path', sourceSets.modules.compileClasspath.asPath,
209         '--add-modules', j11modules
210       ]
211     }
212     print ("Setting target compatibility to "+targetCompatibility+"\n")
213   }
214   classpath += configurations.cloverRuntime
215 }
216
217 clean {
218   delete sourceSets.main.java.outputDir
219 }
220
221 cleanTest {
222   delete sourceSets.test.java.outputDir
223   delete cloverInstrDir
224 }
225
226 def getDate(format) {
227   def date = new Date()
228   //return date.format("dd MMMM yyyy")
229   return date.format(format)
230 }
231
232 def getGitHash() {
233   def stdout = new ByteArrayOutputStream()
234   exec {
235     commandLine "git", "rev-parse", "--short", "HEAD"
236     standardOutput = stdout
237     workingDir = jalviewDir
238   }
239   return stdout.toString().trim()
240 }
241
242 def getGitBranch() {
243   def stdout = new ByteArrayOutputStream()
244   exec {
245     commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
246     standardOutput = stdout
247     workingDir = jalviewDir
248   }
249   return stdout.toString().trim()
250 }
251
252 task createBuildProperties(type: WriteProperties) {
253   inputs.dir("$jalviewDir/$sourceDir")
254   inputs.dir("$jalviewDir/$resourceDir")
255   outputFile "$jalviewDir/$classesDir/$buildPropertiesFile"
256   /* taking time/date specific comment out to allow better incremental builds */
257   //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
258   comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
259   property "BUILD_DATE", getDate("dd MMMM yyyy")
260   property "VERSION", JALVIEW_VERSION
261   property "INSTALLATION", INSTALLATION+" git-commit:"+getGitHash()+" ["+getGitBranch()+"]"
262   outputs.file(outputFile)
263   outputs.dir("$jalviewDir/$classesDir")
264 }
265
266 task syncDocs(type: Sync) {
267   def syncDir = "$jalviewDir/$classesDir/$docDir"
268   from fileTree("$jalviewDir/$docDir")
269   into syncDir
270
271 }
272
273 def helpFile = "$jalviewDir/$classesDir/$helpDir/help.jhm"
274 task syncHelp(type: Sync) {
275   inputs.files("$jalviewDir/$helpDir")
276   outputs.files(helpFile)
277
278   def syncDir = "$jalviewDir/$classesDir/$helpDir"
279   from fileTree("$jalviewDir/$helpDir")
280   into syncDir
281 }
282
283 task copyHelp(type: Copy) {
284   def inputDir = "$jalviewDir/$helpDir"
285   def outputDir = "$jalviewDir/$classesDir/$helpDir"
286   from inputDir
287   into outputDir
288   filter(ReplaceTokens, beginToken: '$$', endToken: '$$', tokens: ['Version-Rel': "USING_FILTER"])
289   inputs.dir(inputDir)
290   outputs.files(helpFile)
291   outputs.dir(outputDir)
292 }
293
294 task syncLib(type: Sync) {
295   def syncDir = "$jalviewDir/$classesDir/$libDir"
296   from fileTree("$jalviewDir/$libDir")
297   into syncDir
298 }
299
300 task syncResources(type: Sync) {
301   from "$jalviewDir/$resourceDir"
302   include "**/*.*"
303   exclude "install4j"
304   into "$jalviewDir/$classesDir"
305   preserve {
306     include "**"
307   }
308 }
309
310 task prepare {
311   dependsOn syncResources
312   dependsOn syncDocs
313   dependsOn copyHelp
314 }
315
316
317 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
318 test {
319   dependsOn prepare
320   
321   
322   useTestNG() {
323     includeGroups testngGroups
324     preserveOrder true
325     useDefaultListeners=true
326   }
327   
328   workingDir = jalviewDir
329   //systemProperties 'clover.jar' System.properties.clover.jar
330   if (JAVA_VERSION.equals("1.8")) {
331     sourceCompatibility = 1.8
332     targetCompatibility = 1.8
333   } else if (JAVA_VERSION.equals("11")) {
334     sourceCompatibility = 11
335     targetCompatibility = 11
336
337     jvmArgs += [
338       '--module-path',
339       sourceSets.modules.compileClasspath.asPath,
340       '--add-modules',
341       j11modules
342     ]
343   }
344   print ("Setting target compatibility to "+targetCompatibility+"\n")
345 }
346
347 task buildIndices(type: JavaExec) {
348   dependsOn copyHelp
349   classpath = sourceSets.main.compileClasspath
350   main = "com.sun.java.help.search.Indexer"
351   workingDir = "$jalviewDir/$classesDir/$helpDir"
352   def argDir = "html"
353   args = [ argDir ]
354   inputs.dir("$workingDir/$argDir")
355
356   outputs.dir("$jalviewDir/$classesDir/doc")
357   outputs.dir("$jalviewDir/$classesDir/help")
358   outputs.file("$workingDir/JavaHelpSearch/DOCS")
359   outputs.file("$workingDir/JavaHelpSearch/DOCS.TAB")
360   outputs.file("$workingDir/JavaHelpSearch/OFFSETS")
361   outputs.file("$workingDir/JavaHelpSearch/POSITIONS")
362   outputs.file("$workingDir/JavaHelpSearch/SCHEMA")
363   outputs.file("$workingDir/JavaHelpSearch/TMAP")
364 }
365
366 task compileLinkCheck(type: JavaCompile) {
367   options.fork = true
368   classpath = files("$jalviewDir/$utilsDir")
369   destinationDir = file("$jalviewDir/$utilsDir")
370   source = fileTree(dir: "$jalviewDir/$utilsDir", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
371
372   outputs.file("$jalviewDir/$utilsDir/HelpLinksChecker.class")
373   outputs.file("$jalviewDir/$utilsDir/BufferedLineReader.class")
374 }
375
376 task linkCheck(type: JavaExec) {
377   dependsOn prepare, compileLinkCheck
378   classpath = files("$jalviewDir/$utilsDir")
379   main = "HelpLinksChecker"
380   workingDir = "$jalviewDir"
381   args = [ "$classesDir/$helpDir", "-nointernet" ]
382
383   doFirst {
384     standardOutput new FileOutputStream("$jalviewDir/$utilsDir/HelpLinksChecker.out")
385   }
386
387   outputs.file("$jalviewDir/$utilsDir/HelpLinksChecker.out")
388 }
389
390 task cleanPackageDir(type: Delete) {
391   delete fileTree("$jalviewDir/$packageDir").include("*.jar")
392 }
393
394 jar {
395   dependsOn linkCheck
396   dependsOn buildIndices
397   dependsOn createBuildProperties
398
399   manifest {
400     attributes "Main-Class": mainClass,
401     "Permissions": "all-permissions",
402     "Application-Name": "Jalview Desktop",
403     "Codebase": application_codebase
404   }
405
406   destinationDir = file("$jalviewDir/$packageDir")
407   archiveName = rootProject.name+".jar"
408
409   exclude "cache*/**"
410   exclude "*.jar"
411   exclude "*.jar.*"
412   exclude "**/*.jar"
413   exclude "**/*.jar.*"
414
415   inputs.dir("$jalviewDir/$classesDir")
416   outputs.file("$jalviewDir/$packageDir/$archiveName")
417 }
418
419 task copyJars(type: Copy) {
420   from fileTree("$jalviewDir/$classesDir").include("**/*.jar").include("*.jar").files
421   into "$jalviewDir/$packageDir"
422 }
423
424 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
425 task syncJars(type: Sync) {
426   from fileTree("$jalviewDir/$libDir").include("**/*.jar").include("*.jar").files
427   into "$jalviewDir/$packageDir"
428   preserve {
429     include jar.archiveName
430   }
431 }
432
433 task makeDist {
434   // order of "cleanPackageDir", "copyJars", "jar" important!
435   jar.mustRunAfter cleanPackageDir
436   syncJars.mustRunAfter cleanPackageDir
437   dependsOn cleanPackageDir
438   dependsOn syncJars
439   dependsOn jar
440   outputs.dir("$jalviewDir/$packageDir")
441 }
442
443 task cleanDist {
444   dependsOn cleanPackageDir
445   dependsOn cleanTest
446   dependsOn clean
447 }
448
449 shadowJar {
450   dependsOn makeDist
451   if (JAVA_VERSION.equals("11")) {
452     from ("$jalviewDir/$j11libDir") {
453       include("*.jar")
454     }
455   }
456   mainClassName = shadowJarMainClass
457   mergeServiceFiles()
458   classifier = "all"
459   minimize()
460 }
461
462 ext {
463   getdownWebsiteDir = jalviewDir + '/' + getdown_website_dir
464   getdownAppDir = getdownWebsiteDir + '/' + getdown_app_dir
465   getdownJ11libDir = getdownWebsiteDir + '/' + getdown_j11lib_dir
466   getdownResourceDir = getdownWebsiteDir + '/' + getdown_resource_dir
467   getdownLauncher = jalviewDir + '/' + getdown_launcher
468   getdownFilesDir = jalviewDir + '/' + getdown_files_dir
469 }
470
471 task getdownWebsite() {
472   dependsOn makeDist
473   def getdownWebsiteResourceFilenames = []
474   def getdownTextString = ""
475   def getdownResourceDir = project.ext.getdownResourceDir
476   def getdownAppDir = project.ext.getdownAppDir
477   def getdownResourceFilenames = []
478   doFirst {
479     // go through properties looking for getdown_txt_...
480     def props = project.properties.sort { it.key }
481     if (JAVA_VERSION.equals("11")) {
482       props.put("getdown_txt_java_min_version", getdown_alt_java11_min_version)
483     } else {
484       props.put("getdown_txt_java_min_version", getdown_alt_java8_min_version)
485     }
486     props.each{ prop, val ->
487       if (prop.startsWith("getdown_txt_") && val != null) {
488         if (prop.startsWith("getdown_txt_multi_")) {
489           def key = prop.substring(18)
490           val.split(",").each{ v ->
491             def line = key + " = " + v + "\n"
492             getdownTextString += line
493           }
494         } else {
495           // file values rationalised
496           if (val.indexOf('/') > -1) {
497             def r = null
498             if (val.indexOf('/') == 0) {
499               // absolute path
500               r = file(val)
501             } else if (val.indexOf('/') > 0) {
502               // relative path (relative to jalviewDir)
503               r = file( jalviewDir + '/' + val )
504             }
505             if (r.exists()) {
506               val = getdown_resource_dir + '/' + r.getName()
507               getdownWebsiteResourceFilenames += val
508               getdownResourceFilenames += r.getPath()
509             }
510           }
511           def line = prop.substring(12) + " = " + val + "\n"
512           getdownTextString += line
513         }
514       }
515     }
516
517     getdownWebsiteResourceFilenames.each{ filename ->
518       getdownTextString += "resource = "+filename+"\n"
519     }
520     getdownResourceFilenames.each{ filename ->
521       copy {
522         from filename
523         into project.ext.getdownResourceDir
524       }
525     }
526
527     def codeFiles = []
528     makeDist.outputs.files.each{ f ->
529       if (f.isDirectory()) {
530         def files = fileTree(dir: f, include: ["*"]).getFiles()
531         codeFiles += files
532       } else if (f.exists()) {
533         codeFiles += f
534       }
535     }
536     codeFiles.sort().each{f ->
537       def line = "code = " + getdown_app_dir + '/' + f.getName() + "\n"
538       getdownTextString += line
539       copy {
540         from f.getPath()
541         into project.ext.getdownAppDir
542       }
543     }
544
545     if (JAVA_VERSION.equals("11")) {
546       def j11libFiles = fileTree(dir: "$jalviewDir/$j11libDir", include: ["*.jar"]).getFiles()
547       j11libFiles.sort().each{f ->
548         def line = "code = " + getdown_j11lib_dir + '/' + f.getName() + "\n"
549         getdownTextString += line
550         copy {
551           from f.getPath()
552           into project.ext.getdownJ11libDir
553         }
554       }
555     }
556
557     getdownTextString += "code = " + file(getdownLauncher).getName() + "\n"
558     getdownTextString += "class = " + mainClass + "\n"
559
560     def getdown_txt = file(project.ext.getdownWebsiteDir + "/getdown.txt")
561     getdown_txt.write(getdownTextString)
562
563     copy {
564       from getdown_txt
565       into project.ext.getdownFilesDir
566     }
567
568     copy {
569       from getdownLauncher
570       into project.ext.getdownWebsiteDir
571     }
572
573     copy {
574       from getdownLauncher
575       into project.ext.getdownFilesDir
576     }
577
578     copy {
579       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.background_image')
580       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.error_background')
581       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.progress_image')
582       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.icon')
583       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.mac_dock_icon')
584       into project.ext.getdownFilesDir + '/' + getdown_resource_dir 
585     }
586   }
587
588   inputs.dir(jalviewDir + '/' + packageDir)
589   outputs.dir(project.ext.getdownWebsiteDir)
590   outputs.dir(project.ext.getdownFilesDir)
591 }
592
593 task getdownDigest(type: JavaExec) {
594   dependsOn getdownWebsite
595   classpath = files(jalviewDir + '/' + getdown_core)
596   main = "com.threerings.getdown.tools.Digester"
597   args project.ext.getdownWebsiteDir
598   outputs.file(project.ext.getdownWebsiteDir + '/' + "digest2.txt")
599 }
600
601 task getdown() {
602   dependsOn getdownDigest
603 }
604
605 clean {
606   delete project.ext.getdownWebsiteDir
607   delete project.ext.getdownFilesDir
608 }
609
610 install4j {
611   def install4jHomeDir = "/opt/install4j"
612   def hostname = "hostname".execute().text.trim()
613   if (hostname.equals("jv-bamboo")) {
614     install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
615   } else if (OperatingSystem.current().isMacOsX()) {
616     install4jHomeDir = '/Applications/install4j.app/Contents/Resources/app'
617     if (! file(install4jHomeDir).exists()) {
618       install4jHomeDir = System.getProperty("user.home")+install4jHomeDir
619     }
620   } else if (OperatingSystem.current().isLinux()) {
621     install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
622   }
623   installDir = file(install4jHomeDir)
624 }
625
626 task installers(type: com.install4j.gradle.Install4jTask) {
627   dependsOn getdown
628   projectFile = "$jalviewDir/$install4jResourceDir/$install4jConf"
629   variables = [majorVersion: version.substring(2, 11), build: 001]
630   destination = "$jalviewDir/$install4jBuildDir"
631   buildSelected = true
632   inputs.dir(project.ext.getdownWebsiteDir)
633   outputs.dir("$jalviewDir/$install4jBuildDir")
634 }
635