JAL-3130 write clover.xml during cloverReport phase
[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         // and generate ${reportsDir}/clover/clover.xml
152         args = ["--initstring", "${buildDir}/clover/clover.db",
153                         "-o", "${reportsDir}/clover/clover.xml"].toArray()
154         com.atlassian.clover.reporters.xml.XMLReporter.runReport(args)
155     }
156 }
157
158 // end clover bits
159
160
161 compileJava {
162
163   doFirst {
164     if (JAVA_VERSION.equals("1.8")) {
165       sourceCompatibility = 1.8
166       targetCompatibility = 1.8
167     } else if (JAVA_VERSION.equals("11")) {
168       sourceCompatibility = 11
169       targetCompatibility = 11
170
171       options.compilerArgs = [
172         '--module-path', sourceSets.modules.compileClasspath.asPath,
173         '--add-modules', j11modules
174       ]
175     }
176     print ("Setting target compatibility to "+targetCompatibility+"\n")
177   }
178
179 }
180
181 compileTestJava {
182   dependsOn compileCloverJava
183   doFirst {
184     if (JAVA_VERSION.equals("1.8")) {
185       sourceCompatibility = 1.8
186       targetCompatibility = 1.8
187     } else if (JAVA_VERSION.equals("11")) {
188       sourceCompatibility = 11
189       targetCompatibility = 11
190
191       options.compilerArgs = [
192         '--module-path', sourceSets.modules.compileClasspath.asPath,
193         '--add-modules', j11modules
194       ]
195     }
196     print ("Setting target compatibility to "+targetCompatibility+"\n")
197   }
198   classpath += configurations.cloverRuntime
199 }
200
201
202 compileCloverJava {
203
204   doFirst {
205     if (JAVA_VERSION.equals("1.8")) {
206       sourceCompatibility = 1.8
207       targetCompatibility = 1.8
208     } else if (JAVA_VERSION.equals("11")) {
209       sourceCompatibility = 11
210       targetCompatibility = 11
211
212       options.compilerArgs += [
213         '--module-path', sourceSets.modules.compileClasspath.asPath,
214         '--add-modules', j11modules
215       ]
216     }
217     print ("Setting target compatibility to "+targetCompatibility+"\n")
218   }
219   classpath += configurations.cloverRuntime
220 }
221
222 clean {
223   delete sourceSets.main.java.outputDir
224 }
225
226 cleanTest {
227   delete sourceSets.test.java.outputDir
228   delete cloverInstrDir
229 }
230
231 def getDate(format) {
232   def date = new Date()
233   //return date.format("dd MMMM yyyy")
234   return date.format(format)
235 }
236
237 def getGitHash() {
238   def stdout = new ByteArrayOutputStream()
239   exec {
240     commandLine "git", "rev-parse", "--short", "HEAD"
241     standardOutput = stdout
242     workingDir = jalviewDir
243   }
244   return stdout.toString().trim()
245 }
246
247 def getGitBranch() {
248   def stdout = new ByteArrayOutputStream()
249   exec {
250     commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
251     standardOutput = stdout
252     workingDir = jalviewDir
253   }
254   return stdout.toString().trim()
255 }
256
257 task createBuildProperties(type: WriteProperties) {
258   inputs.dir("$jalviewDir/$sourceDir")
259   inputs.dir("$jalviewDir/$resourceDir")
260   outputFile "$jalviewDir/$classesDir/$buildPropertiesFile"
261   /* taking time/date specific comment out to allow better incremental builds */
262   //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
263   comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
264   property "BUILD_DATE", getDate("dd MMMM yyyy")
265   property "VERSION", JALVIEW_VERSION
266   property "INSTALLATION", INSTALLATION+" git-commit:"+getGitHash()+" ["+getGitBranch()+"]"
267   outputs.file(outputFile)
268   outputs.dir("$jalviewDir/$classesDir")
269 }
270
271 task syncDocs(type: Sync) {
272   def syncDir = "$jalviewDir/$classesDir/$docDir"
273   from fileTree("$jalviewDir/$docDir")
274   into syncDir
275
276 }
277
278 def helpFile = "$jalviewDir/$classesDir/$helpDir/help.jhm"
279 task syncHelp(type: Sync) {
280   inputs.files("$jalviewDir/$helpDir")
281   outputs.files(helpFile)
282
283   def syncDir = "$jalviewDir/$classesDir/$helpDir"
284   from fileTree("$jalviewDir/$helpDir")
285   into syncDir
286 }
287
288 task copyHelp(type: Copy) {
289   def inputDir = "$jalviewDir/$helpDir"
290   def outputDir = "$jalviewDir/$classesDir/$helpDir"
291   from inputDir
292   into outputDir
293   filter(ReplaceTokens, beginToken: '$$', endToken: '$$', tokens: ['Version-Rel': "USING_FILTER"])
294   inputs.dir(inputDir)
295   outputs.files(helpFile)
296   outputs.dir(outputDir)
297 }
298
299 task syncLib(type: Sync) {
300   def syncDir = "$jalviewDir/$classesDir/$libDir"
301   from fileTree("$jalviewDir/$libDir")
302   into syncDir
303 }
304
305 task syncResources(type: Sync) {
306   from "$jalviewDir/$resourceDir"
307   include "**/*.*"
308   exclude "install4j"
309   into "$jalviewDir/$classesDir"
310   preserve {
311     include "**"
312   }
313 }
314
315 task prepare {
316   dependsOn syncResources
317   dependsOn syncDocs
318   dependsOn copyHelp
319 }
320
321
322 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
323 test {
324   dependsOn prepare
325   
326   
327   useTestNG() {
328     includeGroups testngGroups
329     preserveOrder true
330     useDefaultListeners=true
331   }
332   
333   workingDir = jalviewDir
334   //systemProperties 'clover.jar' System.properties.clover.jar
335   if (JAVA_VERSION.equals("1.8")) {
336     sourceCompatibility = 1.8
337     targetCompatibility = 1.8
338   } else if (JAVA_VERSION.equals("11")) {
339     sourceCompatibility = 11
340     targetCompatibility = 11
341
342     jvmArgs += [
343       '--module-path',
344       sourceSets.modules.compileClasspath.asPath,
345       '--add-modules',
346       j11modules
347     ]
348   }
349   print ("Setting target compatibility to "+targetCompatibility+"\n")
350 }
351
352 task buildIndices(type: JavaExec) {
353   dependsOn copyHelp
354   classpath = sourceSets.main.compileClasspath
355   main = "com.sun.java.help.search.Indexer"
356   workingDir = "$jalviewDir/$classesDir/$helpDir"
357   def argDir = "html"
358   args = [ argDir ]
359   inputs.dir("$workingDir/$argDir")
360
361   outputs.dir("$jalviewDir/$classesDir/doc")
362   outputs.dir("$jalviewDir/$classesDir/help")
363   outputs.file("$workingDir/JavaHelpSearch/DOCS")
364   outputs.file("$workingDir/JavaHelpSearch/DOCS.TAB")
365   outputs.file("$workingDir/JavaHelpSearch/OFFSETS")
366   outputs.file("$workingDir/JavaHelpSearch/POSITIONS")
367   outputs.file("$workingDir/JavaHelpSearch/SCHEMA")
368   outputs.file("$workingDir/JavaHelpSearch/TMAP")
369 }
370
371 task compileLinkCheck(type: JavaCompile) {
372   options.fork = true
373   classpath = files("$jalviewDir/$utilsDir")
374   destinationDir = file("$jalviewDir/$utilsDir")
375   source = fileTree(dir: "$jalviewDir/$utilsDir", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
376
377   outputs.file("$jalviewDir/$utilsDir/HelpLinksChecker.class")
378   outputs.file("$jalviewDir/$utilsDir/BufferedLineReader.class")
379 }
380
381 task linkCheck(type: JavaExec) {
382   dependsOn prepare, compileLinkCheck
383   classpath = files("$jalviewDir/$utilsDir")
384   main = "HelpLinksChecker"
385   workingDir = "$jalviewDir"
386   args = [ "$classesDir/$helpDir", "-nointernet" ]
387
388   doFirst {
389     standardOutput new FileOutputStream("$jalviewDir/$utilsDir/HelpLinksChecker.out")
390   }
391
392   outputs.file("$jalviewDir/$utilsDir/HelpLinksChecker.out")
393 }
394
395 task cleanPackageDir(type: Delete) {
396   delete fileTree("$jalviewDir/$packageDir").include("*.jar")
397 }
398
399 jar {
400   dependsOn linkCheck
401   dependsOn buildIndices
402   dependsOn createBuildProperties
403
404   manifest {
405     attributes "Main-Class": mainClass,
406     "Permissions": "all-permissions",
407     "Application-Name": "Jalview Desktop",
408     "Codebase": application_codebase
409   }
410
411   destinationDir = file("$jalviewDir/$packageDir")
412   archiveName = rootProject.name+".jar"
413
414   exclude "cache*/**"
415   exclude "*.jar"
416   exclude "*.jar.*"
417   exclude "**/*.jar"
418   exclude "**/*.jar.*"
419
420   inputs.dir("$jalviewDir/$classesDir")
421   outputs.file("$jalviewDir/$packageDir/$archiveName")
422 }
423
424 task copyJars(type: Copy) {
425   from fileTree("$jalviewDir/$classesDir").include("**/*.jar").include("*.jar").files
426   into "$jalviewDir/$packageDir"
427 }
428
429 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
430 task syncJars(type: Sync) {
431   from fileTree("$jalviewDir/$libDir").include("**/*.jar").include("*.jar").files
432   into "$jalviewDir/$packageDir"
433   preserve {
434     include jar.archiveName
435   }
436 }
437
438 task makeDist {
439   // order of "cleanPackageDir", "copyJars", "jar" important!
440   jar.mustRunAfter cleanPackageDir
441   syncJars.mustRunAfter cleanPackageDir
442   dependsOn cleanPackageDir
443   dependsOn syncJars
444   dependsOn jar
445   outputs.dir("$jalviewDir/$packageDir")
446 }
447
448 task cleanDist {
449   dependsOn cleanPackageDir
450   dependsOn cleanTest
451   dependsOn clean
452 }
453
454 shadowJar {
455   dependsOn makeDist
456   if (JAVA_VERSION.equals("11")) {
457     from ("$jalviewDir/$j11libDir") {
458       include("*.jar")
459     }
460   }
461   mainClassName = shadowJarMainClass
462   mergeServiceFiles()
463   classifier = "all"
464   minimize()
465 }
466
467 ext {
468   getdownWebsiteDir = jalviewDir + '/' + getdown_website_dir
469   getdownAppDir = getdownWebsiteDir + '/' + getdown_app_dir
470   getdownJ11libDir = getdownWebsiteDir + '/' + getdown_j11lib_dir
471   getdownResourceDir = getdownWebsiteDir + '/' + getdown_resource_dir
472   getdownLauncher = jalviewDir + '/' + getdown_launcher
473   getdownFilesDir = jalviewDir + '/' + getdown_files_dir
474 }
475
476 task getdownWebsite() {
477   dependsOn makeDist
478   def getdownWebsiteResourceFilenames = []
479   def getdownTextString = ""
480   def getdownResourceDir = project.ext.getdownResourceDir
481   def getdownAppDir = project.ext.getdownAppDir
482   def getdownResourceFilenames = []
483   doFirst {
484     // go through properties looking for getdown_txt_...
485     def props = project.properties.sort { it.key }
486     if (JAVA_VERSION.equals("11")) {
487       props.put("getdown_txt_java_min_version", getdown_alt_java11_min_version)
488     } else {
489       props.put("getdown_txt_java_min_version", getdown_alt_java8_min_version)
490     }
491     props.each{ prop, val ->
492       if (prop.startsWith("getdown_txt_") && val != null) {
493         if (prop.startsWith("getdown_txt_multi_")) {
494           def key = prop.substring(18)
495           val.split(",").each{ v ->
496             def line = key + " = " + v + "\n"
497             getdownTextString += line
498           }
499         } else {
500           // file values rationalised
501           if (val.indexOf('/') > -1) {
502             def r = null
503             if (val.indexOf('/') == 0) {
504               // absolute path
505               r = file(val)
506             } else if (val.indexOf('/') > 0) {
507               // relative path (relative to jalviewDir)
508               r = file( jalviewDir + '/' + val )
509             }
510             if (r.exists()) {
511               val = getdown_resource_dir + '/' + r.getName()
512               getdownWebsiteResourceFilenames += val
513               getdownResourceFilenames += r.getPath()
514             }
515           }
516           def line = prop.substring(12) + " = " + val + "\n"
517           getdownTextString += line
518         }
519       }
520     }
521
522     getdownWebsiteResourceFilenames.each{ filename ->
523       getdownTextString += "resource = "+filename+"\n"
524     }
525     getdownResourceFilenames.each{ filename ->
526       copy {
527         from filename
528         into project.ext.getdownResourceDir
529       }
530     }
531
532     def codeFiles = []
533     makeDist.outputs.files.each{ f ->
534       if (f.isDirectory()) {
535         def files = fileTree(dir: f, include: ["*"]).getFiles()
536         codeFiles += files
537       } else if (f.exists()) {
538         codeFiles += f
539       }
540     }
541     codeFiles.sort().each{f ->
542       def line = "code = " + getdown_app_dir + '/' + f.getName() + "\n"
543       getdownTextString += line
544       copy {
545         from f.getPath()
546         into project.ext.getdownAppDir
547       }
548     }
549
550     if (JAVA_VERSION.equals("11")) {
551       def j11libFiles = fileTree(dir: "$jalviewDir/$j11libDir", include: ["*.jar"]).getFiles()
552       j11libFiles.sort().each{f ->
553         def line = "code = " + getdown_j11lib_dir + '/' + f.getName() + "\n"
554         getdownTextString += line
555         copy {
556           from f.getPath()
557           into project.ext.getdownJ11libDir
558         }
559       }
560     }
561
562     getdownTextString += "code = " + file(getdownLauncher).getName() + "\n"
563     getdownTextString += "class = " + mainClass + "\n"
564
565     def getdown_txt = file(project.ext.getdownWebsiteDir + "/getdown.txt")
566     getdown_txt.write(getdownTextString)
567
568     copy {
569       from getdown_txt
570       into project.ext.getdownFilesDir
571     }
572
573     copy {
574       from getdownLauncher
575       into project.ext.getdownWebsiteDir
576     }
577
578     copy {
579       from getdownLauncher
580       into project.ext.getdownFilesDir
581     }
582
583     copy {
584       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.background_image')
585       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.error_background')
586       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.progress_image')
587       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.icon')
588       from jalviewDir + '/' + project.getProperty('getdown_txt_ui.mac_dock_icon')
589       into project.ext.getdownFilesDir + '/' + getdown_resource_dir 
590     }
591   }
592
593   inputs.dir(jalviewDir + '/' + packageDir)
594   outputs.dir(project.ext.getdownWebsiteDir)
595   outputs.dir(project.ext.getdownFilesDir)
596 }
597
598 task getdownDigest(type: JavaExec) {
599   dependsOn getdownWebsite
600   classpath = files(jalviewDir + '/' + getdown_core)
601   main = "com.threerings.getdown.tools.Digester"
602   args project.ext.getdownWebsiteDir
603   outputs.file(project.ext.getdownWebsiteDir + '/' + "digest2.txt")
604 }
605
606 task getdown() {
607   dependsOn getdownDigest
608 }
609
610 clean {
611   delete project.ext.getdownWebsiteDir
612   delete project.ext.getdownFilesDir
613 }
614
615 install4j {
616   def install4jHomeDir = "/opt/install4j"
617   def hostname = "hostname".execute().text.trim()
618   if (hostname.equals("jv-bamboo")) {
619     install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
620   } else if (OperatingSystem.current().isMacOsX()) {
621     install4jHomeDir = '/Applications/install4j.app/Contents/Resources/app'
622     if (! file(install4jHomeDir).exists()) {
623       install4jHomeDir = System.getProperty("user.home")+install4jHomeDir
624     }
625   } else if (OperatingSystem.current().isLinux()) {
626     install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
627   }
628   installDir = file(install4jHomeDir)
629 }
630
631 task installers(type: com.install4j.gradle.Install4jTask) {
632   dependsOn getdown
633   projectFile = "$jalviewDir/$install4jResourceDir/$install4jConf"
634   variables = [majorVersion: version.substring(2, 11), build: 001]
635   destination = "$jalviewDir/$install4jBuildDir"
636   buildSelected = true
637   inputs.dir(project.ext.getdownWebsiteDir)
638   outputs.dir("$jalviewDir/$install4jBuildDir")
639 }
640