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