JAL-3541 selectively merged build.gradle and gradle.properties
authorsoares <bsoares@dundee.ac.uk>
Mon, 25 May 2020 23:14:15 +0000 (00:14 +0100)
committersoares <bsoares@dundee.ac.uk>
Mon, 25 May 2020 23:14:15 +0000 (00:14 +0100)
1  2 
build.gradle
gradle.properties

diff --cc build.gradle
@@@ -630,85 -688,90 +661,142 @@@ eclipse 
    if (IN_ECLIPSE) {
      // Don't want these to be activated if in headless build
      synchronizationTasks "eclipseSynchronizationTask"
-     autoBuildTasks "eclipseAutoBuildTask"
+     //autoBuildTasks "eclipseAutoBuildTask"
+   }
+ }
  
+ /* hack to change eclipse prefs in .settings files other than org.eclipse.jdt.core.prefs */
+ // Class to allow updating arbitrary properties files
+ class PropertiesFile extends PropertiesPersistableConfigurationObject {
+   public PropertiesFile(PropertiesTransformer t) { super(t); }
+   @Override protected void load(Properties properties) { }
+   @Override protected void store(Properties properties) { }
+   @Override protected String getDefaultResourceName() { return ""; }
+   // This is necessary, because PropertiesPersistableConfigurationObject fails
+   // if no default properties file exists.
+   @Override public void loadDefaults() { load(new StringBufferInputStream("")); }
+ }
+ // Task to update arbitrary properties files (set outputFile)
+ class PropertiesFileTask extends PropertiesGeneratorTask<PropertiesFile> {
+   private final PropertiesFileContentMerger file;
+   public PropertiesFileTask() { file = new PropertiesFileContentMerger(getTransformer()); }
+   protected PropertiesFile create() { return new PropertiesFile(getTransformer()); }
+   protected void configure(PropertiesFile props) {
+     file.getBeforeMerged().execute(props); file.getWhenMerged().execute(props);
    }
+   public void file(Closure closure) { ConfigureUtil.configure(closure, file); }
  }
  
+ task eclipseUIPreferences(type: PropertiesFileTask) {
+   description = "Generate Eclipse additional settings"
+   def filename = "org.eclipse.jdt.ui.prefs"
+   outputFile = "$projectDir/.settings/${filename}" as File
+   file {
+     withProperties {
+       it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
+     }
+   }
+ }
+ task eclipseGroovyCorePreferences(type: PropertiesFileTask) {
+   description = "Generate Eclipse additional settings"
+   def filename = "org.eclipse.jdt.groovy.core.prefs"
+   outputFile = "$projectDir/.settings/${filename}" as File
+   file {
+     withProperties {
+       it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
+     }
+   }
+ }
+ task eclipseAllPreferences {
+   dependsOn eclipseJdt
+   dependsOn eclipseUIPreferences
+   dependsOn eclipseGroovyCorePreferences
+ }
+ eclipseUIPreferences.mustRunAfter eclipseJdt
+ eclipseGroovyCorePreferences.mustRunAfter eclipseJdt
+ /* end of eclipse preferences hack */
  
 -task cloverInstr {
 -  // only instrument source, we build test classes as normal
 -  inputs.files files (sourceSets.main.allJava,sourceSets.test.allJava) // , fileTree(dir:"$jalviewDir/$testSourceDir", include: ["**/*.java"]))
 -  outputs.dir cloverInstrDir
 +// clover bits
  
 +
 +task cleanClover {
    doFirst {
 -    delete cloverInstrDir
 -    def argsList = [
 -      "--initstring",
 -      cloverDb,
 -      "-d",
 -      cloverInstrDir.getPath(),
 -    ]
 -    argsList.addAll(
 -      inputs.files.files.collect(
 -        { file -> file.absolutePath }
 -      )
 +    delete cloverBuildDir
 +  }
 +}
 +
 +
 +task cloverInstrJava(type: JavaExec) {
 +  group = "Verification"
 +  description = "Create clover instrumented source java files"
 +
 +  dependsOn cleanClover
 +
 +  inputs.files(sourceSets.main.allJava)
 +  outputs.dir(cloverInstrDir)
 +
 +  //classpath = fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
 +  classpath = sourceSets.clover.compileClasspath
 +  main = "com.atlassian.clover.CloverInstr"
 +
 +  def argsList = [
 +    "--encoding",
 +    "UTF-8",
 +    "--initstring",
 +    cloverDb,
 +    "--destdir",
 +    cloverInstrDir.getPath(),
 +  ]
 +  def srcFiles = sourceSets.main.allJava.files
 +  argsList.addAll(
 +    srcFiles.collect(
 +      { file -> file.absolutePath }
      )
 -    String[] args = argsList.toArray()
 -    println("About to instrument "+args.length +" files")
 -    com.atlassian.clover.CloverInstr.mainImpl(args)
 +  )
 +  args argsList.toArray()
 +
 +  doFirst {
 +    delete cloverInstrDir
 +    println("Clover: About to instrument "+srcFiles.size() +" files")
 +  }
 +}
 +
 +
 +task cloverInstrTests(type: JavaExec) {
 +  group = "Verification"
 +  description = "Create clover instrumented source test files"
 +
 +  dependsOn cleanClover
 +
 +  inputs.files(testDir)
 +  outputs.dir(cloverTestInstrDir)
 +
 +  classpath = sourceSets.clover.compileClasspath
 +  main = "com.atlassian.clover.CloverInstr"
 +
 +  def argsList = [
 +    "--encoding",
 +    "UTF-8",
 +    "--initstring",
 +    cloverDb,
 +    "--srcdir",
 +    testDir,
 +    "--destdir",
 +    cloverTestInstrDir.getPath(),
 +  ]
 +  args argsList.toArray()
 +
 +  doFirst {
 +    delete cloverTestInstrDir
 +    println("Clover: About to instrument test files")
    }
  }
  
@@@ -855,22 -831,29 +943,23 @@@ compileCloverJava 
  
  
  compileJava {
+   // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ?
+   sourceCompatibility = compile_source_compatibility
+   targetCompatibility = compile_target_compatibility
+   options.compilerArgs = additional_compiler_args
+   options.encoding = "UTF-8"
    doFirst {
-     sourceCompatibility = compile_source_compatibility
-     targetCompatibility = compile_target_compatibility
-     options.compilerArgs = additional_compiler_args
--    print ("Setting target compatibility to "+targetCompatibility+"\n")
++    print ("Setting target compatibility to "+compile_target_compatibility+"\n")
    }
  
  }
  
  
  compileTestJava {
 -  if (use_clover) {
 -    dependsOn compileCloverJava
 -    classpath += configurations.cloverRuntime
 -  } else {
 -    classpath += sourceSets.main.runtimeClasspath
 -  }
++  sourceCompatibility = compile_source_compatibility
++  targetCompatibility = compile_target_compatibility
++  options.compilerArgs = additional_compiler_args
    doFirst {
--    sourceCompatibility = compile_source_compatibility
--    targetCompatibility = compile_target_compatibility
--    options.compilerArgs = additional_compiler_args
      print ("Setting target compatibility to "+targetCompatibility+"\n")
    }
  }
@@@ -979,17 -971,10 +1077,10 @@@ task convertBuildingMD(type: Exec) 
  }
  
  
- clean {
-   doFirst {
-     delete buildingHTML
-   }
- }
  task syncDocs(type: Sync) {
    dependsOn convertBuildingMD
-   def syncDir = "${resourceClassesDir}/${doc_dir}"
 -  def syncDir = "${classesDir}/${docDir}"
 -  from fileTree("${jalviewDir}/${docDir}")
++  def syncDir = "${classesDir}/${doc_dir}"
 +  from fileTree("${jalviewDir}/${doc_dir}")
    into syncDir
  
  }
@@@ -1032,9 -1017,10 +1123,10 @@@ task syncLib(type: Sync) 
  
  
  task syncResources(type: Sync) {
+   dependsOn createBuildProperties
    from resourceDir
    include "**/*.*"
 -  into "${classesDir}"
 +  into "${resourceClassesDir}"
    preserve {
      include "**"
    }
@@@ -1350,7 -1333,7 +1443,7 @@@ task getdownWebsite() 
      // 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.
      //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
      getdownTextString += "resource = ${getdown_launcher_new}\n"
--    getdownTextString += "class = ${mainClass}\n"
++    getdownTextString += "class = ${main_class}\n"
  
      def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
      getdown_txt.write(getdownTextString)
@@@ -1776,6 -1769,1026 +1881,1026 @@@ task helppages 
    outputs.dir("${buildDir}/distributions/${help_dir}")
  }
  
- // LARGE AMOUNT OF JALVIEWJS STUFF DELETED HERE
- task eclipseAutoBuildTask {}
- task eclipseSynchronizationTask {}
+ task j2sSetHeadlessBuild {
+   doFirst {
+     IN_ECLIPSE = false
+   }
+ }
+ task jalviewjsSetEclipseWorkspace {
+   def propKey = "jalviewjs_eclipse_workspace"
+   def propVal = null
+   if (project.hasProperty(propKey)) {
+     propVal = project.getProperty(propKey)
+     if (propVal.startsWith("~/")) {
+       propVal = System.getProperty("user.home") + propVal.substring(1)
+     }
+   }
+   def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
+   def propsFile = file(propsFileName)
+   def eclipseWsDir = propVal
+   def props = new Properties()
+   def writeProps = true
+   if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
+     def ins = new FileInputStream(propsFileName)
+     props.load(ins)
+     ins.close()
+     if (props.getProperty(propKey, null) != null) {
+       eclipseWsDir = props.getProperty(propKey)
+       writeProps = false
+     }
+   }
+   if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
+     def tempDir = File.createTempDir()
+     eclipseWsDir = tempDir.getAbsolutePath()
+     writeProps = true
+   }
+   eclipseWorkspace = file(eclipseWsDir)
+   doFirst {
+     // do not run a headless transpile when we claim to be in Eclipse
+     if (IN_ECLIPSE) {
+       println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
+       throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
+     } else {
+       println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
+     }
+     if (writeProps) {
+       props.setProperty(propKey, eclipseWsDir)
+       propsFile.parentFile.mkdirs()
+       def bytes = new ByteArrayOutputStream()
+       props.store(bytes, null)
+       def propertiesString = bytes.toString()
+       propsFile.text = propertiesString
+       print("NEW ")
+     } else {
+       print("EXISTING ")
+     }
+     println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
+   }
+   //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
+   outputs.file(propsFileName)
+   outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
+ }
+ task jalviewjsEclipsePaths {
+   def eclipseProduct
+   def eclipseRoot = jalviewjs_eclipse_root
+   if (eclipseRoot.startsWith("~/")) {
+     eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
+   }
+   if (OperatingSystem.current().isMacOsX()) {
+     eclipseRoot += "/Eclipse.app"
+     eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
+     eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
+   } else if (OperatingSystem.current().isWindows()) { // check these paths!!
+     if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
+       eclipseRoot += "/eclipse"
+     }
+     eclipseBinary = "${eclipseRoot}/eclipse.exe"
+     eclipseProduct = "${eclipseRoot}/.eclipseproduct"
+   } else { // linux or unix
+     if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
+       eclipseRoot += "/eclipse"
+ println("eclipseDir exists")
+     }
+     eclipseBinary = "${eclipseRoot}/eclipse"
+     eclipseProduct = "${eclipseRoot}/.eclipseproduct"
+   }
+   eclipseVersion = "4.13" // default
+   def assumedVersion = true
+   if (file(eclipseProduct).exists()) {
+     def fis = new FileInputStream(eclipseProduct)
+     def props = new Properties()
+     props.load(fis)
+     eclipseVersion = props.getProperty("version")
+     fis.close()
+     assumedVersion = false
+   }
+   
+   def propKey = "eclipse_debug"
+   eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
+   doFirst {
+     // do not run a headless transpile when we claim to be in Eclipse
+     if (IN_ECLIPSE) {
+       println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
+       throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
+     } else {
+       println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
+     }
+     if (!assumedVersion) {
+       println("ECLIPSE VERSION=${eclipseVersion}")
+     }
+   }
+ }
+ task printProperties {
+   group "Debug"
+   description "Output to console all System.properties"
+   doFirst {
+     System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
+   }
+ }
+ task eclipseSetup {
+   dependsOn eclipseProject
+   dependsOn eclipseClasspath
+   dependsOn eclipseJdt
+ }
+ // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
+ task jalviewjsEclipseCopyDropins(type: Copy) {
+   dependsOn jalviewjsEclipsePaths
+   def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
+   inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
+   def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
+   from inputFiles
+   into outputDir
+ }
+ // this eclipse -clean doesn't actually work
+ task jalviewjsCleanEclipse(type: Exec) {
+   dependsOn eclipseSetup
+   dependsOn jalviewjsEclipsePaths
+   dependsOn jalviewjsEclipseCopyDropins
+   executable(eclipseBinary)
+   args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
+   if (eclipseDebug) {
+     args += "-debug"
+   }
+   args += "-l"
+   def inputString = """exit
+ y
+ """
+   def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
+   standardInput = inputByteStream
+ }
+ /* not really working yet
+ jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
+ */
+ task jalviewjsTransferUnzipSwingJs {
+   def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
+   doLast {
+     copy {
+       from zipTree(file_zip)
+       into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
+     }
+   }
+   inputs.file file_zip
+   outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
+ }
+ task jalviewjsTransferUnzipLib {
+   def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
+   doLast {
+     zipFiles.each { file_zip -> 
+       copy {
+         from zipTree(file_zip)
+         into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
+       }
+     }
+   }
+   inputs.files zipFiles
+   outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
+ }
+ task jalviewjsTransferUnzipAllLibs {
+   dependsOn jalviewjsTransferUnzipSwingJs
+   dependsOn jalviewjsTransferUnzipLib
+ }
+ task jalviewjsCreateJ2sSettings(type: WriteProperties) {
+   group "JalviewJS"
+   description "Create the .j2s file from the j2s.* properties"
+   jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
+   def siteDirProperty = "j2s.site.directory"
+   def setSiteDir = false
+   jalviewjsJ2sProps.each { prop, val ->
+     if (val != null) {
+       if (prop == siteDirProperty) {
+         if (!(val.startsWith('/') || val.startsWith("file://") )) {
+           val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
+         }
+         setSiteDir = true
+       }
+       property(prop,val)
+     }
+     if (!setSiteDir) { // default site location, don't override specifically set property
+       property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
+     }
+   }
+   outputFile = jalviewjsJ2sSettingsFileName
+   if (! IN_ECLIPSE) {
+     inputs.properties(jalviewjsJ2sProps)
+     outputs.file(jalviewjsJ2sSettingsFileName)
+   }
+ }
+ task jalviewjsEclipseSetup {
+   dependsOn jalviewjsEclipseCopyDropins
+   dependsOn jalviewjsSetEclipseWorkspace
+   dependsOn jalviewjsCreateJ2sSettings
+ }
+ task jalviewjsSyncAllLibs (type: Sync) {
+   dependsOn jalviewjsTransferUnzipAllLibs
+   def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
+   inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
+   def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
+   from inputFiles
+   into outputDir
+   def outputFiles = []
+   rename { filename ->
+     outputFiles += "${outputDir}/${filename}"
+     null
+   }
+   preserve {
+     include "**"
+   }
+   outputs.files outputFiles
+   inputs.files inputFiles
+ }
+ task jalviewjsSyncResources (type: Sync) {
+   def inputFiles = fileTree(dir: resourceDir)
+   def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
+   from inputFiles
+   into outputDir
+   def outputFiles = []
+   rename { filename ->
+     outputFiles += "${outputDir}/${filename}"
+     null
+   }
+   preserve {
+     include "**"
+   }
+   outputs.files outputFiles
+   inputs.files inputFiles
+ }
+ task jalviewjsSyncSiteResources (type: Sync) {
+   def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
+   def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
+   from inputFiles
+   into outputDir
+   def outputFiles = []
+   rename { filename ->
+     outputFiles += "${outputDir}/${filename}"
+     null
+   }
+   preserve {
+     include "**"
+   }
+   outputs.files outputFiles
+   inputs.files inputFiles
+ }
+ task jalviewjsSyncBuildProperties (type: Sync) {
+   dependsOn createBuildProperties
+   def inputFiles = [file(buildProperties)]
+   def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
+   from inputFiles
+   into outputDir
+   def outputFiles = []
+   rename { filename ->
+     outputFiles += "${outputDir}/${filename}"
+     null
+   }
+   preserve {
+     include "**"
+   }
+   outputs.files outputFiles
+   inputs.files inputFiles
+ }
+ task jalviewjsProjectImport(type: Exec) {
+   dependsOn eclipseSetup
+   dependsOn jalviewjsEclipsePaths
+   dependsOn jalviewjsEclipseSetup
+   doFirst {
+     // do not run a headless import when we claim to be in Eclipse
+     if (IN_ECLIPSE) {
+       println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
+       throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
+     } else {
+       println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
+     }
+   }
+   //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
+   def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
+   executable(eclipseBinary)
+   args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
+   if (eclipseDebug) {
+     args += "-debug"
+   }
+   args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
+   if (!IN_ECLIPSE) {
+     args += [ "-D${j2sHeadlessBuildProperty}=true" ]
+   }
+   inputs.file("${jalviewDir}/.project")
+   outputs.upToDateWhen { 
+     file(projdir).exists()
+   }
+ }
+ task jalviewjsTranspile(type: Exec) {
+   dependsOn jalviewjsEclipseSetup 
+   dependsOn jalviewjsProjectImport
+   dependsOn jalviewjsEclipsePaths
+   doFirst {
+     // do not run a headless transpile when we claim to be in Eclipse
+     if (IN_ECLIPSE) {
+       println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
+       throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
+     } else {
+       println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
+     }
+   }
+   executable(eclipseBinary)
+   args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
+   if (eclipseDebug) {
+     args += "-debug"
+   }
+   args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
+   if (!IN_ECLIPSE) {
+     args += [ "-D${j2sHeadlessBuildProperty}=true" ]
+   }
+   def stdout
+   def stderr
+   doFirst {
+     stdout = new ByteArrayOutputStream()
+     stderr = new ByteArrayOutputStream()
+     def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
+     def logOutFile = file(logOutFileName)
+     logOutFile.createNewFile()
+     logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
+ BINARY: ${eclipseBinary}
+ VERSION: ${eclipseVersion}
+ WORKSPACE: ${eclipseWorkspace}
+ DEBUG: ${eclipseDebug}
+ ----
+ """
+     def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
+     // combine stdout and stderr
+     def logErrFOS = logOutFOS
+     if (jalviewjs_j2s_to_console.equals("true")) {
+       standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
+         new org.apache.tools.ant.util.TeeOutputStream(
+           logOutFOS,
+           stdout),
+         standardOutput)
+       errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
+         new org.apache.tools.ant.util.TeeOutputStream(
+           logErrFOS,
+           stderr),
+         errorOutput)
+     } else {
+       standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
+         logOutFOS,
+         stdout)
+       errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
+         logErrFOS,
+         stderr)
+     }
+   }
+   doLast {
+     if (stdout.toString().contains("Error processing ")) {
+       // j2s did not complete transpile
+       //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
+       if (jalviewjs_ignore_transpile_errors.equals("true")) {
+         println("IGNORING TRANSPILE ERRORS")
+         println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
+       } else {
+         throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
+       }
+     }
+   }
+   inputs.dir("${jalviewDir}/${sourceDir}")
+   outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
+   outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
+ }
+ def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
+   def stdout = new ByteArrayOutputStream()
+   def stderr = new ByteArrayOutputStream()
+   def coreFile = file(jsfile)
+   def msg = ""
+   msg = "Creating core for ${name}...\nGenerating ${jsfile}"
+   println(msg)
+   logOutFile.createNewFile()
+   logOutFile.append(msg+"\n")
+   def coreTop = file(prefixFile)
+   def coreBottom = file(suffixFile)
+   coreFile.getParentFile().mkdirs()
+   coreFile.createNewFile()
+   coreFile.write( coreTop.getText("UTF-8") )
+   list.each {
+     f ->
+     if (f.exists()) {
+       def t = f.getText("UTF-8")
+       t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
+       coreFile.append( t )
+     } else {
+       msg = "...file '"+f.getPath()+"' does not exist, skipping"
+       println(msg)
+       logOutFile.append(msg+"\n")
+     }
+   }
+   coreFile.append( coreBottom.getText("UTF-8") )
+   msg = "Generating ${zjsfile}"
+   println(msg)
+   logOutFile.append(msg+"\n")
+   def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
+   def logErrFOS = logOutFOS
+   javaexec {
+     classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
+     main = "com.google.javascript.jscomp.CommandLineRunner"
+     jvmArgs = [ "-Dfile.encoding=UTF-8" ]
+     args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
+     maxHeapSize = "2g"
+     msg = "\nRunning '"+commandLine.join(' ')+"'\n"
+     println(msg)
+     logOutFile.append(msg+"\n")
+     if (logOutConsole) {
+       standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
+         new org.apache.tools.ant.util.TeeOutputStream(
+           logOutFOS,
+           stdout),
+         standardOutput)
+         errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
+           new org.apache.tools.ant.util.TeeOutputStream(
+             logErrFOS,
+             stderr),
+           errorOutput)
+     } else {
+       standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
+         logOutFOS,
+         stdout)
+         errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
+           logErrFOS,
+           stderr)
+     }
+   }
+   msg = "--"
+   println(msg)
+   logOutFile.append(msg+"\n")
+ }
+ task jalviewjsBuildAllCores {
+   group "JalviewJS"
+   description "Build the core js lib closures listed in the classlists dir"
+   dependsOn jalviewjsTranspile
+   dependsOn jalviewjsTransferUnzipSwingJs
+   def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
+   def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
+   def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
+   def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
+   def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
+   def prefixFile = "${jsDir}/core/coretop2.js"
+   def suffixFile = "${jsDir}/core/corebottom2.js"
+   inputs.file prefixFile
+   inputs.file suffixFile
+   def classlistFiles = []
+   // add the classlists found int the jalviewjs_classlists_dir
+   fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
+     file ->
+     def name = file.getName() - ".txt"
+     classlistFiles += [
+       'file': file,
+       'name': name
+     ]
+   }
+   // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
+   //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
+   classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
+   jalviewjsCoreClasslists = []
+   classlistFiles.each {
+     hash ->
+     def file = hash['file']
+     if (! file.exists()) {
+       //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
+       return false // this is a "continue" in groovy .each closure
+     }
+     def name = hash['name']
+     if (name == null) {
+       name = file.getName() - ".txt"
+     }
+     def filelist = []
+     file.eachLine {
+       line ->
+         filelist += line
+     }
+     def list = fileTree(dir: j2sDir, includes: filelist)
+     def jsfile = "${outputDir}/core${name}.js"
+     def zjsfile = "${outputDir}/core${name}.z.js"
+     jalviewjsCoreClasslists += [
+       'jsfile': jsfile,
+       'zjsfile': zjsfile,
+       'list': list,
+       'name': name
+     ]
+     inputs.file(file)
+     inputs.files(list)
+     outputs.file(jsfile)
+     outputs.file(zjsfile)
+   }
+   
+   // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
+   def stevesoftClasslistName = "_stevesoft"
+   def stevesoftClasslist = [
+     'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
+     'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
+     'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
+     'name': stevesoftClasslistName
+   ]
+   jalviewjsCoreClasslists += stevesoftClasslist
+   inputs.files(stevesoftClasslist['list'])
+   outputs.file(stevesoftClasslist['jsfile'])
+   outputs.file(stevesoftClasslist['zjsfile'])
+   // _all core
+   def allClasslistName = "_all"
+   def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
+   allJsFiles += fileTree(
+     dir: libJ2sDir,
+     include: "**/*.js",
+     excludes: [
+       // these exlusions are files that the closure-compiler produces errors for. Should fix them
+       "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
+       "**/org/jmol/export/JSExporter.js"
+     ]
+   )
+   allJsFiles += fileTree(
+     dir: swingJ2sDir,
+     include: "**/*.js",
+     excludes: [
+       // these exlusions are files that the closure-compiler produces errors for. Should fix them
+       "**/sun/misc/Unsafe.js",
+       "**/swingjs/jquery/jquery-editable-select.js",
+       "**/swingjs/jquery/j2sComboBox.js",
+       "**/sun/misc/FloatingDecimal.js"
+     ]
+   )
+   def allClasslist = [
+     'jsfile': "${outputDir}/core${allClasslistName}.js",
+     'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
+     'list': allJsFiles,
+     'name': allClasslistName
+   ]
+   // not including this version of "all" core at the moment
+   //jalviewjsCoreClasslists += allClasslist
+   inputs.files(allClasslist['list'])
+   outputs.file(allClasslist['jsfile'])
+   outputs.file(allClasslist['zjsfile'])
+   doFirst {
+     def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
+     logOutFile.getParentFile().mkdirs()
+     logOutFile.createNewFile()
+     logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
+     jalviewjsCoreClasslists.each {
+       jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
+     }
+   }
+ }
+ def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
+   copy {
+     from inputFile
+     into file(outputFile).getParentFile()
+     rename { filename ->
+       if (filename.equals(inputFile.getName())) {
+         return file(outputFile).getName()
+       }
+       return null
+     }
+     filter(ReplaceTokens,
+       beginToken: '_',
+       endToken: '_',
+       tokens: [
 -        'MAIN': '"'+mainClass+'"',
++        'MAIN': '"'+main_class+'"',
+         'CODE': "null",
+         'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
+         'COREKEY': jalviewjs_core_key,
+         'CORENAME': coreName
+       ]
+     )
+   }
+ }
+ task jalviewjsPublishCoreTemplates {
+   dependsOn jalviewjsBuildAllCores
+   def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
+   def inputFile = file(inputFileName)
+   def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
+   def outputFiles = []
+   jalviewjsCoreClasslists.each { cl ->
+     def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
+     cl['outputfile'] = outputFile
+     outputFiles += outputFile
+   }
+   doFirst {
+     jalviewjsCoreClasslists.each { cl ->
+       jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
+     }
+   }
+   inputs.file(inputFile)
+   outputs.files(outputFiles)
+ }
+ task jalviewjsSyncCore (type: Sync) {
+   dependsOn jalviewjsBuildAllCores
+   dependsOn jalviewjsPublishCoreTemplates
+   def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
+   def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
+   from inputFiles
+   into outputDir
+   def outputFiles = []
+   rename { filename ->
+     outputFiles += "${outputDir}/${filename}"
+     null
+   }
+   preserve {
+     include "**"
+   }
+   outputs.files outputFiles
+   inputs.files inputFiles
+ }
+ // this Copy version of TransferSiteJs will delete anything else in the target dir
+ task jalviewjsCopyTransferSiteJs(type: Copy) {
+   dependsOn jalviewjsTranspile
+   from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
+   into "${jalviewDir}/${jalviewjsSiteDir}"
+ }
+ // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
+ task jalviewjsSyncTransferSiteJs(type: Sync) {
+   from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
+   include "**/*.*"
+   into "${jalviewDir}/${jalviewjsSiteDir}"
+   preserve {
+     include "**"
+   }
+ }
+ jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
+ jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
+ jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
+ jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
+ jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
+ jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
+ jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
+ jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
+ task jalviewjsPrepareSite {
+   group "JalviewJS"
+   description "Prepares the website folder including unzipping files and copying resources"
+   dependsOn jalviewjsSyncAllLibs
+   dependsOn jalviewjsSyncResources
+   dependsOn jalviewjsSyncSiteResources
+   dependsOn jalviewjsSyncBuildProperties
+   dependsOn jalviewjsSyncCore
+ }
+ task jalviewjsBuildSite {
+   group "JalviewJS"
+   description "Builds the whole website including transpiled code"
+   dependsOn jalviewjsCopyTransferSiteJs
+   dependsOn jalviewjsPrepareSite
+ }
+ task cleanJalviewjsTransferSite {
+   doFirst {
+     delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
+     delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
+     delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
+     delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
+   }
+ }
+ task cleanJalviewjsSite {
+   dependsOn cleanJalviewjsTransferSite
+   doFirst {
+     delete "${jalviewDir}/${jalviewjsSiteDir}"
+   }
+ }
+ task jalviewjsSiteTar(type: Tar) {
+   group "JalviewJS"
+   description "Creates a tar.gz file for the website"
+   dependsOn jalviewjsBuildSite
+   def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
+   try {
+     archiveFileName = outputFilename
+   } catch (Exception e) {
+     archiveName = outputFilename
+   }
+   compression Compression.GZIP
+   from "${jalviewDir}/${jalviewjsSiteDir}"
+   into jalviewjs_site_dir // this is inside the tar file
+   inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
+ }
+ task jalviewjsServer {
+   group "JalviewJS"
+   def filename = "jalviewjsTest.html"
+   description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
+   def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
+   doLast {
+     SimpleHttpFileServerFactory factory = new SimpleHttpFileServerFactory()
+     def port = Integer.valueOf(jalviewjs_server_port)
+     def start = port
+     def running = false
+     def url
+     def jalviewjsServer
+     while(port < start+1000 && !running) {
+       try {
+         def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
+         jalviewjsServer = factory.start(doc_root, port)
+         running = true
+         url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
+         println("SERVER STARTED with document root ${doc_root}.")
+         println("Go to "+url+" . Run  gradle --stop  to stop (kills all gradle daemons).")
+         println("For debug: "+url+"?j2sdebug")
+         println("For verbose: "+url+"?j2sverbose")
+       } catch (Exception e) {
+         port++;
+       }
+     }
+     def htmlText = """
+       <p><a href="${url}">JalviewJS Test. &lt;${url}&gt;</a></p>
+       <p><a href="${url}?j2sdebug">JalviewJS Test with debug. &lt;${url}?j2sdebug&gt;</a></p>
+       <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. &lt;${url}?j2sdebug&gt;</a></p>
+       """
+     jalviewjsCoreClasslists.each { cl ->
+       def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
+       htmlText += """
+       <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. &lt;${urlcore}&gt;</a></p>
+       """
+       println("For core ${cl.name}: "+urlcore)
+     }
+     file(htmlFile).text = htmlText
+   }
+   outputs.file(htmlFile)
+   outputs.upToDateWhen({false})
+ }
+ task cleanJalviewjsAll {
+   group "JalviewJS"
+   description "Delete all configuration and build artifacts to do with JalviewJS build"
+   dependsOn cleanJalviewjsSite
+   dependsOn jalviewjsEclipsePaths
+   
+   doFirst {
+     delete "${jalviewDir}/${jalviewjsBuildDir}"
+     delete "${jalviewDir}/${eclipse_bin_dir}"
+     if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
+       delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
+     }
+     delete "${jalviewDir}/${jalviewjs_j2s_settings}"
+   }
+   outputs.upToDateWhen( { false } )
+ }
+ task jalviewjsIDE_checkJ2sPlugin {
+   group "00 JalviewJS in Eclipse"
+   description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
+   doFirst {
+     def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
+     def j2sPluginFile = file(j2sPlugin)
+     def eclipseHome = System.properties["eclipse.home.location"]
+     if (eclipseHome == null || ! IN_ECLIPSE) {
+       throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
+     }
+     def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
+     def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
+     if (!eclipseJ2sPluginFile.exists()) {
+       def msg = "Eclipse J2S Plugin is not installed (could not find '${eclipseJ2sPlugin}')\nTry running task jalviewjsIDE_copyJ2sPlugin"
+       System.err.println(msg)
+       throw new StopExecutionException(msg)
+     }
+     def digest = MessageDigest.getInstance("MD5")
+     digest.update(j2sPluginFile.text.bytes)
+     def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
+     digest.update(eclipseJ2sPluginFile.text.bytes)
+     def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
+      
+     if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
+       def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
+       System.err.println(msg)
+       throw new StopExecutionException(msg)
+     } else {
+       def msg = "Eclipse J2S Plugin is the same as '${j2sPlugin}' (this is good)"
+       println(msg)
+     }
+   }
+ }
+ task jalviewjsIDE_copyJ2sPlugin {
+   group "00 JalviewJS in Eclipse"
+   description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
+   doFirst {
+     def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
+     def j2sPluginFile = file(j2sPlugin)
+     def eclipseHome = System.properties["eclipse.home.location"]
+     if (eclipseHome == null || ! IN_ECLIPSE) {
+       throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
+     }
+     def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
+     def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
+     def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
+     System.err.println(msg)
+     copy {
+       from j2sPlugin
+       eclipseJ2sPluginFile.getParentFile().mkdirs()
+       into eclipseJ2sPluginFile.getParent()
+     }
+   }
+ }
+ task jalviewjsIDE_j2sFile {
+   group "00 JalviewJS in Eclipse"
+   description "Creates the .j2s file"
+   dependsOn jalviewjsCreateJ2sSettings
+ }
+ task jalviewjsIDE_SyncCore {
+   group "00 JalviewJS in Eclipse"
+   description "Build the core js lib closures listed in the classlists dir and publish core html from template"
+   dependsOn jalviewjsSyncCore
+ }
+ task jalviewjsIDE_SyncSiteAll {
+   dependsOn jalviewjsSyncAllLibs
+   dependsOn jalviewjsSyncResources
+   dependsOn jalviewjsSyncSiteResources
+   dependsOn jalviewjsSyncBuildProperties
+ }
+ cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
+ task jalviewjsIDE_PrepareSite {
+   group "00 JalviewJS in Eclipse"
+   description "Sync libs and resources to site dir, but not closure cores"
+   dependsOn jalviewjsIDE_SyncSiteAll
+   dependsOn cleanJalviewjsTransferSite
+ }
+ task jalviewjsIDE_AssembleSite {
+   group "00 JalviewJS in Eclipse"
+   description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
+   dependsOn jalviewjsPrepareSite
+ }
+ task jalviewjsIDE_SiteClean {
+   group "00 JalviewJS in Eclipse"
+   description "Deletes the Eclipse transpiled site"
+   dependsOn cleanJalviewjsSite
+ }
+ task jalviewjsIDE_Server {
+   group "00 JalviewJS in Eclipse"
+   description "Starts a webserver on localhost to test the website"
+   dependsOn jalviewjsServer
+ }
+ // buildship runs this at import or gradle refresh
+ task eclipseSynchronizationTask {
+   //dependsOn eclipseSetup
+   dependsOn createBuildProperties
+   if (J2S_ENABLED) {
+     dependsOn jalviewjsIDE_j2sFile
+     dependsOn jalviewjsIDE_checkJ2sPlugin
+     dependsOn jalviewjsIDE_PrepareSite
+   }
+ }
+ // buildship runs this at build time or project refresh
+ task eclipseAutoBuildTask {
+   //dependsOn jalviewjsIDE_checkJ2sPlugin
+   //dependsOn jalviewjsIDE_PrepareSite
+ }
+ task jalviewjs {
+   group "JalviewJS"
+   description "Build the site"
+   dependsOn jalviewjsBuildSite
+ }
@@@ -1,3 -1,6 +1,7 @@@
 -org.gradle.jvmargs=-Xmx1536m -Xms512m -Dfile.encoding=UTF-8
 -#systemProp.file.encoding=UTF-8
++# Convention for properties.  Read from this file, use lower_case_underlines for property names.
++# For properties set within build.gradle, use camelCaseNoSpace.
++#
  jalviewDir = .
  
  #JAVA_VERSION = 1.8
@@@ -177,8 -184,10 +182,9 @@@ jalviewjs_core_name = _jalvie
  jalviewjs_name = JalviewJS
  jalviewjs_core_key = core
  #jalviewjs_core_key = preloadCore
+ jalviewjs_ignore_transpile_errors = true
  
  j2s.compiler.status = enable
 -j2s.compiler.java.version = 11
  #j2s.site.directory = null ## site defined from buildDir+'/jalviewjs/'+jalviewjs_site_dir
  #j2s.log.methods.declared = j2s_methods_declared.log
  #j2s.log.methods.called = j2s_methods_called.log