JAL-3449 Now parsing install4j XML file to edit values. Should be safer
[jalview.git] / build.gradle
1 import org.apache.tools.ant.filters.ReplaceTokens
2 import org.gradle.internal.os.OperatingSystem
3 import org.gradle.plugins.ide.eclipse.model.Output
4 import org.gradle.plugins.ide.eclipse.model.Library
5 import java.security.MessageDigest
6 import groovy.transform.ExternalizeMethods
7 import groovy.util.XmlParser
8 import groovy.xml.XmlUtil
9
10 buildscript {
11   dependencies {
12     classpath 'org.openclover:clover:4.3.1'
13   }
14 }
15
16 plugins {
17   id 'java'
18   id 'application'
19   id 'eclipse'
20   id 'com.github.johnrengelman.shadow' version '4.0.3'
21   id 'com.install4j.gradle' version '8.0.2'
22   id 'com.dorongold.task-tree' version '1.4' // only needed to display task dependency tree with  gradle task1 [task2 ...] taskTree
23 }
24
25 repositories {
26   jcenter()
27   mavenCentral()
28   mavenLocal()
29   flatDir {
30     dirs gradlePluginsDir
31   }
32 }
33
34 dependencies {
35   compile 'org.apache.commons:commons-compress:1.18'
36 }
37
38
39 // in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use
40 def string(Object o) {
41   return o.toString()
42 }
43
44
45 ext {
46   jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
47   jalviewDirRelativePath = jalviewDir
48
49   // local build environment properties
50   def localProps = "${jalviewDirAbsolutePath}/local.properties"
51   if (file(localProps).exists()) {
52     try {
53       def p = new Properties()
54       def localPropsFIS = new FileInputStream(localProps)
55       p.load(localPropsFIS)
56       localPropsFIS.close()
57       p.each {
58         key, val -> 
59           def over = getProperty(key) != null
60           setProperty(key, val)
61           if (over) {
62             println("Overriding property '${key}' with local.properties value '${val}'")
63           }
64       }
65     } catch (Exception e) {
66       System.out.println("Exception reading local.properties")
67     }
68   }
69
70   // this property set when running Eclipse headlessly
71   j2sHeadlessBuildProperty = string("net.sf.j2s.core.headlessbuild")
72   // this property set by Eclipse
73   eclipseApplicationProperty = string("eclipse.application")
74   // CHECK IF RUNNING FROM WITHIN ECLIPSE
75   def eclipseApplicationPropertyVal = System.properties[eclipseApplicationProperty]
76   IN_ECLIPSE = eclipseApplicationPropertyVal != null && eclipseApplicationPropertyVal.startsWith("org.eclipse.ui.")
77   // BUT WITHOUT THE HEADLESS BUILD PROPERTY SET
78   if (System.properties[j2sHeadlessBuildProperty].equals("true")) {
79     println("Setting IN_ECLIPSE to ${IN_ECLIPSE} as System.properties['${j2sHeadlessBuildProperty}'] == '${System.properties[j2sHeadlessBuildProperty]}'")
80     IN_ECLIPSE = false
81   }
82   if (IN_ECLIPSE) {
83     println("WITHIN ECLIPSE IDE")
84   } else {
85     println("HEADLESS BUILD")
86   }
87   /* *-/
88   System.properties.sort { it.key }.each {
89     key, val -> println("SYSTEM PROPERTY ${key}='${val}'")
90   }
91   /-* *-/
92   if (false && IN_ECLIPSE) {
93     jalviewDir = jalviewDirAbsolutePath
94   }
95   */
96
97   // essentials
98   bareSourceDir = string(source_dir)
99   sourceDir = string("${jalviewDir}/${bareSourceDir}")
100   resourceDir = string("${jalviewDir}/${resource_dir}")
101   bareTestSourceDir = string(test_source_dir)
102   testSourceDir = string("${jalviewDir}/${bareTestSourceDir}")
103
104   // clover
105   cloverInstrDir = file("${buildDir}/${cloverSourcesInstrDir}")
106   classesDir = string("${jalviewDir}/${classes_dir}")
107   if (clover.equals("true")) {
108     use_clover = true
109     classesDir = string("${buildDir}/${cloverClassesDir}")
110   } else {
111     use_clover = false
112     classesDir = string("${jalviewDir}/${classes_dir}")
113   }
114
115   classes = classesDir
116
117   getdownWebsiteDir = string("${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}")
118   getdownDir = string("")
119   reportRsyncCmd = false
120   buildDist = true
121   buildProperties = build_properties_file
122   getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
123   switch (CHANNEL) {
124
125     case "BUILD":
126     // TODO: get bamboo build artifact URL for getdown artifacts
127     getdown_channel_base = bamboo_channelbase
128     getdown_channel_name = string("${bamboo_planKey}/${JAVA_VERSION}")
129     getdown_app_base = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
130     getdown_app_dir = getdown_app_dir_alt
131     buildProperties = string("${classesDir}/${build_properties_file}")
132     break
133
134     case "RELEASE":
135     getdown_channel_name = CHANNEL.toLowerCase()
136     getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
137     getdown_app_base = string("${getdown_channel_base}/${getdownDir}")
138     getdown_app_dir = getdown_app_dir_release
139     buildProperties = string("${classesDir}/${build_properties_file}")
140     reportRsyncCommand = true
141     break
142
143     case "ARCHIVE":
144     getdown_channel_name = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
145     getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
146     getdown_app_base = string("${getdown_channel_base}/${getdownDir}")
147     getdown_app_dir = getdown_app_dir_alt
148     if (!file("${ARCHIVEDIR}/${packageDir}").exists()) {
149       print "Must provide an ARCHIVEDIR value to produce an archive distribution"
150       exit
151     } else {
152       packageDir = string("${ARCHIVEDIR}/${packageDir}")
153       buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
154       buildDist = false
155     }
156     reportRsyncCommand = true
157     break
158
159     case "ARCHIVELOCAL":
160     getdown_channel_name = string("archive/${JALVIEW_VERSION}")
161     getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
162     getdown_app_base = file(getdownWebsiteDir).toURI().toString()
163     getdown_app_dir = getdown_app_dir_alt
164     if (!file("${ARCHIVEDIR}/${packageDir}").exists()) {
165       print "Must provide an ARCHIVEDIR value to produce an archive distribution"
166       exit
167     } else {
168       packageDir = string("${ARCHIVEDIR}/${packageDir}")
169       buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
170       buildDist = false
171     }
172     reportRsyncCommand = true
173     getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
174     break
175
176     case "DEVELOP":
177     getdown_channel_name = CHANNEL.toLowerCase()
178     getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
179     getdown_app_base = string("${getdown_channel_base}/${getdownDir}")
180     getdown_app_dir = getdown_app_dir_alt
181     buildProperties = string("${classesDir}/${build_properties_file}")
182     reportRsyncCommand = true
183     break
184
185     case "TEST-RELEASE":
186     getdown_channel_name = CHANNEL.toLowerCase()
187     getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
188     getdown_app_base = string("${getdown_channel_base}/${getdownDir}")
189     getdown_app_dir = getdown_app_dir_alt
190     buildProperties = string("${classesDir}/${build_properties_file}")
191     reportRsyncCommand = true
192     break
193
194     case ~/^SCRATCH(|-[-\w]*)$/:
195     getdown_channel_name = CHANNEL
196     getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
197     getdown_app_base = string("${getdown_channel_base}/${getdownDir}")
198     getdown_app_dir = getdown_app_dir_alt
199     buildProperties = string("${classesDir}/${build_properties_file}")
200     reportRsyncCommand = true
201     break
202
203     case "LOCAL":
204     getdown_app_base = file(getdownWebsiteDir).toURI().toString()
205     getdown_app_dir = getdown_app_dir_alt
206     buildProperties = string("${classesDir}/${build_properties_file}")
207     getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
208     break
209
210     default: // something wrong specified
211     print("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
212     exit
213     break
214
215   }
216
217   getdownAppDir = string("${getdownWebsiteDir}/${getdown_app_dir}")
218   //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}"
219   getdownResourceDir = string("${getdownWebsiteDir}/${getdown_resource_dir}")
220   getdownInstallDir = string("${getdownWebsiteDir}/${getdown_install_dir}")
221   getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
222   getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
223   /* compile without modules -- using classpath libraries
224   modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
225   modules_runtimeClasspath = modules_compileClasspath
226   */
227   gitHash = string("")
228   gitBranch = string("")
229
230   println("Using a ${CHANNEL} profile.")
231
232   additional_compiler_args = []
233   // configure classpath/args for j8/j11 compilation
234   if (JAVA_VERSION.equals("1.8")) {
235     JAVA_INTEGER_VERSION = string("8")
236     //libDir = j8libDir
237     libDir = j11libDir
238     libDistDir = j8libDir
239     compile_source_compatibility = 1.8
240     compile_target_compatibility = 1.8
241     // these are getdown.txt properties defined dependent on the JAVA_VERSION
242     getdown_alt_java_min_version = getdown_alt_java8_min_version
243     getdown_alt_java_max_version = getdown_alt_java8_max_version
244     // this property is assigned below and expanded to multiple lines in the getdown task
245     getdown_alt_multi_java_location = getdown_alt_java8_txt_multi_java_location
246     // this property is for the Java library used in eclipse
247     eclipse_java_runtime_name = string("JavaSE-1.8")
248   } else if (JAVA_VERSION.equals("11")) {
249     JAVA_INTEGER_VERSION = string("11")
250     libDir = j11libDir
251     libDistDir = j11libDir
252     compile_source_compatibility = 11
253     compile_target_compatibility = 11
254     getdown_alt_java_min_version = getdown_alt_java11_min_version
255     getdown_alt_java_max_version = getdown_alt_java11_max_version
256     getdown_alt_multi_java_location = getdown_alt_java11_txt_multi_java_location
257     eclipse_java_runtime_name = string("JavaSE-11")
258     /* compile without modules -- using classpath libraries
259     additional_compiler_args += [
260     '--module-path', modules_compileClasspath.asPath,
261     '--add-modules', j11modules
262     ]
263      */
264   } else if (JAVA_VERSION.equals("12") || JAVA_VERSION.equals("13")) {
265     JAVA_INTEGER_VERSION = JAVA_VERSION
266     libDir = j11libDir
267     libDistDir = j11libDir
268     compile_source_compatibility = JAVA_VERSION
269     compile_target_compatibility = JAVA_VERSION
270     getdown_alt_java_min_version = getdown_alt_java11_min_version
271     getdown_alt_java_max_version = getdown_alt_java11_max_version
272     getdown_alt_multi_java_location = getdown_alt_java11_txt_multi_java_location
273     eclipse_java_runtime_name = string("JavaSE-11")
274     /* compile without modules -- using classpath libraries
275     additional_compiler_args += [
276     '--module-path', modules_compileClasspath.asPath,
277     '--add-modules', j11modules
278     ]
279      */
280   } else {
281     throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
282   }
283
284
285   // for install4j
286   JAVA_MIN_VERSION = JAVA_VERSION
287   JAVA_MAX_VERSION = JAVA_VERSION
288   macosJavaVMDir = string("${System.env.HOME}/buildtools/jre/openjdk-java_vm/getdown/macos-jre${JAVA_VERSION}/jre")
289   macosJavaVMTgz = string("${System.env.HOME}/buildtools/jre/openjdk-java_vm/install4j/tgz/macos-jre${JAVA_VERSION}.tar.gz")
290   windowsJavaVMDir = string("${System.env.HOME}/buildtools/jre/openjdk-java_vm/getdown/windows-jre${JAVA_VERSION}/jre")
291   windowsJavaVMTgz = string("${System.env.HOME}/buildtools/jre/openjdk-java_vm/install4j/tgz/windows-jre${JAVA_VERSION}.tar.gz")
292   install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
293   install4jConfFileName = string("jalview-install4j-conf.install4j")
294   install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
295   install4jHomeDir = install4j_home_dir
296   if (install4jHomeDir.startsWith("~/")) {
297     install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1)
298   }
299
300
301
302   buildingHTML = string("${jalviewDir}/${docDir}/building.html")
303   helpFile = string("${classesDir}/${help_dir}/help.jhm")
304   helpParentDir = string("${jalviewDir}/${help_parent_dir}")
305   helpDir = string("${help_dir}")
306   helpSourceDir = string("${helpParentDir}/${helpDir}")
307
308
309   relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
310   jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
311   jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}")
312   if (IN_ECLIPSE) {
313     jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
314   } else {
315     jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
316   }
317   jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
318   jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
319   jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
320   jalviewjsJalviewCoreHtmlFile = string("")
321   jalviewjsJalviewCoreName = string(jalviewjs_core_name)
322   jalviewjsCoreClasslists = []
323   jalviewjsJalviewTemplateName = string(jalviewjs_name)
324   jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
325   jalviewjsJ2sProps = null
326
327   eclipseWorkspace = null
328   eclipseBinary = string("")
329   eclipseVersion = string("")
330   eclipseDebug = false
331   // ENDEXT
332 }
333
334
335 sourceSets {
336   main {
337     java {
338       srcDirs sourceDir
339       outputDir = file(classesDir)
340     }
341
342     resources {
343       srcDirs resourceDir
344     }
345
346     jar.destinationDir = file("${jalviewDir}/${packageDir}")
347
348     compileClasspath = files(sourceSets.main.java.outputDir)
349     compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
350
351     runtimeClasspath = compileClasspath
352   }
353
354   clover {
355     java {
356       srcDirs = [ cloverInstrDir ]
357       outputDir = file("${buildDir}/${cloverClassesDir}")
358     }
359
360     resources {
361       srcDirs = sourceSets.main.resources.srcDirs
362     }
363     compileClasspath = configurations.cloverRuntime + files( sourceSets.clover.java.outputDir )
364     compileClasspath += files(sourceSets.main.java.outputDir)
365     compileClasspath += sourceSets.main.compileClasspath
366     compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}", include: ["**/*.jar"])
367     compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
368
369     runtimeClasspath = compileClasspath
370   }
371
372   test {
373     java {
374       srcDirs testSourceDir
375       outputDir = file("${jalviewDir}/${testOutputDir}")
376     }
377
378     resources {
379       srcDirs = sourceSets.main.resources.srcDirs
380     }
381
382     compileClasspath = files( sourceSets.test.java.outputDir )
383
384     if (use_clover) {
385       compileClasspath += sourceSets.clover.compileClasspath
386     } else {
387       compileClasspath += files(sourceSets.main.java.outputDir)
388     }
389
390     compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
391     compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}/testnglibs", include: ["**/*.jar"])
392     compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}/testlibs", include: ["**/*.jar"])
393
394     runtimeClasspath = compileClasspath
395   }
396 }
397
398
399 // clover bits
400 dependencies {
401   if (use_clover) {
402     cloverCompile 'org.openclover:clover:4.3.1'
403     testCompile 'org.openclover:clover:4.3.1'
404   }
405 }
406
407
408 configurations {
409   cloverRuntime
410   cloverRuntime.extendsFrom cloverCompile
411 }
412
413 eclipse {
414   project {
415     name = eclipse_project_name
416
417     natures 'org.eclipse.jdt.core.javanature',
418     'org.eclipse.jdt.groovy.core.groovyNature',
419     'org.eclipse.buildship.core.gradleprojectnature'
420
421     buildCommand 'org.eclipse.jdt.core.javabuilder'
422     buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
423   }
424
425   classpath {
426     //defaultOutputDir = sourceSets.main.java.outputDir
427     def removeThese = []
428     configurations.each{
429       if (it.isCanBeResolved()) {
430         removeThese += it
431       }
432     }
433
434     minusConfigurations += removeThese
435     plusConfigurations = [ ]
436     file {
437
438       whenMerged { cp ->
439         def removeTheseToo = []
440         HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
441         cp.entries.each { entry ->
442           // This conditional removes all src classpathentries that a) have already been added or b) aren't "src" or "test".
443           // e.g. this removes the resources dir being copied into bin/main, bin/test AND bin/clover
444           // we add the resources and help/help dirs in as libs afterwards (see below)
445           if (entry.kind == 'src') {
446             if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) {
447               removeTheseToo += entry
448             } else {
449               alreadyAddedSrcPath.putAt(entry.path, true)
450             }
451           }
452
453         }
454         cp.entries.removeAll(removeTheseToo)
455
456         //cp.entries += new Output("${eclipse_bin_dir}/main")
457         if (file(helpSourceDir).isDirectory()) {
458           cp.entries += new Library(fileReference(helpSourceDir))
459         }
460         if (file(resourceDir).isDirectory()) {
461           cp.entries += new Library(fileReference(resourceDir))
462         }
463
464         HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
465
466         sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
467           //don't want to add outputDir as eclipse is using its own output dir in bin/main
468           if (it.isDirectory() || ! it.exists()) {
469             // don't add dirs to classpath, especially if they don't exist
470             return false // groovy "continue" in .any closure
471           }
472           def itPath = it.toString()
473           if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
474             // make relative path
475             itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
476           }
477           if (alreadyAddedLibPath.get(itPath)) {
478             //println("Not adding duplicate entry "+itPath)
479           } else {
480             //println("Adding entry "+itPath)
481             cp.entries += new Library(fileReference(itPath))
482             alreadyAddedLibPath.put(itPath, true)
483           }
484         }
485
486         sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
487           //no longer want to add outputDir as eclipse is using its own output dir in bin/main
488           if (it.isDirectory() || ! it.exists()) {
489             // don't add dirs to classpath
490             return false // groovy "continue" in .any closure
491           }
492
493           def itPath = it.toString()
494           if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
495             itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
496           }
497           if (alreadyAddedLibPath.get(itPath)) {
498             // don't duplicate
499           } else {
500             def lib = new Library(fileReference(itPath))
501             lib.entryAttributes["test"] = "true"
502             cp.entries += lib
503             alreadyAddedLibPath.put(itPath, true)
504           }
505         }
506
507       } // whenMerged
508
509     } // file
510
511     containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
512
513   } // classpath
514
515   jdt {
516     // for the IDE, use java 11 compatibility
517     sourceCompatibility = compile_source_compatibility
518     targetCompatibility = compile_target_compatibility
519     javaRuntimeName = eclipse_java_runtime_name
520
521     // add in jalview project specific properties/preferences into eclipse core preferences
522     file {
523       withProperties { props ->
524         def jalview_prefs = new Properties()
525         def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
526         jalview_prefs.load(ins)
527         ins.close()
528         jalview_prefs.forEach { t, v ->
529           if (props.getAt(t) == null) {
530             props.putAt(t, v)
531           }
532         }
533       }
534     }
535
536   } // jdt
537
538   if (IN_ECLIPSE) {
539     // Don't want these to be activated if in headless build
540     synchronizationTasks "eclipseSynchronizationTask"
541     autoBuildTasks "eclipseAutoBuildTask"
542
543   }
544 }
545
546
547 task cloverInstr() {
548   // only instrument source, we build test classes as normal
549   inputs.files files (sourceSets.main.allJava) // , fileTree(dir: testSourceDir, include: ["**/*.java"]))
550   outputs.dir cloverInstrDir
551
552   doFirst {
553     delete cloverInstrDir
554     def argsList = ["--initstring", "${buildDir}/clover/clover.db",
555     "-d", "${buildDir}/${cloverSourcesInstrDir}"]
556     argsList.addAll(inputs.files.files.collect({ file ->
557       file.absolutePath
558     }))
559     String[] args = argsList.toArray()
560     println("About to instrument "+args.length +" files")
561     com.atlassian.clover.CloverInstr.mainImpl(args)
562   }
563 }
564
565
566 task cloverReport {
567   group = "Verification"
568     description = "Createst the Clover report"
569     inputs.dir "${buildDir}/clover"
570     outputs.dir "${reportsDir}/clover"
571     onlyIf {
572       file("${buildDir}/clover/clover.db").exists()
573     }
574   doFirst {
575     def argsList = ["--initstring", "${buildDir}/clover/clover.db",
576     "-o", "${reportsDir}/clover"]
577     String[] args = argsList.toArray()
578     com.atlassian.clover.reporters.html.HtmlReporter.runReport(args)
579
580     // and generate ${reportsDir}/clover/clover.xml
581     args = ["--initstring", "${buildDir}/clover/clover.db",
582     "-o", "${reportsDir}/clover/clover.xml"].toArray()
583     com.atlassian.clover.reporters.xml.XMLReporter.runReport(args)
584   }
585 }
586 // end clover bits
587
588
589 compileJava {
590
591   doFirst {
592     sourceCompatibility = compile_source_compatibility
593     targetCompatibility = compile_target_compatibility
594     options.compilerArgs = additional_compiler_args
595     print ("Setting target compatibility to "+targetCompatibility+"\n")
596   }
597
598 }
599
600
601 compileTestJava {
602   if (use_clover) {
603     dependsOn compileCloverJava
604     classpath += configurations.cloverRuntime
605   } else {
606     classpath += sourceSets.main.runtimeClasspath
607   }
608   doFirst {
609     sourceCompatibility = compile_source_compatibility
610     targetCompatibility = compile_target_compatibility
611     options.compilerArgs = additional_compiler_args
612     print ("Setting target compatibility to "+targetCompatibility+"\n")
613   }
614 }
615
616
617 compileCloverJava {
618
619   doFirst {
620     sourceCompatibility = compile_source_compatibility
621     targetCompatibility = compile_target_compatibility
622     options.compilerArgs += additional_compiler_args
623     print ("Setting target compatibility to "+targetCompatibility+"\n")
624   }
625   classpath += configurations.cloverRuntime
626 }
627
628
629 clean {
630   doFirst {
631     delete sourceSets.main.java.outputDir
632   }
633 }
634
635
636 cleanTest {
637   doFirst {
638     delete sourceSets.test.java.outputDir
639     delete cloverInstrDir
640   }
641 }
642
643
644 // format is a string like date.format("dd MMMM yyyy")
645 def getDate(format) {
646   def date = new Date()
647   return date.format(format)
648 }
649
650
651 task setGitVals {
652   def hashStdOut = new ByteArrayOutputStream()
653   exec {
654     commandLine "git", "rev-parse", "--short", "HEAD"
655     standardOutput = hashStdOut
656     ignoreExitValue true
657   }
658
659   def branchStdOut = new ByteArrayOutputStream()
660   exec {
661     commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
662     standardOutput = branchStdOut
663     ignoreExitValue true
664   }
665
666   gitHash = hashStdOut.toString().trim()
667   gitBranch = branchStdOut.toString().trim()
668
669   outputs.upToDateWhen { false }
670 }
671
672
673 task createBuildProperties(type: WriteProperties) {
674   dependsOn setGitVals
675   inputs.dir(sourceDir)
676   inputs.dir(resourceDir)
677   file(buildProperties).getParentFile().mkdirs()
678   outputFile (buildProperties)
679   // taking time specific comment out to allow better incremental builds
680   comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
681   //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
682   property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
683   property "VERSION", JALVIEW_VERSION
684   property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
685   outputs.file(outputFile)
686 }
687
688
689 task cleanBuildingHTML(type: Delete) {
690   doFirst {
691     delete buildingHTML
692   }
693 }
694
695
696 task convertBuildingMD(type: Exec) {
697   dependsOn cleanBuildingHTML
698   def buildingMD = "${jalviewDir}/${docDir}/building.md"
699   def css = "${jalviewDir}/${docDir}/github.css"
700
701   def pandoc = null
702   pandoc_exec.split(",").each {
703     if (file(it.trim()).exists()) {
704       pandoc = it.trim()
705       return true
706     }
707   }
708
709   def hostname = "hostname".execute().text.trim()
710   if ((pandoc == null || ! file(pandoc).exists()) && hostname.equals("jv-bamboo")) {
711     pandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
712   }
713
714   doFirst {
715     if (pandoc != null && file(pandoc).exists()) {
716         commandLine pandoc, '-s', '-o', buildingHTML, '--metadata', 'pagetitle="Building Jalview from Source"', '--toc', '-H', css, buildingMD
717     } else {
718         println("Cannot find pandoc. Skipping convert building.md to HTML")
719         throw new StopExecutionException("Cannot find pandoc. Skipping convert building.md to HTML")
720     }
721   }
722
723   ignoreExitValue true
724
725   inputs.file(buildingMD)
726   inputs.file(css)
727   outputs.file(buildingHTML)
728 }
729
730
731 clean {
732   doFirst {
733     delete buildingHTML
734   }
735 }
736
737
738 task syncDocs(type: Sync) {
739   dependsOn convertBuildingMD
740   def syncDir = "${classesDir}/${docDir}"
741   from fileTree("${jalviewDir}/${docDir}")
742   into syncDir
743
744 }
745
746
747 task copyHelp(type: Copy) {
748   def inputDir = helpSourceDir
749   def outputDir = "${classesDir}/${helpDir}"
750   from(inputDir) {
751     exclude '**/*.gif'
752     exclude '**/*.jpg'
753     exclude '**/*.png'
754     filter(ReplaceTokens,
755       beginToken: '$$',
756       endToken: '$$',
757       tokens: [
758         'Version-Rel': JALVIEW_VERSION,
759         'Year-Rel': getDate("yyyy")
760       ]
761     )
762   }
763   from(inputDir) {
764     include '**/*.gif'
765     include '**/*.jpg'
766     include '**/*.png'
767   }
768   into outputDir
769
770   inputs.dir(inputDir)
771   outputs.files(helpFile)
772   outputs.dir(outputDir)
773 }
774
775
776 task syncLib(type: Sync) {
777   def syncDir = "${classesDir}/${libDistDir}"
778   from fileTree("${jalviewDir}/${libDistDir}")
779   into syncDir
780 }
781
782
783 task syncResources(type: Sync) {
784   from resourceDir
785   include "**/*.*"
786   into "${classesDir}"
787   preserve {
788     include "**"
789   }
790 }
791
792
793 task prepare {
794   dependsOn syncResources
795   dependsOn syncDocs
796   dependsOn copyHelp
797 }
798
799
800 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
801 test {
802   dependsOn prepare
803   dependsOn compileJava
804   if (use_clover) {
805     dependsOn cloverInstr
806   }
807
808   if (use_clover) {
809     print("Running tests " + (use_clover?"WITH":"WITHOUT") + " clover [clover="+use_clover+"]\n")
810   }
811
812   useTestNG() {
813     includeGroups testngGroups
814     preserveOrder true
815     useDefaultListeners=true
816   }
817
818   workingDir = jalviewDir
819   //systemProperties 'clover.jar' System.properties.clover.jar
820   sourceCompatibility = compile_source_compatibility
821   targetCompatibility = compile_target_compatibility
822   jvmArgs += additional_compiler_args
823
824 }
825
826
827 task buildIndices(type: JavaExec) {
828   dependsOn copyHelp
829   classpath = sourceSets.main.compileClasspath
830   main = "com.sun.java.help.search.Indexer"
831   workingDir = "${classesDir}/${helpDir}"
832   def argDir = "html"
833   args = [ argDir ]
834   inputs.dir("${workingDir}/${argDir}")
835
836   outputs.dir("${classesDir}/doc")
837   outputs.dir("${classesDir}/help")
838   outputs.file("${workingDir}/JavaHelpSearch/DOCS")
839   outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
840   outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
841   outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
842   outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
843   outputs.file("${workingDir}/JavaHelpSearch/TMAP")
844 }
845
846
847 task compileLinkCheck(type: JavaCompile) {
848   options.fork = true
849   classpath = files("${jalviewDir}/${utilsDir}")
850   destinationDir = file("${jalviewDir}/${utilsDir}")
851   source = fileTree(dir: "${jalviewDir}/${utilsDir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
852
853   inputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.java")
854   inputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.java")
855   outputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.class")
856   outputs.file("${jalviewDir}/${utilsDir}/BufferedLineReader.class")
857 }
858
859
860 task linkCheck(type: JavaExec) {
861   dependsOn prepare, compileLinkCheck
862
863   def helpLinksCheckerOutFile = file("${jalviewDir}/${utilsDir}/HelpLinksChecker.out")
864   classpath = files("${jalviewDir}/${utilsDir}")
865   main = "HelpLinksChecker"
866   workingDir = jalviewDir
867   def help = "${classesDir}/${helpDir}"
868   args = [ "${classesDir}/${helpDir}", "-nointernet" ]
869
870   def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
871   def errFOS = outFOS
872   standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
873     outFOS,
874     standardOutput)
875   errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
876     outFOS,
877     errorOutput)
878
879   inputs.dir("${classesDir}/${helpDir}")
880   outputs.file(helpLinksCheckerOutFile)
881 }
882
883 // import the pubhtmlhelp target
884 ant.properties.basedir = "${jalviewDir}"
885 ant.properties.helpBuildDir = "${jalviewDirAbsolutePath}/${classes_dir}/${helpDir}"
886 ant.importBuild "${utilsDir}/publishHelp.xml"
887
888
889 task cleanPackageDir(type: Delete) {
890   doFirst {
891     delete fileTree(dir: "${jalviewDir}/${packageDir}", include: "*.jar")
892   }
893 }
894
895 jar {
896   dependsOn linkCheck
897   dependsOn buildIndices
898   dependsOn createBuildProperties
899
900   manifest {
901     attributes "Main-Class": mainClass,
902     "Permissions": "all-permissions",
903     "Application-Name": "Jalview Desktop",
904     "Codebase": application_codebase
905   }
906
907   destinationDir = file("${jalviewDir}/${packageDir}")
908   archiveName = rootProject.name+".jar"
909
910   exclude "cache*/**"
911   exclude "*.jar"
912   exclude "*.jar.*"
913   exclude "**/*.jar"
914   exclude "**/*.jar.*"
915
916   inputs.dir(classesDir)
917   outputs.file("${jalviewDir}/${packageDir}/${archiveName}")
918 }
919
920
921 task copyJars(type: Copy) {
922   from fileTree(dir: classesDir, include: "**/*.jar").files
923   into "${jalviewDir}/${packageDir}"
924 }
925
926
927 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
928 task syncJars(type: Sync) {
929   from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
930   into "${jalviewDir}/${packageDir}"
931   preserve {
932     include jar.archiveName
933   }
934 }
935
936
937 task makeDist {
938   group = "build"
939   description = "Put all required libraries in dist"
940   // order of "cleanPackageDir", "copyJars", "jar" important!
941   jar.mustRunAfter cleanPackageDir
942   syncJars.mustRunAfter cleanPackageDir
943   dependsOn cleanPackageDir
944   dependsOn syncJars
945   dependsOn jar
946   outputs.dir("${jalviewDir}/${packageDir}")
947 }
948
949
950 task cleanDist {
951   dependsOn cleanPackageDir
952   dependsOn cleanTest
953   dependsOn clean
954 }
955
956 shadowJar {
957   group = "distribution"
958   if (buildDist) {
959     dependsOn makeDist
960   }
961   from ("${jalviewDir}/${libDistDir}") {
962     include("*.jar")
963   }
964   manifest {
965     attributes 'Implementation-Version': JALVIEW_VERSION
966   }
967   mainClassName = shadowJarMainClass
968   mergeServiceFiles()
969   classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
970   minimize()
971 }
972
973
974 task getdownWebsite() {
975   group = "distribution"
976   description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
977   if (buildDist) {
978     dependsOn makeDist
979   }
980
981   def getdownWebsiteResourceFilenames = []
982   def getdownTextString = ""
983   def getdownResourceDir = getdownResourceDir
984   def getdownAppDir = getdownAppDir
985   def getdownResourceFilenames = []
986
987   doFirst {
988     // clean the getdown website and files dir before creating getdown folders
989     delete getdownWebsiteDir
990     delete getdownFilesDir
991
992     copy {
993       from buildProperties
994       rename(build_properties_file, getdown_build_properties)
995       into getdownAppDir
996     }
997     getdownWebsiteResourceFilenames += "${getdown_app_dir}/${getdown_build_properties}"
998
999     // go through properties looking for getdown_txt_...
1000     def props = project.properties.sort { it.key }
1001     if (getdown_alt_java_min_version.length() > 0) {
1002       props.put("getdown_txt_java_min_version", getdown_alt_java_min_version)
1003     }
1004     if (getdown_alt_java_max_version.length() > 0) {
1005       props.put("getdown_txt_java_max_version", getdown_alt_java_max_version)
1006     }
1007     props.put("getdown_txt_multi_java_location", getdown_alt_multi_java_location)
1008
1009     props.put("getdown_txt_appbase", getdown_app_base)
1010     props.each{ prop, val ->
1011       if (prop.startsWith("getdown_txt_") && val != null) {
1012         if (prop.startsWith("getdown_txt_multi_")) {
1013           def key = prop.substring(18)
1014           val.split(",").each{ v ->
1015             def line = "${key} = ${v}\n"
1016             getdownTextString += line
1017           }
1018         } else {
1019           // file values rationalised
1020           if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1021             def r = null
1022             if (val.indexOf('/') == 0) {
1023               // absolute path
1024               r = file(val)
1025             } else if (val.indexOf('/') > 0) {
1026               // relative path (relative to jalviewDir)
1027               r = file( "${jalviewDir}/${val}" )
1028             }
1029             if (r.exists()) {
1030               val = "${getdown_resource_dir}/" + r.getName()
1031               getdownWebsiteResourceFilenames += val
1032               getdownResourceFilenames += r.getPath()
1033             }
1034           }
1035           if (! prop.startsWith("getdown_txt_resource")) {
1036             def line = prop.substring(12) + " = ${val}\n"
1037             getdownTextString += line
1038           }
1039         }
1040       }
1041     }
1042
1043     getdownWebsiteResourceFilenames.each{ filename ->
1044       getdownTextString += "resource = ${filename}\n"
1045     }
1046     getdownResourceFilenames.each{ filename ->
1047       copy {
1048         from filename
1049         into getdownResourceDir
1050       }
1051     }
1052
1053     def codeFiles = []
1054     fileTree(file(packageDir)).each{ f ->
1055       if (f.isDirectory()) {
1056         def files = fileTree(dir: f, include: ["*"]).getFiles()
1057         codeFiles += files
1058       } else if (f.exists()) {
1059         codeFiles += f
1060       }
1061     }
1062     codeFiles.sort().each{f ->
1063       def name = f.getName()
1064       def line = "code = ${getdown_app_dir}/${name}\n"
1065       getdownTextString += line
1066       copy {
1067         from f.getPath()
1068         into getdownAppDir
1069       }
1070     }
1071
1072     // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
1073     /*
1074     if (JAVA_VERSION.equals("11")) {
1075     def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
1076     j11libFiles.sort().each{f ->
1077     def name = f.getName()
1078     def line = "code = ${getdown_j11lib_dir}/${name}\n"
1079     getdownTextString += line
1080     copy {
1081     from f.getPath()
1082     into getdownJ11libDir
1083     }
1084     }
1085     }
1086      */
1087
1088     // getdown-launcher.jar should not be in main application class path so the main application can move it when updated.  Listed as a resource so it gets updated.
1089     //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
1090     getdownTextString += "resource = ${getdown_launcher_new}\n"
1091     getdownTextString += "class = ${mainClass}\n"
1092
1093     def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
1094     getdown_txt.write(getdownTextString)
1095
1096     def launch_jvl = file("${getdownWebsiteDir}/${getdown_launch_jvl}")
1097     launch_jvl.write("appbase="+props.get("getdown_txt_appbase"))
1098
1099     copy {
1100       from getdownLauncher
1101       rename(file(getdownLauncher).getName(), getdown_launcher_new)
1102       into getdownWebsiteDir
1103     }
1104
1105     copy {
1106       from getdownLauncher
1107       if (file(getdownLauncher).getName() != getdown_launcher) {
1108         rename(file(getdownLauncher).getName(), getdown_launcher)
1109       }
1110       into getdownWebsiteDir
1111     }
1112
1113     if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
1114       copy {
1115         from getdown_txt
1116         from getdownLauncher
1117         from "${getdownWebsiteDir}/${getdown_build_properties}"
1118         if (file(getdownLauncher).getName() != getdown_launcher) {
1119           rename(file(getdownLauncher).getName(), getdown_launcher)
1120         }
1121         into getdownInstallDir
1122       }
1123
1124       copy {
1125         from getdownInstallDir
1126         into getdownFilesInstallDir
1127       }
1128     }
1129
1130     copy {
1131       from getdown_txt
1132       from launch_jvl
1133       from getdownLauncher
1134       from "${getdownWebsiteDir}/${getdown_build_properties}"
1135       if (file(getdownLauncher).getName() != getdown_launcher) {
1136         rename(file(getdownLauncher).getName(), getdown_launcher)
1137       }
1138       into getdownFilesDir
1139     }
1140
1141     copy {
1142       from getdownResourceDir
1143       into "${getdownFilesDir}/${getdown_resource_dir}"
1144     }
1145   }
1146
1147   if (buildDist) {
1148     inputs.dir("${jalviewDir}/${packageDir}")
1149   }
1150   outputs.dir(getdownWebsiteDir)
1151   outputs.dir(getdownFilesDir)
1152 }
1153
1154
1155 task getdownDigest(type: JavaExec) {
1156   group = "distribution"
1157   description = "Digest the getdown website folder"
1158   dependsOn getdownWebsite
1159   doFirst {
1160     classpath = files("${getdownWebsiteDir}/${getdown_launcher}")
1161   }
1162   main = "com.threerings.getdown.tools.Digester"
1163   args getdownWebsiteDir
1164   inputs.dir(getdownWebsiteDir)
1165   outputs.file("${getdownWebsiteDir}/digest2.txt")
1166 }
1167
1168
1169 task getdown() {
1170   group = "distribution"
1171   description = "Create the minimal and full getdown app folder for installers and website and create digest file"
1172   dependsOn getdownDigest
1173   doLast {
1174     if (reportRsyncCommand) {
1175       def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
1176       def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
1177       println "LIKELY RSYNC COMMAND:"
1178       println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
1179       if (RUNRSYNC == "true") {
1180         exec {
1181           commandLine "mkdir", "-p", toDir
1182         }
1183         exec {
1184           commandLine "rsync", "-avh", "--delete", fromDir, toDir
1185         }
1186       }
1187     }
1188   }
1189 }
1190
1191
1192 clean {
1193   doFirst {
1194     delete getdownWebsiteDir
1195     delete getdownFilesDir
1196   }
1197 }
1198
1199
1200 install4j {
1201   if (file(install4jHomeDir).exists()) {
1202     // good to go!
1203   } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
1204     install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1205   } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
1206     install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
1207   }
1208   installDir(file(install4jHomeDir))
1209
1210   mediaTypes = Arrays.asList(install4j_media_types.split(","))
1211 }
1212
1213
1214 task copyInstall4jTemplate {
1215
1216   def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
1217   def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
1218   inputs.file(install4jTemplateFile)
1219   inputs.file(install4jFileAssociationsFile)
1220   outputs.file(install4jConfFile)
1221
1222   doLast {
1223     def install4j = new XmlParser().parse(install4jTemplateFile)
1224
1225     // turn off code signing if no OSX_KEYPASS
1226     if (OSX_KEYPASS == "") {
1227       install4j.'**'.codeSigning.each { codeSigning ->
1228         codeSigning.'@macEnabled' = "false"
1229       }
1230       install4j.'**'.windows.each { windows ->
1231         windows.'@runPostProcessor' = "false"
1232       }
1233     }
1234
1235     // put file association actions where placeholder action is
1236     def install4jFileAssociationsText = install4jFileAssociationsFile.text
1237     def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
1238     install4j.'**'.action.any { a ->
1239       if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
1240         def parent = a.parent()
1241         parent.remove(a)
1242         fileAssociationActions.each { faa ->
1243             parent.append(faa)
1244         }
1245         // don't need to continue in .any loop once replacements have been made
1246         return true
1247       }
1248     }
1249
1250     // write install4j file
1251     install4jConfFile.text = XmlUtil.serialize(install4j)
1252   }
1253 }
1254
1255
1256 clean {
1257   doFirst {
1258     delete install4jConfFile
1259   }
1260 }
1261
1262
1263 task installers(type: com.install4j.gradle.Install4jTask) {
1264   group = "distribution"
1265   description = "Create the install4j installers"
1266   dependsOn setGitVals
1267   dependsOn getdown
1268   dependsOn copyInstall4jTemplate
1269
1270   projectFile = install4jConfFile
1271
1272   // create an md5 for the input files to use as version for install4j conf file
1273   def install4jTemplateMd5 = ""
1274   def digest = MessageDigest.getInstance("MD5")
1275   digest.update(
1276     (file("${install4jDir}/${install4j_template}").text + 
1277     file("${install4jDir}/${install4j_info_plist_file_associations}").text +
1278     file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
1279   def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
1280   if (filesMd5.length() >= 8) {
1281     filesMd5 = filesMd5.substring(0,8)
1282   }
1283   install4jTemplateMd5 += filesMd5
1284   install4jTemplateMd5 += "_${gitHash}"
1285   def install4jTemplateVersion = "${JALVIEW_VERSION}_${install4jTemplateMd5}"
1286   def infoPlistFileAssociations = file("${install4jDir}/${install4j_info_plist_file_associations}").text
1287
1288   variables = [
1289     'OSX_KEYSTORE': OSX_KEYSTORE,
1290     'JSIGN_SH': JSIGN_SH,
1291     'JALVIEW_VERSION': JALVIEW_VERSION,
1292     'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
1293     'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
1294     'JAVA_VERSION': JAVA_VERSION,
1295     'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
1296     'VERSION': JALVIEW_VERSION,
1297     'MACOS_JAVA_VM_DIR': macosJavaVMDir,
1298     'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
1299     'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
1300     'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
1301     'INSTALL4JINFOPLISTFILEASSOCIATIONS': install4j_info_plist_file_associations,
1302     'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
1303     'COPYRIGHT_MESSAGE': install4j_copyright_message,
1304     'MACOS_BUNDLE_ID': install4j_macOS_bundle_id,
1305     'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
1306     'GETDOWN_DIST_DIR': getdown_app_dir,
1307     'GETDOWN_ALT_DIR': getdown_app_dir_alt,
1308     'GETDOWN_INSTALL_DIR': getdown_install_dir,
1309     'INFO_PLIST_FILE_ASSOCIATIONS': infoPlistFileAssociations
1310   ]
1311   destination = "${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}"
1312   buildSelected = true
1313
1314   if (install4j_faster.equals("true") || CHANNEL.startsWith("DEVELOP") || CHANNEL.startsWith("LOCAL")) {
1315     // this doesn't seem to work
1316     faster = true
1317     disableSigning = true
1318   }
1319
1320   if (OSX_KEYPASS) {
1321     macKeystorePassword = OSX_KEYPASS
1322   }
1323
1324   doFirst {
1325     println("Using projectFile "+projectFile)
1326   }
1327
1328   inputs.dir(getdownWebsiteDir)
1329   inputs.file(install4jConfFile)
1330   inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
1331   inputs.dir(macosJavaVMDir)
1332   inputs.dir(windowsJavaVMDir)
1333   outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
1334 }
1335
1336
1337 task sourceDist(type: Tar) {
1338   
1339   def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
1340   def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
1341   // cater for buildship < 3.1 [3.0.1 is max version in eclipse 2018-09]
1342   try {
1343     archiveFileName = outputFileName
1344   } catch (Exception e) {
1345     archiveName = outputFileName
1346   }
1347   
1348   compression Compression.GZIP
1349   
1350   into project.name
1351
1352   def EXCLUDE_FILES=["build/*","bin/*","test-output/","test-reports","tests","clover*/*"
1353   ,".*"
1354   ,"benchmarking/*"
1355   ,"**/.*"
1356   ,"*.class"
1357   ,"**/*.class","${j11modDir}/**/*.jar","appletlib","**/*locales"
1358   ,"*locales/**",
1359   ,"utils/InstallAnywhere"] 
1360   def PROCESS_FILES=[   "AUTHORS",
1361   "CITATION",
1362   "FEATURETODO",
1363   "JAVA-11-README",
1364   "FEATURETODO",
1365   "LICENSE",
1366   "**/README",
1367   "RELEASE",
1368   "THIRDPARTYLIBS","TESTNG",
1369   "build.gradle",
1370   "gradle.properties",
1371   "**/*.java",
1372   "**/*.html",
1373   "**/*.xml",
1374   "**/*.gradle",
1375   "**/*.groovy",
1376   "**/*.properties",
1377   "**/*.perl",
1378   "**/*.sh"]
1379
1380   from(jalviewDir) {
1381     exclude (EXCLUDE_FILES)
1382     include (PROCESS_FILES)
1383     filter(ReplaceTokens,
1384       beginToken: '$$',
1385       endToken: '$$',
1386       tokens: [
1387         'Version-Rel': JALVIEW_VERSION,
1388         'Year-Rel': getDate("yyyy")
1389       ]
1390     )
1391   }
1392   from(jalviewDir) {
1393     exclude (EXCLUDE_FILES)
1394     exclude (PROCESS_FILES)
1395     exclude ("appletlib")
1396     exclude ("**/*locales")
1397     exclude ("*locales/**")
1398     exclude ("utils/InstallAnywhere")
1399
1400     exclude (getdown_files_dir)
1401     exclude (getdown_website_dir)
1402
1403     // exluding these as not using jars as modules yet
1404     exclude ("${j11modDir}/**/*.jar")
1405   }
1406   //  from (jalviewDir) {
1407   //    // explicit includes for stuff that seemed to not get included
1408   //    include(fileTree("test/**/*."))
1409   //    exclude(EXCLUDE_FILES)
1410   //    exclude(PROCESS_FILES)
1411   //  }
1412 }
1413
1414
1415 task helppages {
1416   dependsOn copyHelp
1417   dependsOn pubhtmlhelp
1418   
1419   inputs.dir("${classesDir}/${helpDir}")
1420   outputs.dir("${buildDir}/distributions/${helpDir}")
1421 }
1422
1423 // LARGE AMOUNT OF JALVIEWJS STUFF DELETED HERE
1424 task eclipseAutoBuildTask {}
1425 task eclipseSynchronizationTask {}