+
+task copyResources(type: Copy) {
+ group = "build"
+ description = "Copy (and make text substitutions in) the resources dir to the build area"
+
+ def inputDir = resourceDir
+ def outputDir = resourcesBuildDir
+ 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
+
+ inputs.dir(inputDir)
+ outputs.dir(outputDir)
+}
+
+task copyChannelResources(type: Copy) {
+ dependsOn copyResources
+ group = "build"
+ description = "Copy the channel resources dir to the build resources area"
+
+ def inputDir = "${channelDir}/${resource_dir}"
+ def outputDir = resourcesBuildDir
+ from inputDir
+ into outputDir
+
+ inputs.dir(inputDir)
+ outputs.dir(outputDir)
+}
+
+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+"]"
+ if (getdownSetAppBaseProperty) {
+ property "GETDOWNAPPBASE", getdownAppBase
+ property "GETDOWNAPPDISTDIR", getdownAppDistDir
+ }
+ outputs.file(outputFile)
+}
+
+
+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 buildResources {
+ dependsOn copyResources
+ dependsOn copyChannelResources
+ dependsOn createBuildProperties
+}
+
+task prepare {
+ dependsOn buildResources
+ dependsOn copyDocs
+ dependsOn copyHelp
+ 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
+
+ if (useClover) {
+ dependsOn cloverClasses
+ } else { //?
+ dependsOn compileJava //?
+ }
+
+ useTestNG() {
+ includeGroups testng_groups
+ excludeGroups testng_excluded_groups
+ preserveOrder true
+ useDefaultListeners=true
+ }
+
+ maxHeapSize = "1024m"
+
+ workingDir = jalviewDir
+ 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
+
+ doFirst {
+ if (useClover) {
+ println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
+ }
+ }
+}
+
+
+task compileLinkCheck(type: JavaCompile) {
+ options.fork = true
+ classpath = files("${jalviewDir}/${utils_dir}")
+ destinationDir = file("${jalviewDir}/${utils_dir}")
+ source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
+
+ inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
+ inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
+ outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
+ outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
+}
+
+
+task linkCheck(type: JavaExec) {
+ dependsOn prepare
+ dependsOn compileLinkCheck
+
+ def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
+ classpath = files("${jalviewDir}/${utils_dir}")
+ main = "HelpLinksChecker"
+ workingDir = jalviewDir
+ args = [ "${helpBuildDir}/${help_dir}", "-nointernet" ]
+
+ def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
+ standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
+ outFOS,
+ System.out)
+ errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
+ outFOS,
+ System.err)
+
+ inputs.dir(helpBuildDir)
+ outputs.file(helpLinksCheckerOutFile)
+}
+
+
+// import the pubhtmlhelp target
+ant.properties.basedir = "${jalviewDir}"
+ant.properties.helpBuildDir = "${helpBuildDir}/${help_dir}"
+ant.importBuild "${utils_dir}/publishHelp.xml"
+
+
+task cleanPackageDir(type: Delete) {
+ doFirst {
+ delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
+ }
+}
+
+
+jar {
+ dependsOn prepare
+ dependsOn linkCheck
+
+ manifest {
+ attributes "Main-Class": main_class,
+ "Permissions": "all-permissions",
+ "Application-Name": applicationName,
+ "Codebase": application_codebase,
+ "Implementation-Version": JALVIEW_VERSION
+ }
+
+ def outputDir = "${jalviewDir}/${package_dir}"
+ destinationDirectory = file(outputDir)
+ archiveFileName = rootProject.name+".jar"
+ duplicatesStrategy "EXCLUDE"
+
+
+ exclude "cache*/**"
+ exclude "*.jar"
+ exclude "*.jar.*"
+ exclude "**/*.jar"
+ exclude "**/*.jar.*"
+
+ inputs.dir(sourceSets.main.java.outputDir)
+ sourceSets.main.resources.srcDirs.each{ dir ->
+ inputs.dir(dir)
+ }
+ outputs.file("${outputDir}/${archiveFileName}")
+}
+
+
+task copyJars(type: Copy) {
+ from fileTree(dir: classesDir, include: "**/*.jar").files
+ into "${jalviewDir}/${package_dir}"
+}
+
+
+// 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.archiveFileName.getOrNull()
+ }
+}
+
+
+task makeDist {
+ group = "build"
+ description = "Put all required libraries in dist"
+ // order of "cleanPackageDir", "copyJars", "jar" important!
+ jar.mustRunAfter cleanPackageDir
+ syncJars.mustRunAfter cleanPackageDir
+ dependsOn cleanPackageDir
+ dependsOn syncJars
+ dependsOn jar
+ outputs.dir("${jalviewDir}/${package_dir}")
+}
+
+
+task cleanDist {
+ dependsOn cleanPackageDir
+ dependsOn cleanTest
+ 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
+ }
+ from ("${jalviewDir}/${libDistDir}") {
+ include("*.jar")
+ }
+ manifest {
+ attributes "Implementation-Version": JALVIEW_VERSION,
+ "Application-Name": applicationName
+ }
+
+ duplicatesStrategy "INCLUDE"
+
+ mainClassName = shadow_jar_main_class
+ mergeServiceFiles()
+ classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
+ minimize()
+}
+
+
+task getdownWebsite() {
+ group = "distribution"
+ description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
+ if (buildDist) {
+ dependsOn makeDist
+ }
+
+ def getdownWebsiteResourceFilenames = []
+ def getdownResourceDir = getdownResourceDir
+ def getdownResourceFilenames = []
+
+ doFirst {
+ // clean the getdown website and files dir before creating getdown folders
+ delete getdownAppBaseDir
+ delete getdownFilesDir
+
+ copy {
+ from buildProperties
+ rename(file(buildProperties).getName(), getdown_build_properties)
+ into getdownAppDir
+ }
+ getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
+
+ copy {
+ from channelPropsFile
+ into getdownAppBaseDir
+ }
+ getdownWebsiteResourceFilenames += file(channelPropsFile).getName()
+
+ // set some getdownTxt_ properties then go through all properties looking for getdownTxt_...
+ def props = project.properties.sort { it.key }
+ if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
+ props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
+ }
+ 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)
+ }
+ if (getdownImagesDir != null && file(getdownImagesDir).exists()) {
+ props.put("getdown_txt_ui.background_image", "${getdownImagesDir}/${getdown_background_image}")
+ props.put("getdown_txt_ui.instant_background_image", "${getdownImagesDir}/${getdown_instant_background_image}")
+ props.put("getdown_txt_ui.error_background", "${getdownImagesDir}/${getdown_error_background}")
+ props.put("getdown_txt_ui.progress_image", "${getdownImagesDir}/${getdown_progress_image}")
+ props.put("getdown_txt_ui.icon", "${getdownImagesDir}/${getdown_icon}")
+ props.put("getdown_txt_ui.mac_dock_icon", "${getdownImagesDir}/${getdown_mac_dock_icon}")
+ }
+
+ props.put("getdown_txt_title", jalview_name)
+ props.put("getdown_txt_ui.name", applicationName)
+
+ // start with appbase
+ getdownTextLines += "appbase = ${getdownAppBase}"
+ props.each{ prop, val ->
+ if (prop.startsWith("getdown_txt_") && val != null) {
+ if (prop.startsWith("getdown_txt_multi_")) {
+ def key = prop.substring(18)
+ val.split(",").each{ v ->
+ def line = "${key} = ${v}"
+ getdownTextLines += line
+ }
+ } else {
+ // file values rationalised
+ if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
+ def r = null
+ if (val.indexOf('/') == 0) {
+ // absolute path
+ r = file(val)
+ } else if (val.indexOf('/') > 0) {
+ // relative path (relative to jalviewDir)
+ r = file( "${jalviewDir}/${val}" )
+ }
+ if (r.exists()) {
+ val = "${getdown_resource_dir}/" + r.getName()
+ getdownWebsiteResourceFilenames += val
+ getdownResourceFilenames += r.getPath()
+ }
+ }
+ if (! prop.startsWith("getdown_txt_resource")) {
+ def line = prop.substring(12) + " = ${val}"
+ getdownTextLines += line
+ }
+ }
+ }
+ }
+
+ getdownWebsiteResourceFilenames.each{ filename ->
+ getdownTextLines += "resource = ${filename}"
+ }
+ getdownResourceFilenames.each{ filename ->
+ copy {
+ from filename
+ into getdownResourceDir
+ }
+ }
+
+ def getdownWrapperScripts = [ getdown_bash_wrapper_script, getdown_powershell_wrapper_script, getdown_batch_wrapper_script ]
+ getdownWrapperScripts.each{ script ->
+ def s = file( "${jalviewDir}/utils/getdown/${getdown_wrapper_script_dir}/${script}" )
+ if (s.exists()) {
+ copy {
+ from s
+ into "${getdownAppBaseDir}/${getdown_wrapper_script_dir}"
+ }
+ getdownTextLines += "resource = ${getdown_wrapper_script_dir}/${script}"
+ }
+ }
+
+ def codeFiles = []
+ fileTree(file(package_dir)).each{ f ->
+ if (f.isDirectory()) {
+ def files = fileTree(dir: f, include: ["*"]).getFiles()
+ codeFiles += files
+ } else if (f.exists()) {
+ codeFiles += f
+ }
+ }
+ def jalviewJar = jar.archiveFileName.getOrNull()
+ // put jalview.jar first for CLASSPATH and .properties files reasons
+ codeFiles.sort{a, b -> ( a.getName() == jalviewJar ? -1 : ( b.getName() == jalviewJar ? 1 : a <=> b ) ) }.each{f ->
+ def name = f.getName()
+ def line = "code = ${getdownAppDistDir}/${name}"
+ getdownTextLines += line
+ copy {
+ from f.getPath()
+ into getdownAppDir
+ }
+ }
+
+ // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
+ /*
+ if (JAVA_VERSION.equals("11")) {
+ def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
+ j11libFiles.sort().each{f ->
+ def name = f.getName()
+ def line = "code = ${getdown_j11lib_dir}/${name}"
+ getdownTextLines += line
+ copy {
+ from f.getPath()
+ into getdownJ11libDir
+ }
+ }
+ }
+ */
+
+ // 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.
+ //getdownTextLines += "class = " + file(getdownLauncher).getName()
+ getdownTextLines += "resource = ${getdown_launcher_new}"
+ getdownTextLines += "class = ${main_class}"
+ // Not setting these properties in general so that getdownappbase and getdowndistdir will default to release version in jalview.bin.Cache
+ if (getdownSetAppBaseProperty) {
+ getdownTextLines += "jvmarg = -Dgetdowndistdir=${getdownAppDistDir}"
+ getdownTextLines += "jvmarg = -Dgetdownappbase=${getdownAppBase}"
+ }
+
+ def getdownTxt = file("${getdownAppBaseDir}/getdown.txt")
+ getdownTxt.write(getdownTextLines.join("\n"))
+
+ getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
+ def launchJvl = file("${getdownAppBaseDir}/${getdownLaunchJvl}")
+ launchJvl.write("appbase=${getdownAppBase}")
+
+ // files going into the getdown website dir: getdown-launcher.jar
+ copy {
+ from getdownLauncher
+ rename(file(getdownLauncher).getName(), getdown_launcher_new)
+ into getdownAppBaseDir
+ }
+
+ // files going into the getdown website dir: getdown-launcher(-local).jar
+ copy {
+ from getdownLauncher
+ if (file(getdownLauncher).getName() != getdown_launcher) {
+ rename(file(getdownLauncher).getName(), getdown_launcher)
+ }
+ into getdownAppBaseDir
+ }
+
+ // files going into the getdown website dir: ./install dir and files
+ if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
+ copy {
+ from getdownTxt
+ from getdownLauncher
+ from "${getdownAppDir}/${getdown_build_properties}"
+ if (file(getdownLauncher).getName() != getdown_launcher) {
+ rename(file(getdownLauncher).getName(), getdown_launcher)
+ }
+ into getdownInstallDir
+ }
+
+ // and make a copy in the getdown files dir (these are not downloaded by getdown)
+ copy {
+ from getdownInstallDir
+ into getdownFilesInstallDir
+ }
+ }
+
+ // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties
+ copy {
+ from getdownTxt
+ from launchJvl
+ from getdownLauncher
+ from "${getdownAppBaseDir}/${getdown_build_properties}"
+ from "${getdownAppBaseDir}/${channel_props}"
+ if (file(getdownLauncher).getName() != getdown_launcher) {
+ rename(file(getdownLauncher).getName(), getdown_launcher)
+ }
+ into getdownFilesDir
+ }
+
+ // and ./resource (not all downloaded by getdown)
+ copy {
+ from getdownResourceDir
+ into "${getdownFilesDir}/${getdown_resource_dir}"
+ }
+ }
+
+ if (buildDist) {
+ inputs.dir("${jalviewDir}/${package_dir}")
+ }
+ outputs.dir(getdownAppBaseDir)
+ outputs.dir(getdownFilesDir)
+}
+
+
+// a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
+task getdownDigestDir(type: JavaExec) {
+ group "Help"
+ description "A task to run a getdown Digest on a dir with getdown.txt. Provide a DIGESTDIR property via -PDIGESTDIR=..."
+
+ def digestDirPropertyName = "DIGESTDIR"
+ 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(getdownLauncher)
+ }
+ main = "com.threerings.getdown.tools.Digester"
+ args getdownAppBaseDir
+ inputs.dir(getdownAppBaseDir)
+ outputs.file("${getdownAppBaseDir}/digest2.txt")
+}
+
+
+task getdown() {
+ group = "distribution"
+ description = "Create the minimal and full getdown app folder for installers and website and create digest file"
+ dependsOn getdownDigest
+ doLast {
+ if (reportRsyncCommand) {
+ def fromDir = getdownAppBaseDir + (getdownAppBaseDir.endsWith('/')?'':'/')
+ def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
+ println "LIKELY RSYNC COMMAND:"
+ println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
+ if (RUNRSYNC == "true") {
+ exec {
+ commandLine "mkdir", "-p", toDir
+ }
+ exec {
+ commandLine "rsync", "-avh", "--delete", fromDir, toDir
+ }
+ }
+ }
+ }
+}
+
+
+task getdownArchiveBuild() {
+ group = "distribution"
+ description = "Put files in the archive dir to go on the website"
+
+ dependsOn getdownWebsite
+
+ def v = "v${JALVIEW_VERSION_UNDERSCORES}"
+ def vDir = "${getdownArchiveDir}/${v}"
+ getdownFullArchiveDir = "${vDir}/getdown"
+ getdownVersionLaunchJvl = "${vDir}/jalview-${v}.jvl"
+
+ def vAltDir = "alt_${v}"
+ def archiveImagesDir = "${jalviewDir}/${channel_properties_dir}/old/images"
+
+ doFirst {
+ // cleanup old "old" dir
+ delete getdownArchiveDir
+
+ def getdownArchiveTxt = file("${getdownFullArchiveDir}/getdown.txt")
+ getdownArchiveTxt.getParentFile().mkdirs()
+ def getdownArchiveTextLines = []
+ def getdownFullArchiveAppBase = "${getdownArchiveAppBase}${getdownArchiveAppBase.endsWith("/")?"":"/"}${v}/getdown/"
+
+ // the libdir
+ copy {
+ from "${getdownAppBaseDir}/${getdownAppDistDir}"
+ into "${getdownFullArchiveDir}/${vAltDir}"
+ }
+
+ getdownTextLines.each { line ->
+ line = line.replaceAll("^(?<s>appbase\\s*=\\s*).*", '${s}'+getdownFullArchiveAppBase)
+ line = line.replaceAll("^(?<s>(resource|code)\\s*=\\s*)${getdownAppDistDir}/", '${s}'+vAltDir+"/")
+ line = line.replaceAll("^(?<s>ui.background_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background.png")
+ line = line.replaceAll("^(?<s>ui.instant_background_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background_initialising.png")
+ line = line.replaceAll("^(?<s>ui.error_background\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background_error.png")
+ line = line.replaceAll("^(?<s>ui.progress_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_progress_bar.png")
+ // remove the existing resource = resource/ or bin/ lines
+ if (! line.matches("resource\\s*=\\s*(resource|bin)/.*")) {
+ getdownArchiveTextLines += line
+ }
+ }
+
+ // the resource dir -- add these files as resource lines in getdown.txt
+ copy {
+ from "${archiveImagesDir}"
+ into "${getdownFullArchiveDir}/${getdown_resource_dir}"
+ eachFile { file ->
+ getdownArchiveTextLines += "resource = ${getdown_resource_dir}/${file.getName()}"
+ }
+ }
+
+ getdownArchiveTxt.write(getdownArchiveTextLines.join("\n"))
+
+ def vLaunchJvl = file(getdownVersionLaunchJvl)
+ vLaunchJvl.getParentFile().mkdirs()
+ vLaunchJvl.write("appbase=${getdownFullArchiveAppBase}\n")
+ def vLaunchJvlPath = vLaunchJvl.toPath().toAbsolutePath()
+ def jvlLinkPath = file("${vDir}/jalview.jvl").toPath().toAbsolutePath()
+ // for some reason filepath.relativize(fileInSameDirPath) gives a path to "../" which is wrong
+ //java.nio.file.Files.createSymbolicLink(jvlLinkPath, jvlLinkPath.relativize(vLaunchJvlPath));
+ java.nio.file.Files.createSymbolicLink(jvlLinkPath, java.nio.file.Paths.get(".",vLaunchJvl.getName()));
+
+ // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties
+ copy {
+ from getdownLauncher
+ from "${getdownAppBaseDir}/${getdownLaunchJvl}"
+ from "${getdownAppBaseDir}/${getdown_launcher_new}"
+ from "${getdownAppBaseDir}/${channel_props}"
+ if (file(getdownLauncher).getName() != getdown_launcher) {
+ rename(file(getdownLauncher).getName(), getdown_launcher)
+ }
+ into getdownFullArchiveDir
+ }
+
+ }
+}
+
+task getdownArchiveDigest(type: JavaExec) {
+ group = "distribution"
+ description = "Digest the getdown archive folder"
+
+ dependsOn getdownArchiveBuild
+
+ doFirst {
+ classpath = files(getdownLauncher)
+ args getdownFullArchiveDir
+ }
+ main = "com.threerings.getdown.tools.Digester"
+ inputs.dir(getdownFullArchiveDir)
+ outputs.file("${getdownFullArchiveDir}/digest2.txt")
+}
+
+task getdownArchive() {
+ group = "distribution"
+ description = "Build the website archive dir with getdown digest"
+
+ dependsOn getdownArchiveBuild
+ dependsOn getdownArchiveDigest
+}
+
+tasks.withType(JavaCompile) {
+ options.encoding = 'UTF-8'
+}
+
+
+clean {
+ doFirst {
+ delete getdownAppBaseDir
+ delete getdownFilesDir
+ delete getdownArchiveDir
+ }
+}
+
+
+install4j {
+ if (file(install4jHomeDir).exists()) {
+ // good to go!
+ } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
+ install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
+ } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
+ install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
+ }
+ installDir(file(install4jHomeDir))
+
+ mediaTypes = Arrays.asList(install4j_media_types.split(","))
+}
+
+
+task copyInstall4jTemplate {
+ def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
+ def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
+ inputs.file(install4jTemplateFile)
+ inputs.file(install4jFileAssociationsFile)
+ inputs.property("CHANNEL", { CHANNEL })
+ outputs.file(install4jConfFile)
+
+ doLast {
+ def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
+
+ // turn off code signing if no OSX_KEYPASS
+ if (OSX_KEYPASS == "") {
+ install4jConfigXml.'**'.codeSigning.each { codeSigning ->
+ codeSigning.'@macEnabled' = "false"
+ }
+ install4jConfigXml.'**'.windows.each { windows ->
+ windows.'@runPostProcessor' = "false"
+ }
+ }
+
+ // disable install screen for OSX dmg (for 2.11.2.0)
+ install4jConfigXml.'**'.macosArchive.each { macosArchive ->
+ macosArchive.attributes().remove('executeSetupApp')
+ macosArchive.attributes().remove('setupAppId')
+ }
+
+ // turn off checksum creation for LOCAL channel
+ def e = install4jConfigXml.application[0]
+ e.'@createChecksums' = string(install4jCheckSums)
+
+ // put file association actions where placeholder action is
+ def install4jFileAssociationsText = install4jFileAssociationsFile.text
+ def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
+ install4jConfigXml.'**'.action.any { a -> // .any{} stops after the first one that returns true
+ if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
+ 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
+ }
+ }
+
+ // use Windows Program Group with Examples folder for RELEASE, and Program Group without Examples for everything else
+ // NB we're deleting the /other/ one!
+ // Also remove the examples subdir from non-release versions
+ def customizedIdToDelete = "PROGRAM_GROUP_RELEASE"
+ // 2.11.1.0 NOT releasing with the Examples folder in the Program Group
+ if (false && CHANNEL=="RELEASE") { // remove 'false && ' to include Examples folder in RELEASE channel
+ customizedIdToDelete = "PROGRAM_GROUP_NON_RELEASE"
+ } else {
+ // remove the examples subdir from Full File Set
+ def files = install4jConfigXml.files[0]
+ def fileset = files.filesets.fileset.find { fs -> fs.'@customizedId' == "FULL_FILE_SET" }
+ def root = files.roots.root.find { r -> r.'@fileset' == fileset.'@id' }
+ def mountPoint = files.mountPoints.mountPoint.find { mp -> mp.'@root' == root.'@id' }
+ def dirEntry = files.entries.dirEntry.find { de -> de.'@mountPoint' == mountPoint.'@id' && de.'@subDirectory' == "examples" }
+ dirEntry.parent().remove(dirEntry)
+ }
+ install4jConfigXml.'**'.action.any { a ->
+ if (a.'@customizedId' == customizedIdToDelete) {
+ def parent = a.parent()
+ parent.remove(a)
+ return true
+ }
+ }
+
+ // write install4j file
+ install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
+ }
+}
+
+
+clean {
+ doFirst {
+ delete install4jConfFile
+ }
+}
+
+task cleanInstallersDataFiles {
+ def installersOutputTxt = file("${jalviewDir}/${install4jBuildDir}/output.txt")
+ def installersSha256 = file("${jalviewDir}/${install4jBuildDir}/sha256sums")
+ def hugoDataJsonFile = file("${jalviewDir}/${install4jBuildDir}/installers-${JALVIEW_VERSION_UNDERSCORES}.json")
+ doFirst {
+ delete installersOutputTxt
+ delete installersSha256
+ delete hugoDataJsonFile
+ }
+}
+
+task installerFiles(type: com.install4j.gradle.Install4jTask) {
+ group = "distribution"
+ description = "Create the install4j installers"
+ dependsOn getdown
+ dependsOn copyInstall4jTemplate
+ dependsOn cleanInstallersDataFiles
+
+ 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 +
+ file("${install4jDir}/${install4j_info_plist_file_associations}").text +
+ file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
+ def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
+ if (filesMd5.length() >= 8) {
+ filesMd5 = filesMd5.substring(0,8)
+ }
+ def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
+
+ variables = [
+ 'JALVIEW_NAME': jalview_name,
+ 'JALVIEW_APPLICATION_NAME': applicationName,
+ 'JALVIEW_DIR': "../..",
+ 'OSX_KEYSTORE': OSX_KEYSTORE,
+ 'OSX_APPLEID': OSX_APPLEID,
+ 'OSX_ALTOOLPASS': OSX_ALTOOLPASS,
+ '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,
+ 'JAVA_VERSION': JAVA_VERSION,
+ 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,