Revert "JAL-3210 small tidies"
[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
6 import groovy.transform.ExternalizeMethods
7
8 buildscript {
9   dependencies {
10     classpath 'org.openclover:clover:4.3.1'
11   }
12 }
13
14 plugins {
15   id 'java'
16   id 'application'
17   id 'eclipse'
18   id 'com.github.johnrengelman.shadow' version '4.0.3'
19   id 'com.install4j.gradle' version '7.0.9'
20 }
21
22 // local build environment properties
23 def localProps = "${jalviewDir}/local.properties"
24 if (file(localProps).exists()) {
25   try {
26     def p = new Properties()
27     def localPropsFIS = new FileInputStream(localProps)
28     p.load(localPropsFIS)
29     localPropsFIS.close()
30     p.each {
31       key, val -> 
32         def over = getProperty(key) != null
33         setProperty(key, val)
34         if (over) {
35           println("Overriding property '${key}' with local.properties value '${val}'")
36         }
37     }
38   } catch (Exception e) {
39     System.out.println("Exception reading local.properties")
40   }
41 }
42
43 repositories {
44   jcenter()
45   mavenCentral()
46   mavenLocal()
47   flatDir {
48     dirs gradlePluginsDir
49   }
50 }
51
52 dependencies {
53   compile 'org.apache.commons:commons-compress:1.18'
54 }
55
56 mainClassName = launcherClass
57 def cloverInstrDir = file("${buildDir}/${cloverSourcesInstrDir}")
58 def classes = "${jalviewDir}/${classesDir}"
59
60 if (clover.equals("true")) {
61   use_clover = true
62   classes = "${buildDir}/${cloverClassesDir}"
63 } else {
64   use_clover = false
65   classes = "${jalviewDir}/${classesDir}"
66 }
67
68 // configure classpath/args for j8/j11 compilation
69
70 def jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
71 def libDir
72 def libDistDir
73 def compile_source_compatibility
74 def compile_target_compatibility
75
76 ext {
77   getdownWebsiteDir = "${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}"
78   getdownDir = ""
79   reportRsyncCmd = false
80   buildDist = true
81   buildProperties = build_properties_file
82   getdownLauncher = "${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}"
83   switch (CHANNEL) {
84
85     case "BUILD":
86     // TODO: get bamboo build artifact URL for getdown artifacts
87     getdown_channel_base = bamboo_channelbase
88     getdown_channel_name = "${bamboo_planKey}/${JAVA_VERSION}"
89     getdown_app_base = "${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}"
90     getdown_app_dir = getdown_app_dir_alt
91     buildProperties = "${jalviewDir}/${classesDir}/${build_properties_file}"
92     break
93
94     case "RELEASE":
95     getdown_channel_name = CHANNEL.toLowerCase()
96     getdownDir = "${getdown_channel_name}/${JAVA_VERSION}"
97     getdown_app_base = "${getdown_channel_base}/${getdownDir}"
98     getdown_app_dir = getdown_app_dir_release
99     buildProperties = "${jalviewDir}/${classesDir}/${build_properties_file}"
100     reportRsyncCommand = true
101     break
102
103     case "ARCHIVE":
104     getdown_channel_name = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
105     getdownDir = "${getdown_channel_name}/${JAVA_VERSION}"
106     getdown_app_base = "${getdown_channel_base}/${getdownDir}"
107     getdown_app_dir = getdown_app_dir_alt
108     if (!file("${ARCHIVEDIR}/${packageDir}").exists()) {
109       print "Must provide an ARCHIVEDIR value to produce an archive distribution"
110       exit
111     } else {
112       packageDir = "${ARCHIVEDIR}/${packageDir}"
113       buildProperties = "${ARCHIVEDIR}/${classesDir}/${build_properties_file}"
114       buildDist = false
115     }
116     reportRsyncCommand = true
117     break
118
119     case "ARCHIVELOCAL":
120     getdown_channel_name = "archive/${JALVIEW_VERSION}"
121     getdownDir = "${getdown_channel_name}/${JAVA_VERSION}"
122     getdown_app_base = file(getdownWebsiteDir).toURI().toString()
123     getdown_app_dir = getdown_app_dir_alt
124     if (!file("${ARCHIVEDIR}/${packageDir}").exists()) {
125       print "Must provide an ARCHIVEDIR value to produce an archive distribution"
126       exit
127     } else {
128       packageDir = "${ARCHIVEDIR}/${packageDir}"
129       buildProperties = "${ARCHIVEDIR}/${classesDir}/${build_properties_file}"
130       buildDist = false
131     }
132     reportRsyncCommand = true
133     getdownLauncher = "${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}"
134     break
135
136     case "DEVELOP":
137     getdown_channel_name = CHANNEL.toLowerCase()
138     getdownDir = "${getdown_channel_name}/${JAVA_VERSION}"
139     getdown_app_base = "${getdown_channel_base}/${getdownDir}"
140     getdown_app_dir = getdown_app_dir_alt
141     buildProperties = "${jalviewDir}/${classesDir}/${build_properties_file}"
142     reportRsyncCommand = true
143     break
144
145     case "TEST-RELEASE":
146     getdown_channel_name = CHANNEL.toLowerCase()
147     getdownDir = "${getdown_channel_name}/${JAVA_VERSION}"
148     getdown_app_base = "${getdown_channel_base}/${getdownDir}"
149     getdown_app_dir = getdown_app_dir_alt
150     buildProperties = "${jalviewDir}/${classesDir}/${build_properties_file}"
151     reportRsyncCommand = true
152     break
153
154     case ~/^SCRATCH(|-[-\w]*)$/:
155     getdown_channel_name = CHANNEL
156     getdownDir = "${getdown_channel_name}/${JAVA_VERSION}"
157     getdown_app_base = "${getdown_channel_base}/${getdownDir}"
158     getdown_app_dir = getdown_app_dir_alt
159     buildProperties = "${jalviewDir}/${classesDir}/${build_properties_file}"
160     reportRsyncCommand = true
161     break
162
163     case "LOCAL":
164     getdown_app_base = file(getdownWebsiteDir).toURI().toString()
165     getdown_app_dir = getdown_app_dir_alt
166     buildProperties = "${jalviewDir}/${classesDir}/${build_properties_file}"
167     getdownLauncher = "${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}"
168     break
169
170     default: // something wrong specified
171     print("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
172     exit
173     break
174
175   }
176
177   getdownAppDir = "${getdownWebsiteDir}/${getdown_app_dir}"
178   //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}"
179   getdownResourceDir = "${getdownWebsiteDir}/${getdown_resource_dir}"
180   getdownInstallDir = "${getdownWebsiteDir}/${getdown_install_dir}"
181   getdownFilesDir = "${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/"
182   getdownFilesInstallDir = "${getdownFilesDir}/${getdown_install_dir}"
183   /* compile without modules -- using classpath libraries
184   modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
185   modules_runtimeClasspath = modules_compileClasspath
186   */
187   gitHash = ""
188   gitBranch = ""
189
190   println("Using a ${CHANNEL} profile.")
191 }
192
193 def JAVA_INTEGER_VERSION
194 def additional_compiler_args = []
195 // these are getdown.txt properties defined dependent on the JAVA_VERSION
196 def getdown_alt_java_min_version
197 def getdown_alt_java_max_version
198 // this property is assigned below and expanded to multiple lines in the getdown task
199 def getdown_alt_multi_java_location
200 // this property is for the Java library used in eclipse
201 def eclipse_java_runtime_name
202 if (JAVA_VERSION.equals("1.8")) {
203   JAVA_INTEGER_VERSION = "8"
204   //libDir = j8libDir
205   libDir = j11libDir
206   libDistDir = j8libDir
207   compile_source_compatibility = 1.8
208   compile_target_compatibility = 1.8
209   getdown_alt_java_min_version = getdown_alt_java8_min_version
210   getdown_alt_java_max_version = getdown_alt_java8_max_version
211   getdown_alt_multi_java_location = getdown_alt_java8_txt_multi_java_location
212   eclipse_java_runtime_name = "JavaSE-1.8"
213 } else if (JAVA_VERSION.equals("11")) {
214   JAVA_INTEGER_VERSION = "11"
215   libDir = j11libDir
216   libDistDir = j11libDir
217   compile_source_compatibility = 11
218   compile_target_compatibility = 11
219   getdown_alt_java_min_version = getdown_alt_java11_min_version
220   getdown_alt_java_max_version = getdown_alt_java11_max_version
221   getdown_alt_multi_java_location = getdown_alt_java11_txt_multi_java_location
222   eclipse_java_runtime_name = "JavaSE-11"
223   /* compile without modules -- using classpath libraries
224   additional_compiler_args += [
225   '--module-path', ext.modules_compileClasspath.asPath,
226   '--add-modules', j11modules
227   ]
228   */
229 } else if (JAVA_VERSION.equals("12") || JAVA_VERSION.equals("13")) {
230   JAVA_INTEGER_VERSION = JAVA_VERSION
231   libDir = j11libDir
232   libDistDir = j11libDir
233   compile_source_compatibility = JAVA_VERSION
234   compile_target_compatibility = JAVA_VERSION
235   getdown_alt_java_min_version = getdown_alt_java11_min_version
236   getdown_alt_java_max_version = getdown_alt_java11_max_version
237   getdown_alt_multi_java_location = getdown_alt_java11_txt_multi_java_location
238   eclipse_java_runtime_name = "JavaSE-11"
239   /* compile without modules -- using classpath libraries
240   additional_compiler_args += [
241   '--module-path', ext.modules_compileClasspath.asPath,
242   '--add-modules', j11modules
243   ]
244   */
245 } else {
246   throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
247 }
248
249 sourceSets {
250
251   main {
252     java {
253       srcDirs "${jalviewDir}/${sourceDir}"
254       outputDir = file("${classes}")
255     }
256
257     resources {
258       srcDirs "${jalviewDir}/${resourceDir}"
259     }
260
261     jar.destinationDir = file("${jalviewDir}/${packageDir}")
262
263     compileClasspath = files(sourceSets.main.java.outputDir)
264     compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
265
266     runtimeClasspath = compileClasspath
267   }
268
269   clover {
270     java {
271       srcDirs = [ cloverInstrDir ]
272       outputDir = file("${buildDir}/${cloverClassesDir}")
273     }
274
275     resources {
276       srcDirs = sourceSets.main.resources.srcDirs
277     }
278     compileClasspath = configurations.cloverRuntime + files( sourceSets.clover.java.outputDir )
279     compileClasspath += files(sourceSets.main.java.outputDir)
280     compileClasspath += sourceSets.main.compileClasspath
281     compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}", include: ["**/*.jar"])
282     compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
283
284     runtimeClasspath = compileClasspath
285   }
286
287   test {
288     java {
289       srcDirs "${jalviewDir}/${testSourceDir}"
290       outputDir = file("${jalviewDir}/${testOutputDir}")
291     }
292
293     resources {
294       srcDirs = sourceSets.main.resources.srcDirs
295     }
296
297     compileClasspath = files( sourceSets.test.java.outputDir )
298
299     if (use_clover) {
300       compileClasspath += sourceSets.clover.compileClasspath
301     } else {
302       compileClasspath += files(sourceSets.main.java.outputDir)
303     }
304
305     compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
306     compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}/testnglibs", include: ["**/*.jar"])
307     compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}/testlibs", include: ["**/*.jar"])
308
309     runtimeClasspath = compileClasspath
310   }
311 }
312
313 // clover bits
314 dependencies {
315   if (use_clover) {
316     cloverCompile 'org.openclover:clover:4.3.1'
317     testCompile 'org.openclover:clover:4.3.1'
318   }
319 }
320
321 configurations {
322   cloverRuntime
323   cloverRuntime.extendsFrom cloverCompile
324 }
325
326 eclipse {
327   project {
328     name = eclipse_project_name
329
330     natures 'org.eclipse.jdt.core.javanature',
331     'org.eclipse.jdt.groovy.core.groovyNature',
332     'org.eclipse.buildship.core.gradleprojectnature'
333
334     buildCommand 'org.eclipse.jdt.core.javabuilder'
335     buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
336   }
337
338   classpath {
339     //defaultOutputDir = sourceSets.main.java.outputDir
340     def removeThese = []
341     configurations.each{
342       if (it.isCanBeResolved()) {
343         removeThese += it
344       }
345     }
346
347     minusConfigurations += removeThese
348     plusConfigurations = [ ]
349     file {
350
351       whenMerged { cp ->
352         def removeTheseToo = []
353         HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
354         cp.entries.each { entry ->
355           if (entry.kind == 'src') {
356             if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == sourceDir || entry.path == testSourceDir)) {
357               removeTheseToo += entry
358             } else {
359               alreadyAddedSrcPath.putAt(entry.path, true)
360             }
361           }
362         }
363         cp.entries.removeAll(removeTheseToo)
364
365         if (file("${jalviewDir}/${eclipse_bin_dir}/main").isDirectory()) {
366           cp.entries += new Output("${eclipse_bin_dir}/main")
367         }
368         if (file(helpParentDir).isDirectory()) {
369           cp.entries += new Library(fileReference(helpParentDir))
370         }
371         if (file(resourceDir).isDirectory()) {
372           cp.entries += new Library(fileReference(resourceDir))
373         }
374
375         HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
376
377         sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.each {
378           //don't want to add outputDir as eclipse is using its own output dir in bin/main
379           if (it.isDirectory() || ! it.exists()) {
380             // don't add dirs to classpath
381             return
382           }
383           def itPath = it.toString()
384           if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
385             // make relative path
386             itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
387           }
388           if (alreadyAddedLibPath.get(itPath)) {
389             //println("Not adding duplicate entry "+itPath)
390           } else {
391             //println("Adding entry "+itPath)
392             cp.entries += new Library(fileReference(itPath))
393             alreadyAddedLibPath.put(itPath, true)
394           }
395         }
396
397         //fileTree(dir: "$jalviewDir/$utilsDir", include: ["test*/*.jar"]).each {
398         sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.each {
399           //no longer want to add outputDir as eclipse is using its own output dir in bin/main
400           if (it.isDirectory() || ! it.exists()) {
401             // don't add dirs to classpath
402             return false // groovy "break" in .each closure
403           }
404           def itPath = it.toString()
405           if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
406             itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
407           }
408           if (alreadyAddedLibPath.get(itPath)) {
409             // don't duplicate
410           } else {
411             def lib = new Library(fileReference(itPath))
412             lib.entryAttributes["test"] = "true"
413             cp.entries += lib
414             alreadyAddedLibPath.put(itPath, true)
415           }
416         }
417
418       } // whenMerged
419
420     } // file
421
422     containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
423
424   } // classpath
425
426   jdt {
427     // for the IDE, use java 11 compatibility
428     sourceCompatibility = compile_source_compatibility
429     targetCompatibility = compile_target_compatibility
430     javaRuntimeName = eclipse_java_runtime_name
431
432     // add in jalview project specific properties/preferences into eclipse core preferences
433     file {
434       withProperties { props ->
435         def jalview_prefs = new Properties()
436         def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
437         jalview_prefs.load(ins)
438         ins.close()
439         jalview_prefs.forEach { t, v ->
440           if (props.getAt(t) == null) {
441             props.putAt(t, v)
442           }
443         }
444       }
445     }
446
447   } // jdt
448   
449   synchronizationTasks "eclipseSynchronizationTask"
450   autoBuildTasks "eclipseAutoBuildTask"
451
452 }
453
454 task cloverInstr() {
455   // only instrument source, we build test classes as normal
456   inputs.files files (sourceSets.main.allJava) // , fileTree(dir:"$jalviewDir/$testSourceDir", include: ["**/*.java"]))
457   outputs.dir cloverInstrDir
458
459   doFirst {
460     delete cloverInstrDir
461     def argsList = ["--initstring", "${buildDir}/clover/clover.db",
462     "-d", "${buildDir}/${cloverSourcesInstrDir}"]
463     argsList.addAll(inputs.files.files.collect({ file ->
464       file.absolutePath
465     }))
466     String[] args = argsList.toArray()
467     println("About to instrument "+args.length +" files")
468     com.atlassian.clover.CloverInstr.mainImpl(args)
469   }
470 }
471
472
473 task cloverReport {
474   group = "Verification"
475     description = "Createst the Clover report"
476     inputs.dir "${buildDir}/clover"
477     outputs.dir "${reportsDir}/clover"
478     onlyIf {
479       file("${buildDir}/clover/clover.db").exists()
480     }
481   doFirst {
482     def argsList = ["--initstring", "${buildDir}/clover/clover.db",
483     "-o", "${reportsDir}/clover"]
484     String[] args = argsList.toArray()
485     com.atlassian.clover.reporters.html.HtmlReporter.runReport(args)
486
487     // and generate ${reportsDir}/clover/clover.xml
488     args = ["--initstring", "${buildDir}/clover/clover.db",
489     "-o", "${reportsDir}/clover/clover.xml"].toArray()
490     com.atlassian.clover.reporters.xml.XMLReporter.runReport(args)
491   }
492 }
493
494 // end clover bits
495
496
497 compileJava {
498
499   doFirst {
500     sourceCompatibility = compile_source_compatibility
501     targetCompatibility = compile_target_compatibility
502     options.compilerArgs = additional_compiler_args
503     print ("Setting target compatibility to "+targetCompatibility+"\n")
504   }
505
506 }
507
508 compileTestJava {
509   if (use_clover) {
510     dependsOn compileCloverJava
511     classpath += configurations.cloverRuntime
512   } else {
513     classpath += sourceSets.main.runtimeClasspath
514   }
515   doFirst {
516     sourceCompatibility = compile_source_compatibility
517     targetCompatibility = compile_target_compatibility
518     options.compilerArgs = additional_compiler_args
519     print ("Setting target compatibility to "+targetCompatibility+"\n")
520   }
521 }
522
523
524 compileCloverJava {
525
526   doFirst {
527     sourceCompatibility = compile_source_compatibility
528     targetCompatibility = compile_target_compatibility
529     options.compilerArgs += additional_compiler_args
530     print ("Setting target compatibility to "+targetCompatibility+"\n")
531   }
532   classpath += configurations.cloverRuntime
533 }
534
535 clean {
536   doFirst {
537     delete sourceSets.main.java.outputDir
538   }
539 }
540
541 cleanTest {
542   doFirst {
543     delete sourceSets.test.java.outputDir
544     delete cloverInstrDir
545   }
546 }
547
548 // format is a string like date.format("dd MMMM yyyy")
549 def getDate(format) {
550   def date = new Date()
551   return date.format(format)
552 }
553
554 task setGitVals {
555   def hashStdOut = new ByteArrayOutputStream()
556   exec {
557     commandLine "git", "rev-parse", "--short", "HEAD"
558     standardOutput = hashStdOut
559     ignoreExitValue true
560   }
561
562   def branchStdOut = new ByteArrayOutputStream()
563   exec {
564     commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
565     standardOutput = branchStdOut
566     ignoreExitValue true
567   }
568
569   project.ext.gitHash = hashStdOut.toString().trim()
570   project.ext.gitBranch = branchStdOut.toString().trim()
571
572   outputs.upToDateWhen { false }
573 }
574
575 task createBuildProperties(type: WriteProperties) {
576   dependsOn setGitVals
577   inputs.dir("${jalviewDir}/${sourceDir}")
578   inputs.dir("${jalviewDir}/${resourceDir}")
579   file(buildProperties).getParentFile().mkdirs()
580   outputFile (buildProperties)
581   // taking time specific comment out to allow better incremental builds
582   comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
583   //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
584   property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
585   property "VERSION", JALVIEW_VERSION
586   property "INSTALLATION", INSTALLATION+" git-commit:"+project.ext.gitHash+" ["+project.ext.gitBranch+"]"
587   outputs.file(outputFile)
588 }
589
590 def buildingHTML = "${jalviewDir}/${docDir}/building.html"
591 task cleanBuildingHTML(type: Delete) {
592   doFirst {
593     delete buildingHTML
594   }
595 }
596
597 task convertBuildingMD(type: Exec) {
598   dependsOn cleanBuildingHTML
599   def buildingMD = "${jalviewDir}/${docDir}/building.md"
600   def css = "${jalviewDir}/${docDir}/github.css"
601
602   def pandoc = null
603   pandoc_exec.split(",").each {
604     if (file(it.trim()).exists()) {
605       pandoc = it.trim()
606       return true
607     }
608   }
609
610   def hostname = "hostname".execute().text.trim()
611   if ((pandoc == null || ! file(pandoc).exists()) && hostname.equals("jv-bamboo")) {
612     pandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
613   }
614
615   doFirst {
616     if (pandoc != null && file(pandoc).exists()) {
617         commandLine pandoc, '-s', '-o', buildingHTML, '--metadata', 'pagetitle="Building Jalview from Source"', '--toc', '-H', css, buildingMD
618     } else {
619         println("Cannot find pandoc. Skipping convert building.md to HTML")
620         throw new StopExecutionException()
621     }
622   }
623
624   ignoreExitValue true
625
626   inputs.file(buildingMD)
627   inputs.file(css)
628   outputs.file(buildingHTML)
629 }
630
631 clean {
632   doFirst {
633     delete buildingHTML
634   }
635 }
636
637 task syncDocs(type: Sync) {
638   dependsOn convertBuildingMD
639   def syncDir = "${classes}/${docDir}"
640   from fileTree("${jalviewDir}/${docDir}")
641   into syncDir
642
643 }
644
645 def helpFile = "${classes}/${helpDir}/help.jhm"
646
647 task copyHelp(type: Copy) {
648   def inputDir = "${jalviewDir}/${helpParentDir}/${helpDir}"
649   def outputDir = "${classes}/${helpDir}"
650   from(inputDir) {
651     exclude '**/*.gif'
652     exclude '**/*.jpg'
653     exclude '**/*.png'
654     filter(ReplaceTokens, beginToken: '$$', endToken: '$$', tokens: ['Version-Rel': JALVIEW_VERSION,'Year-Rel': getDate("yyyy")])
655   }
656   from(inputDir) {
657     include '**/*.gif'
658     include '**/*.jpg'
659     include '**/*.png'
660   }
661   into outputDir
662
663   inputs.dir(inputDir)
664   outputs.files(helpFile)
665   outputs.dir(outputDir)
666 }
667
668 task syncLib(type: Sync) {
669   def syncDir = "${classes}/${libDistDir}"
670   from fileTree("${jalviewDir}/${libDistDir}")
671   into syncDir
672 }
673
674 task syncResources(type: Sync) {
675   from "${jalviewDir}/${resourceDir}"
676   include "**/*.*"
677   into "${classes}"
678   preserve {
679     include "**"
680   }
681 }
682
683 task prepare {
684   dependsOn syncResources
685   dependsOn syncDocs
686   dependsOn copyHelp
687 }
688
689
690 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
691 test {
692   dependsOn prepare
693   dependsOn compileJava
694   if (use_clover) {
695     dependsOn cloverInstr
696   }
697
698   if (use_clover) {
699     print("Running tests " + (use_clover?"WITH":"WITHOUT") + " clover [clover="+use_clover+"]\n")
700   }
701
702   useTestNG() {
703     includeGroups testngGroups
704     preserveOrder true
705     useDefaultListeners=true
706   }
707
708   workingDir = jalviewDir
709   //systemProperties 'clover.jar' System.properties.clover.jar
710   sourceCompatibility = compile_source_compatibility
711   targetCompatibility = compile_target_compatibility
712   jvmArgs += additional_compiler_args
713
714 }
715
716 task buildIndices(type: JavaExec) {
717   dependsOn copyHelp
718   classpath = sourceSets.main.compileClasspath
719   main = "com.sun.java.help.search.Indexer"
720   workingDir = "${classes}/${helpDir}"
721   def argDir = "html"
722   args = [ argDir ]
723   inputs.dir("${workingDir}/${argDir}")
724
725   outputs.dir("${classes}/doc")
726   outputs.dir("${classes}/help")
727   outputs.file("${workingDir}/JavaHelpSearch/DOCS")
728   outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
729   outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
730   outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
731   outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
732   outputs.file("${workingDir}/JavaHelpSearch/TMAP")
733 }
734
735 task compileLinkCheck(type: JavaCompile) {
736   options.fork = true
737   classpath = files("${jalviewDir}/${utilsDir}")
738   destinationDir = file("${jalviewDir}/${utilsDir}")
739   source = fileTree(dir: "${jalviewDir}/${utilsDir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
740
741   inputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.java")
742   inputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.java")
743   outputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.class")
744   outputs.file("${jalviewDir}/${utilsDir}/BufferedLineReader.class")
745 }
746
747 task linkCheck(type: JavaExec) {
748   dependsOn prepare, compileLinkCheck
749
750   def helpLinksCheckerOutFile = file("${jalviewDir}/${utilsDir}/HelpLinksChecker.out")
751   classpath = files("${jalviewDir}/${utilsDir}")
752   main = "HelpLinksChecker"
753   workingDir = jalviewDir
754   def help = "${classes}/${helpDir}"
755   args = [ "${classes}/${helpDir}", "-nointernet" ]
756
757   def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
758   def errFOS = outFOS
759   standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
760     outFOS,
761     standardOutput)
762   errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
763     outFOS,
764     errorOutput)
765
766   inputs.dir("${classes}/${helpDir}")
767   outputs.file(helpLinksCheckerOutFile)
768 }
769
770 // import the pubhtmlhelp target
771 ant.properties.basedir = "${jalviewDir}"
772 ant.properties.helpBuildDir = "${jalviewDirAbsolutePath}/${classes}/${helpDir}"
773 ant.importBuild "${utilsDir}/publishHelp.xml"
774
775
776 task cleanPackageDir(type: Delete) {
777   doFirst {
778     delete fileTree(dir: "${jalviewDir}/${packageDir}", include: "*.jar")
779   }
780 }
781
782 jar {
783   dependsOn linkCheck
784   dependsOn buildIndices
785   dependsOn createBuildProperties
786
787   manifest {
788     attributes "Main-Class": mainClass,
789     "Permissions": "all-permissions",
790     "Application-Name": "Jalview Desktop",
791     "Codebase": application_codebase
792   }
793
794   destinationDir = file("${jalviewDir}/${packageDir}")
795   archiveName = rootProject.name+".jar"
796
797   exclude "cache*/**"
798   exclude "*.jar"
799   exclude "*.jar.*"
800   exclude "**/*.jar"
801   exclude "**/*.jar.*"
802
803   inputs.dir("${classes}")
804   outputs.file("${jalviewDir}/${packageDir}/${archiveName}")
805 }
806
807 task copyJars(type: Copy) {
808   from fileTree(dir: "${classes}", include: "**/*.jar").files
809   into "${jalviewDir}/${packageDir}"
810 }
811
812 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
813 task syncJars(type: Sync) {
814   from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
815   into "${jalviewDir}/${packageDir}"
816   preserve {
817     include jar.archiveName
818   }
819 }
820
821 task makeDist {
822   group = "build"
823   description = "Put all required libraries in dist"
824   // order of "cleanPackageDir", "copyJars", "jar" important!
825   jar.mustRunAfter cleanPackageDir
826   syncJars.mustRunAfter cleanPackageDir
827   dependsOn cleanPackageDir
828   dependsOn syncJars
829   dependsOn jar
830   outputs.dir("${jalviewDir}/${packageDir}")
831 }
832
833 task cleanDist {
834   dependsOn cleanPackageDir
835   dependsOn cleanTest
836   dependsOn clean
837 }
838
839 shadowJar {
840   group = "distribution"
841   if (buildDist) {
842     dependsOn makeDist
843   }
844   from ("${jalviewDir}/${libDistDir}") {
845     include("*.jar")
846   }
847   manifest {
848     attributes 'Implementation-Version': JALVIEW_VERSION
849   }
850   mainClassName = shadowJarMainClass
851   mergeServiceFiles()
852   classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
853   minimize()
854 }
855
856 task getdownWebsite() {
857   group = "distribution"
858   description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
859   if (buildDist) {
860     dependsOn makeDist
861   }
862
863   def getdownWebsiteResourceFilenames = []
864   def getdownTextString = ""
865   def getdownResourceDir = project.ext.getdownResourceDir
866   def getdownAppDir = project.ext.getdownAppDir
867   def getdownResourceFilenames = []
868
869   doFirst {
870     // clean the getdown website and files dir before creating getdown folders
871     delete project.ext.getdownWebsiteDir
872     delete project.ext.getdownFilesDir
873
874     copy {
875       from buildProperties
876       rename(build_properties_file, getdown_build_properties)
877       into project.ext.getdownAppDir
878     }
879     getdownWebsiteResourceFilenames += "${getdown_app_dir}/${getdown_build_properties}"
880
881     // go through properties looking for getdown_txt_...
882     def props = project.properties.sort { it.key }
883     if (getdown_alt_java_min_version.length() > 0) {
884       props.put("getdown_txt_java_min_version", getdown_alt_java_min_version)
885     }
886     if (getdown_alt_java_max_version.length() > 0) {
887       props.put("getdown_txt_java_max_version", getdown_alt_java_max_version)
888     }
889     props.put("getdown_txt_multi_java_location", getdown_alt_multi_java_location)
890
891     props.put("getdown_txt_appbase", getdown_app_base)
892     props.each{ prop, val ->
893       if (prop.startsWith("getdown_txt_") && val != null) {
894         if (prop.startsWith("getdown_txt_multi_")) {
895           def key = prop.substring(18)
896           val.split(",").each{ v ->
897             def line = "${key} = ${v}\n"
898             getdownTextString += line
899           }
900         } else {
901           // file values rationalised
902           if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
903             def r = null
904             if (val.indexOf('/') == 0) {
905               // absolute path
906               r = file(val)
907             } else if (val.indexOf('/') > 0) {
908               // relative path (relative to jalviewDir)
909               r = file( "${jalviewDir}/${val}" )
910             }
911             if (r.exists()) {
912               val = "${getdown_resource_dir}/" + r.getName()
913               getdownWebsiteResourceFilenames += val
914               getdownResourceFilenames += r.getPath()
915             }
916           }
917           if (! prop.startsWith("getdown_txt_resource")) {
918             def line = prop.substring(12) + " = ${val}\n"
919             getdownTextString += line
920           }
921         }
922       }
923     }
924
925     getdownWebsiteResourceFilenames.each{ filename ->
926       getdownTextString += "resource = ${filename}\n"
927     }
928     getdownResourceFilenames.each{ filename ->
929       copy {
930         from filename
931         into project.ext.getdownResourceDir
932       }
933     }
934
935     def codeFiles = []
936     fileTree(file(packageDir)).each{ f ->
937       if (f.isDirectory()) {
938         def files = fileTree(dir: f, include: ["*"]).getFiles()
939         codeFiles += files
940       } else if (f.exists()) {
941         codeFiles += f
942       }
943     }
944     codeFiles.sort().each{f ->
945       def name = f.getName()
946       def line = "code = ${getdown_app_dir}/${name}\n"
947       getdownTextString += line
948       copy {
949         from f.getPath()
950         into project.ext.getdownAppDir
951       }
952     }
953
954     // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
955     /*
956     if (JAVA_VERSION.equals("11")) {
957     def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
958     j11libFiles.sort().each{f ->
959     def name = f.getName()
960     def line = "code = ${getdown_j11lib_dir}/${name}\n"
961     getdownTextString += line
962     copy {
963     from f.getPath()
964     into project.ext.getdownJ11libDir
965     }
966     }
967     }
968      */
969
970     // 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.
971     //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
972     getdownTextString += "resource = ${getdown_launcher_new}\n"
973     getdownTextString += "class = ${mainClass}\n"
974
975     def getdown_txt = file("${project.ext.getdownWebsiteDir}/getdown.txt")
976     getdown_txt.write(getdownTextString)
977
978     def launch_jvl = file("${project.ext.getdownWebsiteDir}/${getdown_launch_jvl}")
979     launch_jvl.write("appbase="+props.get("getdown_txt_appbase"))
980
981     copy {
982       from getdownLauncher
983       rename(file(getdownLauncher).getName(), getdown_launcher_new)
984       into project.ext.getdownWebsiteDir
985     }
986
987     copy {
988       from getdownLauncher
989       if (file(getdownLauncher).getName() != getdown_launcher) {
990         rename(file(getdownLauncher).getName(), getdown_launcher)
991       }
992       into project.ext.getdownWebsiteDir
993     }
994
995     if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
996       copy {
997         from getdown_txt
998         from getdownLauncher
999         from "${getdownWebsiteDir}/${getdown_build_properties}"
1000         if (file(getdownLauncher).getName() != getdown_launcher) {
1001           rename(file(getdownLauncher).getName(), getdown_launcher)
1002         }
1003         into getdownInstallDir
1004       }
1005
1006       copy {
1007         from getdownInstallDir
1008         into getdownFilesInstallDir
1009       }
1010     }
1011
1012     copy {
1013       from getdown_txt
1014       from launch_jvl
1015       from getdownLauncher
1016       from "${getdownWebsiteDir}/${getdown_build_properties}"
1017       if (file(getdownLauncher).getName() != getdown_launcher) {
1018         rename(file(getdownLauncher).getName(), getdown_launcher)
1019       }
1020       into getdownFilesDir
1021     }
1022
1023     copy {
1024       from getdownResourceDir
1025       into "${project.ext.getdownFilesDir}/${getdown_resource_dir}"
1026     }
1027   }
1028
1029   if (buildDist) {
1030     inputs.dir("${jalviewDir}/${packageDir}")
1031   }
1032   outputs.dir(project.ext.getdownWebsiteDir)
1033   outputs.dir(project.ext.getdownFilesDir)
1034 }
1035
1036 task getdownDigest(type: JavaExec) {
1037   group = "distribution"
1038   description = "Digest the getdown website folder"
1039   dependsOn getdownWebsite
1040   doFirst {
1041     classpath = files("${getdownWebsiteDir}/${getdown_launcher}")
1042   }
1043   main = "com.threerings.getdown.tools.Digester"
1044   args project.ext.getdownWebsiteDir
1045   inputs.dir(project.ext.getdownWebsiteDir)
1046   outputs.file("${project.ext.getdownWebsiteDir}/digest2.txt")
1047 }
1048
1049 task getdown() {
1050   group = "distribution"
1051   description = "Create the minimal and full getdown app folder for installers and website and create digest file"
1052   dependsOn getdownDigest
1053   doLast {
1054     if (reportRsyncCommand) {
1055       def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
1056       def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
1057       println "LIKELY RSYNC COMMAND:"
1058       println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
1059       if (RUNRSYNC == "true") {
1060         exec {
1061           commandLine "mkdir", "-p", toDir
1062         }
1063         exec {
1064           commandLine "rsync", "-avh", "--delete", fromDir, toDir
1065         }
1066       }
1067     }
1068   }
1069 }
1070
1071 clean {
1072   doFirst {
1073     delete project.ext.getdownWebsiteDir
1074     delete project.ext.getdownFilesDir
1075   }
1076 }
1077
1078 install4j {
1079   def install4jHomeDir = "/opt/install4j"
1080   def hostname = "hostname".execute().text.trim()
1081   if (hostname.equals("jv-bamboo")) {
1082     install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1083   } else if (OperatingSystem.current().isMacOsX()) {
1084     install4jHomeDir = '/Applications/install4j.app/Contents/Resources/app'
1085     if (! file(install4jHomeDir).exists()) {
1086       install4jHomeDir = System.getProperty("user.home")+install4jHomeDir
1087     }
1088   } else if (OperatingSystem.current().isLinux()) {
1089     install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1090   }
1091   installDir = file(install4jHomeDir)
1092   mediaTypes = Arrays.asList(install4jMediaTypes.split(","))
1093   if (install4jFaster.equals("true")) {
1094     faster = true
1095   }
1096 }
1097
1098 def install4jConf
1099 def macosJavaVMDir
1100 def macosJavaVMTgz
1101 def windowsJavaVMDir
1102 def windowsJavaVMTgz
1103 def install4jDir = "${jalviewDir}/${install4jResourceDir}"
1104 def install4jConfFile = "jalview-installers-java${JAVA_VERSION}.install4j"
1105 install4jConf = "${install4jDir}/${install4jConfFile}"
1106
1107 task copyInstall4jTemplate(type: Copy) {
1108   macosJavaVMDir = "${System.env.HOME}/buildtools/jre/openjdk-java_vm/getdown/macos-jre${JAVA_VERSION}/jre"
1109   macosJavaVMTgz = "${System.env.HOME}/buildtools/jre/openjdk-java_vm/install4j/tgz/macos-jre${JAVA_VERSION}.tar.gz"
1110   windowsJavaVMDir = "${System.env.HOME}/buildtools/jre/openjdk-java_vm/getdown/windows-jre${JAVA_VERSION}/jre"
1111   windowsJavaVMTgz = "${System.env.HOME}/buildtools/jre/openjdk-java_vm/install4j/tgz/windows-jre${JAVA_VERSION}.tar.gz"
1112   from (install4jDir) {
1113     include install4jTemplate
1114     rename (install4jTemplate, install4jConfFile)
1115     filter(ReplaceTokens, beginToken: '', endToken: '', tokens: ['9999999999': JAVA_VERSION])
1116     filter(ReplaceTokens, beginToken: '$$', endToken: '$$',
1117     tokens: [
1118     'JAVA_VERSION': JAVA_VERSION,
1119     'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
1120     'VERSION': JALVIEW_VERSION,
1121     'MACOS_JAVA_VM_DIR': macosJavaVMDir,
1122     'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
1123     'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
1124     'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
1125     'INSTALL4JINFOPLISTFILEASSOCIATIONS': install4jInfoPlistFileAssociations,
1126     'COPYRIGHT_MESSAGE': install4jCopyrightMessage,
1127     'MACOS_BUNDLE_ID': install4jMacOSBundleId,
1128     'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
1129     'GETDOWN_DIST_DIR': getdown_app_dir,
1130     'GETDOWN_ALT_DIR': getdown_app_dir_alt,
1131     'GETDOWN_INSTALL_DIR': getdown_install_dir
1132     ]
1133     )
1134     if (OSX_KEYPASS=="") {
1135       filter(ReplaceTokens, beginToken: 'codeSigning macEnabled="', endToken: '"', tokens: ['true':'codeSigning macEnabled="false"'])
1136       filter(ReplaceTokens, beginToken: 'runPostProcessor="true" ',endToken: 'Processor', tokens: ['post':'runPostProcessor="false" postProcessor'])
1137     }
1138   }
1139   into install4jDir
1140   outputs.files(install4jConf)
1141
1142   doLast {
1143     // include file associations in installer
1144     def installerFileAssociationsXml = file("${install4jDir}/${install4jInstallerFileAssociations}").text
1145     ant.replaceregexp(
1146       byline: false,
1147       flags: "s",
1148       match: '<action name="EXTENSIONS_REPLACED_BY_GRADLE".*?</action>',
1149       replace: installerFileAssociationsXml,
1150       file: install4jConf
1151     )
1152     /*
1153     // include uninstaller applescript app files in dmg
1154     def installerDMGUninstallerXml = file("$install4jDir/$install4jDMGUninstallerAppFiles").text
1155     ant.replaceregexp(
1156     byline: false,
1157     flags: "s",
1158     match: '<file name="UNINSTALL_OLD_JALVIEW_APP_REPLACED_IN_GRADLE" file=.*?>',
1159     replace: installerDMGUninstallerXml,
1160     file: install4jConf
1161     )
1162      */
1163   }
1164 }
1165
1166 task installers(type: com.install4j.gradle.Install4jTask) {
1167   group = "distribution"
1168   description = "Create the install4j installers"
1169   dependsOn getdown
1170   dependsOn copyInstall4jTemplate
1171   projectFile = file(install4jConf)
1172   variables = [majorVersion: version.substring(2, 11), build: 001, OSX_KEYSTORE: OSX_KEYSTORE, JSIGN_SH: JSIGN_SH]
1173   destination = "${jalviewDir}/${install4jBuildDir}/${JAVA_VERSION}"
1174   buildSelected = true
1175
1176   if (OSX_KEYPASS) {
1177     macKeystorePassword=OSX_KEYPASS
1178   }
1179
1180   doFirst {
1181     println("Using projectFile "+projectFile)
1182   }
1183
1184   inputs.dir(project.ext.getdownWebsiteDir)
1185   inputs.file(install4jConf)
1186   inputs.dir(macosJavaVMDir)
1187   inputs.dir(windowsJavaVMDir)
1188   outputs.dir("${jalviewDir}/${install4jBuildDir}/${JAVA_VERSION}")
1189 }
1190
1191 clean {
1192   doFirst {
1193     delete install4jConf
1194   }
1195 }
1196
1197 task sourceDist (type: Tar) {
1198   
1199   def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
1200   def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
1201   // cater for buildship < 3.1 [3.0.1 is max version in eclipse 2018-09]
1202   try {
1203     archiveFileName = outputFileName
1204   } catch (Exception e) {
1205     archiveName = outputFileName
1206   }
1207   
1208   compression Compression.GZIP
1209   
1210   into project.name
1211
1212   def EXCLUDE_FILES=["build/*","bin/*","test-output/","test-reports","tests","clover*/*"
1213   ,".*"
1214   ,"benchmarking/*"
1215   ,"**/.*"
1216   ,"*.class"
1217   ,"**/*.class","${j11modDir}/**/*.jar","appletlib","**/*locales"
1218   ,"*locales/**",
1219   ,"utils/InstallAnywhere"] 
1220   def PROCESS_FILES=[   "AUTHORS",
1221   "CITATION",
1222   "FEATURETODO",
1223   "JAVA-11-README",
1224   "FEATURETODO",
1225   "LICENSE",
1226   "**/README",
1227   "RELEASE",
1228   "THIRDPARTYLIBS","TESTNG",
1229   "build.gradle",
1230   "gradle.properties",
1231   "**/*.java",
1232   "**/*.html",
1233   "**/*.xml",
1234   "**/*.gradle",
1235   "**/*.groovy",
1236   "**/*.properties",
1237   "**/*.perl",
1238   "**/*.sh"]
1239
1240   from(jalviewDir) {
1241     exclude (EXCLUDE_FILES)
1242     include (PROCESS_FILES)
1243     filter(ReplaceTokens, beginToken: '$$', endToken: '$$', tokens: ['Version-Rel': JALVIEW_VERSION,'Year-Rel': getDate("yyyy")])
1244   }
1245   from(jalviewDir) {
1246     exclude (EXCLUDE_FILES)
1247     exclude (PROCESS_FILES)
1248   exclude ("appletlib")
1249   exclude ("**/*locales")
1250   exclude ("*locales/**")
1251   exclude ("utils/InstallAnywhere")
1252
1253     exclude (getdown_files_dir)
1254   exclude (getdown_website_dir)
1255
1256   // exluding these as not using jars as modules yet
1257   exclude ("${j11modDir}/**/*.jar")
1258 }
1259 //  from (jalviewDir) {
1260 //    // explicit includes for stuff that seemed to not get included
1261 //    include(fileTree("test/**/*."))
1262 //    exclude(EXCLUDE_FILES)
1263 //    exclude(PROCESS_FILES)
1264 //  }
1265 }
1266
1267 task helppages  {
1268   dependsOn copyHelp
1269   dependsOn pubhtmlhelp
1270   
1271   inputs.dir("${classes}/${helpDir}")
1272   outputs.dir("${helpOutputDir}")
1273 }
1274
1275 def jalviewjsBuildDir
1276 def jalviewjsSiteDir
1277 def jalviewjsTransferSiteJsDir
1278 def jalviewjsTransferSiteLibDir
1279 def jalviewjsTransferSiteCoreDir
1280 task jalviewjsSitePath {
1281   def relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
1282   jalviewjsBuildDir = "${relativeBuildDir}/jalviewjs"
1283   jalviewjsSiteDir = "${jalviewjsBuildDir}/${jalviewjs_site_dir}"
1284   jalviewjsTransferSiteJsDir = "${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js"
1285   jalviewjsTransferSiteLibDir = "${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib"
1286   jalviewjsTransferSiteCoreDir = "${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core"
1287 }
1288
1289 def eclipseWorkspace
1290 task jalviewjsSetEclipseWorkspace {
1291   def propKey = "jalviewjs_eclipse_workspace"
1292   def propVal = null
1293   if (project.hasProperty(propKey)) {
1294     propVal = project.getProperty(propKey)
1295     if (propVal.startsWith("~/")) {
1296       propVal = System.getProperty("user.home") + propVal.substring(1)
1297     }
1298   }
1299   def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
1300   def propsFile = file(propsFileName)
1301   def eclipseWsDir = propVal
1302   def props = new Properties()
1303
1304   if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
1305     def ins = new FileInputStream(propsFileName)
1306     props.load(ins)
1307     ins.close()
1308     if (props.getProperty(propKey, null) != null) {
1309       eclipseWsDir = props.getProperty(propKey)
1310     }
1311   }
1312
1313   def writeProps = false
1314   if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
1315     def tempDir = File.createTempDir()
1316     eclipseWsDir = tempDir.getAbsolutePath()
1317     writeProps = true
1318   }
1319   eclipseWorkspace = file(eclipseWsDir)
1320
1321   doFirst {
1322     if (writeProps) {
1323       props.setProperty(propKey, eclipseWsDir)
1324       propsFile.parentFile.mkdirs()
1325       def bytes = new ByteArrayOutputStream()
1326       props.store(bytes, null)
1327       def propertiesString = bytes.toString()
1328       propsFile.text = propertiesString
1329     }
1330
1331     println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
1332   }
1333
1334   //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
1335   outputs.file(propsFileName)
1336   outputs.upToDateWhen { eclipseWorkspace.exists() }
1337 }
1338
1339
1340 def eclipseBinary
1341 def eclipseVersion
1342 def eclipseDebug = false
1343 def eclipseVersionSuffix = ""
1344 task jalviewjsEclipsePaths {
1345   def eclipseProduct
1346
1347   def eclipseRoot = jalviewjs_eclipse_root
1348   if (eclipseRoot.startsWith("~/")) {
1349     eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
1350   }
1351   if (OperatingSystem.current().isMacOsX()) {
1352     eclipseRoot += "/Eclipse.app"
1353     eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
1354     eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
1355   } else if (OperatingSystem.current().isWindows()) { // check these paths!!
1356     if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1357       eclipseRoot += "/eclipse"
1358     }
1359     eclipseBinary = "${eclipseRoot}/eclipse"
1360     eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1361   } else { // linux or unix
1362     if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1363       eclipseRoot += "/eclipse"
1364     }
1365     eclipseBinary = "${eclipseRoot}/eclipse"
1366     eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1367   }
1368
1369   eclipseVersion = "4.12" // default
1370   def assumedVersion = true
1371   if (file(eclipseProduct).exists()) {
1372     def fis = new FileInputStream(eclipseProduct)
1373     def props = new Properties()
1374     props.load(fis)
1375     eclipseVersion = props.getProperty("version")
1376     fis.close()
1377     assumedVersion = false
1378   }
1379   /*
1380   String[] v = eclipseVersion.split("\\.")
1381   def v0 = Integer.valueOf(v[0])
1382   def v1 = Integer.valueOf(v[1])
1383   if (v0 < 4 || ( v0 == 4 && v1 < 13 )) {
1384     eclipseVersionSuffix = "_4.12"
1385   } else {
1386     eclipseVersionSuffix = "_4.13"
1387   }
1388   */
1389
1390   
1391   def propKey = "eclipse_debug"
1392   eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
1393
1394   doFirst {
1395     if (!assumedVersion) {
1396       println("ECLIPSE VERSION=${eclipseVersion}")
1397     }
1398   }
1399 }
1400
1401 task eclipseSetup {
1402   dependsOn eclipseProject
1403   dependsOn eclipseClasspath
1404   dependsOn eclipseJdt
1405 }
1406
1407 /* using the Copy task below
1408 task OLDjalviewjsEclipseCopyDropins {
1409   dependsOn jalviewjsEclipsePaths
1410   dependsOn jalviewjsCleanEclipse
1411   def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
1412   inputFiles += file(jalviewjs_j2s_plugin)
1413   def outputDir = "${buildDir}/jalviewjs
1414
1415   inputs.files inputFiles
1416   inputFiles.each { file ->
1417     outputs.file("${outputDir}/${file.name}")
1418   }
1419
1420   doLast {
1421     inputFiles.each { file ->
1422       copy {
1423         from file
1424         into outputDir
1425       }
1426     }
1427   }
1428 }
1429 */
1430
1431 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
1432 task jalviewjsEclipseCopyDropins(type: Copy) {
1433   dependsOn jalviewjsEclipsePaths
1434
1435   def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
1436   inputFiles += file("${jalviewDir}/${jalviewjs_j2s_plugin}")
1437   def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
1438
1439   from inputFiles
1440   into outputDir
1441 }
1442
1443 // this eclipse -clean doesn't actually work
1444 task jalviewjsCleanEclipse(type: Exec) {
1445   dependsOn eclipseSetup
1446   dependsOn jalviewjsEclipsePaths
1447   dependsOn jalviewjsEclipseCopyDropins
1448
1449   executable(eclipseBinary)
1450   args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
1451   if (eclipseDebug) {
1452     args += "-debug"
1453   }
1454   args += "-l"
1455
1456   def inputString = """exit
1457 y
1458 """
1459   def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
1460   standardInput = inputByteStream
1461 }
1462 /* not really working yet
1463 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
1464 */
1465
1466 def jalviewjsTransferSiteUnzipDir
1467 task jalviewjsTransferUnzipLib {
1468   dependsOn jalviewjsSitePath
1469
1470   def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
1471   zipFiles += "${jalviewDir}/${jalviewjs_swingjs_zip}"
1472
1473   doLast {
1474     zipFiles.each { file_zip -> 
1475       copy {
1476         from zipTree(file_zip)
1477         into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
1478       }
1479     }
1480   }
1481
1482   inputs.files zipFiles
1483   outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
1484 }
1485
1486 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
1487   group "JalviewJS"
1488   description "Create the .j2s file from the j2s.* properties"
1489
1490   dependsOn jalviewjsSitePath
1491
1492   outputFile ("${jalviewDir}/${jalviewjs_j2s_settings}")
1493   def j2s_props = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
1494   def siteDirProperty = "j2s.site.directory"
1495   def setSiteDir = false
1496   j2s_props.each { prop, val ->
1497     if (val != null) {
1498       if (prop == siteDirProperty) {
1499         if (!(val.startsWith('/') || val.startsWith("file://") )) {
1500           val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
1501         }
1502         setSiteDir = true
1503       }
1504       property(prop,val)
1505     }
1506     if (!setSiteDir) { // default site location, don't override specifically set property
1507       property(siteDirProperty,"${jalviewDir}/${jalviewjsTransferSiteJsDir}")
1508     }
1509   }
1510   inputs.properties(j2s_props)
1511   outputs.file(outputFile)
1512 }
1513
1514 task jalviewjsEclipseSetup {
1515   dependsOn jalviewjsEclipseCopyDropins
1516   dependsOn jalviewjsSetEclipseWorkspace
1517   dependsOn jalviewjsCreateJ2sSettings
1518 }
1519
1520 task jalviewjsSyncLib (type: Sync) {
1521   dependsOn jalviewjsSitePath
1522   dependsOn jalviewjsTransferUnzipLib
1523   def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
1524   def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
1525
1526   from inputFiles
1527   into outputDir
1528   def outputFiles = []
1529   rename { filename ->
1530     outputFiles += "${outputDir}/${filename}"
1531     null
1532   }
1533   preserve {
1534     include "**"
1535   }
1536   outputs.files outputFiles
1537   inputs.files inputFiles
1538 }
1539
1540 task jalviewjsSyncCore (type: Sync) {
1541   dependsOn jalviewjsSitePath
1542   dependsOn "jalviewjsBuildAllCores"
1543   def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
1544   def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
1545
1546   from inputFiles
1547   into outputDir
1548   def outputFiles = []
1549   rename { filename ->
1550     outputFiles += "${outputDir}/${filename}"
1551     null
1552   }
1553   preserve {
1554     include "**"
1555   }
1556   outputs.files outputFiles
1557   inputs.files inputFiles
1558 }
1559
1560 task jalviewjsSyncResources (type: Sync) {
1561   dependsOn jalviewjsSitePath
1562   def inputFiles = fileTree(dir: "${jalviewDir}/${resourceDir}")
1563   def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
1564
1565   from inputFiles
1566   into outputDir
1567   def outputFiles = []
1568   rename { filename ->
1569     outputFiles += "${outputDir}/${filename}"
1570     null
1571   }
1572   preserve {
1573     include "**"
1574   }
1575   outputs.files outputFiles
1576   inputs.files inputFiles
1577 }
1578
1579 task jalviewjsSyncSiteResources (type: Sync) {
1580   dependsOn jalviewjsSitePath
1581   def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
1582   def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
1583
1584   from inputFiles
1585   into outputDir
1586   def outputFiles = []
1587   rename { filename ->
1588     outputFiles += "${outputDir}/${filename}"
1589     null
1590   }
1591   preserve {
1592     include "**"
1593   }
1594   outputs.files outputFiles
1595   inputs.files inputFiles
1596 }
1597
1598 task jalviewjsSyncBuildProperties (type: Sync) {
1599   dependsOn jalviewjsSitePath
1600   dependsOn createBuildProperties
1601   def inputFiles = [file(buildProperties)]
1602   def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
1603
1604   from inputFiles
1605   into outputDir
1606   def outputFiles = []
1607   rename { filename ->
1608     outputFiles += "${outputDir}/${filename}"
1609     null
1610   }
1611   preserve {
1612     include "**"
1613   }
1614   outputs.files outputFiles
1615   inputs.files inputFiles
1616 }
1617
1618 task jalviewjsProjectImport(type: Exec) {
1619   dependsOn eclipseSetup
1620   dependsOn jalviewjsEclipsePaths
1621   dependsOn jalviewjsEclipseSetup
1622
1623   //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
1624   def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
1625   executable(eclipseBinary)
1626   args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
1627   if (eclipseDebug) {
1628     args += "-debug"
1629   }
1630   args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
1631
1632   inputs.file("${jalviewDir}/.project")
1633   outputs.upToDateWhen { 
1634     file(projdir).exists()
1635   }
1636 }
1637
1638 task jalviewjsTranspile(type: Exec) {
1639   dependsOn jalviewjsEclipseSetup 
1640   dependsOn jalviewjsProjectImport
1641   dependsOn jalviewjsEclipsePaths
1642
1643   executable(eclipseBinary)
1644   args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
1645   if (eclipseDebug) {
1646     args += "-debug"
1647   }
1648   args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
1649
1650   def stdout
1651   def stderr
1652   doFirst {
1653     stdout = new ByteArrayOutputStream()
1654     stderr = new ByteArrayOutputStream()
1655
1656     def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
1657     def logOutFile = file(logOutFileName)
1658     logOutFile.createNewFile()
1659     logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
1660 BINARY: ${eclipseBinary}
1661 VERSION: ${eclipseVersion}
1662 WORKSPACE: ${eclipseWorkspace}
1663 DEBUG: ${eclipseDebug}
1664 ----
1665 """
1666     def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
1667     //def logErrFileName = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_stderr}"
1668     //def logErrFile = file(logFileName)
1669     //logErrFile.createNewFile()
1670     //def logErrFOS = new FileErrputStream(logErrFile, false)
1671     // combine stdout and stderr
1672     def logErrFOS = logOutFOS
1673
1674     if (jalviewjs_j2s_to_console.equals("true")) {
1675       standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1676         new org.apache.tools.ant.util.TeeOutputStream(
1677           logOutFOS,
1678           stdout),
1679         standardOutput)
1680       errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1681         new org.apache.tools.ant.util.TeeOutputStream(
1682           logErrFOS,
1683           stderr),
1684         errorOutput)
1685     } else {
1686       standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1687         logOutFOS,
1688         stdout)
1689       errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1690         logErrFOS,
1691         stderr)
1692     }
1693   }
1694
1695   doLast {
1696     if (stdout.toString().contains("Error processing ")) {
1697       // j2s did not complete transpile
1698       throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
1699     }
1700   }
1701
1702   inputs.dir("${jalviewDir}/${sourceDir}")
1703   outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
1704   outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
1705 }
1706
1707 // this Copy version of TransferSiteJs will delete anything else in the target dir
1708 task jalviewjsCopyTransferSiteJs(type: Copy) {
1709   dependsOn jalviewjsTranspile
1710   from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
1711   into "${jalviewDir}/${jalviewjsSiteDir}"
1712 }
1713
1714 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
1715 task jalviewjsSyncTransferSiteJs(type: Sync) {
1716   from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
1717   include "**/*.*"
1718   into "${jalviewDir}/${jalviewjsSiteDir}"
1719   preserve {
1720     include "**"
1721   }
1722 }
1723
1724 jalviewjsSyncLib.mustRunAfter jalviewjsCopyTransferSiteJs
1725 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
1726 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
1727 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
1728
1729 jalviewjsSyncLib.mustRunAfter jalviewjsSyncTransferSiteJs
1730 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
1731 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
1732 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
1733
1734 task jalviewjsPrepareSite {
1735   group "JalviewJS"
1736   description "Prepares the website folder including unzipping files and copying resources"
1737   dependsOn jalviewjsSyncLib
1738   dependsOn jalviewjsSyncResources
1739   dependsOn jalviewjsSyncSiteResources
1740   dependsOn jalviewjsSyncBuildProperties
1741   dependsOn jalviewjsSyncCore
1742 }
1743
1744 task jalviewjsBuildSite {
1745   group "JalviewJS"
1746   description "Builds the whole website including transpiled code"
1747   dependsOn jalviewjsCopyTransferSiteJs
1748   dependsOn jalviewjsPrepareSite
1749 }
1750
1751 task cleanJalviewjsSite {
1752   doFirst {
1753     delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
1754     delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
1755     delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
1756     delete "${jalviewDir}/${jalviewjsSiteDir}"
1757   }
1758 }
1759
1760 task jalviewjsSiteTar(type: Tar) {
1761   group "JalviewJS"
1762   description "Creates a tar.gz file for the website"
1763   dependsOn jalviewjsBuildSite
1764   def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
1765   try {
1766     archiveFileName = outputFilename
1767   } catch (Exception e) {
1768     archiveName = outputFilename
1769   }
1770
1771   compression Compression.GZIP
1772
1773   from "${jalviewDir}/${jalviewjsSiteDir}"
1774   into jalviewjs_site_dir // this is inside the tar file
1775
1776   inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
1777 }
1778
1779 task jalviewjsServer {
1780   group "JalviewJS"
1781   def filename = "jalviewjsTest.html"
1782   description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
1783   dependsOn jalviewjsSitePath
1784   def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
1785   doLast {
1786
1787     SimpleHttpFileServerFactory factory = new SimpleHttpFileServerFactory()
1788     def port = Integer.valueOf(jalviewjs_server_port)
1789     def start = port
1790     def running = false
1791     def url
1792     while(port < start+1000 && !running) {
1793       try {
1794         def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
1795         def jalviewjsServer = factory.start(doc_root, port)
1796         running = true
1797         url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
1798         println("SERVER STARTED with document root ${doc_root}.")
1799         println("Go to "+url+" . Run  gradle --stop  to stop (kills all gradle daemons).")
1800         println("For debug: "+url+"?j2sdebug")
1801
1802         file(htmlFile).text = """
1803         <p><a href="${url}">Jalview JS Test. &lt;${url}&gt;</a></p>
1804         <p><a href="${url}?j2sdebug">Jalview JS Test with debug. &lt;${url}?j2sdebug&lt;</a></p>
1805         """
1806
1807       } catch (Exception e) {
1808         port++;
1809       }
1810     }
1811
1812   }
1813
1814   outputs.file(htmlFile)
1815   outputs.upToDateWhen({false})
1816 }
1817
1818 task cleanJalviewjsAll {
1819   group "JalviewJS"
1820   description "Delete all configuration and build artifacts to do with JalviewJS build"
1821   dependsOn cleanJalviewjsSite
1822   dependsOn jalviewjsEclipsePaths
1823   
1824   doFirst {
1825     delete "${jalviewDir}/${jalviewjsBuildDir}"
1826     delete "${jalviewDir}/${eclipse_bin_dir}"
1827     if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
1828       delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
1829     }
1830     delete "${jalviewDir}/${jalviewjs_j2s_settings}"
1831   }
1832
1833   outputs.upToDateWhen( { false } )
1834 }
1835
1836 task jalviewjs {
1837   group "JalviewJS"
1838   description "Build the site"
1839   dependsOn jalviewjsBuildSite
1840 }
1841
1842
1843 task jalviewjsIDE_CopyTransferSiteJs(type: Copy) {
1844   from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
1845   into "${jalviewDir}/${jalviewjsSiteDir}"
1846 }
1847
1848 task jalviewjsIDE_j2sFile {
1849   group "00 JalviewJS in Eclipse"
1850   description "Creates the .j2s file"
1851   dependsOn jalviewjsCreateJ2sSettings
1852 }
1853
1854 task jalviewjsIDE_AssembleSite {
1855   group "00 JalviewJS in Eclipse"
1856   description "Assembles the Eclipse transpiled site and unzips supporting zipfiles"
1857   dependsOn jalviewjsIDE_CopyTransferSiteJs
1858   dependsOn jalviewjsPrepareSite
1859 }
1860
1861 task jalviewjsIDE_SiteClean {
1862   group "00 JalviewJS in Eclipse"
1863   description "Deletes the Eclipse transpiled site"
1864   dependsOn cleanJalviewjsSite
1865 }
1866
1867 task jalviewjsIDE_Server {
1868   group "00 JalviewJS in Eclipse"
1869   description "Starts a webserver on localhost to test the website"
1870   dependsOn jalviewjsServer
1871 }
1872
1873 // buildship runs this at import
1874 task eclipseSynchronizationTask {
1875   dependsOn eclipseSetup
1876   dependsOn jalviewjsIDE_j2sFile
1877 }
1878
1879 // buildship runs this at build time
1880 task eclipseAutoBuildTask {
1881   dependsOn jalviewjsSyncTransferSiteJs
1882   dependsOn jalviewjsPrepareSite
1883 }
1884
1885
1886
1887
1888
1889
1890
1891
1892 // closure
1893
1894 def jalviewjsCallCore(FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
1895
1896   def stdout = new ByteArrayOutputStream()
1897   def stderr = new ByteArrayOutputStream()
1898
1899   def coreFile = file(jsfile)
1900   def msg = ""
1901   msg = "Generating ${jsfile}"
1902   println(msg)
1903   logOutFile.createNewFile()
1904   logOutFile.append(msg+"\n")
1905
1906   def coreTop = file(prefixFile)
1907   def coreBottom = file(suffixFile)
1908   coreFile.getParentFile().mkdirs()
1909   coreFile.createNewFile()
1910   coreFile.write( coreTop.text )
1911   list.each {
1912     f ->
1913     if (f.exists()) {
1914       def t = f.text
1915       t.replaceAll("Clazz\\.","Clazz_")
1916       t.replaceAll("Class__","Clazz._")
1917       coreFile.append( t )
1918     } else {
1919       msg = "...file "+f.getPath()+" does not exist, skipping"
1920       println(msg)
1921       logOutFile.append(msg+"\n")
1922     }
1923   }
1924   coreFile.append( coreBottom.text )
1925
1926   msg = "Generating ${zjsfile}"
1927   println(msg)
1928   logOutFile.append(msg+"\n")
1929   def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
1930   def logErrFOS = logOutFOS
1931
1932   javaexec {
1933     classpath = files(["${jalviewDir}/tools/closure_compiler.jar"])
1934     args = [ "--js", jsfile, "--js_output_file", zjsfile ]
1935
1936     msg = "\nRunning '"+commandLine.join(' ')+"'\n"
1937     println(msg)
1938     logOutFile.append(msg+"\n")
1939
1940     if (logOutConsole) {
1941       standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1942         new org.apache.tools.ant.util.TeeOutputStream(
1943           logOutFOS,
1944           stdout),
1945         standardOutput)
1946         errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1947           new org.apache.tools.ant.util.TeeOutputStream(
1948             logErrFOS,
1949             stderr),
1950           errorOutput)
1951     } else {
1952       standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1953         logOutFOS,
1954         stdout)
1955         errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1956           logErrFOS,
1957           stderr)
1958     }
1959   }
1960   msg = "--"
1961   println(msg)
1962   logOutFile.append(msg+"\n")
1963 }
1964
1965
1966
1967 task jalviewjsBuildAllCores {
1968   group "JalviewJS"
1969   description "Build the core js lib closures"
1970
1971   dependsOn jalviewjsSitePath
1972   dependsOn jalviewjsTransferUnzipLib
1973   dependsOn jalviewjsTranspile
1974
1975   def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
1976   def jsDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_js_subdir}"
1977   def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
1978   def prefixFile = "${jsDir}/core/coretop2.js"
1979   def suffixFile = "${jsDir}/core/corebottom2.js"
1980
1981   inputs.file prefixFile
1982   inputs.file suffixFile
1983
1984   def classlists = []
1985   fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
1986     file ->
1987     def name = file.getName() - ".txt"
1988
1989     def filelist = []
1990     file.eachLine {
1991       line ->
1992       filelist += line
1993     }
1994     def list = fileTree(dir: j2sDir, includes: filelist)
1995
1996     def coreFileName = "core${name}.js"
1997     def jsfile = "${outputDir}/${coreFileName}"
1998     def coreZFileName = "core${name}.z.js"
1999     def zjsfile = "${outputDir}/${coreZFileName}"
2000
2001     classlists += [
2002       'jsfile': jsfile,
2003       'zjsfile': zjsfile,
2004       'list': list
2005     ]
2006
2007     inputs.file(file)
2008     inputs.files(list)
2009     outputs.file(jsfile)
2010     outputs.file(zjsfile)
2011   } 
2012
2013
2014   doFirst {
2015     def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
2016     logOutFile.getParentFile().mkdirs()
2017     logOutFile.createNewFile()
2018     logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
2019
2020     classlists.each {
2021       jalviewjsCallCore(it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
2022     }
2023   }
2024
2025 }