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