JAL-3543 remove debugging output
[jalview.git] / build.gradle
index 32816f3..ca73859 100644 (file)
@@ -4,13 +4,12 @@ import org.gradle.plugins.ide.eclipse.model.Output
 import org.gradle.plugins.ide.eclipse.model.Library
 import java.security.MessageDigest
 import groovy.transform.ExternalizeMethods
-import groovy.util.XmlSlurper
 import groovy.util.XmlParser
 import groovy.xml.XmlUtil
 
 buildscript {
   dependencies {
-    classpath 'org.openclover:clover:4.3.1'
+    classpath 'org.openclover:clover:4.4.1'
   }
 }
 
@@ -20,7 +19,7 @@ plugins {
   id 'eclipse'
   id 'com.github.johnrengelman.shadow' version '4.0.3'
   id 'com.install4j.gradle' version '8.0.2'
-  id 'com.dorongold.task-tree' version '1.4' // only needed to display task dependency tree with  gradle task1 [task2 ...] taskTree
+  id 'com.dorongold.task-tree' version '1.5' // only needed to display task dependency tree with  gradle task1 [task2 ...] taskTree
 }
 
 repositories {
@@ -33,13 +32,12 @@ repositories {
 }
 
 dependencies {
-  compile 'org.apache.commons:commons-compress:1.18'
 }
 
 
 // in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use
 def string(Object o) {
-  return o.toString()
+  return o == null ? "" : o.toString()
 }
 
 
@@ -57,10 +55,12 @@ ext {
       localPropsFIS.close()
       p.each {
         key, val -> 
-          def over = getProperty(key) != null
+          def oldval = findProperty(key)
           setProperty(key, val)
-          if (over) {
-            println("Overriding property '${key}' with local.properties value '${val}'")
+          if (oldval != null) {
+            println("Overriding property '${key}' ('${oldval}') with local.properties value '${val}'")
+          } else {
+            println("Setting unknown property '${key}' with local.properties value '${val}'")
           }
       }
     } catch (Exception e) {
@@ -116,39 +116,38 @@ ext {
   classes = classesDir
 
   getdownWebsiteDir = string("${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}")
-  getdownDir = string("")
-  reportRsyncCmd = false
   buildDist = true
-  buildProperties = build_properties_file
+
+  // the following values might be overridden by the CHANNEL switch
+  getdownChannelName = CHANNEL.toLowerCase()
+  getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
+  getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
   getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
+  getdownAppDistDir = getdown_app_dir_alt
+  buildProperties = string("${classesDir}/${build_properties_file}")
+  reportRsyncCmd = false
+  jvlChannelName = CHANNEL.toLowerCase()
   switch (CHANNEL) {
 
     case "BUILD":
     // TODO: get bamboo build artifact URL for getdown artifacts
     getdown_channel_base = bamboo_channelbase
-    getdown_channel_name = string("${bamboo_planKey}/${JAVA_VERSION}")
-    getdown_app_base = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
-    getdown_app_dir = getdown_app_dir_alt
-    buildProperties = string("${classesDir}/${build_properties_file}")
+    getdownChannelName = string("${bamboo_planKey}/${JAVA_VERSION}")
+    getdownAppBase = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
+    jvlChannelName += "_${getdownChannelName}"
     break
 
     case "RELEASE":
-    getdown_channel_name = CHANNEL.toLowerCase()
-    getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
-    getdown_app_base = string("${getdown_channel_base}/${getdownDir}")
-    getdown_app_dir = getdown_app_dir_release
-    buildProperties = string("${classesDir}/${build_properties_file}")
+    getdownAppDistDir = getdown_app_dir_release
     reportRsyncCommand = true
     break
 
     case "ARCHIVE":
-    getdown_channel_name = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
-    getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
-    getdown_app_base = string("${getdown_channel_base}/${getdownDir}")
-    getdown_app_dir = getdown_app_dir_alt
+    getdownChannelName = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
+    getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
+    getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
     if (!file("${ARCHIVEDIR}/${packageDir}").exists()) {
-      print "Must provide an ARCHIVEDIR value to produce an archive distribution"
-      exit
+      throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
     } else {
       packageDir = string("${ARCHIVEDIR}/${packageDir}")
       buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
@@ -158,13 +157,11 @@ ext {
     break
 
     case "ARCHIVELOCAL":
-    getdown_channel_name = string("archive/${JALVIEW_VERSION}")
-    getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
-    getdown_app_base = file(getdownWebsiteDir).toURI().toString()
-    getdown_app_dir = getdown_app_dir_alt
+    getdownChannelName = string("archive/${JALVIEW_VERSION}")
+    getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
+    getdownAppBase = file(getdownWebsiteDir).toURI().toString()
     if (!file("${ARCHIVEDIR}/${packageDir}").exists()) {
-      print "Must provide an ARCHIVEDIR value to produce an archive distribution"
-      exit
+      throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
     } else {
       packageDir = string("${ARCHIVEDIR}/${packageDir}")
       buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
@@ -175,47 +172,48 @@ ext {
     break
 
     case "DEVELOP":
-    getdown_channel_name = CHANNEL.toLowerCase()
-    getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
-    getdown_app_base = string("${getdown_channel_base}/${getdownDir}")
-    getdown_app_dir = getdown_app_dir_alt
-    buildProperties = string("${classesDir}/${build_properties_file}")
     reportRsyncCommand = true
     break
 
     case "TEST-RELEASE":
-    getdown_channel_name = CHANNEL.toLowerCase()
-    getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
-    getdown_app_base = string("${getdown_channel_base}/${getdownDir}")
-    getdown_app_dir = getdown_app_dir_alt
-    buildProperties = string("${classesDir}/${build_properties_file}")
     reportRsyncCommand = true
     break
 
     case ~/^SCRATCH(|-[-\w]*)$/:
-    getdown_channel_name = CHANNEL
-    getdownDir = string("${getdown_channel_name}/${JAVA_VERSION}")
-    getdown_app_base = string("${getdown_channel_base}/${getdownDir}")
-    getdown_app_dir = getdown_app_dir_alt
-    buildProperties = string("${classesDir}/${build_properties_file}")
+    getdownChannelName = CHANNEL
+    getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
+    getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
     reportRsyncCommand = true
     break
 
+    case "TEST-LOCAL":
+    if (!file("${LOCALDIR}").exists()) {
+      throw new GradleException("Must provide a LOCALDIR value to produce a local distribution")
+    } else {
+      getdownAppBase = file(file("${LOCALDIR}").getAbsolutePath()).toURI().toString()
+      getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
+    }
+    break
+
     case "LOCAL":
-    getdown_app_base = file(getdownWebsiteDir).toURI().toString()
-    getdown_app_dir = getdown_app_dir_alt
-    buildProperties = string("${classesDir}/${build_properties_file}")
+    getdownAppBase = file(getdownWebsiteDir).toURI().toString()
     getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
     break
 
     default: // something wrong specified
-    print("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
-    exit
+    throw new GradleException("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
     break
 
   }
+  // override getdownAppBase if requested
+  if (findProperty("getdown_appbase_override") != null) {
+    getdownAppBase = string(getProperty("getdown_appbase_override"))
+    println("Overriding getdown appbase with '${getdownAppBase}'")
+  }
+  // sanitise file name for jalview launcher file for this channel
+  jvlChannelName = jvlChannelName.replaceAll(/[^\w\-]/,"_")
 
-  getdownAppDir = string("${getdownWebsiteDir}/${getdown_app_dir}")
+  getdownAppDir = string("${getdownWebsiteDir}/${getdownAppDistDir}")
   //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}"
   getdownResourceDir = string("${getdownWebsiteDir}/${getdown_resource_dir}")
   getdownInstallDir = string("${getdownWebsiteDir}/${getdown_install_dir}")
@@ -240,22 +238,22 @@ ext {
     compile_source_compatibility = 1.8
     compile_target_compatibility = 1.8
     // these are getdown.txt properties defined dependent on the JAVA_VERSION
-    getdown_alt_java_min_version = getdown_alt_java8_min_version
-    getdown_alt_java_max_version = getdown_alt_java8_max_version
+    getdownAltJavaMinVersion = string(findProperty("getdown_alt_java8_min_version"))
+    getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java8_max_version"))
     // this property is assigned below and expanded to multiple lines in the getdown task
-    getdown_alt_multi_java_location = getdown_alt_java8_txt_multi_java_location
+    getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java8_txt_multi_java_location"))
     // this property is for the Java library used in eclipse
-    eclipse_java_runtime_name = string("JavaSE-1.8")
+    eclipseJavaRuntimeName = string("JavaSE-1.8")
   } else if (JAVA_VERSION.equals("11")) {
     JAVA_INTEGER_VERSION = string("11")
     libDir = j11libDir
     libDistDir = j11libDir
     compile_source_compatibility = 11
     compile_target_compatibility = 11
-    getdown_alt_java_min_version = getdown_alt_java11_min_version
-    getdown_alt_java_max_version = getdown_alt_java11_max_version
-    getdown_alt_multi_java_location = getdown_alt_java11_txt_multi_java_location
-    eclipse_java_runtime_name = string("JavaSE-11")
+    getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
+    getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
+    getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
+    eclipseJavaRuntimeName = string("JavaSE-11")
     /* compile without modules -- using classpath libraries
     additional_compiler_args += [
     '--module-path', modules_compileClasspath.asPath,
@@ -268,10 +266,10 @@ ext {
     libDistDir = j11libDir
     compile_source_compatibility = JAVA_VERSION
     compile_target_compatibility = JAVA_VERSION
-    getdown_alt_java_min_version = getdown_alt_java11_min_version
-    getdown_alt_java_max_version = getdown_alt_java11_max_version
-    getdown_alt_multi_java_location = getdown_alt_java11_txt_multi_java_location
-    eclipse_java_runtime_name = string("JavaSE-11")
+    getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
+    getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
+    getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
+    eclipseJavaRuntimeName = string("JavaSE-11")
     /* compile without modules -- using classpath libraries
     additional_compiler_args += [
     '--module-path', modules_compileClasspath.asPath,
@@ -286,13 +284,19 @@ ext {
   // for install4j
   JAVA_MIN_VERSION = JAVA_VERSION
   JAVA_MAX_VERSION = JAVA_VERSION
-  macosJavaVMDir = string("${System.env.HOME}/buildtools/jre/openjdk-java_vm/getdown/macos-jre${JAVA_VERSION}/jre")
-  macosJavaVMTgz = string("${System.env.HOME}/buildtools/jre/openjdk-java_vm/install4j/tgz/macos-jre${JAVA_VERSION}.tar.gz")
-  windowsJavaVMDir = string("${System.env.HOME}/buildtools/jre/openjdk-java_vm/getdown/windows-jre${JAVA_VERSION}/jre")
-  windowsJavaVMTgz = string("${System.env.HOME}/buildtools/jre/openjdk-java_vm/install4j/tgz/windows-jre${JAVA_VERSION}.tar.gz")
+  def jreInstallsDir = string(jre_installs_dir)
+  if (jreInstallsDir.startsWith("~/")) {
+    jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1)
+  }
+  macosJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-mac-x64/jre")
+  macosJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-mac-x64.tar.gz")
+  windowsJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-windows-x64/jre")
+  windowsJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-windows-x64.tar.gz")
+  linuxJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-linux-x64/jre")
+  linuxJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-linux-x64.tar.gz")
   install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
-  install4jConfFileName = string("jalview-installers-java${JAVA_VERSION}.install4j")
-  install4jConfFile = string("${install4jDir}/${install4jConfFileName}")
+  install4jConfFileName = string("jalview-install4j-conf.install4j")
+  install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
   install4jHomeDir = install4j_home_dir
   if (install4jHomeDir.startsWith("~/")) {
     install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1)
@@ -303,8 +307,7 @@ ext {
   buildingHTML = string("${jalviewDir}/${docDir}/building.html")
   helpFile = string("${classesDir}/${help_dir}/help.jhm")
   helpParentDir = string("${jalviewDir}/${help_parent_dir}")
-  helpDir = string("${help_dir}")
-  helpSourceDir = string("${helpParentDir}/${helpDir}")
+  helpSourceDir = string("${helpParentDir}/${help_dir}")
 
 
   relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
@@ -342,11 +345,13 @@ sourceSets {
 
     resources {
       srcDirs resourceDir
+      srcDirs += helpParentDir
     }
 
     jar.destinationDir = file("${jalviewDir}/${packageDir}")
 
     compileClasspath = files(sourceSets.main.java.outputDir)
+    //compileClasspath += files(sourceSets.main.resources.srcDirs)
     compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
 
     runtimeClasspath = compileClasspath
@@ -383,7 +388,7 @@ sourceSets {
     compileClasspath = files( sourceSets.test.java.outputDir )
 
     if (use_clover) {
-      compileClasspath += sourceSets.clover.compileClasspath
+      compileClasspath = sourceSets.clover.compileClasspath
     } else {
       compileClasspath += files(sourceSets.main.java.outputDir)
     }
@@ -400,8 +405,8 @@ sourceSets {
 // clover bits
 dependencies {
   if (use_clover) {
-    cloverCompile 'org.openclover:clover:4.3.1'
-    testCompile 'org.openclover:clover:4.3.1'
+    cloverCompile 'org.openclover:clover:4.4.1'
+    testCompile 'org.openclover:clover:4.4.1'
   }
 }
 
@@ -455,8 +460,8 @@ eclipse {
         cp.entries.removeAll(removeTheseToo)
 
         //cp.entries += new Output("${eclipse_bin_dir}/main")
-        if (file(helpSourceDir).isDirectory()) {
-          cp.entries += new Library(fileReference(helpSourceDir))
+        if (file(helpParentDir).isDirectory()) {
+          cp.entries += new Library(fileReference(helpParentDir))
         }
         if (file(resourceDir).isDirectory()) {
           cp.entries += new Library(fileReference(resourceDir))
@@ -464,7 +469,7 @@ eclipse {
 
         HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
 
-        sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.each {
+        sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
           //don't want to add outputDir as eclipse is using its own output dir in bin/main
           if (it.isDirectory() || ! it.exists()) {
             // don't add dirs to classpath, especially if they don't exist
@@ -484,7 +489,6 @@ eclipse {
           }
         }
 
-        //fileTree(dir: "$jalviewDir/$utilsDir", include: ["test*/*.jar"]).each {
         sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
           //no longer want to add outputDir as eclipse is using its own output dir in bin/main
           if (it.isDirectory() || ! it.exists()) {
@@ -518,7 +522,7 @@ eclipse {
     // for the IDE, use java 11 compatibility
     sourceCompatibility = compile_source_compatibility
     targetCompatibility = compile_target_compatibility
-    javaRuntimeName = eclipse_java_runtime_name
+    javaRuntimeName = eclipseJavaRuntimeName
 
     // add in jalview project specific properties/preferences into eclipse core preferences
     file {
@@ -548,7 +552,7 @@ eclipse {
 
 task cloverInstr() {
   // only instrument source, we build test classes as normal
-  inputs.files files (sourceSets.main.allJava) // , fileTree(dir: testSourceDir, include: ["**/*.java"]))
+  inputs.files files (sourceSets.main.allJava,sourceSets.test.allJava) // , fileTree(dir:"$jalviewDir/$testSourceDir", include: ["**/*.java"]))
   outputs.dir cloverInstrDir
 
   doFirst {
@@ -565,25 +569,43 @@ task cloverInstr() {
 }
 
 
+task cloverReportHTML (type: JavaExec) {
+    inputs.dir "${buildDir}/clover"
+    outputs.dir "${reportsDir}/clover"
+
+    classpath configurations.cloverRuntime
+    maxHeapSize "${cloverReportJVMHeap}"
+    jvmArgs += "${cloverReportJVMArgs}"
+    main = "com.atlassian.clover.reporters.html.HtmlReporter"
+    args  "--initstring", "${buildDir}/clover/clover.db", "-o", "${reportsDir}/clover"
+    "${cloverReportHTMLOptions}".split(",").each {
+      args+= it.trim()
+      }
+}
+
+task cloverReportXML (type: JavaExec) {
+    inputs.dir "${buildDir}/clover"
+    outputs.dir "${reportsDir}/clover"
+    maxHeapSize "${cloverReportJVMHeap}"
+    jvmArgs "${cloverReportJVMArgs}"
+    classpath configurations.cloverRuntime
+    main = "com.atlassian.clover.reporters.xml.XMLReporter"
+    args  "--initstring", "${buildDir}/clover/clover.db", "-o", "${reportsDir}/clover/clover.xml"
+    
+    "${cloverReportXMLOptions}".split(",").each {
+      args+= it.trim()
+      }
+}
 task cloverReport {
   group = "Verification"
-    description = "Createst the Clover report"
+    description = "Creates the Clover report"
     inputs.dir "${buildDir}/clover"
     outputs.dir "${reportsDir}/clover"
     onlyIf {
       file("${buildDir}/clover/clover.db").exists()
     }
-  doFirst {
-    def argsList = ["--initstring", "${buildDir}/clover/clover.db",
-    "-o", "${reportsDir}/clover"]
-    String[] args = argsList.toArray()
-    com.atlassian.clover.reporters.html.HtmlReporter.runReport(args)
-
-    // and generate ${reportsDir}/clover/clover.xml
-    args = ["--initstring", "${buildDir}/clover/clover.db",
-    "-o", "${reportsDir}/clover/clover.xml"].toArray()
-    com.atlassian.clover.reporters.xml.XMLReporter.runReport(args)
-  }
+    dependsOn cloverReportXML
+    dependsOn cloverReportHTML
 }
 // end clover bits
 
@@ -709,7 +731,8 @@ task convertBuildingMD(type: Exec) {
   }
 
   def hostname = "hostname".execute().text.trim()
-  if ((pandoc == null || ! file(pandoc).exists()) && hostname.equals("jv-bamboo")) {
+  def buildtoolsPandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
+  if ((pandoc == null || ! file(pandoc).exists()) && file(buildtoolsPandoc).exists()) {
     pandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
   }
 
@@ -748,7 +771,7 @@ task syncDocs(type: Sync) {
 
 task copyHelp(type: Copy) {
   def inputDir = helpSourceDir
-  def outputDir = "${classesDir}/${helpDir}"
+  def outputDir = "${classesDir}/${help_dir}"
   from(inputDir) {
     exclude '**/*.gif'
     exclude '**/*.jpg'
@@ -830,7 +853,7 @@ task buildIndices(type: JavaExec) {
   dependsOn copyHelp
   classpath = sourceSets.main.compileClasspath
   main = "com.sun.java.help.search.Indexer"
-  workingDir = "${classesDir}/${helpDir}"
+  workingDir = "${classesDir}/${help_dir}"
   def argDir = "html"
   args = [ argDir ]
   inputs.dir("${workingDir}/${argDir}")
@@ -866,8 +889,7 @@ task linkCheck(type: JavaExec) {
   classpath = files("${jalviewDir}/${utilsDir}")
   main = "HelpLinksChecker"
   workingDir = jalviewDir
-  def help = "${classesDir}/${helpDir}"
-  args = [ "${classesDir}/${helpDir}", "-nointernet" ]
+  args = [ "${classesDir}/${help_dir}", "-nointernet" ]
 
   def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
   def errFOS = outFOS
@@ -878,13 +900,13 @@ task linkCheck(type: JavaExec) {
     outFOS,
     errorOutput)
 
-  inputs.dir("${classesDir}/${helpDir}")
+  inputs.dir("${classesDir}/${help_dir}")
   outputs.file(helpLinksCheckerOutFile)
 }
 
 // import the pubhtmlhelp target
 ant.properties.basedir = "${jalviewDir}"
-ant.properties.helpBuildDir = "${jalviewDirAbsolutePath}/${classes_dir}/${helpDir}"
+ant.properties.helpBuildDir = "${jalviewDirAbsolutePath}/${classes_dir}/${help_dir}"
 ant.importBuild "${utilsDir}/publishHelp.xml"
 
 
@@ -983,7 +1005,6 @@ task getdownWebsite() {
   def getdownWebsiteResourceFilenames = []
   def getdownTextString = ""
   def getdownResourceDir = getdownResourceDir
-  def getdownAppDir = getdownAppDir
   def getdownResourceFilenames = []
 
   doFirst {
@@ -996,19 +1017,21 @@ task getdownWebsite() {
       rename(build_properties_file, getdown_build_properties)
       into getdownAppDir
     }
-    getdownWebsiteResourceFilenames += "${getdown_app_dir}/${getdown_build_properties}"
+    getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
 
     // go through properties looking for getdown_txt_...
     def props = project.properties.sort { it.key }
-    if (getdown_alt_java_min_version.length() > 0) {
-      props.put("getdown_txt_java_min_version", getdown_alt_java_min_version)
+    if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
+      props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
     }
-    if (getdown_alt_java_max_version.length() > 0) {
-      props.put("getdown_txt_java_max_version", getdown_alt_java_max_version)
+    if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) {
+      props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion)
+    }
+    if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
+      props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
     }
-    props.put("getdown_txt_multi_java_location", getdown_alt_multi_java_location)
 
-    props.put("getdown_txt_appbase", getdown_app_base)
+    props.put("getdown_txt_appbase", getdownAppBase)
     props.each{ prop, val ->
       if (prop.startsWith("getdown_txt_") && val != null) {
         if (prop.startsWith("getdown_txt_multi_")) {
@@ -1063,7 +1086,7 @@ task getdownWebsite() {
     }
     codeFiles.sort().each{f ->
       def name = f.getName()
-      def line = "code = ${getdown_app_dir}/${name}\n"
+      def line = "code = ${getdownAppDistDir}/${name}\n"
       getdownTextString += line
       copy {
         from f.getPath()
@@ -1095,8 +1118,9 @@ task getdownWebsite() {
     def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
     getdown_txt.write(getdownTextString)
 
-    def launch_jvl = file("${getdownWebsiteDir}/${getdown_launch_jvl}")
-    launch_jvl.write("appbase="+props.get("getdown_txt_appbase"))
+    def getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
+    def launchJvl = file("${getdownWebsiteDir}/${getdownLaunchJvl}")
+    launchJvl.write("appbase="+props.get("getdown_txt_appbase"))
 
     copy {
       from getdownLauncher
@@ -1131,7 +1155,7 @@ task getdownWebsite() {
 
     copy {
       from getdown_txt
-      from launch_jvl
+      from launchJvl
       from getdownLauncher
       from "${getdownWebsiteDir}/${getdown_build_properties}"
       if (file(getdownLauncher).getName() != getdown_launcher) {
@@ -1154,12 +1178,28 @@ task getdownWebsite() {
 }
 
 
+// a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
+task getdownDigestDir(type: JavaExec) {
+  def digestDirPropertyName = "DIGESTDIR"
+  description = "Digest a local dir (-P${digestDirPropertyName}=...) for getdown"
+  doFirst {
+    classpath = files(getdownLauncher)
+    def digestDir = findProperty(digestDirPropertyName)
+    if (digestDir == null) {
+      throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest")
+    }
+    args digestDir
+  }
+  main = "com.threerings.getdown.tools.Digester"
+}
+
+
 task getdownDigest(type: JavaExec) {
   group = "distribution"
   description = "Digest the getdown website folder"
   dependsOn getdownWebsite
   doFirst {
-    classpath = files("${getdownWebsiteDir}/${getdown_launcher}")
+    classpath = files(getdownLauncher)
   }
   main = "com.threerings.getdown.tools.Digester"
   args getdownWebsiteDir
@@ -1213,101 +1253,51 @@ install4j {
 }
 
 
-task copyInstall4jTemplate(type: Copy) {
-  dependsOn setGitVals
-
-  inputs.file("${install4jDir}/${install4j_template}")
-  inputs.file("${install4jDir}/${install4j_installer_file_associations}")
-  outputs.files(install4jConfFile)
-
-  from (install4jDir) {
-    include install4j_template
-    rename (install4j_template, install4jConfFileName)
-    // TODO change these ReplaceTokens to something better.  Possibly ${compiler:variables} but also the ant.replaceregexp below, or perhaps a proper xmldom parse
-
-    /*
-    if (OSX_KEYPASS == "") {
-      filter(ReplaceTokens,
-        beginToken: 'codeSigning macEnabled="',
-        endToken: '"',
-        tokens: [
-          'true': 'codeSigning macEnabled="false"'
-        ]
-      )
-      filter(ReplaceTokens,
-        beginToken: 'runPostProcessor="true" ',
-        endToken: 'Processor',
-        tokens: [
-          'post': 'runPostProcessor="false" postProcessor'
-        ]
-      )
-    }
-    */
-  }
-  into install4jDir
+task copyInstall4jTemplate {
+  def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
+  def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
+  inputs.file(install4jTemplateFile)
+  inputs.file(install4jFileAssociationsFile)
+  outputs.file(install4jConfFile)
 
   doLast {
-    // include file associations in installer
-    def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
-    def install4jFileAssociationsText = install4jFileAssociationsFile.text
-/*
-    ant.replaceregexp(
-      byline: false,
-      flags: "s",
-      match: '<action name="EXTENSIONS_REPLACED_BY_GRADLE".*?</action>',
-      replace: install4jFileAssociationsText,
-      file: install4jConfFile
-    )
-*/
-
-    def install4jFileAssociations = new XmlParser().parseText('''
-<install4jFileAssociations>
-${install4jFileAssociationsText}
-</install4jFileAssociations>
-'''
-    )
-
-println("TEXT=${install4jFileAssociationsText}")
-println("ACTIONS")
-install4jFileAssociationsXml.action.each { a ->
-  println("ACTION="+XmlUtil.serialize(a))
-}
-
-
-    def install4j = new XmlParser().parse(install4jConfFile)
+    def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
 
+    // turn off code signing if no OSX_KEYPASS
     if (OSX_KEYPASS == "") {
-      install4j.application.codeSigning.each { codeSigning ->
+      install4jConfigXml.'**'.codeSigning.each { codeSigning ->
         codeSigning.'@macEnabled' = "false"
       }
-      install4j.mediaSets.windows.each { windows ->
+      install4jConfigXml.'**'.windows.each { windows ->
         windows.'@runPostProcessor' = "false"
       }
     }
-    // reparse
-    //install4j = new XmlSlurper().parseText(XmlUtil.serialize(install4j))
 
-    install4j.'**'.action.each { a ->
+    // turn off checksum creation for LOCAL channel
+    def e = install4jConfigXml.application[0]
+    if (CHANNEL == "LOCAL") {
+      e.'@createChecksums' = "false"
+    } else {
+      e.'@createChecksums' = "true"
+    }
+
+    // put file association actions where placeholder action is
+    def install4jFileAssociationsText = install4jFileAssociationsFile.text
+    def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
+    install4jConfigXml.'**'.action.any { a ->
       if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
-        //a.replaceNode(install4jFileAssociationsXml.action[0])
+        def parent = a.parent()
+        parent.remove(a)
+        fileAssociationActions.each { faa ->
+            parent.append(faa)
+        }
+        // don't need to continue in .any loop once replacements have been made
+        return true
       }
     }
-    // reparse
-    //install4j = new XmlSlurper().parseText(XmlUtil.serialize(install4j))
-
-    file(install4jConfFile).text = XmlUtil.serialize(install4j)
 
-    /*
-    // include uninstaller applescript app files in dmg
-    def installerDMGUninstallerXml = file("$install4jDir/$install4j_DMG_uninstaller_app_files").text
-    ant.replaceregexp(
-    byline: false,
-    flags: "s",
-    match: '<file name="UNINSTALL_OLD_JALVIEW_APP_REPLACED_IN_GRADLE" file=.*?>',
-    replace: installerDMGUninstallerXml,
-    file: install4jConfFile
-    )
-     */
+    // write install4j file
+    install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
   }
 }
 
@@ -1322,11 +1312,13 @@ clean {
 task installers(type: com.install4j.gradle.Install4jTask) {
   group = "distribution"
   description = "Create the install4j installers"
+  dependsOn setGitVals
   dependsOn getdown
   dependsOn copyInstall4jTemplate
-  projectFile = file(install4jConfFile)
 
-  def install4jTemplateMd5 = ""
+  projectFile = install4jConfFile
+
+  // create an md5 for the input files to use as version for install4j conf file
   def digest = MessageDigest.getInstance("MD5")
   digest.update(
     (file("${install4jDir}/${install4j_template}").text + 
@@ -1336,14 +1328,17 @@ task installers(type: com.install4j.gradle.Install4jTask) {
   if (filesMd5.length() >= 8) {
     filesMd5 = filesMd5.substring(0,8)
   }
-  install4jTemplateMd5 += filesMd5
-  install4jTemplateMd5 += "_${gitHash}"
-  def install4jTemplateVersion = "${JALVIEW_VERSION}_${install4jTemplateMd5}"
-  def infoPlistFileAssociations = file("${install4jDir}/${install4j_info_plist_file_associations}").text
+  def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
+  // make install4jBuildDir relative to jalviewDir
+  def install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
 
   variables = [
+    'JALVIEW_NAME': getdown_txt_title,
+    'JALVIEW_DIR': "../..",
     'OSX_KEYSTORE': OSX_KEYSTORE,
     'JSIGN_SH': JSIGN_SH,
+    'JRE_DIR': getdown_app_dir_java,
+    'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
     'JALVIEW_VERSION': JALVIEW_VERSION,
     'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
     'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
@@ -1351,30 +1346,35 @@ task installers(type: com.install4j.gradle.Install4jTask) {
     'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
     'VERSION': JALVIEW_VERSION,
     'MACOS_JAVA_VM_DIR': macosJavaVMDir,
-    'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
     'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
+    'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
+    'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
     'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
-    'INSTALL4JINFOPLISTFILEASSOCIATIONS': install4j_info_plist_file_associations,
-    'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
+    'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
     'COPYRIGHT_MESSAGE': install4j_copyright_message,
     'MACOS_BUNDLE_ID': install4j_macOS_bundle_id,
+    'INSTALLER_NAME': install4j_installer_name,
+    'INSTALL4J_UTILS_DIR': install4j_utils_dir,
+    'GETDOWN_WEBSITE_DIR': getdown_website_dir,
+    'GETDOWN_FILES_DIR': getdown_files_dir,
     'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
-    'GETDOWN_DIST_DIR': getdown_app_dir,
+    'GETDOWN_DIST_DIR': getdownAppDistDir,
     'GETDOWN_ALT_DIR': getdown_app_dir_alt,
     'GETDOWN_INSTALL_DIR': getdown_install_dir,
-    'INFO_PLIST_FILE_ASSOCIATIONS': infoPlistFileAssociations
+    'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
+    'BUILD_DIR': install4jBuildDir,
   ]
-  destination = "${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}"
+
+  destination = "${jalviewDir}/${install4jBuildDir}"
   buildSelected = true
 
-  if (install4j_faster.equals("true") || CHANNEL.startsWith("DEVELOP") || CHANNEL.startsWith("LOCAL")) {
-    // this doesn't seem to work
+  if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
     faster = true
     disableSigning = true
   }
 
   if (OSX_KEYPASS) {
-    macKeystorePassword=OSX_KEYPASS
+    macKeystorePassword = OSX_KEYPASS
   }
 
   doFirst {
@@ -1390,7 +1390,7 @@ task installers(type: com.install4j.gradle.Install4jTask) {
 }
 
 
-task sourceDist (type: Tar) {
+task sourceDist(type: Tar) {
   
   def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
   def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
@@ -1405,33 +1405,47 @@ task sourceDist (type: Tar) {
   
   into project.name
 
-  def EXCLUDE_FILES=["build/*","bin/*","test-output/","test-reports","tests","clover*/*"
-  ,".*"
-  ,"benchmarking/*"
-  ,"**/.*"
-  ,"*.class"
-  ,"**/*.class","${j11modDir}/**/*.jar","appletlib","**/*locales"
-  ,"*locales/**",
-  ,"utils/InstallAnywhere"] 
-  def PROCESS_FILES=[   "AUTHORS",
-  "CITATION",
-  "FEATURETODO",
-  "JAVA-11-README",
-  "FEATURETODO",
-  "LICENSE",
-  "**/README",
-  "RELEASE",
-  "THIRDPARTYLIBS","TESTNG",
-  "build.gradle",
-  "gradle.properties",
-  "**/*.java",
-  "**/*.html",
-  "**/*.xml",
-  "**/*.gradle",
-  "**/*.groovy",
-  "**/*.properties",
-  "**/*.perl",
-  "**/*.sh"]
+  def EXCLUDE_FILES=[
+    "build/*",
+    "bin/*",
+    "test-output/",
+    "test-reports",
+    "tests",
+    "clover*/*",
+    ".*",
+    "benchmarking/*",
+    "**/.*",
+    "*.class",
+    "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
+    "*locales/**",
+    "utils/InstallAnywhere",
+    "**/*.log",
+  ] 
+  def PROCESS_FILES=[
+    "AUTHORS",
+    "CITATION",
+    "FEATURETODO",
+    "JAVA-11-README",
+    "FEATURETODO",
+    "LICENSE",
+    "**/README",
+    "RELEASE",
+    "THIRDPARTYLIBS",
+    "TESTNG",
+    "build.gradle",
+    "gradle.properties",
+    "**/*.java",
+    "**/*.html",
+    "**/*.xml",
+    "**/*.gradle",
+    "**/*.groovy",
+    "**/*.properties",
+    "**/*.perl",
+    "**/*.sh",
+  ]
+  def INCLUDE_FILES=[
+    ".settings/org.eclipse.jdt.core.jalview.prefs",
+  ]
 
   from(jalviewDir) {
     exclude (EXCLUDE_FILES)
@@ -1457,23 +1471,26 @@ task sourceDist (type: Tar) {
     exclude (getdown_website_dir)
 
     // exluding these as not using jars as modules yet
-    exclude ("${j11modDir}/**/*.jar")
-  }
-  //  from (jalviewDir) {
-  //    // explicit includes for stuff that seemed to not get included
-  //    include(fileTree("test/**/*."))
-  //    exclude(EXCLUDE_FILES)
-  //    exclude(PROCESS_FILES)
-  //  }
+    exclude ("$j11modDir/**/*.jar")
+  }
+  from(jalviewDir) {
+    include(INCLUDE_FILES)
+  }
+//  from (jalviewDir) {
+//    // explicit includes for stuff that seemed to not get included
+//    include(fileTree("test/**/*."))
+//    exclude(EXCLUDE_FILES)
+//    exclude(PROCESS_FILES)
+//  }
 }
 
 
-task helppages  {
+task helppages {
   dependsOn copyHelp
   dependsOn pubhtmlhelp
   
-  inputs.dir("${classesDir}/${helpDir}")
-  outputs.dir("${buildDir}/distributions/${helpDir}")
+  inputs.dir("${classesDir}/${help_dir}")
+  outputs.dir("${buildDir}/distributions/${help_dir}")
 }
 
 // LARGE AMOUNT OF JALVIEWJS STUFF DELETED HERE