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