JAL-3447 Change to install4j template version, JAL-3394 removed redundant compiler...
[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   helpSourceDir = string("${helpParentDir}/${help_dir}")
306
307
308   relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
309   jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
310   jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}")
311   if (IN_ECLIPSE) {
312     jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
313   } else {
314     jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
315   }
316   jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
317   jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
318   jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
319   jalviewjsJalviewCoreHtmlFile = string("")
320   jalviewjsJalviewCoreName = string(jalviewjs_core_name)
321   jalviewjsCoreClasslists = []
322   jalviewjsJalviewTemplateName = string(jalviewjs_name)
323   jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
324   jalviewjsJ2sProps = null
325
326   eclipseWorkspace = null
327   eclipseBinary = string("")
328   eclipseVersion = string("")
329   eclipseDebug = false
330   // ENDEXT
331 }
332
333
334 sourceSets {
335   main {
336     java {
337       srcDirs sourceDir
338       outputDir = file(classesDir)
339     }
340
341     resources {
342       srcDirs resourceDir
343       srcDirs += helpParentDir
344     }
345
346     jar.destinationDir = file("${jalviewDir}/${packageDir}")
347
348     compileClasspath = files(sourceSets.main.java.outputDir)
349     //compileClasspath += files(sourceSets.main.resources.srcDirs)
350     compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
351
352     runtimeClasspath = compileClasspath
353   }
354
355   clover {
356     java {
357       srcDirs = [ cloverInstrDir ]
358       outputDir = file("${buildDir}/${cloverClassesDir}")
359     }
360
361     resources {
362       srcDirs = sourceSets.main.resources.srcDirs
363     }
364     compileClasspath = configurations.cloverRuntime + files( sourceSets.clover.java.outputDir )
365     compileClasspath += files(sourceSets.main.java.outputDir)
366     compileClasspath += sourceSets.main.compileClasspath
367     compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}", include: ["**/*.jar"])
368     compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
369
370     runtimeClasspath = compileClasspath
371   }
372
373   test {
374     java {
375       srcDirs testSourceDir
376       outputDir = file("${jalviewDir}/${testOutputDir}")
377     }
378
379     resources {
380       srcDirs = sourceSets.main.resources.srcDirs
381     }
382
383     compileClasspath = files( sourceSets.test.java.outputDir )
384
385     if (use_clover) {
386       compileClasspath += sourceSets.clover.compileClasspath
387     } else {
388       compileClasspath += files(sourceSets.main.java.outputDir)
389     }
390
391     compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
392     compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}/testnglibs", include: ["**/*.jar"])
393     compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}/testlibs", include: ["**/*.jar"])
394
395     runtimeClasspath = compileClasspath
396   }
397 }
398
399
400 // clover bits
401 dependencies {
402   if (use_clover) {
403     cloverCompile 'org.openclover:clover:4.3.1'
404     testCompile 'org.openclover:clover:4.3.1'
405   }
406 }
407
408
409 configurations {
410   cloverRuntime
411   cloverRuntime.extendsFrom cloverCompile
412 }
413
414 eclipse {
415   project {
416     name = eclipse_project_name
417
418     natures 'org.eclipse.jdt.core.javanature',
419     'org.eclipse.jdt.groovy.core.groovyNature',
420     'org.eclipse.buildship.core.gradleprojectnature'
421
422     buildCommand 'org.eclipse.jdt.core.javabuilder'
423     buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
424   }
425
426   classpath {
427     //defaultOutputDir = sourceSets.main.java.outputDir
428     def removeThese = []
429     configurations.each{
430       if (it.isCanBeResolved()) {
431         removeThese += it
432       }
433     }
434
435     minusConfigurations += removeThese
436     plusConfigurations = [ ]
437     file {
438
439       whenMerged { cp ->
440         def removeTheseToo = []
441         HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
442         cp.entries.each { entry ->
443           // This conditional removes all src classpathentries that a) have already been added or b) aren't "src" or "test".
444           // e.g. this removes the resources dir being copied into bin/main, bin/test AND bin/clover
445           // we add the resources and help/help dirs in as libs afterwards (see below)
446           if (entry.kind == 'src') {
447             if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) {
448               removeTheseToo += entry
449             } else {
450               alreadyAddedSrcPath.putAt(entry.path, true)
451             }
452           }
453
454         }
455         cp.entries.removeAll(removeTheseToo)
456
457         //cp.entries += new Output("${eclipse_bin_dir}/main")
458         if (file(helpParentDir).isDirectory()) {
459           cp.entries += new Library(fileReference(helpParentDir))
460         }
461         if (file(resourceDir).isDirectory()) {
462           cp.entries += new Library(fileReference(resourceDir))
463         }
464
465         HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
466
467         sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
468           //don't want to add outputDir as eclipse is using its own output dir in bin/main
469           if (it.isDirectory() || ! it.exists()) {
470             // don't add dirs to classpath, especially if they don't exist
471             return false // groovy "continue" in .any closure
472           }
473           def itPath = it.toString()
474           if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
475             // make relative path
476             itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
477           }
478           if (alreadyAddedLibPath.get(itPath)) {
479             //println("Not adding duplicate entry "+itPath)
480           } else {
481             //println("Adding entry "+itPath)
482             cp.entries += new Library(fileReference(itPath))
483             alreadyAddedLibPath.put(itPath, true)
484           }
485         }
486
487         sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
488           //no longer want to add outputDir as eclipse is using its own output dir in bin/main
489           if (it.isDirectory() || ! it.exists()) {
490             // don't add dirs to classpath
491             return false // groovy "continue" in .any closure
492           }
493
494           def itPath = it.toString()
495           if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
496             itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
497           }
498           if (alreadyAddedLibPath.get(itPath)) {
499             // don't duplicate
500           } else {
501             def lib = new Library(fileReference(itPath))
502             lib.entryAttributes["test"] = "true"
503             cp.entries += lib
504             alreadyAddedLibPath.put(itPath, true)
505           }
506         }
507
508       } // whenMerged
509
510     } // file
511
512     containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
513
514   } // classpath
515
516   jdt {
517     // for the IDE, use java 11 compatibility
518     sourceCompatibility = compile_source_compatibility
519     targetCompatibility = compile_target_compatibility
520     javaRuntimeName = eclipse_java_runtime_name
521
522     // add in jalview project specific properties/preferences into eclipse core preferences
523     file {
524       withProperties { props ->
525         def jalview_prefs = new Properties()
526         def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
527         jalview_prefs.load(ins)
528         ins.close()
529         jalview_prefs.forEach { t, v ->
530           if (props.getAt(t) == null) {
531             props.putAt(t, v)
532           }
533         }
534       }
535     }
536
537   } // jdt
538
539   if (IN_ECLIPSE) {
540     // Don't want these to be activated if in headless build
541     synchronizationTasks "eclipseSynchronizationTask"
542     autoBuildTasks "eclipseAutoBuildTask"
543
544   }
545 }
546
547
548 task cloverInstr() {
549   // only instrument source, we build test classes as normal
550   inputs.files files (sourceSets.main.allJava) // , fileTree(dir: testSourceDir, include: ["**/*.java"]))
551   outputs.dir cloverInstrDir
552
553   doFirst {
554     delete cloverInstrDir
555     def argsList = ["--initstring", "${buildDir}/clover/clover.db",
556     "-d", "${buildDir}/${cloverSourcesInstrDir}"]
557     argsList.addAll(inputs.files.files.collect({ file ->
558       file.absolutePath
559     }))
560     String[] args = argsList.toArray()
561     println("About to instrument "+args.length +" files")
562     com.atlassian.clover.CloverInstr.mainImpl(args)
563   }
564 }
565
566
567 task cloverReport {
568   group = "Verification"
569     description = "Createst the Clover report"
570     inputs.dir "${buildDir}/clover"
571     outputs.dir "${reportsDir}/clover"
572     onlyIf {
573       file("${buildDir}/clover/clover.db").exists()
574     }
575   doFirst {
576     def argsList = ["--initstring", "${buildDir}/clover/clover.db",
577     "-o", "${reportsDir}/clover"]
578     String[] args = argsList.toArray()
579     com.atlassian.clover.reporters.html.HtmlReporter.runReport(args)
580
581     // and generate ${reportsDir}/clover/clover.xml
582     args = ["--initstring", "${buildDir}/clover/clover.db",
583     "-o", "${reportsDir}/clover/clover.xml"].toArray()
584     com.atlassian.clover.reporters.xml.XMLReporter.runReport(args)
585   }
586 }
587 // end clover bits
588
589
590 compileJava {
591
592   doFirst {
593     sourceCompatibility = compile_source_compatibility
594     targetCompatibility = compile_target_compatibility
595     options.compilerArgs = additional_compiler_args
596     print ("Setting target compatibility to "+targetCompatibility+"\n")
597   }
598
599 }
600
601
602 compileTestJava {
603   if (use_clover) {
604     dependsOn compileCloverJava
605     classpath += configurations.cloverRuntime
606   } else {
607     classpath += sourceSets.main.runtimeClasspath
608   }
609   doFirst {
610     sourceCompatibility = compile_source_compatibility
611     targetCompatibility = compile_target_compatibility
612     options.compilerArgs = additional_compiler_args
613     print ("Setting target compatibility to "+targetCompatibility+"\n")
614   }
615 }
616
617
618 compileCloverJava {
619
620   doFirst {
621     sourceCompatibility = compile_source_compatibility
622     targetCompatibility = compile_target_compatibility
623     options.compilerArgs += additional_compiler_args
624     print ("Setting target compatibility to "+targetCompatibility+"\n")
625   }
626   classpath += configurations.cloverRuntime
627 }
628
629
630 clean {
631   doFirst {
632     delete sourceSets.main.java.outputDir
633   }
634 }
635
636
637 cleanTest {
638   doFirst {
639     delete sourceSets.test.java.outputDir
640     delete cloverInstrDir
641   }
642 }
643
644
645 // format is a string like date.format("dd MMMM yyyy")
646 def getDate(format) {
647   def date = new Date()
648   return date.format(format)
649 }
650
651
652 task setGitVals {
653   def hashStdOut = new ByteArrayOutputStream()
654   exec {
655     commandLine "git", "rev-parse", "--short", "HEAD"
656     standardOutput = hashStdOut
657     ignoreExitValue true
658   }
659
660   def branchStdOut = new ByteArrayOutputStream()
661   exec {
662     commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
663     standardOutput = branchStdOut
664     ignoreExitValue true
665   }
666
667   gitHash = hashStdOut.toString().trim()
668   gitBranch = branchStdOut.toString().trim()
669
670   outputs.upToDateWhen { false }
671 }
672
673
674 task createBuildProperties(type: WriteProperties) {
675   dependsOn setGitVals
676   inputs.dir(sourceDir)
677   inputs.dir(resourceDir)
678   file(buildProperties).getParentFile().mkdirs()
679   outputFile (buildProperties)
680   // taking time specific comment out to allow better incremental builds
681   comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
682   //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
683   property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
684   property "VERSION", JALVIEW_VERSION
685   property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
686   outputs.file(outputFile)
687 }
688
689
690 task cleanBuildingHTML(type: Delete) {
691   doFirst {
692     delete buildingHTML
693   }
694 }
695
696
697 task convertBuildingMD(type: Exec) {
698   dependsOn cleanBuildingHTML
699   def buildingMD = "${jalviewDir}/${docDir}/building.md"
700   def css = "${jalviewDir}/${docDir}/github.css"
701
702   def pandoc = null
703   pandoc_exec.split(",").each {
704     if (file(it.trim()).exists()) {
705       pandoc = it.trim()
706       return true
707     }
708   }
709
710   def hostname = "hostname".execute().text.trim()
711   if ((pandoc == null || ! file(pandoc).exists()) && hostname.equals("jv-bamboo")) {
712     pandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
713   }
714
715   doFirst {
716     if (pandoc != null && file(pandoc).exists()) {
717         commandLine pandoc, '-s', '-o', buildingHTML, '--metadata', 'pagetitle="Building Jalview from Source"', '--toc', '-H', css, buildingMD
718     } else {
719         println("Cannot find pandoc. Skipping convert building.md to HTML")
720         throw new StopExecutionException("Cannot find pandoc. Skipping convert building.md to HTML")
721     }
722   }
723
724   ignoreExitValue true
725
726   inputs.file(buildingMD)
727   inputs.file(css)
728   outputs.file(buildingHTML)
729 }
730
731
732 clean {
733   doFirst {
734     delete buildingHTML
735   }
736 }
737
738
739 task syncDocs(type: Sync) {
740   dependsOn convertBuildingMD
741   def syncDir = "${classesDir}/${docDir}"
742   from fileTree("${jalviewDir}/${docDir}")
743   into syncDir
744
745 }
746
747
748 task copyHelp(type: Copy) {
749   def inputDir = helpSourceDir
750   def outputDir = "${classesDir}/${help_dir}"
751   from(inputDir) {
752     exclude '**/*.gif'
753     exclude '**/*.jpg'
754     exclude '**/*.png'
755     filter(ReplaceTokens,
756       beginToken: '$$',
757       endToken: '$$',
758       tokens: [
759         'Version-Rel': JALVIEW_VERSION,
760         'Year-Rel': getDate("yyyy")
761       ]
762     )
763   }
764   from(inputDir) {
765     include '**/*.gif'
766     include '**/*.jpg'
767     include '**/*.png'
768   }
769   into outputDir
770
771   inputs.dir(inputDir)
772   outputs.files(helpFile)
773   outputs.dir(outputDir)
774 }
775
776
777 task syncLib(type: Sync) {
778   def syncDir = "${classesDir}/${libDistDir}"
779   from fileTree("${jalviewDir}/${libDistDir}")
780   into syncDir
781 }
782
783
784 task syncResources(type: Sync) {
785   from resourceDir
786   include "**/*.*"
787   into "${classesDir}"
788   preserve {
789     include "**"
790   }
791 }
792
793
794 task prepare {
795   dependsOn syncResources
796   dependsOn syncDocs
797   dependsOn copyHelp
798 }
799
800
801 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
802 test {
803   dependsOn prepare
804   dependsOn compileJava
805   if (use_clover) {
806     dependsOn cloverInstr
807   }
808
809   if (use_clover) {
810     print("Running tests " + (use_clover?"WITH":"WITHOUT") + " clover [clover="+use_clover+"]\n")
811   }
812
813   useTestNG() {
814     includeGroups testngGroups
815     preserveOrder true
816     useDefaultListeners=true
817   }
818
819   workingDir = jalviewDir
820   //systemProperties 'clover.jar' System.properties.clover.jar
821   sourceCompatibility = compile_source_compatibility
822   targetCompatibility = compile_target_compatibility
823   jvmArgs += additional_compiler_args
824
825 }
826
827
828 task buildIndices(type: JavaExec) {
829   dependsOn copyHelp
830   classpath = sourceSets.main.compileClasspath
831   main = "com.sun.java.help.search.Indexer"
832   workingDir = "${classesDir}/${help_dir}"
833   def argDir = "html"
834   args = [ argDir ]
835   inputs.dir("${workingDir}/${argDir}")
836
837   outputs.dir("${classesDir}/doc")
838   outputs.dir("${classesDir}/help")
839   outputs.file("${workingDir}/JavaHelpSearch/DOCS")
840   outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
841   outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
842   outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
843   outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
844   outputs.file("${workingDir}/JavaHelpSearch/TMAP")
845 }
846
847
848 task compileLinkCheck(type: JavaCompile) {
849   options.fork = true
850   classpath = files("${jalviewDir}/${utilsDir}")
851   destinationDir = file("${jalviewDir}/${utilsDir}")
852   source = fileTree(dir: "${jalviewDir}/${utilsDir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
853
854   inputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.java")
855   inputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.java")
856   outputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.class")
857   outputs.file("${jalviewDir}/${utilsDir}/BufferedLineReader.class")
858 }
859
860
861 task linkCheck(type: JavaExec) {
862   dependsOn prepare, compileLinkCheck
863
864   def helpLinksCheckerOutFile = file("${jalviewDir}/${utilsDir}/HelpLinksChecker.out")
865   classpath = files("${jalviewDir}/${utilsDir}")
866   main = "HelpLinksChecker"
867   workingDir = jalviewDir
868   args = [ "${classesDir}/${help_dir}", "-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}/${help_dir}")
880   outputs.file(helpLinksCheckerOutFile)
881 }
882
883 // import the pubhtmlhelp target
884 ant.properties.basedir = "${jalviewDir}"
885 ant.properties.helpBuildDir = "${jalviewDirAbsolutePath}/${classes_dir}/${help_dir}"
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   def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
1216   def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
1217   inputs.file(install4jTemplateFile)
1218   inputs.file(install4jFileAssociationsFile)
1219   outputs.file(install4jConfFile)
1220
1221   doLast {
1222     def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
1223
1224     // turn off code signing if no OSX_KEYPASS
1225     if (OSX_KEYPASS == "") {
1226       install4jConfigXml.'**'.codeSigning.each { codeSigning ->
1227         codeSigning.'@macEnabled' = "false"
1228       }
1229       install4jConfigXml.'**'.windows.each { windows ->
1230         windows.'@runPostProcessor' = "false"
1231       }
1232     }
1233
1234     // put file association actions where placeholder action is
1235     def install4jFileAssociationsText = install4jFileAssociationsFile.text
1236     def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
1237     install4jConfigXml.'**'.action.any { a ->
1238       if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
1239         def parent = a.parent()
1240         parent.remove(a)
1241         fileAssociationActions.each { faa ->
1242             parent.append(faa)
1243         }
1244         // don't need to continue in .any loop once replacements have been made
1245         return true
1246       }
1247     }
1248
1249     // write install4j file
1250     install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
1251   }
1252 }
1253
1254
1255 clean {
1256   doFirst {
1257     delete install4jConfFile
1258   }
1259 }
1260
1261
1262 task installers(type: com.install4j.gradle.Install4jTask) {
1263   group = "distribution"
1264   description = "Create the install4j installers"
1265   dependsOn setGitVals
1266   dependsOn getdown
1267   dependsOn copyInstall4jTemplate
1268
1269   projectFile = install4jConfFile
1270
1271   // create an md5 for the input files to use as version for install4j conf file
1272   def digest = MessageDigest.getInstance("MD5")
1273   digest.update(
1274     (file("${install4jDir}/${install4j_template}").text + 
1275     file("${install4jDir}/${install4j_info_plist_file_associations}").text +
1276     file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
1277   def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
1278   if (filesMd5.length() >= 8) {
1279     filesMd5 = filesMd5.substring(0,8)
1280   }
1281   def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
1282
1283   variables = [
1284     'OSX_KEYSTORE': OSX_KEYSTORE,
1285     'JSIGN_SH': JSIGN_SH,
1286     'JRE_DIR': getdown_app_dir_java,
1287     'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
1288     'JALVIEW_VERSION': JALVIEW_VERSION,
1289     'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
1290     'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
1291     'JAVA_VERSION': JAVA_VERSION,
1292     'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
1293     'VERSION': JALVIEW_VERSION,
1294     'MACOS_JAVA_VM_DIR': macosJavaVMDir,
1295     'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
1296     'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
1297     'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
1298     'COPYRIGHT_MESSAGE': install4j_copyright_message,
1299     'MACOS_BUNDLE_ID': install4j_macOS_bundle_id,
1300     'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
1301     'GETDOWN_DIST_DIR': getdown_app_dir,
1302     'GETDOWN_ALT_DIR': getdown_app_dir_alt,
1303     'GETDOWN_INSTALL_DIR': getdown_install_dir,
1304     'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
1305   ]
1306
1307   destination = "${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}"
1308   buildSelected = true
1309
1310   if (install4j_faster.equals("true") || CHANNEL.startsWith("DEVELOP") || CHANNEL.startsWith("LOCAL")) {
1311     // this doesn't seem to work
1312     faster = true
1313     disableSigning = true
1314   }
1315
1316   if (OSX_KEYPASS) {
1317     macKeystorePassword = OSX_KEYPASS
1318   }
1319
1320   doFirst {
1321     println("Using projectFile "+projectFile)
1322   }
1323
1324   inputs.dir(getdownWebsiteDir)
1325   inputs.file(install4jConfFile)
1326   inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
1327   inputs.dir(macosJavaVMDir)
1328   inputs.dir(windowsJavaVMDir)
1329   outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
1330 }
1331
1332
1333 task sourceDist(type: Tar) {
1334   
1335   def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
1336   def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
1337   // cater for buildship < 3.1 [3.0.1 is max version in eclipse 2018-09]
1338   try {
1339     archiveFileName = outputFileName
1340   } catch (Exception e) {
1341     archiveName = outputFileName
1342   }
1343   
1344   compression Compression.GZIP
1345   
1346   into project.name
1347
1348   def EXCLUDE_FILES=["build/*","bin/*","test-output/","test-reports","tests","clover*/*"
1349   ,".*"
1350   ,"benchmarking/*"
1351   ,"**/.*"
1352   ,"*.class"
1353   ,"**/*.class","${j11modDir}/**/*.jar","appletlib","**/*locales"
1354   ,"*locales/**",
1355   ,"utils/InstallAnywhere"] 
1356   def PROCESS_FILES=[   "AUTHORS",
1357   "CITATION",
1358   "FEATURETODO",
1359   "JAVA-11-README",
1360   "FEATURETODO",
1361   "LICENSE",
1362   "**/README",
1363   "RELEASE",
1364   "THIRDPARTYLIBS","TESTNG",
1365   "build.gradle",
1366   "gradle.properties",
1367   "**/*.java",
1368   "**/*.html",
1369   "**/*.xml",
1370   "**/*.gradle",
1371   "**/*.groovy",
1372   "**/*.properties",
1373   "**/*.perl",
1374   "**/*.sh"]
1375
1376   from(jalviewDir) {
1377     exclude (EXCLUDE_FILES)
1378     include (PROCESS_FILES)
1379     filter(ReplaceTokens,
1380       beginToken: '$$',
1381       endToken: '$$',
1382       tokens: [
1383         'Version-Rel': JALVIEW_VERSION,
1384         'Year-Rel': getDate("yyyy")
1385       ]
1386     )
1387   }
1388   from(jalviewDir) {
1389     exclude (EXCLUDE_FILES)
1390     exclude (PROCESS_FILES)
1391     exclude ("appletlib")
1392     exclude ("**/*locales")
1393     exclude ("*locales/**")
1394     exclude ("utils/InstallAnywhere")
1395
1396     exclude (getdown_files_dir)
1397     exclude (getdown_website_dir)
1398
1399     // exluding these as not using jars as modules yet
1400     exclude ("${j11modDir}/**/*.jar")
1401   }
1402   //  from (jalviewDir) {
1403   //    // explicit includes for stuff that seemed to not get included
1404   //    include(fileTree("test/**/*."))
1405   //    exclude(EXCLUDE_FILES)
1406   //    exclude(PROCESS_FILES)
1407   //  }
1408 }
1409
1410
1411 task helppages {
1412   dependsOn copyHelp
1413   dependsOn pubhtmlhelp
1414   
1415   inputs.dir("${classesDir}/${help_dir}")
1416   outputs.dir("${buildDir}/distributions/${help_dir}")
1417 }
1418
1419 // LARGE AMOUNT OF JALVIEWJS STUFF DELETED HERE
1420 task eclipseAutoBuildTask {}
1421 task eclipseSynchronizationTask {}