JAL-3633 Small changes to allow future fitting with ApplicationSingletonI/Jalview...
[jalview.git] / build.gradle
index bd0ae20..d7382cb 100644 (file)
@@ -12,13 +12,25 @@ import java.security.MessageDigest
 import groovy.transform.ExternalizeMethods
 import groovy.util.XmlParser
 import groovy.xml.XmlUtil
-
+import com.vladsch.flexmark.util.ast.Node
+import com.vladsch.flexmark.html.HtmlRenderer
+import com.vladsch.flexmark.parser.Parser
+import com.vladsch.flexmark.util.data.MutableDataSet
+import com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension
+import com.vladsch.flexmark.ext.tables.TablesExtension
+import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension
+import com.vladsch.flexmark.ext.autolink.AutolinkExtension
+import com.vladsch.flexmark.ext.anchorlink.AnchorLinkExtension
+import com.vladsch.flexmark.ext.toc.TocExtension
 
 buildscript {
   repositories {
     mavenCentral()
     mavenLocal()
   }
+  dependencies {
+    classpath "com.vladsch.flexmark:flexmark-all:0.62.0"
+  }
 }
 
 
@@ -30,6 +42,7 @@ plugins {
   id 'com.github.johnrengelman.shadow' version '4.0.3'
   id 'com.install4j.gradle' version '8.0.4'
   id 'com.dorongold.task-tree' version '1.5' // only needed to display task dependency tree with  gradle task1 [task2 ...] taskTree
+  id 'com.palantir.git-version' version '0.12.3'
 }
 
 repositories {
@@ -98,7 +111,7 @@ ext {
   }
   ////
   // Set JALVIEW_VERSION if it is not already set
-  if (findProperty(JALVIEW_VERSION)==null || "".equals(JALVIEW_VERSION)) {
+  if (findProperty("JALVIEW_VERSION")==null || "".equals(JALVIEW_VERSION)) {
     JALVIEW_VERSION = releaseProps.get("jalview.version")
   }
   
@@ -148,14 +161,12 @@ ext {
   cloverBuildDir = "${buildDir}/clover"
   cloverInstrDir = file("${cloverBuildDir}/clover-instr")
   cloverClassesDir = file("${cloverBuildDir}/clover-classes")
-  cloverReportDir = file("${buildDir}/reports")
+  cloverReportDir = file("${buildDir}/reports/clover")
   cloverTestInstrDir = file("${cloverBuildDir}/clover-test-instr")
   cloverTestClassesDir = file("${cloverBuildDir}/clover-test-classes")
   //cloverTestClassesDir = cloverClassesDir
   cloverDb = string("${cloverBuildDir}/clover.db")
 
-  resourceClassesDir = useClover ? cloverClassesDir : classesDir
-
   testSourceDir = useClover ? cloverTestInstrDir : testDir
   testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}"
 
@@ -168,7 +179,6 @@ ext {
   getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
   getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
   getdownAppDistDir = getdown_app_dir_alt
-  buildProperties = string("${resourceDir}/${build_properties_file}")
   reportRsyncCommand = false
   jvlChannelName = CHANNEL.toLowerCase()
   install4jSuffix = CHANNEL.substring(0, 1).toUpperCase() + CHANNEL.substring(1).toLowerCase(); // BUILD -> Build
@@ -239,11 +249,19 @@ ext {
     // DEVELOP-RELEASE is usually associated with a Jalview release series so set the version
     JALVIEW_VERSION=JALVIEW_VERSION+"-develop"
     
+    channelPropertiesFile = string("${channel_properties_dir}/develop_properties")
+    getdownImagesDir = "${getdown_images_dir}/develop"
+    getdownBgColour = "000000"
+    getdownFgColour = "FFFFFF"
+    getdownLightFgColour = "CCCCFF"
     install4jSuffix = "Develop"
     install4jDSStore = "DS_Store-DEVELOP"
     install4jDMGBackgroundImage = "jalview_dmg_background-DEVELOP.png"
     install4jExtraScheme = "jalviewd"
     install4jInstallerName = "${jalview_name} Develop Installer"
+    install4jMacIconsFile = string("${install4j_utils_dir}/develop/${install4j_mac_icons_file}")
+    install4jWindowsIconsFile = string("${install4j_utils_dir}/develop/${install4j_windows_icons_file}")
+    install4jPngIconFile = string("${install4j_utils_dir}/develop/${install4j_png_icon_file}")
     break
 
     case "TEST-RELEASE":
@@ -346,8 +364,9 @@ ext {
   modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
   modules_runtimeClasspath = modules_compileClasspath
   */
-  gitHash = string("")
-  gitBranch = string("")
+  def details = versionDetails()
+  gitHash = details.gitHash
+  gitBranch = details.branchName
 
   println("Using a ${CHANNEL} profile.")
 
@@ -425,12 +444,16 @@ ext {
     install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1)
   }
 
+  resourceBuildDir = string("${buildDir}/resources")
+  resourcesBuildDir = string("${resourceBuildDir}/resources_build")
+  helpBuildDir = string("${resourceBuildDir}/help_build")
+  docBuildDir = string("${resourceBuildDir}/doc_build")
 
-
+  buildProperties = string("${resourcesBuildDir}/${build_properties_file}")
   buildingHTML = string("${jalviewDir}/${doc_dir}/building.html")
-  helpFile = string("${resourceClassesDir}/${help_dir}/help.jhm")
   helpParentDir = string("${jalviewDir}/${help_parent_dir}")
   helpSourceDir = string("${helpParentDir}/${help_dir}")
+  helpFile = string("${helpBuildDir}/${help_dir}/help.jhm")
 
 
   relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
@@ -468,16 +491,14 @@ sourceSets {
     }
 
     resources {
-      srcDirs resourceDir
-      srcDirs += helpParentDir
+      srcDirs = [ resourcesBuildDir, docBuildDir, helpBuildDir ]
     }
 
-    jar.destinationDir = file("${jalviewDir}/${package_dir}")
-
     compileClasspath = files(sourceSets.main.java.outputDir)
     compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
 
     runtimeClasspath = compileClasspath
+    runtimeClasspath += files(sourceSets.main.resources.srcDirs)
   }
 
   clover {
@@ -514,6 +535,7 @@ sourceSets {
     compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
 
     runtimeClasspath = compileClasspath
+    runtimeClasspath += files(sourceSets.test.resources.srcDirs)
   }
 
 }
@@ -534,14 +556,12 @@ eclipse {
 
   classpath {
     //defaultOutputDir = sourceSets.main.java.outputDir
-    def removeThese = []
-    configurations.each{
-      if (it.isCanBeResolved()) {
-        removeThese += it
+    configurations.each{ c->
+      if (c.isCanBeResolved()) {
+        minusConfigurations += [c]
       }
     }
 
-    minusConfigurations += removeThese
     plusConfigurations = [ ]
     file {
 
@@ -733,6 +753,7 @@ eclipseGroovyCorePreferences.mustRunAfter eclipseJdt
 task cleanClover {
   doFirst {
     delete cloverBuildDir
+    delete cloverReportDir
   }
 }
 
@@ -855,7 +876,7 @@ task cloverHtmlReport(type: JavaExec) {
     file(cloverDb).exists()
   }
 
-  def cloverHtmlDir = "${cloverReportDir}/clover"
+  def cloverHtmlDir = cloverReportDir
   inputs.dir cloverClassesDir
   outputs.dir cloverHtmlDir
 
@@ -893,7 +914,7 @@ task cloverXmlReport(type: JavaExec) {
     file(cloverDb).exists()
   }
 
-  def cloverXmlFile = "${cloverReportDir}/clover/clover.xml"
+  def cloverXmlFile = "${cloverReportDir}/clover.xml"
   inputs.dir cloverClassesDir
   outputs.file cloverXmlFile
 
@@ -990,112 +1011,179 @@ def getDate(format) {
 }
 
 
-task setGitVals {
-  def hashStdOut = new ByteArrayOutputStream()
-  exec {
-    commandLine "git", "rev-parse", "--short", "HEAD"
-    standardOutput = hashStdOut
-    ignoreExitValue true
-  }
+def convertMdToHtml (FileTree mdFiles, File cssFile) {
+  MutableDataSet options = new MutableDataSet()
 
-  def branchStdOut = new ByteArrayOutputStream()
-  exec {
-    commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
-    standardOutput = branchStdOut
-    ignoreExitValue true
+  def extensions = new ArrayList<>()
+  extensions.add(AnchorLinkExtension.create()) 
+  extensions.add(AutolinkExtension.create())
+  extensions.add(StrikethroughExtension.create())
+  extensions.add(TaskListExtension.create())
+  extensions.add(TablesExtension.create())
+  extensions.add(TocExtension.create())
+  
+  options.set(Parser.EXTENSIONS, extensions)
+
+  // set GFM table parsing options
+  options.set(TablesExtension.WITH_CAPTION, false)
+  options.set(TablesExtension.COLUMN_SPANS, false)
+  options.set(TablesExtension.MIN_HEADER_ROWS, 1)
+  options.set(TablesExtension.MAX_HEADER_ROWS, 1)
+  options.set(TablesExtension.APPEND_MISSING_COLUMNS, true)
+  options.set(TablesExtension.DISCARD_EXTRA_COLUMNS, true)
+  options.set(TablesExtension.HEADER_SEPARATOR_COLUMN_MATCH, true)
+  // GFM anchor links
+  options.set(AnchorLinkExtension.ANCHORLINKS_SET_ID, false)
+  options.set(AnchorLinkExtension.ANCHORLINKS_ANCHOR_CLASS, "anchor")
+  options.set(AnchorLinkExtension.ANCHORLINKS_SET_NAME, true)
+  options.set(AnchorLinkExtension.ANCHORLINKS_TEXT_PREFIX, "<span class=\"octicon octicon-link\"></span>")
+
+  Parser parser = Parser.builder(options).build()
+  HtmlRenderer renderer = HtmlRenderer.builder(options).build()
+
+  mdFiles.each { mdFile ->
+    // add table of contents
+    def mdText = "[TOC]\n"+mdFile.text
+
+    // grab the first top-level title
+    def title = null
+    def titleRegex = /(?m)^#(\s+|([^#]))(.*)/
+    def matcher = mdText =~ titleRegex
+    if (matcher.size() > 0) {
+      // matcher[0][2] is the first character of the title if there wasn't any whitespace after the #
+      title = (matcher[0][2] != null ? matcher[0][2] : "")+matcher[0][3]
+    }
+    // or use the filename if none found
+    if (title == null) {
+      title = mdFile.getName()
+    }
+
+    Node document = parser.parse(mdText)
+    String htmlBody = renderer.render(document)
+    def htmlText = '''<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <meta http-equiv="Content-Style-Type" content="text/css" />
+    <meta name="generator" content="flexmark" />
+'''
+    htmlText += ((title != null) ? "  <title>${title}</title>" : '' )
+    htmlText += '''
+    <style type="text/css">code{white-space: pre;}</style>
+'''
+    htmlText += ((cssFile != null) ? cssFile.text : '')
+    htmlText += '''</head>
+  <body>
+'''
+    htmlText += htmlBody
+    htmlText += '''
+  </body>
+</html>
+'''
+
+    def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
+    def htmlFile = file(htmlFilePath)
+    println("Creating ${htmlFilePath}")
+    htmlFile.text = htmlText
+  }
+}
+
+
+task copyDocs(type: Copy) {
+  def inputDir = "${jalviewDir}/${doc_dir}"
+  def outputDir = "${docBuildDir}/${doc_dir}"
+  from(inputDir) {
+    include('**/*.txt')
+    include('**/*.md')
+    include('**/*.html')
+    include('**/*.xml')
+    filter(ReplaceTokens,
+      beginToken: '$$',
+      endToken: '$$',
+      tokens: [
+        'Version-Rel': JALVIEW_VERSION,
+        'Year-Rel': getDate("yyyy")
+      ]
+    )
   }
+  from(inputDir) {
+    exclude('**/*.txt')
+    exclude('**/*.md')
+    exclude('**/*.html')
+    exclude('**/*.xml')
+  }
+  into outputDir
 
-  gitHash = hashStdOut.toString().trim()
-  gitBranch = branchStdOut.toString().trim()
-
-  outputs.upToDateWhen { false }
+  inputs.dir(inputDir)
+  outputs.dir(outputDir)
 }
 
 
-task createBuildProperties(type: WriteProperties) {
-  group = "build"
-  description = "Create the ${buildProperties} file"
-  
-  dependsOn setGitVals
-  inputs.dir(sourceDir)
-  inputs.dir(resourceDir)
-  file(buildProperties).getParentFile().mkdirs()
-  outputFile (buildProperties)
-  // taking time specific comment out to allow better incremental builds
-  comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
-  //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
-  property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
-  property "VERSION", JALVIEW_VERSION
-  property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
-  outputs.file(outputFile)
-}
+task convertMdFiles {
+  dependsOn copyDocs
+  def mdFiles = fileTree(dir: docBuildDir, include: "**/*.md")
+  def cssFile = file("${jalviewDir}/${flexmark_css}")
 
-
-clean {
-  doFirst {
-    delete buildProperties
+  doLast {
+    convertMdToHtml(mdFiles, cssFile)
   }
-}
 
+  inputs.files(mdFiles)
+  inputs.file(cssFile)
 
-task cleanBuildingHTML(type: Delete) {
-  doFirst {
-    delete buildingHTML
+  def htmlFiles = []
+  mdFiles.each { mdFile ->
+    def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
+    htmlFiles.add(file(htmlFilePath))
   }
+  outputs.files(htmlFiles)
 }
 
 
-task convertBuildingMD(type: Exec) {
-  dependsOn cleanBuildingHTML
-  def buildingMD = "${jalviewDir}/${doc_dir}/building.md"
-  def css = "${jalviewDir}/${doc_dir}/github.css"
-
-  def pandoc = null
-  pandoc_exec.split(",").each {
-    if (file(it.trim()).exists()) {
-      pandoc = it.trim()
-      return true
-    }
-  }
-
-  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"
+task copyHelp(type: Copy) {
+  def inputDir = helpSourceDir
+  def outputDir = "${helpBuildDir}/${help_dir}"
+  from(inputDir) {
+    include('**/*.txt')
+    include('**/*.md')
+    include('**/*.html')
+    include('**/*.hs')
+    include('**/*.xml')
+    include('**/*.jhm')
+    filter(ReplaceTokens,
+      beginToken: '$$',
+      endToken: '$$',
+      tokens: [
+        'Version-Rel': JALVIEW_VERSION,
+        'Year-Rel': getDate("yyyy")
+      ]
+    )
   }
-
-  doFirst {
-    if (pandoc != null && file(pandoc).exists()) {
-        commandLine pandoc, '-s', '-o', buildingHTML, '--metadata', 'pagetitle="Building Jalview from Source"', '--toc', '-H', css, buildingMD
-    } else {
-        println("Cannot find pandoc. Skipping convert building.md to HTML")
-        throw new StopExecutionException("Cannot find pandoc. Skipping convert building.md to HTML")
-    }
+  from(inputDir) {
+    exclude('**/*.txt')
+    exclude('**/*.md')
+    exclude('**/*.html')
+    exclude('**/*.hs')
+    exclude('**/*.xml')
+    exclude('**/*.jhm')
   }
+  into outputDir
 
-  ignoreExitValue true
-
-  inputs.file(buildingMD)
-  inputs.file(css)
-  outputs.file(buildingHTML)
-}
-
-
-task syncDocs(type: Sync) {
-  dependsOn convertBuildingMD
-  def syncDir = "${classesDir}/${doc_dir}"
-  from fileTree("${jalviewDir}/${doc_dir}")
-  into syncDir
-
+  inputs.dir(inputDir)
+  outputs.files(helpFile)
+  outputs.dir(outputDir)
 }
 
 
-task copyHelp(type: Copy) {
-  def inputDir = helpSourceDir
-  def outputDir = "${resourceClassesDir}/${help_dir}"
+task copyResources(type: Copy) {
+  def inputDir = resourceDir
+  def outputDir = resourcesBuildDir
   from(inputDir) {
-    exclude '**/*.gif'
-    exclude '**/*.jpg'
-    exclude '**/*.png'
+    include('**/*.txt')
+    include('**/*.md')
+    include('**/*.html')
+    include('**/*.xml')
     filter(ReplaceTokens,
       beginToken: '$$',
       endToken: '$$',
@@ -1106,52 +1194,79 @@ task copyHelp(type: Copy) {
     )
   }
   from(inputDir) {
-    include '**/*.gif'
-    include '**/*.jpg'
-    include '**/*.png'
+    exclude('**/*.txt')
+    exclude('**/*.md')
+    exclude('**/*.html')
+    exclude('**/*.xml')
   }
   into outputDir
 
   inputs.dir(inputDir)
-  outputs.files(helpFile)
   outputs.dir(outputDir)
 }
 
 
-task syncLib(type: Sync) {
-  def syncDir = "${resourceClassesDir}/${libDistDir}"
-  from fileTree("${jalviewDir}/${libDistDir}")
-  into syncDir
+task createBuildProperties(type: WriteProperties) {
+  dependsOn copyResources
+  group = "build"
+  description = "Create the ${buildProperties} file"
+  
+  inputs.dir(sourceDir)
+  inputs.dir(resourcesBuildDir)
+  outputFile (buildProperties)
+  // taking time specific comment out to allow better incremental builds
+  comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
+  //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
+  property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
+  property "VERSION", JALVIEW_VERSION
+  property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
+  outputs.file(outputFile)
 }
 
 
-task syncResources(type: Sync) {
-  dependsOn createBuildProperties
-  from resourceDir
-  include "**/*.*"
-  into "${resourceClassesDir}"
-  preserve {
-    include "**"
-  }
+task buildIndices(type: JavaExec) {
+  dependsOn copyHelp
+  classpath = sourceSets.main.compileClasspath
+  main = "com.sun.java.help.search.Indexer"
+  workingDir = "${helpBuildDir}/${help_dir}"
+  def argDir = "html"
+  args = [ argDir ]
+  inputs.dir("${workingDir}/${argDir}")
+
+  outputs.dir("${classesDir}/doc")
+  outputs.dir("${classesDir}/help")
+  outputs.file("${workingDir}/JavaHelpSearch/DOCS")
+  outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
+  outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
+  outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
+  outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
+  outputs.file("${workingDir}/JavaHelpSearch/TMAP")
 }
 
 
 task prepare {
-  dependsOn syncResources
-  dependsOn syncDocs
+  dependsOn copyResources
+  dependsOn copyDocs
   dependsOn copyHelp
+  dependsOn createBuildProperties
+  dependsOn convertMdFiles
+  dependsOn buildIndices
 }
 
 
+compileJava.dependsOn prepare
+run.dependsOn compileJava
+//run.dependsOn prepare
+
+
 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
 test {
   dependsOn prepare
-  //dependsOn compileJava ////? DELETE
 
   if (useClover) {
     dependsOn cloverClasses
    } else { //?
-     dependsOn compileJava //?
+    dependsOn compileJava //?
   }
 
   useTestNG() {
@@ -1164,7 +1279,16 @@ test {
   maxHeapSize = "1024m"
 
   workingDir = jalviewDir
-  //systemProperties 'clover.jar' System.properties.clover.jar
+  def testLaf = project.findProperty("test_laf")
+  if (testLaf != null) {
+    println("Setting Test LaF to '${testLaf}'")
+    systemProperty "laf", testLaf
+  }
+  def testHiDPIScale = project.findProperty("test_HiDPIScale")
+  if (testHiDPIScale != null) {
+    println("Setting Test HiDPI Scale to '${testHiDPIScale}'")
+    systemProperty "sun.java2d.uiScale", testHiDPIScale
+  }
   sourceCompatibility = compile_source_compatibility
   targetCompatibility = compile_target_compatibility
   jvmArgs += additional_compiler_args
@@ -1177,26 +1301,6 @@ test {
 }
 
 
-task buildIndices(type: JavaExec) {
-  dependsOn copyHelp
-  classpath = sourceSets.main.compileClasspath
-  main = "com.sun.java.help.search.Indexer"
-  workingDir = "${classesDir}/${help_dir}"
-  def argDir = "html"
-  args = [ argDir ]
-  inputs.dir("${workingDir}/${argDir}")
-
-  outputs.dir("${classesDir}/doc")
-  outputs.dir("${classesDir}/help")
-  outputs.file("${workingDir}/JavaHelpSearch/DOCS")
-  outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
-  outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
-  outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
-  outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
-  outputs.file("${workingDir}/JavaHelpSearch/TMAP")
-}
-
-
 task compileLinkCheck(type: JavaCompile) {
   options.fork = true
   classpath = files("${jalviewDir}/${utils_dir}")
@@ -1211,13 +1315,14 @@ task compileLinkCheck(type: JavaCompile) {
 
 
 task linkCheck(type: JavaExec) {
-  dependsOn prepare, compileLinkCheck
+  dependsOn prepare
+  dependsOn compileLinkCheck
 
   def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
   classpath = files("${jalviewDir}/${utils_dir}")
   main = "HelpLinksChecker"
   workingDir = jalviewDir
-  args = [ "${classesDir}/${help_dir}", "-nointernet" ]
+  args = [ "${helpBuildDir}/${help_dir}", "-nointernet" ]
 
   def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
   def errFOS = outFOS
@@ -1228,13 +1333,14 @@ task linkCheck(type: JavaExec) {
     outFOS,
     errorOutput)
 
-  inputs.dir("${classesDir}/${help_dir}")
+  inputs.dir(helpBuildDir)
   outputs.file(helpLinksCheckerOutFile)
 }
 
+
 // import the pubhtmlhelp target
 ant.properties.basedir = "${jalviewDir}"
-ant.properties.helpBuildDir = "${jalviewDirAbsolutePath}/${classes_dir}/${help_dir}"
+ant.properties.helpBuildDir = "${helpBuildDir}/${help_dir}"
 ant.importBuild "${utils_dir}/publishHelp.xml"
 
 
@@ -1246,19 +1352,19 @@ task cleanPackageDir(type: Delete) {
 
 
 jar {
+  dependsOn prepare
   dependsOn linkCheck
-  dependsOn buildIndices
-  dependsOn createBuildProperties
 
   manifest {
     attributes "Main-Class": main_class,
     "Permissions": "all-permissions",
-    "Application-Name": "Jalview Desktop",
-    "Codebase": application_codebase
+    "Application-Name": install4jApplicationName,
+    "Codebase": application_codebase,
+    "Implementation-Version": JALVIEW_VERSION
   }
 
-  destinationDir = file("${jalviewDir}/${package_dir}")
-  archiveName = rootProject.name+".jar"
+  destinationDirectory = file("${jalviewDir}/${package_dir}")
+  archiveFileName = rootProject.name+".jar"
 
   exclude "cache*/**"
   exclude "*.jar"
@@ -1266,8 +1372,11 @@ jar {
   exclude "**/*.jar"
   exclude "**/*.jar.*"
 
-  inputs.dir(classesDir)
-  outputs.file("${jalviewDir}/${package_dir}/${archiveName}")
+  inputs.dir(sourceSets.main.java.outputDir)
+  sourceSets.main.resources.srcDirs.each{ dir ->
+    inputs.dir(dir)
+  }
+  outputs.file("${destinationDirectory}/${archiveFileName}")
 }
 
 
@@ -1279,10 +1388,11 @@ task copyJars(type: Copy) {
 
 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
 task syncJars(type: Sync) {
+  dependsOn jar
   from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
   into "${jalviewDir}/${package_dir}"
   preserve {
-    include jar.archiveName
+    include jar.archiveFileName.getOrNull()
   }
 }
 
@@ -1306,8 +1416,10 @@ task cleanDist {
   dependsOn clean
 }
 
+
 shadowJar {
   group = "distribution"
+  description = "Create a single jar file with all dependency libraries merged. Can be run with java -jar"
   if (buildDist) {
     dependsOn makeDist
   }
@@ -1315,7 +1427,8 @@ shadowJar {
     include("*.jar")
   }
   manifest {
-    attributes 'Implementation-Version': JALVIEW_VERSION
+    attributes "Implementation-Version": JALVIEW_VERSION,
+    "Application-Name": install4jApplicationName
   }
   mainClassName = shadow_jar_main_class
   mergeServiceFiles()
@@ -1683,7 +1796,6 @@ clean {
 task installers(type: com.install4j.gradle.Install4jTask) {
   group = "distribution"
   description = "Create the install4j installers"
-  dependsOn setGitVals
   dependsOn getdown
   dependsOn copyInstall4jTemplate
 
@@ -1782,15 +1894,14 @@ spotless {
 
 
 task sourceDist(type: Tar) {
+  group "distribution"
+  description "Create a source .tar.gz file for distribution"
   
+  dependsOn convertMdFiles
+
   def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
   def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
-  // cater for buildship < 3.1 [3.0.1 is max version in eclipse 2018-09]
-  try {
-    archiveFileName = outputFileName
-  } catch (Exception e) {
-    archiveName = outputFileName
-  }
+  archiveFileName = outputFileName
   
   compression Compression.GZIP
   
@@ -1880,7 +1991,7 @@ task helppages {
   dependsOn copyHelp
   dependsOn pubhtmlhelp
   
-  inputs.dir("${classesDir}/${help_dir}")
+  inputs.dir("${helpBuildDir}/${help_dir}")
   outputs.dir("${buildDir}/distributions/${help_dir}")
 }
 
@@ -2684,11 +2795,7 @@ task jalviewjsSiteTar(type: Tar) {
   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
-  }
+  archiveFileName = outputFilename
 
   compression Compression.GZIP
 
@@ -2777,10 +2884,25 @@ task jalviewjsIDE_checkJ2sPlugin {
     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"
+    def eclipseJ2sPluginDirs = [ "${eclipseHome}/dropins" ]
+    def altPluginsDir = System.properties["org.eclipse.equinox.p2.reconciler.dropins.directory"]
+    if (altPluginsDir != null && file(altPluginsDir).exists()) {
+      eclipseJ2sPluginDirs += altPluginsDir
+    }
+    def foundPlugin = false
+    def j2sPluginFileName = j2sPluginFile.getName()
+    def eclipseJ2sPlugin
+    def eclipseJ2sPluginFile
+    eclipseJ2sPluginDirs.any { dir ->
+      eclipseJ2sPlugin = "${dir}/${j2sPluginFileName}"
+      eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
+      if (eclipseJ2sPluginFile.exists()) {
+        foundPlugin = true
+        return true
+      }
+    }
+    if (!foundPlugin) {
+      def msg = "Eclipse J2S Plugin is not installed (could not find '${j2sPluginFileName}' in\n"+eclipseJ2sPluginDirs.join("\n")+"\n)\nTry running task jalviewjsIDE_copyJ2sPlugin"
       System.err.println(msg)
       throw new StopExecutionException(msg)
     }
@@ -2798,7 +2920,7 @@ task jalviewjsIDE_checkJ2sPlugin {
       System.err.println(msg)
       throw new StopExecutionException(msg)
     } else {
-      def msg = "Eclipse J2S Plugin is the same as '${j2sPlugin}' (this is good)"
+      def msg = "Eclipse J2S Plugin '${eclipseJ2sPlugin}' is the same as '${j2sPlugin}' (this is good)"
       println(msg)
     }
   }
@@ -2858,7 +2980,7 @@ task jalviewjsIDE_PrepareSite {
   description "Sync libs and resources to site dir, but not closure cores"
 
   dependsOn jalviewjsIDE_SyncSiteAll
-  dependsOn cleanJalviewjsTransferSite
+  //dependsOn cleanJalviewjsTransferSite // not sure why this clean is here -- will slow down a re-run of this task
 }