+
+
+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) {
+ from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
+ into "${jalviewDir}/${package_dir}"
+ preserve {
+ include jar.archiveName
+ }
+}
+
+
+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"
+ if (buildDist) {
+ dependsOn makeDist
+ }
+ from ("${jalviewDir}/${libDistDir}") {
+ include("*.jar")
+ }
+ manifest {
+ attributes 'Implementation-Version': JALVIEW_VERSION
+ }
+ 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 getdownTextString = ""
+ def getdownResourceDir = getdownResourceDir
+ def getdownResourceFilenames = []
+
+ doFirst {
+ // clean the getdown website and files dir before creating getdown folders
+ delete getdownWebsiteDir
+ delete getdownFilesDir
+
+ copy {
+ from buildProperties
+ rename(build_properties_file, getdown_build_properties)
+ into getdownAppDir
+ }
+ getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
+
+ // set some getdown_txt_ properties then go through all properties looking for getdown_txt_...
+ 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)
+ }
+
+ props.put("getdown_txt_title", jalview_name)
+ props.put("getdown_txt_ui.name", install4jApplicationName)
+
+ // start with appbase
+ getdownTextString += "appbase = ${getdownAppBase}\n"
+ 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}\n"
+ getdownTextString += 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}\n"
+ getdownTextString += line
+ }
+ }
+ }
+ }
+
+ getdownWebsiteResourceFilenames.each{ filename ->
+ getdownTextString += "resource = ${filename}\n"
+ }
+ getdownResourceFilenames.each{ filename ->
+ copy {
+ from filename
+ into getdownResourceDir
+ }
+ }
+
+ 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
+ }
+ }
+ codeFiles.sort().each{f ->
+ def name = f.getName()
+ def line = "code = ${getdownAppDistDir}/${name}\n"
+ getdownTextString += line
+ copy {
+ from f.getPath()
+ into getdownAppDir
+ }
+ }
+
+ fileTree(dir: digestonlyDir, include: ["*"]).getFiles().sort().each{f ->
+ def name = f.getName()
+ def line = "digestonly = ${getdownAppDistDir}/${name}\n"
+ getdownTextString += 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}\n"
+ getdownTextString += 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.
+ //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
+ getdownTextString += "resource = ${getdown_launcher_new}\n"
+ getdownTextString += "class = ${main_class}\n"
+ /* NOT setting these properties so that getdownappbase and getdowndistdir will default to release version
+ * getdownTextString += "jvmarg = -Dgetdowndistdir=${getdownAppDistDir}\n"
+ * getdownTextString += "jvmarg = -Dgetdownappbase=${getdownAppBase}\n"
+ */
+
+ def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
+ getdown_txt.write(getdownTextString)
+
+ def getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
+ def launchJvl = file("${getdownWebsiteDir}/${getdownLaunchJvl}")
+ launchJvl.write("appbase=${getdownAppBase}")
+
+ copy {
+ from getdownLauncher
+ rename(file(getdownLauncher).getName(), getdown_launcher_new)
+ into getdownWebsiteDir
+ }
+
+ copy {
+ from getdownLauncher
+ if (file(getdownLauncher).getName() != getdown_launcher) {
+ rename(file(getdownLauncher).getName(), getdown_launcher)
+ }
+ into getdownWebsiteDir
+ }
+
+ if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
+ copy {
+ from getdown_txt
+ from getdownLauncher
+ from "${getdownAppDir}/${getdown_build_properties}"
+ if (file(getdownLauncher).getName() != getdown_launcher) {
+ rename(file(getdownLauncher).getName(), getdown_launcher)
+ }
+ into getdownInstallDir
+ }
+
+ copy {
+ from getdownInstallDir
+ into getdownFilesInstallDir
+ }
+ }
+
+ copy {
+ from getdown_txt
+ from launchJvl
+ from getdownLauncher
+ from "${getdownWebsiteDir}/${getdown_build_properties}"
+ if (file(getdownLauncher).getName() != getdown_launcher) {
+ rename(file(getdownLauncher).getName(), getdown_launcher)
+ }
+ into getdownFilesDir
+ }
+
+ copy {
+ from getdownResourceDir
+ into "${getdownFilesDir}/${getdown_resource_dir}"
+ }
+ }
+
+ if (buildDist) {
+ inputs.dir("${jalviewDir}/${package_dir}")
+ }
+ outputs.dir(getdownWebsiteDir)
+ 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 getdownWebsiteDir
+ inputs.dir(getdownWebsiteDir)
+ outputs.file("${getdownWebsiteDir}/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 = getdownWebsiteDir + (getdownWebsiteDir.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
+ }
+ }
+ }
+ }
+}
+
+
+clean {
+ doFirst {
+ delete getdownWebsiteDir
+ delete getdownFilesDir
+ }
+}
+
+
+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"
+ }
+ }
+
+ // turn off checksum creation for LOCAL channel
+ def e = install4jConfigXml.application[0]
+ if (CHANNEL == "LOCAL") {
+ e.'@createChecksums' = "false"
+ } else {
+ e.'@createChecksums' = "true"
+ }
+
+ // put file association actions where placeholder action is
+ def install4jFileAssociationsText = install4jFileAssociationsFile.text
+ def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
+ install4jConfigXml.'**'.action.any { a -> // .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
+ }
+ }
+
+ // remove the "Uninstall Old Jalview (optional)" symlink from DMG for non-release DS_Stores
+ if (! (CHANNEL == "RELEASE" || CHANNEL == "TEST-RELEASE" ) ) {
+ def symlink = install4jConfigXml.'**'.topLevelFiles.symlink.find { sl -> sl.'@name' == "Uninstall Old Jalview (optional).app" }
+ symlink.parent().remove(symlink)
+ }
+
+ // write install4j file
+ install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
+ }
+}
+
+
+clean {
+ doFirst {
+ delete install4jConfFile
+ }
+}
+
+
+task installers(type: com.install4j.gradle.Install4jTask) {
+ group = "distribution"
+ description = "Create the install4j installers"
+ dependsOn setGitVals
+ dependsOn getdown
+ dependsOn copyInstall4jTemplate
+
+ 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}"
+ // make install4jBuildDir relative to jalviewDir
+ def install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
+
+ variables = [
+ 'JALVIEW_NAME': jalview_name,
+ 'JALVIEW_APPLICATION_NAME': install4jApplicationName,
+ 'JALVIEW_DIR': "../..",
+ 'OSX_KEYSTORE': OSX_KEYSTORE,
+ 'JSIGN_SH': JSIGN_SH,
+ 'JRE_DIR': getdown_app_dir_java,
+ 'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
+ 'JALVIEW_VERSION': JALVIEW_VERSION,
+ 'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
+ 'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
+ 'JAVA_VERSION': JAVA_VERSION,
+ 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
+ 'VERSION': JALVIEW_VERSION,
+ 'MACOS_JAVA_VM_DIR': macosJavaVMDir,
+ 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
+ 'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
+ 'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
+ 'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
+ 'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
+ 'COPYRIGHT_MESSAGE': install4j_copyright_message,
+ 'BUNDLE_ID': install4jBundleId,
+ 'INTERNAL_ID': install4jInternalId,
+ 'WINDOWS_APPLICATION_ID': install4jWinApplicationId,
+ 'MACOS_DS_STORE': install4jDSStore,
+ 'MACOS_DMG_BG_IMAGE': install4jDMGBackgroundImage,
+ 'INSTALLER_NAME': install4jInstallerName,
+ 'INSTALL4J_UTILS_DIR': install4j_utils_dir,
+ 'GETDOWN_WEBSITE_DIR': getdown_website_dir,
+ 'GETDOWN_FILES_DIR': getdown_files_dir,
+ 'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
+ 'GETDOWN_DIST_DIR': getdownAppDistDir,
+ 'GETDOWN_ALT_DIR': getdown_app_dir_alt,
+ 'GETDOWN_INSTALL_DIR': getdown_install_dir,
+ 'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
+ 'BUILD_DIR': install4jBuildDir,
+ 'APPLICATION_CATEGORIES': install4j_application_categories,
+ 'APPLICATION_FOLDER': install4jApplicationFolder,
+ 'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder,
+ 'EXECUTABLE_NAME': install4jExecutableName,
+ 'EXTRA_SCHEME': install4jExtraScheme,
+ ]
+
+ //println("INSTALL4J VARIABLES:")
+ //variables.each{k,v->println("${k}=${v}")}
+
+ destination = "${jalviewDir}/${install4jBuildDir}"
+ buildSelected = true
+
+ if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
+ faster = true
+ disableSigning = true
+ }
+
+ if (OSX_KEYPASS) {
+ macKeystorePassword = OSX_KEYPASS
+ }
+
+ doFirst {
+ println("Using projectFile "+projectFile)
+ }
+
+ inputs.dir(getdownWebsiteDir)
+ inputs.file(install4jConfFile)
+ inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
+ inputs.dir(macosJavaVMDir)
+ inputs.dir(windowsJavaVMDir)
+ outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
+}
+
+
+task sourceDist(type: Tar) {
+ dependsOn createBuildProperties
+
+ 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
+ }
+
+ compression Compression.GZIP
+
+ into project.name
+
+ def EXCLUDE_FILES=[
+ "build/*",
+ "bin/*",
+ "test-output/",
+ "test-reports",
+ "tests",
+ "clover*/*",
+ ".*",
+ "benchmarking/*",
+ "**/.*",
+ "*.class",
+ "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
+ "*locales/**",
+ "utils/InstallAnywhere",
+ "**/*.log",
+ ]
+ def PROCESS_FILES=[
+ "AUTHORS",
+ "CITATION",
+ "FEATURETODO",
+ "JAVA-11-README",
+ "FEATURETODO",
+ "LICENSE",
+ "**/README",
+ "RELEASE",
+ "THIRDPARTYLIBS",
+ "TESTNG",
+ "build.gradle",
+ "gradle.properties",
+ "**/*.java",
+ "**/*.html",
+ "**/*.xml",
+ "**/*.gradle",
+ "**/*.groovy",
+ "**/*.properties",
+ "**/*.perl",
+ "**/*.sh",
+ ]
+ def INCLUDE_FILES=[
+ ".settings/org.eclipse.jdt.core.jalview.prefs",
+ ]
+
+ from(jalviewDir) {
+ exclude (EXCLUDE_FILES)
+ include (PROCESS_FILES)
+ filter(ReplaceTokens,
+ beginToken: '$$',
+ endToken: '$$',
+ tokens: [
+ 'Version-Rel': JALVIEW_VERSION,
+ 'Year-Rel': getDate("yyyy")
+ ]
+ )
+ }
+ from(jalviewDir) {
+ exclude (EXCLUDE_FILES)
+ exclude (PROCESS_FILES)
+ exclude ("appletlib")
+ exclude ("**/*locales")
+ exclude ("*locales/**")
+ exclude ("utils/InstallAnywhere")
+
+ exclude (getdown_files_dir)
+ exclude (getdown_website_dir)
+
+ // exluding these as not using jars as modules yet
+ exclude ("$j11modDir/**/*.jar")
+ }
+ from(jalviewDir) {
+ include(INCLUDE_FILES)
+ }
+// from (jalviewDir) {
+// // explicit includes for stuff that seemed to not get included
+// include(fileTree("test/**/*."))
+// exclude(EXCLUDE_FILES)
+// exclude(PROCESS_FILES)
+// }
+
+ from(file(buildProperties).getParent()) {
+ include(file(buildProperties).getName())
+ rename(file(buildProperties).getName(), "build_properties")
+ filter({ line ->
+ line.replaceAll("^INSTALLATION=.*\$","INSTALLATION=Source Release"+" git-commit\\\\:"+gitHash+" ["+gitBranch+"]")
+ })
+ }
+
+}
+
+
+task helppages {
+ dependsOn copyHelp
+ dependsOn pubhtmlhelp
+
+ inputs.dir("${classesDir}/${help_dir}")
+ outputs.dir("${buildDir}/distributions/${help_dir}")
+}
+
+// LARGE AMOUNT OF JALVIEWJS STUFF DELETED HERE
+task eclipseAutoBuildTask {}
+task eclipseSynchronizationTask {}