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