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