*/
import org.apache.tools.ant.filters.ReplaceTokens
import org.gradle.internal.os.OperatingSystem
+import org.gradle.plugins.ide.internal.generator.PropertiesPersistableConfigurationObject
+import org.gradle.api.internal.PropertiesTransformer
+import org.gradle.util.ConfigureUtil
import org.gradle.plugins.ide.eclipse.model.Output
import org.gradle.plugins.ide.eclipse.model.Library
import java.security.MessageDigest
+import java.util.regex.Matcher
import groovy.transform.ExternalizeMethods
import groovy.util.XmlParser
import groovy.xml.XmlUtil
-
+import groovy.json.JsonBuilder
+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
+import com.google.common.hash.HashCode
+import com.google.common.hash.Hashing
+import com.google.common.io.Files
+import org.jsoup.Jsoup
+import org.jsoup.nodes.Element
buildscript {
repositories {
mavenCentral()
mavenLocal()
}
+ dependencies {
+ classpath "com.vladsch.flexmark:flexmark-all:0.62.0"
+ classpath "org.jsoup:jsoup:1.14.3"
+ classpath "com.eowise:gradle-imagemagick:0.5.1"
+ }
}
id 'java'
id 'application'
id 'eclipse'
+ id "com.diffplug.gradle.spotless" version "3.28.0"
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.install4j.gradle' version '10.0.3'
+ id 'com.dorongold.task-tree' version '2.1.1' // only needed to display task dependency tree with gradle task1 [task2 ...] taskTree
+ id 'com.palantir.git-version' version '0.13.0' apply false
}
repositories {
}
+
// in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use
def string(Object o) {
return o == null ? "" : o.toString()
}
-
-ext {
- jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
- jalviewDirRelativePath = jalviewDir
-
- // local build environment properties
- // can be "projectDir/local.properties"
- def localProps = "${projectDir}/local.properties"
- def propsFile = null;
- if (file(localProps).exists()) {
- propsFile = localProps
- }
- // or "../projectDir_local.properties"
- def dirLocalProps = projectDir.getParent() + "/" + projectDir.getName() + "_local.properties"
- if (file(dirLocalProps).exists()) {
- propsFile = dirLocalProps
+def overrideProperties(String propsFileName, boolean output = false) {
+ if (propsFileName == null) {
+ return
}
- if (propsFile != null) {
+ def propsFile = file(propsFileName)
+ if (propsFile != null && propsFile.exists()) {
+ println("Using properties from file '${propsFileName}'")
try {
def p = new Properties()
def localPropsFIS = new FileInputStream(propsFile)
localPropsFIS.close()
p.each {
key, val ->
- def oldval = findProperty(key)
- setProperty(key, val)
- if (oldval != null) {
- println("Overriding property '${key}' ('${oldval}') with ${file(propsFile).getName()} value '${val}'")
+ def oldval
+ if (project.hasProperty(key)) {
+ oldval = project.findProperty(key)
+ project.setProperty(key, val)
+ if (output) {
+ println("Overriding property '${key}' ('${oldval}') with ${file(propsFile).getName()} value '${val}'")
+ }
} else {
- println("Setting unknown property '${key}' with ${file(propsFile).getName()}s value '${val}'")
+ ext.setProperty(key, val)
+ if (output) {
+ println("Setting ext property '${key}' with ${file(propsFile).getName()}s value '${val}'")
+ }
}
}
} catch (Exception e) {
- System.out.println("Exception reading local.properties")
+ println("Exception reading local.properties")
+ e.printStackTrace()
}
}
+}
+
+ext {
+ jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
+ jalviewDirRelativePath = jalviewDir
+ date = new Date()
+
+ getdownChannelName = CHANNEL.toLowerCase()
+ // default to "default". Currently only has different cosmetics for "develop", "release", "default"
+ propertiesChannelName = ["develop", "release", "test-release", "jalviewjs", "jalviewjs-release" ].contains(getdownChannelName) ? getdownChannelName : "default"
+ channelDirName = propertiesChannelName
+ // Import channel_properties
+ if (getdownChannelName.startsWith("develop-")) {
+ channelDirName = "develop-SUFFIX"
+ }
+ channelDir = string("${jalviewDir}/${channel_properties_dir}/${channelDirName}")
+ channelGradleProperties = string("${channelDir}/channel_gradle.properties")
+ channelPropsFile = string("${channelDir}/${resource_dir}/${channel_props}")
+ overrideProperties(channelGradleProperties, false)
+ // local build environment properties
+ // can be "projectDir/local.properties"
+ overrideProperties("${projectDir}/local.properties", true)
+ // or "../projectDir_local.properties"
+ overrideProperties(projectDir.getParent() + "/" + projectDir.getName() + "_local.properties", true)
////
// Import releaseProps from the RELEASE file
// or a file specified via JALVIEW_RELEASE_FILE if defined
// Expect jalview.version and target release branch in jalview.release
- def releaseProps = new Properties();
+ releaseProps = new Properties();
def releasePropFile = findProperty("JALVIEW_RELEASE_FILE");
def defaultReleasePropFile = "${jalviewDirAbsolutePath}/RELEASE";
try {
if (findProperty("JALVIEW_VERSION")==null || "".equals(JALVIEW_VERSION)) {
JALVIEW_VERSION = releaseProps.get("jalview.version")
}
+ println("JALVIEW_VERSION is set to '${JALVIEW_VERSION}'")
// this property set when running Eclipse headlessly
j2sHeadlessBuildProperty = string("net.sf.j2s.core.headlessbuild")
} else {
println("HEADLESS BUILD")
}
+
+ J2S_ENABLED = (project.hasProperty('j2s.compiler.status') && project['j2s.compiler.status'] != null && project['j2s.compiler.status'] == "enable")
+ if (J2S_ENABLED) {
+ println("J2S ENABLED")
+ }
/* *-/
System.properties.sort { it.key }.each {
key, val -> println("SYSTEM PROPERTY ${key}='${val}'")
}
*/
+ // datestamp
+ buildDate = new Date().format("yyyyMMdd")
+
// essentials
bareSourceDir = string(source_dir)
sourceDir = string("${jalviewDir}/${bareSourceDir}")
//cloverTestClassesDir = cloverClassesDir
cloverDb = string("${cloverBuildDir}/clover.db")
- resourceClassesDir = useClover ? cloverClassesDir : classesDir
-
testSourceDir = useClover ? cloverTestInstrDir : testDir
testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}"
- getdownWebsiteDir = string("${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}")
+ channelSuffix = ""
+ backgroundImageText = BACKGROUNDIMAGETEXT
+ getdownChannelDir = string("${getdown_website_dir}/${propertiesChannelName}")
+ getdownAppBaseDir = string("${jalviewDir}/${getdownChannelDir}/${JAVA_VERSION}")
+ getdownArchiveDir = string("${jalviewDir}/${getdown_archive_dir}")
+ getdownFullArchiveDir = null
+ getdownTextLines = []
+ getdownLaunchJvl = null
+ getdownVersionLaunchJvl = null
buildDist = true
+ buildProperties = null
// the following values might be overridden by the CHANNEL switch
- getdownChannelName = CHANNEL.toLowerCase()
getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
+ getdownArchiveAppBase = getdown_archive_base
getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
getdownAppDistDir = getdown_app_dir_alt
- buildProperties = string("${classesDir}/${build_properties_file}")
+ getdownImagesDir = string("${jalviewDir}/${getdown_images_dir}")
+ getdownImagesBuildDir = string("${buildDir}/imagemagick/getdown")
+ getdownSetAppBaseProperty = false // whether to pass the appbase and appdistdir to the application
reportRsyncCommand = false
jvlChannelName = CHANNEL.toLowerCase()
install4jSuffix = CHANNEL.substring(0, 1).toUpperCase() + CHANNEL.substring(1).toLowerCase(); // BUILD -> Build
- install4jDSStore = "DS_Store-NON-RELEASE"
- install4jDMGBackgroundImage = "jalview_dmg_background-NON-RELEASE.png"
+ install4jDMGDSStore = "${install4j_images_dir}/${install4j_dmg_ds_store}"
+ install4jDMGBackgroundImageDir = "${install4j_images_dir}"
+ install4jDMGBackgroundImageBuildDir = "build/imagemagick/install4j"
+ install4jDMGBackgroundImageFile = "${install4j_dmg_background}"
install4jInstallerName = "${jalview_name} Non-Release Installer"
- install4jExecutableName = jalview_name.replaceAll("[^\\w]+", "_").toLowerCase()
+ install4jExecutableName = install4j_executable_name
install4jExtraScheme = "jalviewx"
+ install4jMacIconsFile = string("${install4j_images_dir}/${install4j_mac_icons_file}")
+ install4jWindowsIconsFile = string("${install4j_images_dir}/${install4j_windows_icons_file}")
+ install4jPngIconFile = string("${install4j_images_dir}/${install4j_png_icon_file}")
+ install4jBackground = string("${install4j_images_dir}/${install4j_background}")
+ install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
+ install4jCheckSums = true
+
+ applicationName = "${jalview_name}"
switch (CHANNEL) {
case "BUILD":
testng_excluded_groups = "Not-bamboo"
}
install4jExtraScheme = "jalviewb"
+ backgroundImageText = true
break
- case "RELEASE":
+ case [ "RELEASE", "JALVIEWJS-RELEASE" ]:
getdownAppDistDir = getdown_app_dir_release
+ getdownSetAppBaseProperty = true
reportRsyncCommand = true
install4jSuffix = ""
- install4jDSStore = "DS_Store"
- install4jDMGBackgroundImage = "jalview_dmg_background.png"
install4jInstallerName = "${jalview_name} Installer"
break
case "ARCHIVELOCAL":
getdownChannelName = string("archive/${JALVIEW_VERSION}")
getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
- getdownAppBase = file(getdownWebsiteDir).toURI().toString()
+ getdownAppBase = file(getdownAppBaseDir).toURI().toString()
if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
- throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
+ throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution [did not find '${ARCHIVEDIR}/${package_dir}']")
} else {
package_dir = string("${ARCHIVEDIR}/${package_dir}")
buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
install4jExtraScheme = "jalviewa"
break
+ case ~/^DEVELOP-([\.\-\w]*)$/:
+ def suffix = Matcher.lastMatcher[0][1]
+ reportRsyncCommand = true
+ getdownSetAppBaseProperty = true
+ JALVIEW_VERSION=JALVIEW_VERSION+"-d${suffix}-${buildDate}"
+ install4jSuffix = "Develop ${suffix}"
+ install4jExtraScheme = "jalviewd"
+ install4jInstallerName = "${jalview_name} Develop ${suffix} Installer"
+ getdownChannelName = string("develop-${suffix}")
+ getdownChannelDir = string("${getdown_website_dir}/${getdownChannelName}")
+ getdownAppBaseDir = string("${jalviewDir}/${getdownChannelDir}/${JAVA_VERSION}")
+ getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
+ getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
+ channelSuffix = string(suffix)
+ backgroundImageText = true
+ break
+
case "DEVELOP":
reportRsyncCommand = true
-
+ getdownSetAppBaseProperty = true
// DEVELOP-RELEASE is usually associated with a Jalview release series so set the version
- JALVIEW_VERSION=JALVIEW_VERSION+"-develop"
+ JALVIEW_VERSION=JALVIEW_VERSION+"-d${buildDate}"
install4jSuffix = "Develop"
- install4jDSStore = "DS_Store-DEVELOP"
- install4jDMGBackgroundImage = "jalview_dmg_background-DEVELOP.png"
install4jExtraScheme = "jalviewd"
install4jInstallerName = "${jalview_name} Develop Installer"
+ backgroundImageText = true
break
case "TEST-RELEASE":
reportRsyncCommand = true
-
- // TEST-RELEASE is usually associated with a Jalview release series so set the version
- JALVIEW_VERSION=JALVIEW_VERSION+"-test"
-
+ getdownSetAppBaseProperty = true
+ // Don't ignore transpile errors for release build
+ if (jalviewjs_ignore_transpile_errors.equals("true")) {
+ jalviewjs_ignore_transpile_errors = "false"
+ println("Setting jalviewjs_ignore_transpile_errors to 'false'")
+ }
+ JALVIEW_VERSION = JALVIEW_VERSION+"-test"
install4jSuffix = "Test"
- install4jDSStore = "DS_Store-TEST-RELEASE"
- install4jDMGBackgroundImage = "jalview_dmg_background-TEST.png"
install4jExtraScheme = "jalviewt"
install4jInstallerName = "${jalview_name} Test Installer"
+ backgroundImageText = true
break
case ~/^SCRATCH(|-[-\w]*)$/:
getdownChannelName = CHANNEL
+ JALVIEW_VERSION = JALVIEW_VERSION+"-"+CHANNEL
+
getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
reportRsyncCommand = true
}
JALVIEW_VERSION = "TEST"
install4jSuffix = "Test-Local"
- install4jDSStore = "DS_Store-TEST-RELEASE"
- install4jDMGBackgroundImage = "jalview_dmg_background-TEST.png"
install4jExtraScheme = "jalviewt"
install4jInstallerName = "${jalview_name} Test Installer"
+ backgroundImageText = true
break
- case "LOCAL":
- getdownAppBase = file(getdownWebsiteDir).toURI().toString()
+ case [ "LOCAL", "JALVIEWJS" ]:
+ JALVIEW_VERSION = "TEST"
+ getdownAppBase = file(getdownAppBaseDir).toURI().toString()
+ getdownArchiveAppBase = file("${jalviewDir}/${getdown_archive_dir}").toURI().toString()
getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
install4jExtraScheme = "jalviewl"
+ install4jCheckSums = false
break
default: // something wrong specified
break
}
+ JALVIEW_VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
+ hugoDataJsonFile = file("${jalviewDir}/${hugo_build_dir}/${hugo_data_installers_dir}/installers-${JALVIEW_VERSION_UNDERSCORES}.json")
+ hugoArchiveMdFile = file("${jalviewDir}/${hugo_build_dir}/${hugo_version_archive_dir}/Version-${JALVIEW_VERSION_UNDERSCORES}/_index.md")
// override getdownAppBase if requested
if (findProperty("getdown_appbase_override") != null) {
- getdownAppBase = string(getProperty("getdown_appbase_override"))
+ // revert to LOCAL if empty string
+ if (string(getdown_appbase_override) == "") {
+ getdownAppBase = file(getdownAppBaseDir).toURI().toString()
+ getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
+ } else if (string(getdown_appbase_override).startsWith("file://")) {
+ getdownAppBase = string(getdown_appbase_override)
+ getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
+ } else {
+ getdownAppBase = string(getdown_appbase_override)
+ }
println("Overriding getdown appbase with '${getdownAppBase}'")
}
// sanitise file name for jalview launcher file for this channel
jvlChannelName = jvlChannelName.replaceAll("[^\\w\\-]+", "_")
// install4j application and folder names
if (install4jSuffix == "") {
- install4jApplicationName = "${jalview_name}"
install4jBundleId = "${install4j_bundle_id}"
install4jWinApplicationId = install4j_release_win_application_id
} else {
- install4jApplicationName = "${jalview_name} ${install4jSuffix}"
+ applicationName = "${jalview_name} ${install4jSuffix}"
install4jBundleId = "${install4j_bundle_id}-" + install4jSuffix.toLowerCase()
// add int hash of install4jSuffix to the last part of the application_id
def id = install4j_release_win_application_id
}
// sanitise folder and id names
// install4jApplicationFolder = e.g. "Jalview Build"
- install4jApplicationFolder = install4jApplicationName
+ install4jApplicationFolder = applicationName
.replaceAll("[\"'~:/\\\\\\s]", "_") // replace all awkward filename chars " ' ~ : / \
.replaceAll("_+", "_") // collapse __
- install4jInternalId = install4jApplicationName
+ install4jInternalId = applicationName
.replaceAll(" ","_")
.replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
.replaceAll("_+", "") // collapse __
//.replaceAll("_*-_*", "-") // collapse _-_
- install4jUnixApplicationFolder = install4jApplicationName
+ install4jUnixApplicationFolder = applicationName
.replaceAll(" ","_")
.replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
.replaceAll("_+", "_") // collapse __
.replaceAll("_*-_*", "-") // collapse _-_
.toLowerCase()
- getdownAppDir = string("${getdownWebsiteDir}/${getdownAppDistDir}")
- //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}"
- getdownResourceDir = string("${getdownWebsiteDir}/${getdown_resource_dir}")
- getdownInstallDir = string("${getdownWebsiteDir}/${getdown_install_dir}")
+ getdownWrapperLink = install4jUnixApplicationFolder // e.g. "jalview_local"
+ getdownAppDir = string("${getdownAppBaseDir}/${getdownAppDistDir}")
+ //getdownJ11libDir = "${getdownAppBaseDir}/${getdown_j11lib_dir}"
+ getdownResourceDir = string("${getdownAppBaseDir}/${getdown_resource_dir}")
+ getdownInstallDir = string("${getdownAppBaseDir}/${getdown_install_dir}")
getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
/* compile without modules -- using classpath libraries
modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
modules_runtimeClasspath = modules_compileClasspath
*/
- gitHash = string("")
- gitBranch = string("")
+
+ gitHash = "SOURCE"
+ gitBranch = "Source"
+ try {
+ apply plugin: "com.palantir.git-version"
+ def details = versionDetails()
+ gitHash = details.gitHash
+ gitBranch = details.branchName
+ } catch(org.gradle.api.internal.plugins.PluginApplicationException e) {
+ println("Not in a git repository. Using git values from RELEASE properties file.")
+ gitHash = releaseProps.getProperty("git.hash")
+ gitBranch = releaseProps.getProperty("git.branch")
+ } catch(java.lang.RuntimeException e1) {
+ throw new GradleException("Error with git-version plugin. Directory '.git' exists but versionDetails() cannot be found.")
+ }
println("Using a ${CHANNEL} profile.")
//libDir = j8libDir
libDir = j11libDir
libDistDir = j8libDir
- digestonlyDir = j8digestonlyDir
compile_source_compatibility = 1.8
compile_target_compatibility = 1.8
// these are getdown.txt properties defined dependent on the JAVA_VERSION
JAVA_INTEGER_VERSION = string("11")
libDir = j11libDir
libDistDir = j11libDir
- digestonlyDir = j11digestonlyDir
compile_source_compatibility = 11
compile_target_compatibility = 11
getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
'--add-modules', j11modules
]
*/
- } else if (JAVA_VERSION.equals("12") || JAVA_VERSION.equals("13")) {
- JAVA_INTEGER_VERSION = JAVA_VERSION
- libDir = j11libDir
- libDistDir = j11libDir
- compile_source_compatibility = JAVA_VERSION
- compile_target_compatibility = JAVA_VERSION
+ } else if (JAVA_VERSION.equals("17")) {
+ JAVA_INTEGER_VERSION = string("17")
+ libDir = j17libDir
+ libDistDir = j17libDir
+ compile_source_compatibility = 17
+ compile_target_compatibility = 17
getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
- eclipseJavaRuntimeName = string("JavaSE-11")
+ eclipseJavaRuntimeName = string("JavaSE-17")
/* compile without modules -- using classpath libraries
additional_compiler_args += [
'--module-path', modules_compileClasspath.asPath,
// for install4j
JAVA_MIN_VERSION = JAVA_VERSION
JAVA_MAX_VERSION = JAVA_VERSION
- def jreInstallsDir = string(jre_installs_dir)
+ jreInstallsDir = string(jre_installs_dir)
if (jreInstallsDir.startsWith("~/")) {
jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1)
}
- macosJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-mac-x64/jre")
- macosJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-mac-x64.tar.gz")
- windowsJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-windows-x64/jre")
- windowsJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-windows-x64.tar.gz")
- linuxJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-linux-x64/jre")
- linuxJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-linux-x64.tar.gz")
install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
install4jConfFileName = string("jalview-install4j-conf.install4j")
install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
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")
-
+ if (buildProperties == null) {
+ 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")
+ convertBinary = null
+ convertBinaryExpectedLocation = imagemagick_convert
+ if (convertBinaryExpectedLocation.startsWith("~/")) {
+ convertBinaryExpectedLocation = System.getProperty("user.home") + convertBinaryExpectedLocation.substring(1)
+ }
+ if (file(convertBinaryExpectedLocation).exists()) {
+ convertBinary = convertBinaryExpectedLocation
+ }
relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
jalviewjsCoreClasslists = []
jalviewjsJalviewTemplateName = string(jalviewjs_name)
jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
+ jalviewjsJ2sAltSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_alt_settings}")
jalviewjsJ2sProps = null
+ jalviewjsJ2sPlugin = jalviewjs_j2s_plugin
+ jalviewjsStderrLaunchFilename = "${jalviewjsSiteDir}/"+(file(jalviewjs_stderr_launch).getName())
eclipseWorkspace = null
eclipseBinary = string("")
eclipseVersion = string("")
eclipseDebug = false
+
// ENDEXT
}
}
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 {
compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
runtimeClasspath = compileClasspath
+ runtimeClasspath += files(sourceSets.test.resources.srcDirs)
}
}
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 {
props.putAt(t, v)
}
}
+ // codestyle file -- overrides previous formatter prefs
+ def csFile = file("${jalviewDirAbsolutePath}/${eclipse_codestyle_file}")
+ if (csFile.exists()) {
+ XmlParser parser = new XmlParser()
+ def profiles = parser.parse(csFile)
+ def profile = profiles.'profile'.find { p -> (p.'@kind' == "CodeFormatterProfile" && p.'@name' == "Jalview") }
+ if (profile != null) {
+ profile.'setting'.each { s ->
+ def id = s.'@id'
+ def value = s.'@value'
+ if (id != null && value != null) {
+ props.putAt(id, value)
+ }
+ }
+ }
+ }
}
}
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 */
+
// clover bits
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 {
+ 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")
}
}
// format is a string like date.format("dd MMMM yyyy")
def getDate(format) {
- def date = new Date()
return date.format(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 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()
+ }
- def branchStdOut = new ByteArrayOutputStream()
- exec {
- commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
- standardOutput = branchStdOut
- ignoreExitValue true
+ 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
}
+}
+
- gitHash = hashStdOut.toString().trim()
- gitBranch = branchStdOut.toString().trim()
+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
- outputs.upToDateWhen { false }
+ inputs.dir(inputDir)
+ outputs.dir(outputDir)
}
-task createBuildProperties(type: WriteProperties) {
- 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}")
+
+ 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 hugoTemplateSubstitutions(String input, Map extras=null) {
+ def replacements = [
+ DATE: getDate("yyyy-MM-dd"),
+ CHANNEL: propertiesChannelName,
+ APPLICATION_NAME: applicationName,
+ GIT_HASH: gitHash,
+ GIT_BRANCH: gitBranch,
+ VERSION: JALVIEW_VERSION,
+ JAVA_VERSION: JAVA_VERSION,
+ VERSION_UNDERSCORES: JALVIEW_VERSION_UNDERSCORES,
+ DRAFT: "false",
+ JVL_HEADER: ""
+ ]
+ def output = input
+ if (extras != null) {
+ extras.each{ k, v ->
+ output = output.replaceAll("__${k}__", ((v == null)?"":v))
}
}
+ replacements.each{ k, v ->
+ output = output.replaceAll("__${k}__", ((v == null)?"":v))
+ }
+ return output
+}
- def hostname = "hostname".execute().text.trim()
- 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"
+def mdFileComponents(File mdFile, def dateOnly=false) {
+ def map = [:]
+ def content = ""
+ if (mdFile.exists()) {
+ def inFrontMatter = false
+ def firstLine = true
+ mdFile.eachLine { line ->
+ if (line.matches("---")) {
+ def prev = inFrontMatter
+ inFrontMatter = firstLine
+ if (inFrontMatter != prev)
+ return false
+ }
+ if (inFrontMatter) {
+ def m = null
+ if (m = line =~ /^date:\s*(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/) {
+ map["date"] = new Date().parse("yyyy-MM-dd HH:mm:ss", m[0][1])
+ } else if (m = line =~ /^date:\s*(\d{4}-\d{2}-\d{2})/) {
+ map["date"] = new Date().parse("yyyy-MM-dd", m[0][1])
+ } else if (m = line =~ /^channel:\s*(\S+)/) {
+ map["channel"] = m[0][1]
+ } else if (m = line =~ /^version:\s*(\S+)/) {
+ map["version"] = m[0][1]
+ } else if (m = line =~ /^\s*([^:]+)\s*:\s*(\S.*)/) {
+ map[ m[0][1] ] = m[0][2]
+ }
+ if (dateOnly && map["date"] != null) {
+ return false
+ }
+ } else {
+ if (dateOnly)
+ return false
+ content += line+"\n"
+ }
+ firstLine = false
+ }
}
+ return dateOnly ? map["date"] : [map, content]
+}
+
+task hugoTemplates {
+ group "website"
+ description "Create partially populated md pages for hugo website build"
+
+ def hugoTemplatesDir = file("${jalviewDir}/${hugo_templates_dir}")
+ def hugoBuildDir = "${jalviewDir}/${hugo_build_dir}"
+ def templateFiles = fileTree(dir: hugoTemplatesDir)
+ def releaseMdFile = file("${jalviewDir}/${releases_dir}/release-${JALVIEW_VERSION_UNDERSCORES}.md")
+ def whatsnewMdFile = file("${jalviewDir}/${whatsnew_dir}/whatsnew-${JALVIEW_VERSION_UNDERSCORES}.md")
+ def oldJvlFile = file("${jalviewDir}/${hugo_old_jvl}")
+ def jalviewjsFile = file("${jalviewDir}/${hugo_jalviewjs}")
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")
+ // specific release template for version archive
+ def changes = ""
+ def whatsnew = null
+ def givenDate = null
+ def givenChannel = null
+ def givenVersion = null
+ if (CHANNEL == "RELEASE") {
+ def (map, content) = mdFileComponents(releaseMdFile)
+ givenDate = map.date
+ givenChannel = map.channel
+ givenVersion = map.version
+ changes = content
+ if (givenVersion != null && givenVersion != JALVIEW_VERSION) {
+ throw new GradleException("'version' header (${givenVersion}) found in ${releaseMdFile} does not match JALVIEW_VERSION (${JALVIEW_VERSION})")
+ }
+
+ if (whatsnewMdFile.exists())
+ whatsnew = whatsnewMdFile.text
+ }
+
+ def oldJvl = oldJvlFile.exists() ? oldJvlFile.collect{it} : []
+ def jalviewjsLink = jalviewjsFile.exists() ? jalviewjsFile.collect{it} : []
+
+ def changesHugo = null
+ if (changes != null) {
+ changesHugo = '<div class="release_notes">\n\n'
+ def inSection = false
+ changes.eachLine { line ->
+ def m = null
+ if (m = line =~ /^##([^#].*)$/) {
+ if (inSection) {
+ changesHugo += "</div>\n\n"
+ }
+ def section = m[0][1].trim()
+ section = section.toLowerCase()
+ section = section.replaceAll(/ +/, "_")
+ section = section.replaceAll(/[^a-z0-9_\-]/, "")
+ changesHugo += "<div class=\"${section}\">\n\n"
+ inSection = true
+ } else if (m = line =~ /^(\s*-\s*)<!--([^>]+)-->(.*?)(<br\/?>)?\s*$/) {
+ def comment = m[0][2].trim()
+ if (comment != "") {
+ comment = comment.replaceAll('"', """)
+ def issuekeys = []
+ comment.eachMatch(/JAL-\d+/) { jal -> issuekeys += jal }
+ def newline = m[0][1]
+ if (comment.trim() != "")
+ newline += "{{<comment>}}${comment}{{</comment>}} "
+ newline += m[0][3].trim()
+ if (issuekeys.size() > 0)
+ newline += " {{< jal issue=\"${issuekeys.join(",")}\" alt=\"${comment}\" >}}"
+ if (m[0][4] != null)
+ newline += m[0][4]
+ line = newline
+ }
+ }
+ changesHugo += line+"\n"
+ }
+ if (inSection) {
+ changesHugo += "\n</div>\n\n"
+ }
+ changesHugo += '</div>'
}
- }
- ignoreExitValue true
+ templateFiles.each{ templateFile ->
+ def newFileName = string(hugoTemplateSubstitutions(templateFile.getName()))
+ def relPath = hugoTemplatesDir.toPath().relativize(templateFile.toPath()).getParent()
+ def newRelPathName = hugoTemplateSubstitutions( relPath.toString() )
- inputs.file(buildingMD)
- inputs.file(css)
- outputs.file(buildingHTML)
-}
+ def outPathName = string("${hugoBuildDir}/$newRelPathName")
+
+ copy {
+ from templateFile
+ rename(templateFile.getName(), newFileName)
+ into outPathName
+ }
+ def newFile = file("${outPathName}/${newFileName}".toString())
+ def content = newFile.text
+ newFile.text = hugoTemplateSubstitutions(content,
+ [
+ WHATSNEW: whatsnew,
+ CHANGES: changesHugo,
+ DATE: givenDate == null ? "" : givenDate.format("yyyy-MM-dd"),
+ DRAFT: givenDate == null ? "true" : "false",
+ JALVIEWJSLINK: jalviewjsLink.contains(JALVIEW_VERSION) ? "true" : "false",
+ JVL_HEADER: oldJvl.contains(JALVIEW_VERSION) ? "jvl: true" : ""
+ ]
+ )
+ }
-clean {
- doFirst {
- delete buildingHTML
}
-}
+ inputs.file(oldJvlFile)
+ inputs.dir(hugoTemplatesDir)
+ inputs.property("JALVIEW_VERSION", { JALVIEW_VERSION })
+ inputs.property("CHANNEL", { CHANNEL })
+}
-task syncDocs(type: Sync) {
- dependsOn convertBuildingMD
- def syncDir = "${resourceClassesDir}/${doc_dir}"
- from fileTree("${jalviewDir}/${doc_dir}")
- into syncDir
+def getMdDate(File mdFile) {
+ return mdFileComponents(mdFile, true)
+}
+def getMdSections(String content) {
+ def sections = [:]
+ def sectionContent = ""
+ def sectionName = null
+ content.eachLine { line ->
+ def m = null
+ if (m = line =~ /^##([^#].*)$/) {
+ if (sectionName != null) {
+ sections[sectionName] = sectionContent
+ sectionName = null
+ sectionContent = ""
+ }
+ sectionName = m[0][1].trim()
+ sectionName = sectionName.toLowerCase()
+ sectionName = sectionName.replaceAll(/ +/, "_")
+ sectionName = sectionName.replaceAll(/[^a-z0-9_\-]/, "")
+ } else if (sectionName != null) {
+ sectionContent += line+"\n"
+ }
+ }
+ if (sectionContent != null) {
+ sections[sectionName] = sectionContent
+ }
+ return sections
}
task copyHelp(type: Copy) {
def inputDir = helpSourceDir
- def outputDir = "${resourceClassesDir}/${help_dir}"
+ def outputDir = "${helpBuildDir}/${help_dir}"
from(inputDir) {
- exclude '**/*.gif'
- exclude '**/*.jpg'
- exclude '**/*.png'
+ include('**/*.txt')
+ include('**/*.md')
+ include('**/*.html')
+ include('**/*.hs')
+ include('**/*.xml')
+ include('**/*.jhm')
filter(ReplaceTokens,
beginToken: '$$',
endToken: '$$',
)
}
from(inputDir) {
- include '**/*.gif'
- include '**/*.jpg'
- include '**/*.png'
+ exclude('**/*.txt')
+ exclude('**/*.md')
+ exclude('**/*.html')
+ exclude('**/*.hs')
+ exclude('**/*.xml')
+ exclude('**/*.jhm')
}
into outputDir
}
-task syncLib(type: Sync) {
- def syncDir = "${resourceClassesDir}/${libDistDir}"
- from fileTree("${jalviewDir}/${libDistDir}")
- into syncDir
-}
+task releasesTemplates {
+ group "help"
+ description "Recreate whatsNew.html and releases.html from markdown files and templates in help"
+ dependsOn copyHelp
-task syncResources(type: Sync) {
- from resourceDir
- include "**/*.*"
- into "${resourceClassesDir}"
- preserve {
- include "**"
- }
-}
+ def releasesTemplateFile = file("${jalviewDir}/${releases_template}")
+ def whatsnewTemplateFile = file("${jalviewDir}/${whatsnew_template}")
+ def releasesHtmlFile = file("${helpBuildDir}/${help_dir}/${releases_html}")
+ def whatsnewHtmlFile = file("${helpBuildDir}/${help_dir}/${whatsnew_html}")
+ def releasesMdDir = "${jalviewDir}/${releases_dir}"
+ def whatsnewMdDir = "${jalviewDir}/${whatsnew_dir}"
+ doFirst {
+ def releaseMdFile = file("${releasesMdDir}/release-${JALVIEW_VERSION_UNDERSCORES}.md")
+ def whatsnewMdFile = file("${whatsnewMdDir}/whatsnew-${JALVIEW_VERSION_UNDERSCORES}.md")
-task prepare {
- dependsOn syncResources
- dependsOn syncDocs
- dependsOn copyHelp
-}
+ if (CHANNEL == "RELEASE") {
+ if (!releaseMdFile.exists()) {
+ throw new GradleException("File ${releaseMdFile} must be created for RELEASE")
+ }
+ if (!whatsnewMdFile.exists()) {
+ throw new GradleException("File ${whatsnewMdFile} must be created for RELEASE")
+ }
+ }
+ def releaseFiles = fileTree(dir: releasesMdDir, include: "release-*.md")
+ def releaseFilesDates = releaseFiles.collectEntries {
+ [(it): getMdDate(it)]
+ }
+ releaseFiles = releaseFiles.sort { a,b -> releaseFilesDates[a].compareTo(releaseFilesDates[b]) }
-//testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
-test {
- dependsOn prepare
- //dependsOn compileJava ////? DELETE
+ def releasesTemplate = releasesTemplateFile.text
+ def m = releasesTemplate =~ /(?s)__VERSION_LOOP_START__(.*)__VERSION_LOOP_END__/
+ def versionTemplate = m[0][1]
- if (useClover) {
- dependsOn cloverClasses
- } else { //?
- dependsOn compileJava //?
- }
+ MutableDataSet options = new MutableDataSet()
- useTestNG() {
- includeGroups testng_groups
- excludeGroups testng_excluded_groups
- preserveOrder true
- useDefaultListeners=true
- }
+ def extensions = new ArrayList<>()
+ options.set(Parser.EXTENSIONS, extensions)
+ options.set(Parser.HTML_BLOCK_COMMENT_ONLY_FULL_LINE, true)
- maxHeapSize = "1024m"
+ Parser parser = Parser.builder(options).build()
+ HtmlRenderer renderer = HtmlRenderer.builder(options).build()
- 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
+ def actualVersions = releaseFiles.collect { rf ->
+ def (rfMap, rfContent) = mdFileComponents(rf)
+ return rfMap.version
+ }
+ def versionsHtml = ""
+ def linkedVersions = []
+ releaseFiles.reverse().each { rFile ->
+ def (rMap, rContent) = mdFileComponents(rFile)
+
+ def versionLink = ""
+ def partialVersion = ""
+ def firstPart = true
+ rMap.version.split("\\.").each { part ->
+ def displayPart = ( firstPart ? "" : "." ) + part
+ partialVersion += displayPart
+ if (
+ linkedVersions.contains(partialVersion)
+ || ( actualVersions.contains(partialVersion) && partialVersion != rMap.version )
+ ) {
+ versionLink += displayPart
+ } else {
+ versionLink += "<a id=\"Jalview.${partialVersion}\">${displayPart}</a>"
+ linkedVersions += partialVersion
+ }
+ firstPart = false
+ }
+ def displayDate = releaseFilesDates[rFile].format("dd/MM/yyyy")
+
+ def lm = null
+ def rContentProcessed = ""
+ rContent.eachLine { line ->
+ if (lm = line =~ /^(\s*-)(\s*<!--[^>]*?-->)(.*)$/) {
+ line = "${lm[0][1]}${lm[0][3]}${lm[0][2]}"
+ } else if (lm = line =~ /^###([^#]+.*)$/) {
+ line = "_${lm[0][1].trim()}_"
+ }
+ rContentProcessed += line + "\n"
+ }
- doFirst {
- if (useClover) {
- println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
+ def rContentSections = getMdSections(rContentProcessed)
+ def rVersion = versionTemplate
+ if (rVersion != "") {
+ def rNewFeatures = rContentSections["new_features"]
+ def rIssuesResolved = rContentSections["issues_resolved"]
+ Node newFeaturesNode = parser.parse(rNewFeatures)
+ String newFeaturesHtml = renderer.render(newFeaturesNode)
+ Node issuesResolvedNode = parser.parse(rIssuesResolved)
+ String issuesResolvedHtml = renderer.render(issuesResolvedNode)
+ rVersion = hugoTemplateSubstitutions(rVersion,
+ [
+ VERSION: rMap.version,
+ VERSION_LINK: versionLink,
+ DISPLAY_DATE: displayDate,
+ NEW_FEATURES: newFeaturesHtml,
+ ISSUES_RESOLVED: issuesResolvedHtml
+ ]
+ )
+ versionsHtml += rVersion
+ }
}
- }
-}
+ releasesTemplate = releasesTemplate.replaceAll("(?s)__VERSION_LOOP_START__.*__VERSION_LOOP_END__", versionsHtml)
+ releasesTemplate = hugoTemplateSubstitutions(releasesTemplate)
+ releasesHtmlFile.text = releasesTemplate
+
+ if (whatsnewMdFile.exists()) {
+ def wnDisplayDate = releaseFilesDates[releaseMdFile] != null ? releaseFilesDates[releaseMdFile].format("dd MMMM yyyy") : ""
+ def whatsnewMd = hugoTemplateSubstitutions(whatsnewMdFile.text)
+ Node whatsnewNode = parser.parse(whatsnewMd)
+ String whatsnewHtml = renderer.render(whatsnewNode)
+ whatsnewHtml = whatsnewTemplateFile.text.replaceAll("__WHATS_NEW__", whatsnewHtml)
+ whatsnewHtmlFile.text = hugoTemplateSubstitutions(whatsnewHtml,
+ [
+ VERSION: JALVIEW_VERSION,
+ DISPLAY_DATE: wnDisplayDate
+ ]
+ )
+ } else if (gradle.taskGraph.hasTask(":linkCheck")) {
+ whatsnewHtmlFile.text = "Development build " + getDate("yyyy-MM-dd HH:mm:ss")
+ }
-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")
+ inputs.file(releasesTemplateFile)
+ inputs.file(whatsnewTemplateFile)
+ inputs.dir(releasesMdDir)
+ inputs.dir(whatsnewMdDir)
+ outputs.file(releasesHtmlFile)
+ outputs.file(whatsnewHtmlFile)
}
-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"])
+task copyResources(type: Copy) {
+ group = "build"
+ description = "Copy (and make text substitutions in) the resources dir to the build area"
- 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")
-}
+ 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) {
+ include(channel_props)
+ filter(ReplaceTokens,
+ beginToken: '__',
+ endToken: '__',
+ tokens: [
+ 'SUFFIX': channelSuffix
+ ]
+ )
+ }
+ from(inputDir) {
+ exclude(channel_props)
+ }
+ 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+"]"
+ property "JAVA_COMPILE_VERSION", JAVA_INTEGER_VERSION
+ 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 releasesTemplates
+ dependsOn convertMdFiles
+ dependsOn buildIndices
+}
+
+
+compileJava.dependsOn prepare
+run.dependsOn compileJava
+compileTestJava.dependsOn compileJava
+
+
+
+test {
+ group = "Verification"
+ description = "Runs all testTaskN tasks)"
+
+ if (useClover) {
+ dependsOn cloverClasses
+ } else { //?
+ dependsOn testClasses
+ }
+
+ // not running tests in this task
+ exclude "**/*"
+}
+/* testTask0 is the main test task */
+task testTask0(type: Test) {
+ group = "Verification"
+ description = "The main test task. Runs all non-testTaskN-labelled tests (unless excluded)"
+ useTestNG() {
+ includeGroups testng_groups.split(",")
+ excludeGroups testng_excluded_groups.split(",")
+ tasks.withType(Test).matching {it.name.startsWith("testTask") && it.name != name}.all {t -> excludeGroups t.name}
+ preserveOrder true
+ useDefaultListeners=true
+ }
+}
+
+/* separated tests */
+task testTask1(type: Test) {
+ group = "Verification"
+ description = "Tests that need to be isolated from the main test run"
+ useTestNG() {
+ includeGroups name
+ excludeGroups testng_excluded_groups.split(",")
+ preserveOrder true
+ useDefaultListeners=true
+ }
+}
+
+/* insert more testTaskNs here -- change N to next digit or other string */
+/*
+task testTaskN(type: Test) {
+ group = "Verification"
+ description = "Tests that need to be isolated from the main test run"
+ useTestNG() {
+ includeGroups name
+ excludeGroups testng_excluded_groups.split(",")
+ preserveOrder true
+ useDefaultListeners=true
+ }
+}
+*/
+
+/*
+ * adapted from https://medium.com/@wasyl/pretty-tests-summary-in-gradle-744804dd676c
+ * to summarise test results from all Test tasks
+ */
+/* START of test tasks results summary */
+import groovy.time.TimeCategory
+import org.gradle.api.tasks.testing.logging.TestExceptionFormat
+import org.gradle.api.tasks.testing.logging.TestLogEvent
+rootProject.ext.testsResults = [] // Container for tests summaries
+
+tasks.withType(Test).matching {t -> t.getName().startsWith("testTask")}.all { testTask ->
+
+ // from original test task
+ if (useClover) {
+ dependsOn cloverClasses
+ } else { //?
+ dependsOn testClasses //?
+ }
+
+ // run main tests first
+ if (!testTask.name.equals("testTask0"))
+ testTask.mustRunAfter "testTask0"
+
+ testTask.testLogging { logging ->
+ events TestLogEvent.FAILED
+// TestLogEvent.SKIPPED,
+// TestLogEvent.STANDARD_OUT,
+// TestLogEvent.STANDARD_ERROR
+
+ exceptionFormat TestExceptionFormat.FULL
+ showExceptions true
+ showCauses true
+ showStackTraces true
+
+ info.events = [ TestLogEvent.FAILED ]
+ }
+
+
+
+ ignoreFailures = true // Always try to run all tests for all modules
+
+ afterSuite { desc, result ->
+ if (desc.parent)
+ return // Only summarize results for whole modules
+
+ def resultsInfo = [testTask.project.name, testTask.name, result, TimeCategory.minus(new Date(result.endTime), new Date(result.startTime)), testTask.reports.html.entryPoint]
+
+ rootProject.ext.testsResults.add(resultsInfo)
+ }
+
+ // from original test task
+ 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 {
+ // this is not perfect yet -- we should only add the commandLineIncludePatterns to the
+ // testTasks that include the tests, and exclude all from the others.
+ // get --test argument
+ filter.commandLineIncludePatterns = test.filter.commandLineIncludePatterns
+ // do something with testTask.getCandidateClassFiles() to see if the test should silently finish because of the
+ // commandLineIncludePatterns not matching anything. Instead we are doing setFailOnNoMatchingTests(false) below
+
+
+ if (useClover) {
+ println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
+ }
+ }
+
+
+ /* don't fail on no matching tests (so --tests will run across all testTasks) */
+ testTask.filter.setFailOnNoMatchingTests(false)
+
+ /* ensure the "test" task dependsOn all the testTasks */
+ test.dependsOn testTask
+}
+
+gradle.buildFinished {
+ def allResults = rootProject.ext.testsResults
+
+ if (!allResults.isEmpty()) {
+ printResults allResults
+ allResults.each {r ->
+ if (r[2].resultType == TestResult.ResultType.FAILURE)
+ throw new GradleException("Failed tests!")
+ }
+ }
+}
+
+private static String colString(styler, col, colour, text) {
+ return col?"${styler[colour](text)}":text
+}
+
+private static String getSummaryLine(s, pn, tn, rt, rc, rs, rf, rsk, t, col) {
+ def colour = 'black'
+ def text = rt
+ def nocol = false
+ if (rc == 0) {
+ text = "-----"
+ nocol = true
+ } else {
+ switch(rt) {
+ case TestResult.ResultType.SUCCESS:
+ colour = 'green'
+ break;
+ case TestResult.ResultType.FAILURE:
+ colour = 'red'
+ break;
+ default:
+ nocol = true
+ break;
+ }
+ }
+ StringBuilder sb = new StringBuilder()
+ sb.append("${pn}")
+ if (tn != null)
+ sb.append(":${tn}")
+ sb.append(" results: ")
+ sb.append(colString(s, col && !nocol, colour, text))
+ sb.append(" (")
+ sb.append("${rc} tests, ")
+ sb.append(colString(s, col && rs > 0, 'green', rs))
+ sb.append(" successes, ")
+ sb.append(colString(s, col && rf > 0, 'red', rf))
+ sb.append(" failures, ")
+ sb.append("${rsk} skipped) in ${t}")
+ return sb.toString()
+}
+
+private static void printResults(allResults) {
+
+ // styler from https://stackoverflow.com/a/56139852
+ def styler = 'black red green yellow blue magenta cyan white'.split().toList().withIndex(30).collectEntries { key, val -> [(key) : { "\033[${val}m${it}\033[0m" }] }
+
+ def maxLength = 0
+ def failedTests = false
+ def summaryLines = []
+ def totalcount = 0
+ def totalsuccess = 0
+ def totalfail = 0
+ def totalskip = 0
+ def totaltime = TimeCategory.getSeconds(0)
+ // sort on project name then task name
+ allResults.sort {a, b -> a[0] == b[0]? a[1]<=>b[1]:a[0] <=> b[0]}.each {
+ def projectName = it[0]
+ def taskName = it[1]
+ def result = it[2]
+ def time = it[3]
+ def report = it[4]
+ def summaryCol = getSummaryLine(styler, projectName, taskName, result.resultType, result.testCount, result.successfulTestCount, result.failedTestCount, result.skippedTestCount, time, true)
+ def summaryPlain = getSummaryLine(styler, projectName, taskName, result.resultType, result.testCount, result.successfulTestCount, result.failedTestCount, result.skippedTestCount, time, false)
+ def reportLine = "Report file: ${report}"
+ def ls = summaryPlain.length()
+ def lr = reportLine.length()
+ def m = [ls, lr].max()
+ if (m > maxLength)
+ maxLength = m
+ def info = [ls, summaryCol, reportLine]
+ summaryLines.add(info)
+ failedTests |= result.resultType == TestResult.ResultType.FAILURE
+ totalcount += result.testCount
+ totalsuccess += result.successfulTestCount
+ totalfail += result.failedTestCount
+ totalskip += result.skippedTestCount
+ totaltime += time
+ }
+ def totalSummaryCol = getSummaryLine(styler, "OVERALL", "", failedTests?TestResult.ResultType.FAILURE:TestResult.ResultType.SUCCESS, totalcount, totalsuccess, totalfail, totalskip, totaltime, true)
+ def totalSummaryPlain = getSummaryLine(styler, "OVERALL", "", failedTests?TestResult.ResultType.FAILURE:TestResult.ResultType.SUCCESS, totalcount, totalsuccess, totalfail, totalskip, totaltime, false)
+ def tls = totalSummaryPlain.length()
+ if (tls > maxLength)
+ maxLength = tls
+ def info = [tls, totalSummaryCol, null]
+ summaryLines.add(info)
+
+ def allSummaries = []
+ for(sInfo : summaryLines) {
+ def ls = sInfo[0]
+ def summary = sInfo[1]
+ def report = sInfo[2]
+
+ StringBuilder sb = new StringBuilder()
+ sb.append("│" + summary + " " * (maxLength - ls) + "│")
+ if (report != null) {
+ sb.append("\n│" + report + " " * (maxLength - report.length()) + "│")
+ }
+ allSummaries += sb.toString()
+ }
+
+ println "┌${"${"─" * maxLength}"}┐"
+ println allSummaries.join("\n├${"${"─" * maxLength}"}┤\n")
+ println "└${"${"─" * maxLength}"}┘"
+}
+/* END of test tasks results summary */
+
+
+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, 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" ]
+ workingDir = "${helpBuildDir}"
+ args = [ "${helpBuildDir}/${help_dir}", "-nointernet" ]
def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
- def errFOS = outFOS
standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
outFOS,
- standardOutput)
+ System.out)
errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
outFOS,
- errorOutput)
+ System.err)
- 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"
}
}
+
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": applicationName,
+ "Codebase": application_codebase,
+ "Implementation-Version": JALVIEW_VERSION
}
- destinationDir = file("${jalviewDir}/${package_dir}")
- archiveName = rootProject.name+".jar"
+ def outputDir = "${jalviewDir}/${package_dir}"
+ destinationDirectory = file(outputDir)
+ archiveFileName = rootProject.name+".jar"
+ duplicatesStrategy "EXCLUDE"
+
exclude "cache*/**"
exclude "*.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("${outputDir}/${archiveFileName}")
}
// 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()
}
}
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
}
include("*.jar")
}
manifest {
- attributes 'Implementation-Version': JALVIEW_VERSION
+ 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 getdownImagesCopy() {
+ inputs.dir getdownImagesDir
+ outputs.dir getdownImagesBuildDir
+
+ doFirst {
+ copy {
+ from(getdownImagesDir) {
+ include("*getdown*.png")
+ }
+ into getdownImagesBuildDir
+ }
+ }
+}
+
+task getdownImagesProcess() {
+ dependsOn getdownImagesCopy
+
+ doFirst {
+ if (backgroundImageText) {
+ if (convertBinary == null) {
+ throw new StopExecutionException("No ImageMagick convert binary installed at '${convertBinaryExpectedLocation}'")
+ }
+ if (!project.hasProperty("getdown_background_image_text_suffix_cmd")) {
+ throw new StopExecutionException("No property 'getdown_background_image_text_suffix_cmd' defined. See channel_gradle.properties for channel ${CHANNEL}")
+ }
+ fileTree(dir: getdownImagesBuildDir, include: "*background*.png").getFiles().each { file ->
+ exec {
+ executable convertBinary
+ args = [
+ file.getPath(),
+ '-font', getdown_background_image_text_font,
+ '-fill', getdown_background_image_text_colour,
+ '-draw', sprintf(getdown_background_image_text_suffix_cmd, channelSuffix),
+ '-draw', sprintf(getdown_background_image_text_commit_cmd, "git-commit: ${gitHash}"),
+ '-draw', sprintf(getdown_background_image_text_date_cmd, getDate("yyyy-MM-dd HH:mm:ss")),
+ file.getPath()
+ ]
+ }
+ }
+ }
+ }
+}
+
+task getdownImages() {
+ dependsOn getdownImagesProcess
+}
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"
+
+ dependsOn getdownImages
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 getdownAppBaseDir
delete getdownFilesDir
copy {
from buildProperties
- rename(build_properties_file, getdown_build_properties)
+ rename(file(buildProperties).getName(), getdown_build_properties)
into getdownAppDir
}
getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
- // set some getdown_txt_ properties then go through all properties looking for getdown_txt_...
+ copy {
+ from channelPropsFile
+ filter(ReplaceTokens,
+ beginToken: '__',
+ endToken: '__',
+ tokens: [
+ 'SUFFIX': channelSuffix
+ ]
+ )
+ 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 (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
}
+ if (getdownImagesBuildDir != null && file(getdownImagesBuildDir).exists()) {
+ props.put("getdown_txt_ui.background_image", "${getdownImagesBuildDir}/${getdown_background_image}")
+ props.put("getdown_txt_ui.instant_background_image", "${getdownImagesBuildDir}/${getdown_instant_background_image}")
+ props.put("getdown_txt_ui.error_background", "${getdownImagesBuildDir}/${getdown_error_background}")
+ props.put("getdown_txt_ui.progress_image", "${getdownImagesBuildDir}/${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", install4jApplicationName)
+ props.put("getdown_txt_ui.name", applicationName)
// start with appbase
- getdownTextString += "appbase = ${getdownAppBase}\n"
+ 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}\n"
- getdownTextString += line
+ def line = "${key} = ${v}"
+ getdownTextLines += line
}
} else {
// file values rationalised
}
}
if (! prop.startsWith("getdown_txt_resource")) {
- def line = prop.substring(12) + " = ${val}\n"
- getdownTextString += line
+ def line = prop.substring(12) + " = ${val}"
+ getdownTextLines += line
}
}
}
}
getdownWebsiteResourceFilenames.each{ filename ->
- getdownTextString += "resource = ${filename}\n"
+ getdownTextLines += "resource = ${filename}"
}
getdownResourceFilenames.each{ filename ->
copy {
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 ->
codeFiles += f
}
}
- codeFiles.sort().each{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}\n"
- getdownTextString += line
+ def line = "code = ${getdownAppDistDir}/${name}"
+ getdownTextLines += 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
+ 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.
- //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"
- */
+ //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 getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
- getdown_txt.write(getdownTextString)
+ def getdownTxt = file("${getdownAppBaseDir}/getdown.txt")
+ getdownTxt.write(getdownTextLines.join("\n"))
- def getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
- def launchJvl = file("${getdownWebsiteDir}/${getdownLaunchJvl}")
+ 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 getdownWebsiteDir
+ 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 getdownWebsiteDir
+ into getdownAppBaseDir
}
+ // files going into the getdown website dir: ./install dir and files
if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
copy {
- from getdown_txt
+ from getdownTxt
from getdownLauncher
from "${getdownAppDir}/${getdown_build_properties}"
if (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 getdown_txt
+ from getdownTxt
from launchJvl
from getdownLauncher
- from "${getdownWebsiteDir}/${getdown_build_properties}"
+ 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(getdownWebsiteDir)
+ outputs.dir(getdownAppBaseDir)
outputs.dir(getdownFilesDir)
}
classpath = files(getdownLauncher)
}
main = "com.threerings.getdown.tools.Digester"
- args getdownWebsiteDir
- inputs.dir(getdownWebsiteDir)
- outputs.file("${getdownWebsiteDir}/digest2.txt")
+ args getdownAppBaseDir
+ inputs.dir(getdownAppBaseDir)
+ outputs.file("${getdownAppBaseDir}/digest2.txt")
}
dependsOn getdownDigest
doLast {
if (reportRsyncCommand) {
- def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
+ 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'"
}
-clean {
- doFirst {
- delete getdownWebsiteDir
- delete getdownFilesDir
- }
-}
+task getdownArchiveBuild() {
+ group = "distribution"
+ description = "Put files in the archive dir to go on the website"
+ dependsOn getdownWebsite
-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))
+ def v = "v${JALVIEW_VERSION_UNDERSCORES}"
+ def vDir = "${getdownArchiveDir}/${v}"
+ getdownFullArchiveDir = "${vDir}/getdown"
+ getdownVersionLaunchJvl = "${vDir}/jalview-${v}.jvl"
- mediaTypes = Arrays.asList(install4j_media_types.split(","))
-}
+ def vAltDir = "alt_${v}"
+ def archiveImagesDir = "${jalviewDir}/${channel_properties_dir}/old/images"
+ doFirst {
+ // cleanup old "old" dir
+ delete getdownArchiveDir
-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)
+ def getdownArchiveTxt = file("${getdownFullArchiveDir}/getdown.txt")
+ getdownArchiveTxt.getParentFile().mkdirs()
+ def getdownArchiveTextLines = []
+ def getdownFullArchiveAppBase = "${getdownArchiveAppBase}${getdownArchiveAppBase.endsWith("/")?"":"/"}${v}/getdown/"
- doLast {
- def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
+ // the libdir
+ copy {
+ from "${getdownAppBaseDir}/${getdownAppDistDir}"
+ into "${getdownFullArchiveDir}/${vAltDir}"
+ }
- // turn off code signing if no OSX_KEYPASS
+ 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"
}
}
+ // 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]
- if (CHANNEL == "LOCAL") {
- e.'@createChecksums' = "false"
- } else {
- e.'@createChecksums' = "true"
- }
+ e.'@createChecksums' = string(install4jCheckSums)
// put file association actions where placeholder action is
def install4jFileAssociationsText = install4jFileAssociationsFile.text
}
}
- // 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)
}
}
}
+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 install4jDMGBackgroundImageCopy {
+ inputs.file "${install4jDMGBackgroundImageDir}/${install4jDMGBackgroundImageFile}"
+ outputs.dir "${install4jDMGBackgroundImageBuildDir}"
+ doFirst {
+ copy {
+ from(install4jDMGBackgroundImageDir) {
+ include(install4jDMGBackgroundImageFile)
+ }
+ into install4jDMGBackgroundImageBuildDir
+ }
+ }
+}
+
+task install4jDMGBackgroundImageProcess {
+ dependsOn install4jDMGBackgroundImageCopy
+
+ doFirst {
+ if (backgroundImageText) {
+ if (convertBinary == null) {
+ throw new StopExecutionException("No ImageMagick convert binary installed at '${convertBinaryExpectedLocation}'")
+ }
+ if (!project.hasProperty("install4j_background_image_text_suffix_cmd")) {
+ throw new StopExecutionException("No property 'install4j_background_image_text_suffix_cmd' defined. See channel_gradle.properties for channel ${CHANNEL}")
+ }
+ fileTree(dir: install4jDMGBackgroundImageBuildDir, include: "*.png").getFiles().each { file ->
+ exec {
+ executable convertBinary
+ args = [
+ file.getPath(),
+ '-font', install4j_background_image_text_font,
+ '-fill', install4j_background_image_text_colour,
+ '-draw', sprintf(install4j_background_image_text_suffix_cmd, channelSuffix),
+ '-draw', sprintf(install4j_background_image_text_commit_cmd, "git-commit: ${gitHash}"),
+ '-draw', sprintf(install4j_background_image_text_date_cmd, getDate("yyyy-MM-dd HH:mm:ss")),
+ file.getPath()
+ ]
+ }
+ }
+ }
+ }
+}
+
+task install4jDMGBackgroundImage {
+ dependsOn install4jDMGBackgroundImageProcess
+}
-task installers(type: com.install4j.gradle.Install4jTask) {
+task installerFiles(type: com.install4j.gradle.Install4jTask) {
group = "distribution"
description = "Create the install4j installers"
- dependsOn setGitVals
dependsOn getdown
dependsOn copyInstall4jTemplate
+ dependsOn cleanInstallersDataFiles
+ dependsOn install4jDMGBackgroundImage
projectFile = install4jConfFile
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_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,
'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,
+ 'MACOS_DMG_DS_STORE': install4jDMGDSStore,
+ 'MACOS_DMG_BG_IMAGE': "${install4jDMGBackgroundImageBuildDir}/${install4jDMGBackgroundImageFile}",
+ 'WRAPPER_LINK': getdownWrapperLink,
+ 'BASH_WRAPPER_SCRIPT': getdown_bash_wrapper_script,
+ 'POWERSHELL_WRAPPER_SCRIPT': getdown_powershell_wrapper_script,
+ 'BATCH_WRAPPER_SCRIPT': getdown_batch_wrapper_script,
+ 'WRAPPER_SCRIPT_BIN_DIR': getdown_wrapper_script_dir,
'INSTALLER_NAME': install4jInstallerName,
'INSTALL4J_UTILS_DIR': install4j_utils_dir,
- 'GETDOWN_WEBSITE_DIR': getdown_website_dir,
+ 'GETDOWN_CHANNEL_DIR': getdownChannelDir,
'GETDOWN_FILES_DIR': getdown_files_dir,
'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
'GETDOWN_DIST_DIR': getdownAppDistDir,
'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder,
'EXECUTABLE_NAME': install4jExecutableName,
'EXTRA_SCHEME': install4jExtraScheme,
+ 'MAC_ICONS_FILE': install4jMacIconsFile,
+ 'WINDOWS_ICONS_FILE': install4jWindowsIconsFile,
+ 'PNG_ICON_FILE': install4jPngIconFile,
+ 'BACKGROUND': install4jBackground,
+ ]
+
+ def varNameMap = [
+ 'mac': 'MACOS',
+ 'windows': 'WINDOWS',
+ 'linux': 'LINUX'
+ ]
+
+ // these are the bundled OS/architecture VMs needed by install4j
+ def osArch = [
+ [ "mac", "x64" ],
+ [ "mac", "aarch64" ],
+ [ "windows", "x64" ],
+ [ "linux", "x64" ],
+ [ "linux", "aarch64" ]
]
+ osArch.forEach { os, arch ->
+ variables[ sprintf("%s_%s_JAVA_VM_DIR", varNameMap[os], arch.toUpperCase(Locale.ROOT)) ] = sprintf("%s/jre-%s-%s-%s/jre", jreInstallsDir, JAVA_INTEGER_VERSION, os, arch)
+ // N.B. For some reason install4j requires the below filename to have underscores and not hyphens
+ // otherwise running `gradle installers` generates a non-useful error:
+ // `install4j: compilation failed. Reason: java.lang.NumberFormatException: For input string: "windows"`
+ variables[ sprintf("%s_%s_JAVA_VM_TGZ", varNameMap[os], arch.toUpperCase(Locale.ROOT)) ] = sprintf("%s/tgz/jre_%s_%s_%s.tar.gz", jreInstallsDir, JAVA_INTEGER_VERSION, os, arch)
+ }
//println("INSTALL4J VARIABLES:")
//variables.each{k,v->println("${k}=${v}")}
if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
faster = true
disableSigning = true
+ disableNotarization = true
}
if (OSX_KEYPASS) {
macKeystorePassword = OSX_KEYPASS
+ }
+
+ if (OSX_ALTOOLPASS) {
+ appleIdPassword = OSX_ALTOOLPASS
+ disableNotarization = false
+ } else {
+ disableNotarization = true
}
doFirst {
println("Using projectFile "+projectFile)
+ if (!disableNotarization) { println("Will notarize OSX App DMG") }
}
+ //verbose=true
- inputs.dir(getdownWebsiteDir)
+ inputs.dir(getdownAppBaseDir)
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}")
}
+def getDataHash(File myFile) {
+ HashCode hash = Files.asByteSource(myFile).hash(Hashing.sha256())
+ return myFile.exists()
+ ? [
+ "file" : myFile.getName(),
+ "filesize" : myFile.length(),
+ "sha256" : hash.toString()
+ ]
+ : null
+}
-task sourceDist(type: Tar) {
- dependsOn createBuildProperties
+def writeDataJsonFile(File installersOutputTxt, File installersSha256, File dataJsonFile) {
+ def hash = [
+ "channel" : getdownChannelName,
+ "date" : getDate("yyyy-MM-dd HH:mm:ss"),
+ "git-commit" : "${gitHash} [${gitBranch}]",
+ "version" : JALVIEW_VERSION
+ ]
+ // install4j installer files
+ if (installersOutputTxt.exists()) {
+ def idHash = [:]
+ installersOutputTxt.readLines().each { def line ->
+ if (line.startsWith("#")) {
+ return;
+ }
+ line.replaceAll("\n","")
+ def vals = line.split("\t")
+ def filename = vals[3]
+ def filesize = file(filename).length()
+ filename = filename.replaceAll(/^.*\//, "")
+ hash[vals[0]] = [ "id" : vals[0], "os" : vals[1], "name" : vals[2], "file" : filename, "filesize" : filesize ]
+ idHash."${filename}" = vals[0]
+ }
+ if (install4jCheckSums && installersSha256.exists()) {
+ installersSha256.readLines().each { def line ->
+ if (line.startsWith("#")) {
+ return;
+ }
+ line.replaceAll("\n","")
+ def vals = line.split(/\s+\*?/)
+ def filename = vals[1]
+ def innerHash = (hash.(idHash."${filename}"))."sha256" = vals[0]
+ }
+ }
+ }
+
+ [
+ "JAR": shadowJar.archiveFile, // executable JAR
+ "JVL": getdownVersionLaunchJvl, // version JVL
+ "SOURCE": sourceDist.archiveFile // source TGZ
+ ].each { key, value ->
+ def file = file(value)
+ if (file.exists()) {
+ def fileHash = getDataHash(file)
+ if (fileHash != null) {
+ hash."${key}" = fileHash;
+ }
+ }
+ }
+ return dataJsonFile.write(new JsonBuilder(hash).toPrettyString())
+}
+
+task staticMakeInstallersJsonFile {
+ doFirst {
+ def output = findProperty("i4j_output")
+ def sha256 = findProperty("i4j_sha256")
+ def json = findProperty("i4j_json")
+ if (output == null || sha256 == null || json == null) {
+ throw new GradleException("Must provide paths to all of output.txt, sha256sums, and output.json with '-Pi4j_output=... -Pi4j_sha256=... -Pi4j_json=...")
+ }
+ writeDataJsonFile(file(output), file(sha256), file(json))
+ }
+}
+
+task installers {
+ dependsOn installerFiles
+}
+
+
+spotless {
+ java {
+ eclipse().configFile(eclipse_codestyle_file)
+ }
+}
+
+task createSourceReleaseProperties(type: WriteProperties) {
+ group = "distribution"
+ description = "Create the source RELEASE properties file"
- 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
+ def sourceTarBuildDir = "${buildDir}/sourceTar"
+ def sourceReleasePropertiesFile = "${sourceTarBuildDir}/RELEASE"
+ outputFile (sourceReleasePropertiesFile)
+
+ doFirst {
+ releaseProps.each{ key, val -> property key, val }
+ property "git.branch", gitBranch
+ property "git.hash", gitHash
}
+
+ outputs.file(outputFile)
+}
+
+task sourceDist(type: Tar) {
+ group "distribution"
+ description "Create a source .tar.gz file for distribution"
+
+ dependsOn createBuildProperties
+ dependsOn convertMdFiles
+ dependsOn eclipseAllPreferences
+ dependsOn createSourceReleaseProperties
+
+
+ def outputFileName = "${project.name}_${JALVIEW_VERSION_UNDERSCORES}.tar.gz"
+ archiveFileName = outputFileName
compression Compression.GZIP
"*locales/**",
"utils/InstallAnywhere",
"**/*.log",
+ "RELEASE",
]
def PROCESS_FILES=[
"AUTHORS",
"FEATURETODO",
"LICENSE",
"**/README",
- "RELEASE",
"THIRDPARTYLIBS",
"TESTNG",
"build.gradle",
"**/*.sh",
]
def INCLUDE_FILES=[
- ".settings/org.eclipse.jdt.core.jalview.prefs",
+ ".classpath",
+ ".settings/org.eclipse.buildship.core.prefs",
+ ".settings/org.eclipse.jdt.core.prefs"
]
from(jalviewDir) {
exclude ("utils/InstallAnywhere")
exclude (getdown_files_dir)
- exclude (getdown_website_dir)
+ // getdown_website_dir and getdown_archive_dir moved to build/website/docroot/getdown
+ //exclude (getdown_website_dir)
+ //exclude (getdown_archive_dir)
// exluding these as not using jars as modules yet
- exclude ("$j11modDir/**/*.jar")
+ exclude ("${j11modDir}/**/*.jar")
}
from(jalviewDir) {
include(INCLUDE_FILES)
include(file(buildProperties).getName())
rename(file(buildProperties).getName(), "build_properties")
filter({ line ->
- line.replaceAll("^INSTALLATION=.*\$","INSTALLATION=SourceDist"+" git-commit\\\\:"+gitHash+" ["+gitBranch+"]")
+ line.replaceAll("^INSTALLATION=.*\$","INSTALLATION=Source Release"+" git-commit\\\\:"+gitHash+" ["+gitBranch+"]")
})
}
+ def sourceTarBuildDir = "${buildDir}/sourceTar"
+ from(sourceTarBuildDir) {
+ // this includes the appended RELEASE properties file
+ }
}
+task dataInstallersJson {
+ group "website"
+ description "Create the installers-VERSION.json data file for installer files created"
+
+ mustRunAfter installers
+ mustRunAfter shadowJar
+ mustRunAfter sourceDist
+ mustRunAfter getdownArchive
+
+ def installersOutputTxt = file("${jalviewDir}/${install4jBuildDir}/output.txt")
+ def installersSha256 = file("${jalviewDir}/${install4jBuildDir}/sha256sums")
+
+ if (installersOutputTxt.exists()) {
+ inputs.file(installersOutputTxt)
+ }
+ if (install4jCheckSums && installersSha256.exists()) {
+ inputs.file(installersSha256)
+ }
+ [
+ shadowJar.archiveFile, // executable JAR
+ getdownVersionLaunchJvl, // version JVL
+ sourceDist.archiveFile // source TGZ
+ ].each { fileName ->
+ if (file(fileName).exists()) {
+ inputs.file(fileName)
+ }
+ }
+
+ outputs.file(hugoDataJsonFile)
+
+ doFirst {
+ writeDataJsonFile(installersOutputTxt, installersSha256, hugoDataJsonFile)
+ }
+}
task helppages {
+ group "help"
+ description "Copies all help pages to build dir. Runs ant task 'pubhtmlhelp'."
+
dependsOn copyHelp
dependsOn pubhtmlhelp
- inputs.dir("${classesDir}/${help_dir}")
+ inputs.dir("${helpBuildDir}/${help_dir}")
outputs.dir("${buildDir}/distributions/${help_dir}")
}
-// LARGE AMOUNT OF JALVIEWJS STUFF DELETED HERE
-task eclipseAutoBuildTask {}
-task eclipseSynchronizationTask {}
+
+task j2sSetHeadlessBuild {
+ doFirst {
+ IN_ECLIPSE = false
+ }
+}
+
+
+task jalviewjsEnableAltFileProperty(type: WriteProperties) {
+ group "jalviewjs"
+ description "Enable the alternative J2S Config file for headless build"
+
+ outputFile = jalviewjsJ2sSettingsFileName
+ def j2sPropsFile = file(jalviewjsJ2sSettingsFileName)
+ def j2sProps = new Properties()
+ if (j2sPropsFile.exists()) {
+ try {
+ def j2sPropsFileFIS = new FileInputStream(j2sPropsFile)
+ j2sProps.load(j2sPropsFileFIS)
+ j2sPropsFileFIS.close()
+
+ j2sProps.each { prop, val ->
+ property(prop, val)
+ }
+ } catch (Exception e) {
+ println("Exception reading ${jalviewjsJ2sSettingsFileName}")
+ e.printStackTrace()
+ }
+ }
+ if (! j2sProps.stringPropertyNames().contains(jalviewjs_j2s_alt_file_property_config)) {
+ property(jalviewjs_j2s_alt_file_property_config, jalviewjs_j2s_alt_file_property)
+ }
+}
+
+
+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 alternative 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 = jalviewjsJ2sAltSettingsFileName
+
+ if (! IN_ECLIPSE) {
+ inputs.properties(jalviewjsJ2sProps)
+ outputs.file(jalviewjsJ2sAltSettingsFileName)
+ }
+}
+
+
+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 "**"
+ }
+
+ // should this be exclude really ?
+ duplicatesStrategy "INCLUDE"
+
+ outputs.files outputFiles
+ inputs.files inputFiles
+}
+
+
+task jalviewjsSyncResources (type: Sync) {
+ dependsOn buildResources
+
+ def inputFiles = fileTree(dir: resourcesBuildDir)
+ 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" ]
+ args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
+ }
+
+ inputs.file("${jalviewDir}/.project")
+ outputs.upToDateWhen {
+ file(projdir).exists()
+ }
+}
+
+
+task jalviewjsTranspile(type: Exec) {
+ dependsOn jalviewjsEclipseSetup
+ dependsOn jalviewjsProjectImport
+ dependsOn jalviewjsEclipsePaths
+ if (!IN_ECLIPSE) {
+ dependsOn jalviewjsEnableAltFileProperty
+ }
+
+ 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" ]
+ args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
+ }
+
+ 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),
+ System.out)
+ errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
+ new org.apache.tools.ant.util.TeeOutputStream(
+ logErrFOS,
+ stderr),
+ System.err)
+ } 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),
+ System.err)
+ } 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': '"'+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"
+ archiveFileName = 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 {
+
+ def factory
+ try {
+ def f = Class.forName("org.gradle.plugins.javascript.envjs.http.simple.SimpleHttpFileServerFactory")
+ factory = f.newInstance()
+ } catch (ClassNotFoundException e) {
+ throw new GradleException("Unable to create 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. <${url}></a></p>
+ <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
+ <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
+ """
+ jalviewjsCoreClasslists.each { cl ->
+ def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
+ htmlText += """
+ <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></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 jalviewjsJ2sAltSettingsFileName
+ }
+
+ 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 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)
+ }
+
+ 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 '${eclipseJ2sPlugin}' 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 // not sure why this clean is here -- will slow down a re-run of this task
+}
+
+
+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
+}
+
+
+task jalviewjsCopyStderrLaunchFile(type: Copy) {
+ from file(jalviewjs_stderr_launch)
+ into jalviewjsSiteDir
+
+ inputs.file jalviewjs_stderr_launch
+ outputs.file jalviewjsStderrLaunchFilename
+}
+
+task jalviewjsChromiumProfile {
+ def profileDir = "${jalviewjsBuildDir}/${jalviewjs_chromium_user_dir}/${jalviewjs_chromium_profile_name}"
+ def firstRun = file("${profileDir}/First Run")
+
+ doFirst {
+ mkdir profileDir
+ firstRun.text = ""
+ }
+
+ outputs.file firstRun
+}
+
+task jalviewjsLaunchTest(type: Exec) {
+ group "Test"
+ description "Check JalviewJS opens in a browser"
+ dependsOn jalviewjsBuildSite
+ dependsOn jalviewjsCopyStderrLaunchFile
+ dependsOn jalviewjsChromiumProfile
+
+ def chromiumBinary = jalviewjs_chromium_binary
+ if (chromiumBinary.startsWith("~/")) {
+ chromiumBinary = System.getProperty("user.home") + chromiumBinary.substring(1)
+ }
+
+ doFirst {
+ def exec = file(chromiumBinary)
+ if (!exec.exists()) {
+ throw new GradleException("Could not find chromium binary '${chromiumBinary}'. Cannot run task ${name}.")
+ }
+ }
+
+ executable(chromiumBinary)
+ args([
+ "--headless=new",
+ "--timeout=60000",
+ "--virtual-time-budget=60000",
+ "--user-data-dir=${jalviewjsBuildDir}/${jalviewjs_chromium_user_dir}",
+ "--profile-directory=${jalviewjs_chromium_profile_name}",
+ "--allow-file-access-from-files",
+ "--enable-logging=stderr",
+ jalviewjsStderrLaunchFilename
+ ])
+
+ /*
+ standardOutput = new ByteArrayOutputStream()
+ errorOutput = new ByteArrayOutputStream()
+
+ doLast {
+ println("Chrome STDOUT: ")
+ println(standardOutput.toString())
+ println("Chrome STDERR: ")
+ println(errorOutput.toString())
+
+ def found = false
+ def stderr = errorOutput.toString()
+ stderr.eachLine { line ->
+ if (line.contains(jalviewjs_desktop_init_string)) {
+ println("Found line '"+line+"'")
+ found = true
+ return
+ }
+ }
+ if (!found) {
+ throw new GradleException("Could not find evidence of Desktop launch in JalviewJS.")
+ }
+ }
+ */
+}