JAL-3210 merged from develop: build.gradle and gradle.properties
[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   J2S_ENABLED = (project.hasProperty('j2s.compiler.status') && project['j2s.compiler.status'] != null && project['j2s.compiler.status'] == "enable")
100   if (J2S_ENABLED) {
101     println("J2S ENABLED")
102   }
103   
104   /* *-/
105   System.properties.sort { it.key }.each {
106     key, val -> println("SYSTEM PROPERTY ${key}='${val}'")
107   }
108   /-* *-/
109   if (false && IN_ECLIPSE) {
110     jalviewDir = jalviewDirAbsolutePath
111   }
112   */
113
114   // essentials
115   bareSourceDir = string(source_dir)
116   sourceDir = string("${jalviewDir}/${bareSourceDir}")
117   resourceDir = string("${jalviewDir}/${resource_dir}")
118   bareTestSourceDir = string(test_source_dir)
119   testSourceDir = string("${jalviewDir}/${bareTestSourceDir}")
120
121   // clover
122   cloverInstrDir = file("${buildDir}/${cloverSourcesInstrDir}")
123   cloverDb = string("${buildDir}/clover/clover.db")
124   classesDir = string("${jalviewDir}/${classes_dir}")
125   if (clover.equals("true")) {
126     use_clover = true
127     classesDir = string("${buildDir}/${cloverClassesDir}")
128   } else {
129     use_clover = false
130     classesDir = string("${jalviewDir}/${classes_dir}")
131   }
132
133   classes = classesDir
134
135   getdownWebsiteDir = string("${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}")
136   buildDist = true
137
138   // the following values might be overridden by the CHANNEL switch
139   getdownChannelName = CHANNEL.toLowerCase()
140   getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
141   getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
142   getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
143   getdownAppDistDir = getdown_app_dir_alt
144   buildProperties = string("${resourceDir}/${build_properties_file}")
145   reportRsyncCommand = false
146   jvlChannelName = CHANNEL.toLowerCase()
147   switch (CHANNEL) {
148
149     case "BUILD":
150     // TODO: get bamboo build artifact URL for getdown artifacts
151     getdown_channel_base = bamboo_channelbase
152     getdownChannelName = string("${bamboo_planKey}/${JAVA_VERSION}")
153     getdownAppBase = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
154     jvlChannelName += "_${getdownChannelName}"
155     // automatically add the test group Not-bamboo for exclusion 
156     if ("".equals(testngExcludedGroups)) { 
157       testngExcludedGroups = "Not-bamboo"
158     }
159     break
160
161     case "RELEASE":
162     getdownAppDistDir = getdown_app_dir_release
163     reportRsyncCommand = true
164     // Don't ignore transpile errors for release build
165     if (jalviewjs_ignore_transpile_errors.equals("true")) {
166       jalviewjs_ignore_transpile_errors = "false"
167       println("Setting jalviewjs_ignore_transpile_errors to 'false'")
168     }
169     break
170
171     case "ARCHIVE":
172     getdownChannelName = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
173     getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
174     getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
175     if (!file("${ARCHIVEDIR}/${packageDir}").exists()) {
176       throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
177     } else {
178       packageDir = string("${ARCHIVEDIR}/${packageDir}")
179       buildProperties = string("${buildDir}/archive/${build_properties_file}")
180       buildDist = false
181     }
182     reportRsyncCommand = true
183     break
184
185     case "ARCHIVELOCAL":
186     getdownChannelName = string("archive/${JALVIEW_VERSION}")
187     getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
188     getdownAppBase = file(getdownWebsiteDir).toURI().toString()
189     if (!file("${ARCHIVEDIR}/${packageDir}").exists()) {
190       throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
191     } else {
192       packageDir = string("${ARCHIVEDIR}/${packageDir}")
193       buildProperties = string("${buildDir}/archive/${build_properties_file}")
194       buildDist = false
195     }
196     reportRsyncCommand = true
197     getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
198     break
199
200     case "DEVELOP":
201     reportRsyncCommand = true
202     break
203
204     case "TEST-RELEASE":
205     reportRsyncCommand = true
206     // Don't ignore transpile errors for release build
207     if (jalviewjs_ignore_transpile_errors.equals("true")) {
208       jalviewjs_ignore_transpile_errors = "false"
209       println("Setting jalviewjs_ignore_transpile_errors to 'false'")
210     }
211     break
212
213     case ~/^SCRATCH(|-[-\w]*)$/:
214     getdownChannelName = CHANNEL
215     getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
216     getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
217     reportRsyncCommand = true
218     break
219
220     case "TEST-LOCAL":
221     if (!file("${LOCALDIR}").exists()) {
222       throw new GradleException("Must provide a LOCALDIR value to produce a local distribution")
223     } else {
224       getdownAppBase = file(file("${LOCALDIR}").getAbsolutePath()).toURI().toString()
225       getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
226     }
227     break
228
229     case "LOCAL":
230     getdownAppBase = file(getdownWebsiteDir).toURI().toString()
231     getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
232     break
233
234     default: // something wrong specified
235     throw new GradleException("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
236     break
237
238   }
239   // override getdownAppBase if requested
240   if (findProperty("getdown_appbase_override") != null) {
241     getdownAppBase = string(getProperty("getdown_appbase_override"))
242     println("Overriding getdown appbase with '${getdownAppBase}'")
243   }
244   // sanitise file name for jalview launcher file for this channel
245   jvlChannelName = jvlChannelName.replaceAll(/[^\w\-]/,"_")
246
247   getdownAppDir = string("${getdownWebsiteDir}/${getdownAppDistDir}")
248   //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}"
249   getdownResourceDir = string("${getdownWebsiteDir}/${getdown_resource_dir}")
250   getdownInstallDir = string("${getdownWebsiteDir}/${getdown_install_dir}")
251   getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
252   getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
253   /* compile without modules -- using classpath libraries
254   modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
255   modules_runtimeClasspath = modules_compileClasspath
256   */
257   gitHash = string("")
258   gitBranch = string("")
259
260   println("Using a ${CHANNEL} profile.")
261
262   additional_compiler_args = []
263   // configure classpath/args for j8/j11 compilation
264   if (JAVA_VERSION.equals("1.8")) {
265     JAVA_INTEGER_VERSION = string("8")
266     //libDir = j8libDir
267     libDir = j11libDir
268     libDistDir = j8libDir
269     compile_source_compatibility = 1.8
270     compile_target_compatibility = 1.8
271     // these are getdown.txt properties defined dependent on the JAVA_VERSION
272     getdownAltJavaMinVersion = string(findProperty("getdown_alt_java8_min_version"))
273     getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java8_max_version"))
274     // this property is assigned below and expanded to multiple lines in the getdown task
275     getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java8_txt_multi_java_location"))
276     // this property is for the Java library used in eclipse
277     eclipseJavaRuntimeName = string("JavaSE-1.8")
278   } else if (JAVA_VERSION.equals("11")) {
279     JAVA_INTEGER_VERSION = string("11")
280     libDir = j11libDir
281     libDistDir = j11libDir
282     compile_source_compatibility = 11
283     compile_target_compatibility = 11
284     getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
285     getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
286     getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
287     eclipseJavaRuntimeName = string("JavaSE-11")
288     /* compile without modules -- using classpath libraries
289     additional_compiler_args += [
290     '--module-path', modules_compileClasspath.asPath,
291     '--add-modules', j11modules
292     ]
293      */
294   } else if (JAVA_VERSION.equals("12") || JAVA_VERSION.equals("13")) {
295     JAVA_INTEGER_VERSION = JAVA_VERSION
296     libDir = j11libDir
297     libDistDir = j11libDir
298     compile_source_compatibility = JAVA_VERSION
299     compile_target_compatibility = JAVA_VERSION
300     getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
301     getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
302     getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
303     eclipseJavaRuntimeName = string("JavaSE-11")
304     /* compile without modules -- using classpath libraries
305     additional_compiler_args += [
306     '--module-path', modules_compileClasspath.asPath,
307     '--add-modules', j11modules
308     ]
309      */
310   } else {
311     throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
312   }
313
314
315   // for install4j
316   JAVA_MIN_VERSION = JAVA_VERSION
317   JAVA_MAX_VERSION = JAVA_VERSION
318   def jreInstallsDir = string(jre_installs_dir)
319   if (jreInstallsDir.startsWith("~/")) {
320     jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1)
321   }
322   macosJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-mac-x64/jre")
323   macosJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-mac-x64.tar.gz")
324   windowsJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-windows-x64/jre")
325   windowsJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-windows-x64.tar.gz")
326   linuxJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-linux-x64/jre")
327   linuxJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-linux-x64.tar.gz")
328   install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
329   install4jConfFileName = string("jalview-install4j-conf.install4j")
330   install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
331   install4jHomeDir = install4j_home_dir
332   if (install4jHomeDir.startsWith("~/")) {
333     install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1)
334   }
335
336
337
338   buildingHTML = string("${jalviewDir}/${docDir}/building.html")
339   helpFile = string("${classesDir}/${help_dir}/help.jhm")
340   helpParentDir = string("${jalviewDir}/${help_parent_dir}")
341   helpSourceDir = string("${helpParentDir}/${help_dir}")
342
343
344   relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
345   jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
346   jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}")
347   if (IN_ECLIPSE) {
348     jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
349   } else {
350     jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
351   }
352   jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
353   jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
354   jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
355   jalviewjsJalviewCoreHtmlFile = string("")
356   jalviewjsJalviewCoreName = string(jalviewjs_core_name)
357   jalviewjsCoreClasslists = []
358   jalviewjsJalviewTemplateName = string(jalviewjs_name)
359   jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
360   jalviewjsJ2sProps = null
361   jalviewjsJ2sPlugin = jalviewjs_j2s_plugin
362
363   eclipseWorkspace = null
364   eclipseBinary = string("")
365   eclipseVersion = string("")
366   eclipseDebug = false
367   // ENDEXT
368 }
369
370
371 sourceSets {
372   main {
373     java {
374       srcDirs sourceDir
375       outputDir = file(classesDir)
376     }
377
378     resources {
379       srcDirs resourceDir
380       srcDirs += helpParentDir
381     }
382
383     jar.destinationDir = file("${jalviewDir}/${packageDir}")
384
385     compileClasspath = files(sourceSets.main.java.outputDir)
386     //compileClasspath += files(sourceSets.main.resources.srcDirs)
387     compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
388
389     runtimeClasspath = compileClasspath
390   }
391
392   clover {
393     java {
394       srcDirs = [ cloverInstrDir ]
395       outputDir = file("${buildDir}/${cloverClassesDir}")
396     }
397
398     resources {
399       srcDirs = sourceSets.main.resources.srcDirs
400     }
401     compileClasspath = configurations.cloverRuntime + files( sourceSets.clover.java.outputDir )
402     compileClasspath += files(sourceSets.main.java.outputDir)
403     compileClasspath += sourceSets.main.compileClasspath
404     compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}", include: ["**/*.jar"])
405     compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
406
407     runtimeClasspath = compileClasspath
408   }
409
410   test {
411     java {
412       srcDirs testSourceDir
413       outputDir = file("${jalviewDir}/${testOutputDir}")
414     }
415
416     resources {
417       srcDirs = sourceSets.main.resources.srcDirs
418     }
419
420     compileClasspath = files( sourceSets.test.java.outputDir )
421
422     if (use_clover) {
423       compileClasspath = sourceSets.clover.compileClasspath
424     } else {
425       compileClasspath += files(sourceSets.main.java.outputDir)
426     }
427
428     compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
429     compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}/testnglibs", include: ["**/*.jar"])
430     compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}/testlibs", include: ["**/*.jar"])
431
432     runtimeClasspath = compileClasspath
433   }
434 }
435
436
437 // clover bits
438 dependencies {
439   if (use_clover) {
440     cloverCompile 'org.openclover:clover:4.4.1'
441     testCompile 'org.openclover:clover:4.4.1'
442   }
443 }
444
445
446 configurations {
447   cloverRuntime
448   cloverRuntime.extendsFrom cloverCompile
449 }
450
451
452 // eclipse project and settings files creation, also used by buildship
453 eclipse {
454   project {
455     name = eclipse_project_name
456
457     natures 'org.eclipse.jdt.core.javanature',
458     'org.eclipse.jdt.groovy.core.groovyNature',
459     'org.eclipse.buildship.core.gradleprojectnature'
460
461     buildCommand 'org.eclipse.jdt.core.javabuilder'
462     buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
463   }
464
465   classpath {
466     //defaultOutputDir = sourceSets.main.java.outputDir
467     def removeThese = []
468     configurations.each{
469       if (it.isCanBeResolved()) {
470         removeThese += it
471       }
472     }
473
474     minusConfigurations += removeThese
475     plusConfigurations = [ ]
476     file {
477
478       whenMerged { cp ->
479         def removeTheseToo = []
480         HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
481         cp.entries.each { entry ->
482           // This conditional removes all src classpathentries that a) have already been added or b) aren't "src" or "test".
483           // e.g. this removes the resources dir being copied into bin/main, bin/test AND bin/clover
484           // we add the resources and help/help dirs in as libs afterwards (see below)
485           if (entry.kind == 'src') {
486             if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) {
487               removeTheseToo += entry
488             } else {
489               alreadyAddedSrcPath.putAt(entry.path, true)
490             }
491           }
492
493         }
494         cp.entries.removeAll(removeTheseToo)
495
496         //cp.entries += new Output("${eclipse_bin_dir}/main")
497         if (file(helpParentDir).isDirectory()) {
498           cp.entries += new Library(fileReference(helpParentDir))
499         }
500         if (file(resourceDir).isDirectory()) {
501           cp.entries += new Library(fileReference(resourceDir))
502         }
503
504         HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
505
506         sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
507           //don't want to add outputDir as eclipse is using its own output dir in bin/main
508           if (it.isDirectory() || ! it.exists()) {
509             // don't add dirs to classpath, especially if they don't exist
510             return false // groovy "continue" in .any closure
511           }
512           def itPath = it.toString()
513           if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
514             // make relative path
515             itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
516           }
517           if (alreadyAddedLibPath.get(itPath)) {
518             //println("Not adding duplicate entry "+itPath)
519           } else {
520             //println("Adding entry "+itPath)
521             cp.entries += new Library(fileReference(itPath))
522             alreadyAddedLibPath.put(itPath, true)
523           }
524         }
525
526         sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
527           //no longer want to add outputDir as eclipse is using its own output dir in bin/main
528           if (it.isDirectory() || ! it.exists()) {
529             // don't add dirs to classpath
530             return false // groovy "continue" in .any closure
531           }
532
533           def itPath = it.toString()
534           if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
535             itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
536           }
537           if (alreadyAddedLibPath.get(itPath)) {
538             // don't duplicate
539           } else {
540             def lib = new Library(fileReference(itPath))
541             lib.entryAttributes["test"] = "true"
542             cp.entries += lib
543             alreadyAddedLibPath.put(itPath, true)
544           }
545         }
546
547       } // whenMerged
548
549     } // file
550
551     containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
552
553   } // classpath
554
555   jdt {
556     // for the IDE, use java 11 compatibility
557     sourceCompatibility = compile_source_compatibility
558     targetCompatibility = compile_target_compatibility
559     javaRuntimeName = eclipseJavaRuntimeName
560
561     // add in jalview project specific properties/preferences into eclipse core preferences
562     // and also the codestyle XML file
563     file {
564       withProperties { props ->
565         def jalview_prefs = new Properties()
566         def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
567         jalview_prefs.load(ins)
568         ins.close()
569         jalview_prefs.forEach { t, v ->
570           if (props.getAt(t) == null) {
571             props.putAt(t, v)
572           }
573         }
574         // codestyle file -- overrides previous formatter prefs
575         def csFile = file("${jalviewDirAbsolutePath}/${eclipse_codestyle_file}")
576         if (csFile.exists()) {
577           XmlParser parser = new XmlParser()
578           def profiles = parser.parse(csFile)
579           def profile = profiles.'profile'.find { p -> (p.'@kind' == "CodeFormatterProfile" && p.'@name' == "Jalview") }
580           if (profile != null) {
581             profile.'setting'.each { s ->
582               def id = s.'@id'
583               def value = s.'@value'
584               if (id != null && value != null) {
585                 props.putAt(id, value)
586               }
587             }
588           }
589         }
590       }
591     }
592
593   } // jdt
594
595   if (IN_ECLIPSE) {
596     // Don't want these to be activated if in headless build
597     synchronizationTasks "eclipseSynchronizationTask"
598     //autoBuildTasks "eclipseAutoBuildTask"
599
600   }
601 }
602
603
604 task cloverInstr {
605   // only instrument source, we build test classes as normal
606   inputs.files files (sourceSets.main.allJava,sourceSets.test.allJava) // , fileTree(dir:"$jalviewDir/$testSourceDir", include: ["**/*.java"]))
607   outputs.dir cloverInstrDir
608
609   doFirst {
610     delete cloverInstrDir
611     def argsList = [
612       "--initstring",
613       cloverDb,
614       "-d",
615       cloverInstrDir.getPath(),
616     ]
617     argsList.addAll(
618       inputs.files.files.collect(
619         { file -> file.absolutePath }
620       )
621     )
622     String[] args = argsList.toArray()
623     println("About to instrument "+args.length +" files")
624     com.atlassian.clover.CloverInstr.mainImpl(args)
625   }
626 }
627
628
629 cloverClasses.dependsOn cloverInstr
630
631
632 task cloverReport {
633   group = "Verification"
634   description = "Creates the Clover report"
635   inputs.dir "${buildDir}/clover"
636   outputs.dir "${reportsDir}/clover"
637   onlyIf {
638     file(cloverDb).exists()
639   }
640   doFirst {
641     def argsList = [
642       "--initstring",
643       cloverDb,
644       "-o",
645       "${reportsDir}/clover"
646     ]
647     String[] args = argsList.toArray()
648     com.atlassian.clover.reporters.html.HtmlReporter.runReport(args)
649
650     // and generate ${reportsDir}/clover/clover.xml
651     args = [
652       "--initstring",
653       cloverDb,
654       "-o",
655       "${reportsDir}/clover/clover.xml"
656     ].toArray()
657     com.atlassian.clover.reporters.xml.XMLReporter.runReport(args)
658   }
659 }
660
661
662 compileCloverJava {
663
664   doFirst {
665     sourceCompatibility = compile_source_compatibility
666     targetCompatibility = compile_target_compatibility
667     options.compilerArgs += additional_compiler_args
668     print ("Setting target compatibility to "+targetCompatibility+"\n")
669   }
670   classpath += configurations.cloverRuntime
671 }
672
673
674 task cleanClover {
675   doFirst {
676     delete cloverInstrDir
677     delete cloverDb
678   }
679 }
680 // end clover bits
681
682
683 compileJava {
684
685   doFirst {
686     sourceCompatibility = compile_source_compatibility
687     targetCompatibility = compile_target_compatibility
688     options.compilerArgs = additional_compiler_args
689     print ("Setting target compatibility to "+targetCompatibility+"\n")
690   }
691
692 }
693
694
695 compileTestJava {
696   if (use_clover) {
697     dependsOn compileCloverJava
698     classpath += configurations.cloverRuntime
699   } else {
700     classpath += sourceSets.main.runtimeClasspath
701   }
702   doFirst {
703     sourceCompatibility = compile_source_compatibility
704     targetCompatibility = compile_target_compatibility
705     options.compilerArgs = additional_compiler_args
706     print ("Setting target compatibility to "+targetCompatibility+"\n")
707   }
708 }
709
710
711 clean {
712   doFirst {
713     delete sourceSets.main.java.outputDir
714   }
715 }
716
717
718 cleanTest {
719   dependsOn cleanClover
720   doFirst {
721     delete sourceSets.test.java.outputDir
722   }
723 }
724
725
726 // format is a string like date.format("dd MMMM yyyy")
727 def getDate(format) {
728   def date = new Date()
729   return date.format(format)
730 }
731
732
733 task setGitVals {
734   def hashStdOut = new ByteArrayOutputStream()
735   exec {
736     commandLine "git", "rev-parse", "--short", "HEAD"
737     standardOutput = hashStdOut
738     ignoreExitValue true
739   }
740
741   def branchStdOut = new ByteArrayOutputStream()
742   exec {
743     commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
744     standardOutput = branchStdOut
745     ignoreExitValue true
746   }
747
748   gitHash = hashStdOut.toString().trim()
749   gitBranch = branchStdOut.toString().trim()
750
751   outputs.upToDateWhen { false }
752 }
753
754
755 task createBuildProperties(type: WriteProperties) {
756   group = "build"
757   description = "Create the ${buildProperties} file"
758   dependsOn setGitVals
759   inputs.dir(sourceDir)
760   inputs.dir(resourceDir)
761   file(buildProperties).getParentFile().mkdirs()
762   outputFile (buildProperties)
763   // taking time specific comment out to allow better incremental builds
764   comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
765   //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
766   property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
767   property "VERSION", JALVIEW_VERSION
768   property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
769   outputs.file(outputFile)
770 }
771
772
773 clean {
774   doFirst {
775     delete buildProperties
776   }
777 }
778
779
780 task cleanBuildingHTML(type: Delete) {
781   doFirst {
782     delete buildingHTML
783   }
784 }
785
786
787 task convertBuildingMD(type: Exec) {
788   dependsOn cleanBuildingHTML
789   def buildingMD = "${jalviewDir}/${docDir}/building.md"
790   def css = "${jalviewDir}/${docDir}/github.css"
791
792   def pandoc = null
793   pandoc_exec.split(",").each {
794     if (file(it.trim()).exists()) {
795       pandoc = it.trim()
796       return true
797     }
798   }
799
800   def buildtoolsPandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
801   if ((pandoc == null || ! file(pandoc).exists()) && file(buildtoolsPandoc).exists()) {
802     pandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
803   }
804
805   doFirst {
806     if (pandoc != null && file(pandoc).exists()) {
807         commandLine pandoc, '-s', '-o', buildingHTML, '--metadata', 'pagetitle="Building Jalview from Source"', '--toc', '-H', css, buildingMD
808     } else {
809         println("Cannot find pandoc. Skipping convert building.md to HTML")
810         throw new StopExecutionException("Cannot find pandoc. Skipping convert building.md to HTML")
811     }
812   }
813
814   ignoreExitValue true
815
816   inputs.file(buildingMD)
817   inputs.file(css)
818   outputs.file(buildingHTML)
819 }
820
821
822 clean {
823   doFirst {
824     delete buildingHTML
825   }
826 }
827
828
829 task syncDocs(type: Sync) {
830   dependsOn convertBuildingMD
831   def syncDir = "${classesDir}/${docDir}"
832   from fileTree("${jalviewDir}/${docDir}")
833   into syncDir
834
835 }
836
837
838 task copyHelp(type: Copy) {
839   def inputDir = helpSourceDir
840   def outputDir = "${classesDir}/${help_dir}"
841   from(inputDir) {
842     exclude '**/*.gif'
843     exclude '**/*.jpg'
844     exclude '**/*.png'
845     filter(ReplaceTokens,
846       beginToken: '$$',
847       endToken: '$$',
848       tokens: [
849         'Version-Rel': JALVIEW_VERSION,
850         'Year-Rel': getDate("yyyy")
851       ]
852     )
853   }
854   from(inputDir) {
855     include '**/*.gif'
856     include '**/*.jpg'
857     include '**/*.png'
858   }
859   into outputDir
860
861   inputs.dir(inputDir)
862   outputs.files(helpFile)
863   outputs.dir(outputDir)
864 }
865
866
867 task syncLib(type: Sync) {
868   def syncDir = "${classesDir}/${libDistDir}"
869   from fileTree("${jalviewDir}/${libDistDir}")
870   into syncDir
871 }
872
873
874 task syncResources(type: Sync) {
875   dependsOn createBuildProperties
876   from resourceDir
877   include "**/*.*"
878   into "${classesDir}"
879   preserve {
880     include "**"
881   }
882 }
883
884
885 task prepare {
886   dependsOn syncResources
887   dependsOn syncDocs
888   dependsOn copyHelp
889 }
890
891
892 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
893 test {
894   dependsOn prepare
895   dependsOn compileJava
896   if (use_clover) {
897     dependsOn cloverInstr
898   }
899
900   if (use_clover) {
901     print("Running tests " + (use_clover?"WITH":"WITHOUT") + " clover [clover="+use_clover+"]\n")
902   }
903
904   useTestNG() {
905     includeGroups testngGroups
906     excludeGroups testngExcludedGroups
907     preserveOrder true
908     useDefaultListeners=true
909   }
910
911   maxHeapSize = "1024m"
912
913   workingDir = jalviewDir
914   //systemProperties 'clover.jar' System.properties.clover.jar
915   sourceCompatibility = compile_source_compatibility
916   targetCompatibility = compile_target_compatibility
917   jvmArgs += additional_compiler_args
918
919 }
920
921
922 task buildIndices(type: JavaExec) {
923   dependsOn copyHelp
924   classpath = sourceSets.main.compileClasspath
925   main = "com.sun.java.help.search.Indexer"
926   workingDir = "${classesDir}/${help_dir}"
927   def argDir = "html"
928   args = [ argDir ]
929   inputs.dir("${workingDir}/${argDir}")
930
931   outputs.dir("${classesDir}/doc")
932   outputs.dir("${classesDir}/help")
933   outputs.file("${workingDir}/JavaHelpSearch/DOCS")
934   outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
935   outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
936   outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
937   outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
938   outputs.file("${workingDir}/JavaHelpSearch/TMAP")
939 }
940
941
942 task compileLinkCheck(type: JavaCompile) {
943   options.fork = true
944   classpath = files("${jalviewDir}/${utilsDir}")
945   destinationDir = file("${jalviewDir}/${utilsDir}")
946   source = fileTree(dir: "${jalviewDir}/${utilsDir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
947
948   inputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.java")
949   inputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.java")
950   outputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.class")
951   outputs.file("${jalviewDir}/${utilsDir}/BufferedLineReader.class")
952 }
953
954
955 task linkCheck(type: JavaExec) {
956   dependsOn prepare, compileLinkCheck
957
958   def helpLinksCheckerOutFile = file("${jalviewDir}/${utilsDir}/HelpLinksChecker.out")
959   classpath = files("${jalviewDir}/${utilsDir}")
960   main = "HelpLinksChecker"
961   workingDir = jalviewDir
962   args = [ "${classesDir}/${help_dir}", "-nointernet" ]
963
964   def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
965   def errFOS = outFOS
966   standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
967     outFOS,
968     standardOutput)
969   errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
970     outFOS,
971     errorOutput)
972
973   inputs.dir("${classesDir}/${help_dir}")
974   outputs.file(helpLinksCheckerOutFile)
975 }
976
977 // import the pubhtmlhelp target
978 ant.properties.basedir = "${jalviewDir}"
979 ant.properties.helpBuildDir = "${jalviewDirAbsolutePath}/${classes_dir}/${help_dir}"
980 ant.importBuild "${utilsDir}/publishHelp.xml"
981
982
983 task cleanPackageDir(type: Delete) {
984   doFirst {
985     delete fileTree(dir: "${jalviewDir}/${packageDir}", include: "*.jar")
986   }
987 }
988
989
990 jar {
991   dependsOn linkCheck
992   dependsOn buildIndices
993   dependsOn createBuildProperties
994
995   manifest {
996     attributes "Main-Class": mainClass,
997     "Permissions": "all-permissions",
998     "Application-Name": "Jalview Desktop",
999     "Codebase": application_codebase
1000   }
1001
1002   destinationDir = file("${jalviewDir}/${packageDir}")
1003   archiveName = rootProject.name+".jar"
1004
1005   exclude "cache*/**"
1006   exclude "*.jar"
1007   exclude "*.jar.*"
1008   exclude "**/*.jar"
1009   exclude "**/*.jar.*"
1010
1011   inputs.dir(classesDir)
1012   outputs.file("${jalviewDir}/${packageDir}/${archiveName}")
1013 }
1014
1015
1016 task copyJars(type: Copy) {
1017   from fileTree(dir: classesDir, include: "**/*.jar").files
1018   into "${jalviewDir}/${packageDir}"
1019 }
1020
1021
1022 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
1023 task syncJars(type: Sync) {
1024   from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
1025   into "${jalviewDir}/${packageDir}"
1026   preserve {
1027     include jar.archiveName
1028   }
1029 }
1030
1031
1032 task makeDist {
1033   group = "build"
1034   description = "Put all required libraries in dist"
1035   // order of "cleanPackageDir", "copyJars", "jar" important!
1036   jar.mustRunAfter cleanPackageDir
1037   syncJars.mustRunAfter cleanPackageDir
1038   dependsOn cleanPackageDir
1039   dependsOn syncJars
1040   dependsOn jar
1041   outputs.dir("${jalviewDir}/${packageDir}")
1042 }
1043
1044
1045 task cleanDist {
1046   dependsOn cleanPackageDir
1047   dependsOn cleanTest
1048   dependsOn clean
1049 }
1050
1051 shadowJar {
1052   group = "distribution"
1053   if (buildDist) {
1054     dependsOn makeDist
1055   }
1056   from ("${jalviewDir}/${libDistDir}") {
1057     include("*.jar")
1058   }
1059   manifest {
1060     attributes 'Implementation-Version': JALVIEW_VERSION
1061   }
1062   mainClassName = shadowJarMainClass
1063   mergeServiceFiles()
1064   classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
1065   minimize()
1066 }
1067
1068
1069 task getdownWebsite() {
1070   group = "distribution"
1071   description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
1072   if (buildDist) {
1073     dependsOn makeDist
1074   }
1075
1076   def getdownWebsiteResourceFilenames = []
1077   def getdownTextString = ""
1078   def getdownResourceDir = getdownResourceDir
1079   def getdownResourceFilenames = []
1080
1081   doFirst {
1082     // clean the getdown website and files dir before creating getdown folders
1083     delete getdownWebsiteDir
1084     delete getdownFilesDir
1085
1086     copy {
1087       from buildProperties
1088       rename(build_properties_file, getdown_build_properties)
1089       into getdownAppDir
1090     }
1091     getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
1092
1093     // go through properties looking for getdown_txt_...
1094     def props = project.properties.sort { it.key }
1095     if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
1096       props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
1097     }
1098     if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) {
1099       props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion)
1100     }
1101     if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
1102       props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
1103     }
1104
1105     props.put("getdown_txt_appbase", getdownAppBase)
1106     props.each{ prop, val ->
1107       if (prop.startsWith("getdown_txt_") && val != null) {
1108         if (prop.startsWith("getdown_txt_multi_")) {
1109           def key = prop.substring(18)
1110           val.split(",").each{ v ->
1111             def line = "${key} = ${v}\n"
1112             getdownTextString += line
1113           }
1114         } else {
1115           // file values rationalised
1116           if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1117             def r = null
1118             if (val.indexOf('/') == 0) {
1119               // absolute path
1120               r = file(val)
1121             } else if (val.indexOf('/') > 0) {
1122               // relative path (relative to jalviewDir)
1123               r = file( "${jalviewDir}/${val}" )
1124             }
1125             if (r.exists()) {
1126               val = "${getdown_resource_dir}/" + r.getName()
1127               getdownWebsiteResourceFilenames += val
1128               getdownResourceFilenames += r.getPath()
1129             }
1130           }
1131           if (! prop.startsWith("getdown_txt_resource")) {
1132             def line = prop.substring(12) + " = ${val}\n"
1133             getdownTextString += line
1134           }
1135         }
1136       }
1137     }
1138
1139     getdownWebsiteResourceFilenames.each{ filename ->
1140       getdownTextString += "resource = ${filename}\n"
1141     }
1142     getdownResourceFilenames.each{ filename ->
1143       copy {
1144         from filename
1145         into getdownResourceDir
1146       }
1147     }
1148
1149     def codeFiles = []
1150     fileTree(file(packageDir)).each{ f ->
1151       if (f.isDirectory()) {
1152         def files = fileTree(dir: f, include: ["*"]).getFiles()
1153         codeFiles += files
1154       } else if (f.exists()) {
1155         codeFiles += f
1156       }
1157     }
1158     codeFiles.sort().each{f ->
1159       def name = f.getName()
1160       def line = "code = ${getdownAppDistDir}/${name}\n"
1161       getdownTextString += line
1162       copy {
1163         from f.getPath()
1164         into getdownAppDir
1165       }
1166     }
1167
1168     // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
1169     /*
1170     if (JAVA_VERSION.equals("11")) {
1171     def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
1172     j11libFiles.sort().each{f ->
1173     def name = f.getName()
1174     def line = "code = ${getdown_j11lib_dir}/${name}\n"
1175     getdownTextString += line
1176     copy {
1177     from f.getPath()
1178     into getdownJ11libDir
1179     }
1180     }
1181     }
1182      */
1183
1184     // 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.
1185     //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
1186     getdownTextString += "resource = ${getdown_launcher_new}\n"
1187     getdownTextString += "class = ${mainClass}\n"
1188
1189     def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
1190     getdown_txt.write(getdownTextString)
1191
1192     def getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
1193     def launchJvl = file("${getdownWebsiteDir}/${getdownLaunchJvl}")
1194     launchJvl.write("appbase="+props.get("getdown_txt_appbase"))
1195
1196     copy {
1197       from getdownLauncher
1198       rename(file(getdownLauncher).getName(), getdown_launcher_new)
1199       into getdownWebsiteDir
1200     }
1201
1202     copy {
1203       from getdownLauncher
1204       if (file(getdownLauncher).getName() != getdown_launcher) {
1205         rename(file(getdownLauncher).getName(), getdown_launcher)
1206       }
1207       into getdownWebsiteDir
1208     }
1209
1210     if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
1211       copy {
1212         from getdown_txt
1213         from getdownLauncher
1214         from "${getdownWebsiteDir}/${getdown_build_properties}"
1215         if (file(getdownLauncher).getName() != getdown_launcher) {
1216           rename(file(getdownLauncher).getName(), getdown_launcher)
1217         }
1218         into getdownInstallDir
1219       }
1220
1221       copy {
1222         from getdownInstallDir
1223         into getdownFilesInstallDir
1224       }
1225     }
1226
1227     copy {
1228       from getdown_txt
1229       from launchJvl
1230       from getdownLauncher
1231       from "${getdownWebsiteDir}/${getdown_build_properties}"
1232       if (file(getdownLauncher).getName() != getdown_launcher) {
1233         rename(file(getdownLauncher).getName(), getdown_launcher)
1234       }
1235       into getdownFilesDir
1236     }
1237
1238     copy {
1239       from getdownResourceDir
1240       into "${getdownFilesDir}/${getdown_resource_dir}"
1241     }
1242   }
1243
1244   if (buildDist) {
1245     inputs.dir("${jalviewDir}/${packageDir}")
1246   }
1247   outputs.dir(getdownWebsiteDir)
1248   outputs.dir(getdownFilesDir)
1249 }
1250
1251
1252 // a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
1253 task getdownDigestDir(type: JavaExec) {
1254   def digestDirPropertyName = "DIGESTDIR"
1255   description = "Digest a local dir (-P${digestDirPropertyName}=...) for getdown"
1256   doFirst {
1257     classpath = files(getdownLauncher)
1258     def digestDir = findProperty(digestDirPropertyName)
1259     if (digestDir == null) {
1260       throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest")
1261     }
1262     args digestDir
1263   }
1264   main = "com.threerings.getdown.tools.Digester"
1265 }
1266
1267
1268 task getdownDigest(type: JavaExec) {
1269   group = "distribution"
1270   description = "Digest the getdown website folder"
1271   dependsOn getdownWebsite
1272   doFirst {
1273     classpath = files(getdownLauncher)
1274   }
1275   main = "com.threerings.getdown.tools.Digester"
1276   args getdownWebsiteDir
1277   inputs.dir(getdownWebsiteDir)
1278   outputs.file("${getdownWebsiteDir}/digest2.txt")
1279 }
1280
1281
1282 task getdown() {
1283   group = "distribution"
1284   description = "Create the minimal and full getdown app folder for installers and website and create digest file"
1285   dependsOn getdownDigest
1286   doLast {
1287     if (reportRsyncCommand) {
1288       def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
1289       def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
1290       println "LIKELY RSYNC COMMAND:"
1291       println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
1292       if (RUNRSYNC == "true") {
1293         exec {
1294           commandLine "mkdir", "-p", toDir
1295         }
1296         exec {
1297           commandLine "rsync", "-avh", "--delete", fromDir, toDir
1298         }
1299       }
1300     }
1301   }
1302 }
1303
1304
1305 clean {
1306   doFirst {
1307     delete getdownWebsiteDir
1308     delete getdownFilesDir
1309   }
1310 }
1311
1312
1313 install4j {
1314   if (file(install4jHomeDir).exists()) {
1315     // good to go!
1316   } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
1317     install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1318   } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
1319     install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
1320   }
1321   installDir(file(install4jHomeDir))
1322
1323   mediaTypes = Arrays.asList(install4j_media_types.split(","))
1324 }
1325
1326
1327 task copyInstall4jTemplate {
1328   def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
1329   def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
1330   inputs.file(install4jTemplateFile)
1331   inputs.file(install4jFileAssociationsFile)
1332   outputs.file(install4jConfFile)
1333
1334   doLast {
1335     def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
1336
1337     // turn off code signing if no OSX_KEYPASS
1338     if (OSX_KEYPASS == "") {
1339       install4jConfigXml.'**'.codeSigning.each { codeSigning ->
1340         codeSigning.'@macEnabled' = "false"
1341       }
1342       install4jConfigXml.'**'.windows.each { windows ->
1343         windows.'@runPostProcessor' = "false"
1344       }
1345     }
1346
1347     // turn off checksum creation for LOCAL channel
1348     def e = install4jConfigXml.application[0]
1349     if (CHANNEL == "LOCAL") {
1350       e.'@createChecksums' = "false"
1351     } else {
1352       e.'@createChecksums' = "true"
1353     }
1354
1355     // put file association actions where placeholder action is
1356     def install4jFileAssociationsText = install4jFileAssociationsFile.text
1357     def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
1358     install4jConfigXml.'**'.action.any { a ->
1359       if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
1360         def parent = a.parent()
1361         parent.remove(a)
1362         fileAssociationActions.each { faa ->
1363             parent.append(faa)
1364         }
1365         // don't need to continue in .any loop once replacements have been made
1366         return true
1367       }
1368     }
1369
1370     // write install4j file
1371     install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
1372   }
1373 }
1374
1375
1376 clean {
1377   doFirst {
1378     delete install4jConfFile
1379   }
1380 }
1381
1382
1383 task installers(type: com.install4j.gradle.Install4jTask) {
1384   group = "distribution"
1385   description = "Create the install4j installers"
1386   dependsOn setGitVals
1387   dependsOn getdown
1388   dependsOn copyInstall4jTemplate
1389
1390   projectFile = install4jConfFile
1391
1392   // create an md5 for the input files to use as version for install4j conf file
1393   def digest = MessageDigest.getInstance("MD5")
1394   digest.update(
1395     (file("${install4jDir}/${install4j_template}").text + 
1396     file("${install4jDir}/${install4j_info_plist_file_associations}").text +
1397     file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
1398   def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
1399   if (filesMd5.length() >= 8) {
1400     filesMd5 = filesMd5.substring(0,8)
1401   }
1402   def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
1403   // make install4jBuildDir relative to jalviewDir
1404   def install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
1405
1406   variables = [
1407     'JALVIEW_NAME': getdown_txt_title,
1408     'JALVIEW_DIR': "../..",
1409     'OSX_KEYSTORE': OSX_KEYSTORE,
1410     'JSIGN_SH': JSIGN_SH,
1411     'JRE_DIR': getdown_app_dir_java,
1412     'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
1413     'JALVIEW_VERSION': JALVIEW_VERSION,
1414     'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
1415     'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
1416     'JAVA_VERSION': JAVA_VERSION,
1417     'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
1418     'VERSION': JALVIEW_VERSION,
1419     'MACOS_JAVA_VM_DIR': macosJavaVMDir,
1420     'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
1421     'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
1422     'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
1423     'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
1424     'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
1425     'COPYRIGHT_MESSAGE': install4j_copyright_message,
1426     'MACOS_BUNDLE_ID': install4j_macOS_bundle_id,
1427     'INSTALLER_NAME': install4j_installer_name,
1428     'INSTALL4J_UTILS_DIR': install4j_utils_dir,
1429     'GETDOWN_WEBSITE_DIR': getdown_website_dir,
1430     'GETDOWN_FILES_DIR': getdown_files_dir,
1431     'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
1432     'GETDOWN_DIST_DIR': getdownAppDistDir,
1433     'GETDOWN_ALT_DIR': getdown_app_dir_alt,
1434     'GETDOWN_INSTALL_DIR': getdown_install_dir,
1435     'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
1436     'BUILD_DIR': install4jBuildDir,
1437   ]
1438
1439   destination = "${jalviewDir}/${install4jBuildDir}"
1440   buildSelected = true
1441
1442   if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
1443     faster = true
1444     disableSigning = true
1445   }
1446
1447   if (OSX_KEYPASS) {
1448     macKeystorePassword = OSX_KEYPASS
1449   }
1450
1451   doFirst {
1452     println("Using projectFile "+projectFile)
1453   }
1454
1455   inputs.dir(getdownWebsiteDir)
1456   inputs.file(install4jConfFile)
1457   inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
1458   inputs.dir(macosJavaVMDir)
1459   inputs.dir(windowsJavaVMDir)
1460   outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
1461 }
1462
1463
1464 task sourceDist(type: Tar) {
1465   
1466   def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
1467   def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
1468   // cater for buildship < 3.1 [3.0.1 is max version in eclipse 2018-09]
1469   try {
1470     archiveFileName = outputFileName
1471   } catch (Exception e) {
1472     archiveName = outputFileName
1473   }
1474   
1475   compression Compression.GZIP
1476   
1477   into project.name
1478
1479   def EXCLUDE_FILES=[
1480     "build/*",
1481     "bin/*",
1482     "test-output/",
1483     "test-reports",
1484     "tests",
1485     "clover*/*",
1486     ".*",
1487     "benchmarking/*",
1488     "**/.*",
1489     "*.class",
1490     "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
1491     "*locales/**",
1492     "utils/InstallAnywhere",
1493     "**/*.log",
1494   ] 
1495   def PROCESS_FILES=[
1496     "AUTHORS",
1497     "CITATION",
1498     "FEATURETODO",
1499     "JAVA-11-README",
1500     "FEATURETODO",
1501     "LICENSE",
1502     "**/README",
1503     "RELEASE",
1504     "THIRDPARTYLIBS",
1505     "TESTNG",
1506     "build.gradle",
1507     "gradle.properties",
1508     "**/*.java",
1509     "**/*.html",
1510     "**/*.xml",
1511     "**/*.gradle",
1512     "**/*.groovy",
1513     "**/*.properties",
1514     "**/*.perl",
1515     "**/*.sh",
1516   ]
1517   def INCLUDE_FILES=[
1518     ".settings/org.eclipse.jdt.core.jalview.prefs",
1519   ]
1520
1521   from(jalviewDir) {
1522     exclude (EXCLUDE_FILES)
1523     include (PROCESS_FILES)
1524     filter(ReplaceTokens,
1525       beginToken: '$$',
1526       endToken: '$$',
1527       tokens: [
1528         'Version-Rel': JALVIEW_VERSION,
1529         'Year-Rel': getDate("yyyy")
1530       ]
1531     )
1532   }
1533   from(jalviewDir) {
1534     exclude (EXCLUDE_FILES)
1535     exclude (PROCESS_FILES)
1536     exclude ("appletlib")
1537     exclude ("**/*locales")
1538     exclude ("*locales/**")
1539     exclude ("utils/InstallAnywhere")
1540
1541     exclude (getdown_files_dir)
1542     exclude (getdown_website_dir)
1543
1544     // exluding these as not using jars as modules yet
1545     exclude ("${j11modDir}/**/*.jar")
1546   }
1547   from(jalviewDir) {
1548     include(INCLUDE_FILES)
1549   }
1550 //  from (jalviewDir) {
1551 //    // explicit includes for stuff that seemed to not get included
1552 //    include(fileTree("test/**/*."))
1553 //    exclude(EXCLUDE_FILES)
1554 //    exclude(PROCESS_FILES)
1555 //  }
1556 }
1557
1558
1559 task helppages {
1560   dependsOn copyHelp
1561   dependsOn pubhtmlhelp
1562   
1563   inputs.dir("${classesDir}/${help_dir}")
1564   outputs.dir("${buildDir}/distributions/${help_dir}")
1565 }
1566
1567
1568 task j2sSetHeadlessBuild {
1569   doFirst {
1570     IN_ECLIPSE = false
1571   }
1572 }
1573
1574
1575 task jalviewjsSetEclipseWorkspace {
1576   def propKey = "jalviewjs_eclipse_workspace"
1577   def propVal = null
1578   if (project.hasProperty(propKey)) {
1579     propVal = project.getProperty(propKey)
1580     if (propVal.startsWith("~/")) {
1581       propVal = System.getProperty("user.home") + propVal.substring(1)
1582     }
1583   }
1584   def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
1585   def propsFile = file(propsFileName)
1586   def eclipseWsDir = propVal
1587   def props = new Properties()
1588
1589   def writeProps = true
1590   if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
1591     def ins = new FileInputStream(propsFileName)
1592     props.load(ins)
1593     ins.close()
1594     if (props.getProperty(propKey, null) != null) {
1595       eclipseWsDir = props.getProperty(propKey)
1596       writeProps = false
1597     }
1598   }
1599
1600   if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
1601     def tempDir = File.createTempDir()
1602     eclipseWsDir = tempDir.getAbsolutePath()
1603     writeProps = true
1604   }
1605   eclipseWorkspace = file(eclipseWsDir)
1606
1607   doFirst {
1608     // do not run a headless transpile when we claim to be in Eclipse
1609     if (IN_ECLIPSE) {
1610       println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1611       throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
1612     } else {
1613       println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1614     }
1615
1616     if (writeProps) {
1617       props.setProperty(propKey, eclipseWsDir)
1618       propsFile.parentFile.mkdirs()
1619       def bytes = new ByteArrayOutputStream()
1620       props.store(bytes, null)
1621       def propertiesString = bytes.toString()
1622       propsFile.text = propertiesString
1623       print("NEW ")
1624     } else {
1625       print("EXISTING ")
1626     }
1627
1628     println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
1629   }
1630
1631   //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
1632   outputs.file(propsFileName)
1633   outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
1634 }
1635
1636
1637 task jalviewjsEclipsePaths {
1638   def eclipseProduct
1639
1640   def eclipseRoot = jalviewjs_eclipse_root
1641   if (eclipseRoot.startsWith("~/")) {
1642     eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
1643   }
1644   if (OperatingSystem.current().isMacOsX()) {
1645     eclipseRoot += "/Eclipse.app"
1646     eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
1647     eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
1648   } else if (OperatingSystem.current().isWindows()) { // check these paths!!
1649     if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1650       eclipseRoot += "/eclipse.exe"
1651     }
1652     eclipseBinary = "${eclipseRoot}/eclipse"
1653     eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1654   } else { // linux or unix
1655     if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1656       eclipseRoot += "/eclipse"
1657     }
1658     eclipseBinary = "${eclipseRoot}/eclipse"
1659     eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1660   }
1661
1662   eclipseVersion = "4.13" // default
1663   def assumedVersion = true
1664   if (file(eclipseProduct).exists()) {
1665     def fis = new FileInputStream(eclipseProduct)
1666     def props = new Properties()
1667     props.load(fis)
1668     eclipseVersion = props.getProperty("version")
1669     fis.close()
1670     assumedVersion = false
1671   }
1672   
1673   def propKey = "eclipse_debug"
1674   eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
1675
1676   doFirst {
1677     // do not run a headless transpile when we claim to be in Eclipse
1678     if (IN_ECLIPSE) {
1679       println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1680       throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
1681     } else {
1682       println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1683     }
1684
1685     if (!assumedVersion) {
1686       println("ECLIPSE VERSION=${eclipseVersion}")
1687     }
1688   }
1689 }
1690
1691
1692 task printProperties {
1693   group "Debug"
1694   description "Output to console all System.properties"
1695   doFirst {
1696     System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
1697   }
1698 }
1699
1700
1701 task eclipseSetup {
1702   dependsOn eclipseProject
1703   dependsOn eclipseClasspath
1704   dependsOn eclipseJdt
1705 }
1706
1707
1708 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
1709 task jalviewjsEclipseCopyDropins(type: Copy) {
1710   dependsOn jalviewjsEclipsePaths
1711
1712   def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
1713   inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
1714   def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
1715
1716   from inputFiles
1717   into outputDir
1718 }
1719
1720
1721 // this eclipse -clean doesn't actually work
1722 task jalviewjsCleanEclipse(type: Exec) {
1723   dependsOn eclipseSetup
1724   dependsOn jalviewjsEclipsePaths
1725   dependsOn jalviewjsEclipseCopyDropins
1726
1727   executable(eclipseBinary)
1728   args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
1729   if (eclipseDebug) {
1730     args += "-debug"
1731   }
1732   args += "-l"
1733
1734   def inputString = """exit
1735 y
1736 """
1737   def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
1738   standardInput = inputByteStream
1739 }
1740
1741 /* not really working yet
1742 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
1743 */
1744
1745
1746 task jalviewjsTransferUnzipSwingJs {
1747   def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
1748
1749   doLast {
1750     copy {
1751       from zipTree(file_zip)
1752       into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
1753     }
1754   }
1755
1756   inputs.file file_zip
1757   outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
1758 }
1759
1760
1761 task jalviewjsTransferUnzipLib {
1762   def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
1763
1764   doLast {
1765     zipFiles.each { file_zip -> 
1766       copy {
1767         from zipTree(file_zip)
1768         into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
1769       }
1770     }
1771   }
1772
1773   inputs.files zipFiles
1774   outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
1775 }
1776
1777
1778 task jalviewjsTransferUnzipAllLibs {
1779   dependsOn jalviewjsTransferUnzipSwingJs
1780   dependsOn jalviewjsTransferUnzipLib
1781 }
1782
1783
1784 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
1785   group "JalviewJS"
1786   description "Create the .j2s file from the j2s.* properties"
1787
1788   jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
1789   def siteDirProperty = "j2s.site.directory"
1790   def setSiteDir = false
1791   jalviewjsJ2sProps.each { prop, val ->
1792     if (val != null) {
1793       if (prop == siteDirProperty) {
1794         if (!(val.startsWith('/') || val.startsWith("file://") )) {
1795           val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
1796         }
1797         setSiteDir = true
1798       }
1799       property(prop,val)
1800     }
1801     if (!setSiteDir) { // default site location, don't override specifically set property
1802       property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
1803     }
1804   }
1805   outputFile = jalviewjsJ2sSettingsFileName
1806
1807   if (! IN_ECLIPSE) {
1808     inputs.properties(jalviewjsJ2sProps)
1809     outputs.file(jalviewjsJ2sSettingsFileName)
1810   }
1811 }
1812
1813
1814 task jalviewjsEclipseSetup {
1815   dependsOn jalviewjsEclipseCopyDropins
1816   dependsOn jalviewjsSetEclipseWorkspace
1817   dependsOn jalviewjsCreateJ2sSettings
1818 }
1819
1820
1821 task jalviewjsSyncAllLibs (type: Sync) {
1822   dependsOn jalviewjsTransferUnzipAllLibs
1823   def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
1824   inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
1825   def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
1826
1827   from inputFiles
1828   into outputDir
1829   def outputFiles = []
1830   rename { filename ->
1831     outputFiles += "${outputDir}/${filename}"
1832     null
1833   }
1834   preserve {
1835     include "**"
1836   }
1837   outputs.files outputFiles
1838   inputs.files inputFiles
1839 }
1840
1841
1842 task jalviewjsSyncResources (type: Sync) {
1843   def inputFiles = fileTree(dir: resourceDir)
1844   def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
1845
1846   from inputFiles
1847   into outputDir
1848   def outputFiles = []
1849   rename { filename ->
1850     outputFiles += "${outputDir}/${filename}"
1851     null
1852   }
1853   preserve {
1854     include "**"
1855   }
1856   outputs.files outputFiles
1857   inputs.files inputFiles
1858 }
1859
1860
1861 task jalviewjsSyncSiteResources (type: Sync) {
1862   def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
1863   def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
1864
1865   from inputFiles
1866   into outputDir
1867   def outputFiles = []
1868   rename { filename ->
1869     outputFiles += "${outputDir}/${filename}"
1870     null
1871   }
1872   preserve {
1873     include "**"
1874   }
1875   outputs.files outputFiles
1876   inputs.files inputFiles
1877 }
1878
1879
1880 task jalviewjsSyncBuildProperties (type: Sync) {
1881   dependsOn createBuildProperties
1882   def inputFiles = [file(buildProperties)]
1883   def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
1884
1885   from inputFiles
1886   into outputDir
1887   def outputFiles = []
1888   rename { filename ->
1889     outputFiles += "${outputDir}/${filename}"
1890     null
1891   }
1892   preserve {
1893     include "**"
1894   }
1895   outputs.files outputFiles
1896   inputs.files inputFiles
1897 }
1898
1899
1900 task jalviewjsProjectImport(type: Exec) {
1901   dependsOn eclipseSetup
1902   dependsOn jalviewjsEclipsePaths
1903   dependsOn jalviewjsEclipseSetup
1904
1905   doFirst {
1906     // do not run a headless import when we claim to be in Eclipse
1907     if (IN_ECLIPSE) {
1908       println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1909       throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
1910     } else {
1911       println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1912     }
1913   }
1914
1915   //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
1916   def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
1917   executable(eclipseBinary)
1918   args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
1919   if (eclipseDebug) {
1920     args += "-debug"
1921   }
1922   args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
1923   if (!IN_ECLIPSE) {
1924     args += [ "-D${j2sHeadlessBuildProperty}=true" ]
1925   }
1926
1927   inputs.file("${jalviewDir}/.project")
1928   outputs.upToDateWhen { 
1929     file(projdir).exists()
1930   }
1931 }
1932
1933
1934 task jalviewjsTranspile(type: Exec) {
1935   dependsOn jalviewjsEclipseSetup 
1936   dependsOn jalviewjsProjectImport
1937   dependsOn jalviewjsEclipsePaths
1938
1939   doFirst {
1940     // do not run a headless transpile when we claim to be in Eclipse
1941     if (IN_ECLIPSE) {
1942       println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1943       throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
1944     } else {
1945       println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1946     }
1947   }
1948
1949   executable(eclipseBinary)
1950   args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
1951   if (eclipseDebug) {
1952     args += "-debug"
1953   }
1954   args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
1955   if (!IN_ECLIPSE) {
1956     args += [ "-D${j2sHeadlessBuildProperty}=true" ]
1957   }
1958
1959   def stdout
1960   def stderr
1961   doFirst {
1962     stdout = new ByteArrayOutputStream()
1963     stderr = new ByteArrayOutputStream()
1964
1965     def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
1966     def logOutFile = file(logOutFileName)
1967     logOutFile.createNewFile()
1968     logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
1969 BINARY: ${eclipseBinary}
1970 VERSION: ${eclipseVersion}
1971 WORKSPACE: ${eclipseWorkspace}
1972 DEBUG: ${eclipseDebug}
1973 ----
1974 """
1975     def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
1976     // combine stdout and stderr
1977     def logErrFOS = logOutFOS
1978
1979     if (jalviewjs_j2s_to_console.equals("true")) {
1980       standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1981         new org.apache.tools.ant.util.TeeOutputStream(
1982           logOutFOS,
1983           stdout),
1984         standardOutput)
1985       errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1986         new org.apache.tools.ant.util.TeeOutputStream(
1987           logErrFOS,
1988           stderr),
1989         errorOutput)
1990     } else {
1991       standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1992         logOutFOS,
1993         stdout)
1994       errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1995         logErrFOS,
1996         stderr)
1997     }
1998   }
1999
2000   doLast {
2001     if (stdout.toString().contains("Error processing ")) {
2002       // j2s did not complete transpile
2003       //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2004       if (jalviewjs_ignore_transpile_errors.equals("true")) {
2005         println("IGNORING TRANSPILE ERRORS")
2006         println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2007       } else {
2008         throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2009       }
2010     }
2011   }
2012
2013   inputs.dir("${jalviewDir}/${sourceDir}")
2014   outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
2015   outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
2016 }
2017
2018
2019 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
2020
2021   def stdout = new ByteArrayOutputStream()
2022   def stderr = new ByteArrayOutputStream()
2023
2024   def coreFile = file(jsfile)
2025   def msg = ""
2026   msg = "Creating core for ${name}...\nGenerating ${jsfile}"
2027   println(msg)
2028   logOutFile.createNewFile()
2029   logOutFile.append(msg+"\n")
2030
2031   def coreTop = file(prefixFile)
2032   def coreBottom = file(suffixFile)
2033   coreFile.getParentFile().mkdirs()
2034   coreFile.createNewFile()
2035   coreFile.write( coreTop.text )
2036   list.each {
2037     f ->
2038     if (f.exists()) {
2039       def t = f.text
2040       t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
2041       coreFile.append( t )
2042     } else {
2043       msg = "...file '"+f.getPath()+"' does not exist, skipping"
2044       println(msg)
2045       logOutFile.append(msg+"\n")
2046     }
2047   }
2048   coreFile.append( coreBottom.text )
2049
2050   msg = "Generating ${zjsfile}"
2051   println(msg)
2052   logOutFile.append(msg+"\n")
2053   def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2054   def logErrFOS = logOutFOS
2055
2056   javaexec {
2057     classpath = files(["${jalviewDir}/tools/closure_compiler.jar"])
2058     args = [ "--js", jsfile, "--js_output_file", zjsfile ]
2059     maxHeapSize = "2g"
2060
2061     msg = "\nRunning '"+commandLine.join(' ')+"'\n"
2062     println(msg)
2063     logOutFile.append(msg+"\n")
2064
2065     if (logOutConsole) {
2066       standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2067         new org.apache.tools.ant.util.TeeOutputStream(
2068           logOutFOS,
2069           stdout),
2070         standardOutput)
2071         errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2072           new org.apache.tools.ant.util.TeeOutputStream(
2073             logErrFOS,
2074             stderr),
2075           errorOutput)
2076     } else {
2077       standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2078         logOutFOS,
2079         stdout)
2080         errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2081           logErrFOS,
2082           stderr)
2083     }
2084   }
2085   msg = "--"
2086   println(msg)
2087   logOutFile.append(msg+"\n")
2088 }
2089
2090
2091 task jalviewjsBuildAllCores {
2092   group "JalviewJS"
2093   description "Build the core js lib closures listed in the classlists dir"
2094   dependsOn jalviewjsTranspile
2095   dependsOn jalviewjsTransferUnzipSwingJs
2096
2097   def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
2098   def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
2099   def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
2100   def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
2101   def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
2102   def prefixFile = "${jsDir}/core/coretop2.js"
2103   def suffixFile = "${jsDir}/core/corebottom2.js"
2104
2105   inputs.file prefixFile
2106   inputs.file suffixFile
2107
2108   def classlistFiles = []
2109   // add the classlists found int the jalviewjs_classlists_dir
2110   fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
2111     file ->
2112     def name = file.getName() - ".txt"
2113     classlistFiles += [
2114       'file': file,
2115       'name': name
2116     ]
2117   }
2118
2119   // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
2120   //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
2121   classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
2122
2123   jalviewjsCoreClasslists = []
2124
2125   classlistFiles.each {
2126     hash ->
2127
2128     def file = hash['file']
2129     if (! file.exists()) {
2130       //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
2131       return false // this is a "continue" in groovy .each closure
2132     }
2133     def name = hash['name']
2134     if (name == null) {
2135       name = file.getName() - ".txt"
2136     }
2137
2138     def filelist = []
2139     file.eachLine {
2140       line ->
2141         filelist += line
2142     }
2143     def list = fileTree(dir: j2sDir, includes: filelist)
2144
2145     def jsfile = "${outputDir}/core${name}.js"
2146     def zjsfile = "${outputDir}/core${name}.z.js"
2147
2148     jalviewjsCoreClasslists += [
2149       'jsfile': jsfile,
2150       'zjsfile': zjsfile,
2151       'list': list,
2152       'name': name
2153     ]
2154
2155     inputs.file(file)
2156     inputs.files(list)
2157     outputs.file(jsfile)
2158     outputs.file(zjsfile)
2159   }
2160   
2161   // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
2162   def stevesoftClasslistName = "_stevesoft"
2163   def stevesoftClasslist = [
2164     'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
2165     'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
2166     'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
2167     'name': stevesoftClasslistName
2168   ]
2169   jalviewjsCoreClasslists += stevesoftClasslist
2170   inputs.files(stevesoftClasslist['list'])
2171   outputs.file(stevesoftClasslist['jsfile'])
2172   outputs.file(stevesoftClasslist['zjsfile'])
2173
2174   // _all core
2175   def allClasslistName = "_all"
2176   def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
2177   allJsFiles += fileTree(
2178     dir: libJ2sDir,
2179     include: "**/*.js",
2180     excludes: [
2181       // these exlusions are files that the closure-compiler produces errors for. Should fix them
2182       "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
2183       "**/org/jmol/export/JSExporter.js"
2184     ]
2185   )
2186   allJsFiles += fileTree(
2187     dir: swingJ2sDir,
2188     include: "**/*.js",
2189     excludes: [
2190       // these exlusions are files that the closure-compiler produces errors for. Should fix them
2191       "**/sun/misc/Unsafe.js",
2192       "**/swingjs/jquery/jquery-editable-select.js",
2193       "**/swingjs/jquery/j2sComboBox.js",
2194       "**/sun/misc/FloatingDecimal.js"
2195     ]
2196   )
2197   def allClasslist = [
2198     'jsfile': "${outputDir}/core${allClasslistName}.js",
2199     'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
2200     'list': allJsFiles,
2201     'name': allClasslistName
2202   ]
2203   // not including this version of "all" core at the moment
2204   //jalviewjsCoreClasslists += allClasslist
2205   inputs.files(allClasslist['list'])
2206   outputs.file(allClasslist['jsfile'])
2207   outputs.file(allClasslist['zjsfile'])
2208
2209   doFirst {
2210     def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
2211     logOutFile.getParentFile().mkdirs()
2212     logOutFile.createNewFile()
2213     logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
2214
2215     jalviewjsCoreClasslists.each {
2216       jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
2217     }
2218   }
2219
2220 }
2221
2222
2223 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
2224   copy {
2225     from inputFile
2226     into file(outputFile).getParentFile()
2227     rename { filename ->
2228       if (filename.equals(inputFile.getName())) {
2229         return file(outputFile).getName()
2230       }
2231       return null
2232     }
2233     filter(ReplaceTokens,
2234       beginToken: '_',
2235       endToken: '_',
2236       tokens: [
2237         'MAIN': '"'+mainClass+'"',
2238         'CODE': "null",
2239         'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
2240         'COREKEY': jalviewjs_core_key,
2241         'CORENAME': coreName
2242       ]
2243     )
2244   }
2245 }
2246
2247
2248 task jalviewjsPublishCoreTemplates {
2249   dependsOn jalviewjsBuildAllCores
2250   def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
2251   def inputFile = file(inputFileName)
2252   def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2253
2254   def outputFiles = []
2255   jalviewjsCoreClasslists.each { cl ->
2256     def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
2257     cl['outputfile'] = outputFile
2258     outputFiles += outputFile
2259   }
2260
2261   doFirst {
2262     jalviewjsCoreClasslists.each { cl ->
2263       jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
2264     }
2265   }
2266   inputs.file(inputFile)
2267   outputs.files(outputFiles)
2268 }
2269
2270
2271 task jalviewjsSyncCore (type: Sync) {
2272   dependsOn jalviewjsBuildAllCores
2273   dependsOn jalviewjsPublishCoreTemplates
2274   def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
2275   def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2276
2277   from inputFiles
2278   into outputDir
2279   def outputFiles = []
2280   rename { filename ->
2281     outputFiles += "${outputDir}/${filename}"
2282     null
2283   }
2284   preserve {
2285     include "**"
2286   }
2287   outputs.files outputFiles
2288   inputs.files inputFiles
2289 }
2290
2291
2292 // this Copy version of TransferSiteJs will delete anything else in the target dir
2293 task jalviewjsCopyTransferSiteJs(type: Copy) {
2294   dependsOn jalviewjsTranspile
2295   from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2296   into "${jalviewDir}/${jalviewjsSiteDir}"
2297 }
2298
2299
2300 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
2301 task jalviewjsSyncTransferSiteJs(type: Sync) {
2302   from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2303   include "**/*.*"
2304   into "${jalviewDir}/${jalviewjsSiteDir}"
2305   preserve {
2306     include "**"
2307   }
2308 }
2309
2310
2311 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
2312 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
2313 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
2314 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
2315
2316 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
2317 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
2318 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
2319 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
2320
2321
2322 task jalviewjsPrepareSite {
2323   group "JalviewJS"
2324   description "Prepares the website folder including unzipping files and copying resources"
2325   dependsOn jalviewjsSyncAllLibs
2326   dependsOn jalviewjsSyncResources
2327   dependsOn jalviewjsSyncSiteResources
2328   dependsOn jalviewjsSyncBuildProperties
2329   dependsOn jalviewjsSyncCore
2330 }
2331
2332
2333 task jalviewjsBuildSite {
2334   group "JalviewJS"
2335   description "Builds the whole website including transpiled code"
2336   dependsOn jalviewjsCopyTransferSiteJs
2337   dependsOn jalviewjsPrepareSite
2338 }
2339
2340
2341 task cleanJalviewjsTransferSite {
2342   doFirst {
2343     delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2344     delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2345     delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2346     delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2347   }
2348 }
2349
2350
2351 task cleanJalviewjsSite {
2352   dependsOn cleanJalviewjsTransferSite
2353   doFirst {
2354     delete "${jalviewDir}/${jalviewjsSiteDir}"
2355   }
2356 }
2357
2358
2359 task jalviewjsSiteTar(type: Tar) {
2360   group "JalviewJS"
2361   description "Creates a tar.gz file for the website"
2362   dependsOn jalviewjsBuildSite
2363   def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
2364   try {
2365     archiveFileName = outputFilename
2366   } catch (Exception e) {
2367     archiveName = outputFilename
2368   }
2369
2370   compression Compression.GZIP
2371
2372   from "${jalviewDir}/${jalviewjsSiteDir}"
2373   into jalviewjs_site_dir // this is inside the tar file
2374
2375   inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
2376 }
2377
2378
2379 task jalviewjsServer {
2380   group "JalviewJS"
2381   def filename = "jalviewjsTest.html"
2382   description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
2383   def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
2384   doLast {
2385
2386     SimpleHttpFileServerFactory factory = new SimpleHttpFileServerFactory()
2387     def port = Integer.valueOf(jalviewjs_server_port)
2388     def start = port
2389     def running = false
2390     def url
2391     def jalviewjsServer
2392     while(port < start+1000 && !running) {
2393       try {
2394         def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
2395         jalviewjsServer = factory.start(doc_root, port)
2396         running = true
2397         url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
2398         println("SERVER STARTED with document root ${doc_root}.")
2399         println("Go to "+url+" . Run  gradle --stop  to stop (kills all gradle daemons).")
2400         println("For debug: "+url+"?j2sdebug")
2401         println("For verbose: "+url+"?j2sverbose")
2402       } catch (Exception e) {
2403         port++;
2404       }
2405     }
2406     def htmlText = """
2407       <p><a href="${url}">JalviewJS Test. &lt;${url}&gt;</a></p>
2408       <p><a href="${url}?j2sdebug">JalviewJS Test with debug. &lt;${url}?j2sdebug&gt;</a></p>
2409       <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. &lt;${url}?j2sdebug&gt;</a></p>
2410       """
2411     jalviewjsCoreClasslists.each { cl ->
2412       def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
2413       htmlText += """
2414       <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. &lt;${urlcore}&gt;</a></p>
2415       """
2416       println("For core ${cl.name}: "+urlcore)
2417     }
2418
2419     file(htmlFile).text = htmlText
2420   }
2421
2422   outputs.file(htmlFile)
2423   outputs.upToDateWhen({false})
2424 }
2425
2426
2427 task cleanJalviewjsAll {
2428   group "JalviewJS"
2429   description "Delete all configuration and build artifacts to do with JalviewJS build"
2430   dependsOn cleanJalviewjsSite
2431   dependsOn jalviewjsEclipsePaths
2432   
2433   doFirst {
2434     delete "${jalviewDir}/${jalviewjsBuildDir}"
2435     delete "${jalviewDir}/${eclipse_bin_dir}"
2436     if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
2437       delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
2438     }
2439     delete "${jalviewDir}/${jalviewjs_j2s_settings}"
2440   }
2441
2442   outputs.upToDateWhen( { false } )
2443 }
2444
2445
2446 task jalviewjsIDE_checkJ2sPlugin {
2447   group "00 JalviewJS in Eclipse"
2448   description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
2449
2450   doFirst {
2451     def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
2452     def j2sPluginFile = file(j2sPlugin)
2453     def eclipseHome = System.properties["eclipse.home.location"]
2454     if (eclipseHome == null || ! IN_ECLIPSE) {
2455       throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
2456     }
2457     def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
2458     def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
2459     if (!eclipseJ2sPluginFile.exists()) {
2460       def msg = "Eclipse J2S Plugin is not installed (could not find '${eclipseJ2sPlugin}')\nTry running task jalviewjsIDE_copyJ2sPlugin"
2461       System.err.println(msg)
2462       throw new StopExecutionException(msg)
2463     }
2464
2465     def digest = MessageDigest.getInstance("MD5")
2466
2467     digest.update(j2sPluginFile.text.bytes)
2468     def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
2469
2470     digest.update(eclipseJ2sPluginFile.text.bytes)
2471     def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
2472      
2473     if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
2474       def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
2475       System.err.println(msg)
2476       throw new StopExecutionException(msg)
2477     } else {
2478       def msg = "Eclipse J2S Plugin is the same as '${j2sPlugin}' (this is good)"
2479       println(msg)
2480     }
2481   }
2482 }
2483
2484 task jalviewjsIDE_copyJ2sPlugin {
2485   group "00 JalviewJS in Eclipse"
2486   description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
2487
2488   doFirst {
2489     def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
2490     def j2sPluginFile = file(j2sPlugin)
2491     def eclipseHome = System.properties["eclipse.home.location"]
2492     if (eclipseHome == null || ! IN_ECLIPSE) {
2493       throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
2494     }
2495     def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
2496     def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
2497     def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
2498     System.err.println(msg)
2499     copy {
2500       from j2sPlugin
2501       eclipseJ2sPluginFile.getParentFile().mkdirs()
2502       into eclipseJ2sPluginFile.getParent()
2503     }
2504   }
2505 }
2506
2507
2508 task jalviewjsIDE_j2sFile {
2509   group "00 JalviewJS in Eclipse"
2510   description "Creates the .j2s file"
2511   dependsOn jalviewjsCreateJ2sSettings
2512 }
2513
2514
2515 task jalviewjsIDE_SyncCore {
2516   group "00 JalviewJS in Eclipse"
2517   description "Build the core js lib closures listed in the classlists dir and publish core html from template"
2518   dependsOn jalviewjsSyncCore
2519 }
2520
2521
2522 task jalviewjsIDE_SyncSiteAll {
2523   dependsOn jalviewjsSyncAllLibs
2524   dependsOn jalviewjsSyncResources
2525   dependsOn jalviewjsSyncSiteResources
2526   dependsOn jalviewjsSyncBuildProperties
2527 }
2528
2529
2530 cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
2531
2532
2533 task jalviewjsIDE_PrepareSite {
2534   group "00 JalviewJS in Eclipse"
2535   description "Sync libs and resources to site dir, but not closure cores"
2536
2537   dependsOn jalviewjsIDE_SyncSiteAll
2538   dependsOn cleanJalviewjsTransferSite
2539 }
2540
2541
2542 task jalviewjsIDE_AssembleSite {
2543   group "00 JalviewJS in Eclipse"
2544   description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
2545   dependsOn jalviewjsPrepareSite
2546 }
2547
2548
2549 task jalviewjsIDE_SiteClean {
2550   group "00 JalviewJS in Eclipse"
2551   description "Deletes the Eclipse transpiled site"
2552   dependsOn cleanJalviewjsSite
2553 }
2554
2555
2556 task jalviewjsIDE_Server {
2557   group "00 JalviewJS in Eclipse"
2558   description "Starts a webserver on localhost to test the website"
2559   dependsOn jalviewjsServer
2560 }
2561
2562
2563 // buildship runs this at import or gradle refresh
2564 task eclipseSynchronizationTask {
2565   //dependsOn eclipseSetup
2566   dependsOn createBuildProperties
2567   if (J2S_ENABLED) {
2568     dependsOn jalviewjsIDE_j2sFile
2569     dependsOn jalviewjsIDE_checkJ2sPlugin
2570     dependsOn jalviewjsIDE_PrepareSite
2571   }
2572 }
2573
2574
2575 // buildship runs this at build time or project refresh
2576 task eclipseAutoBuildTask {
2577   //dependsOn jalviewjsIDE_checkJ2sPlugin
2578   //dependsOn jalviewjsIDE_PrepareSite
2579 }
2580
2581
2582 task jalviewjs {
2583   group "JalviewJS"
2584   description "Build the site"
2585   dependsOn jalviewjsBuildSite
2586 }