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