import org.gradle.plugins.ide.eclipse.model.Library
import java.security.MessageDigest
import java.util.regex.Matcher
+import java.util.concurrent.Executors
+import java.util.concurrent.Future
+import java.util.concurrent.ScheduledExecutorService
+import java.util.concurrent.TimeUnit
+import java.nio.file.Path
import groovy.transform.ExternalizeMethods
import groovy.util.XmlParser
import groovy.xml.XmlUtil
id 'application'
id 'eclipse'
id "com.diffplug.gradle.spotless" version "3.28.0"
- id 'com.github.johnrengelman.shadow' version '4.0.3'
+ id 'com.github.johnrengelman.shadow' version '6.0.0'
id 'com.install4j.gradle' version '10.0.3'
- id 'com.dorongold.task-tree' version '2.1.0' // only needed to display task dependency tree with gradle task1 [task2 ...] taskTree
+ 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
}
return o == null ? "" : o.toString()
}
-def overrideProperties(String propsFileName, boolean output = false) {
- if (propsFileName == null) {
- return
- }
+def Properties readPropertiesFile(String propsFileName) {
+ def p = null
def propsFile = file(propsFileName)
if (propsFile != null && propsFile.exists()) {
println("Using properties from file '${propsFileName}'")
try {
- def p = new Properties()
+ p = new Properties()
def localPropsFIS = new FileInputStream(propsFile)
p.load(localPropsFIS)
localPropsFIS.close()
- p.each {
- key, 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 {
- ext.setProperty(key, val)
- if (output) {
- println("Setting ext property '${key}' with ${file(propsFile).getName()}s value '${val}'")
- }
- }
- }
} catch (Exception e) {
- println("Exception reading local.properties")
+ println("Exception reading properties file '${propsFileName}'")
e.printStackTrace()
}
}
+ return p
+}
+
+def overrideProperties(String propsFileName, boolean output = false) {
+ if (propsFileName == null) {
+ return
+ }
+ def propsFile = file(propsFileName)
+ if (propsFile != null && propsFile.exists()) {
+ println("Using properties from file '${propsFileName}'")
+ def p = readPropertiesFile(propsFileName)
+ p.each { key, 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 {
+ ext.setProperty(key, val)
+ if (output) {
+ println("Setting ext property '${key}' with ${file(propsFile).getName()}s value '${val}'")
+ }
+ }
+ }
+ }
}
ext {
channelDir = string("${jalviewDir}/${channel_properties_dir}/${channelDirName}")
channelGradleProperties = string("${channelDir}/channel_gradle.properties")
channelPropsFile = string("${channelDir}/${resource_dir}/${channel_props}")
+ localProperties = "local.properties"
+ localEclipseProperties = "local_eclipse.properties"
overrideProperties(channelGradleProperties, false)
// local build environment properties
// can be "projectDir/local.properties"
- overrideProperties("${projectDir}/local.properties", true)
+ overrideProperties("${projectDir}/${localProperties}", true)
// or "../projectDir_local.properties"
- overrideProperties(projectDir.getParent() + "/" + projectDir.getName() + "_local.properties", true)
+ overrideProperties(projectDir.getParent() + "/" + projectDir.getName() + "_${localProperties}", true)
////
// Import releaseProps from the RELEASE file
if (IN_ECLIPSE) {
jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
} else {
- jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
+ jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}/sitejs")
}
- jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
- jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
- jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
+ jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}/lib")
+ jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}/swingjs")
+ jalviewjsTransferSiteMergeDir = string("${jalviewjsBuildDir}/merge/${jalviewjs_site_dir}")
+ jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}/core")
jalviewjsJalviewCoreHtmlFile = string("")
jalviewjsJalviewCoreName = string(jalviewjs_core_name)
jalviewjsCoreClasslists = []
jalviewjsJ2sAltSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_alt_settings}")
jalviewjsJ2sProps = null
jalviewjsJ2sPlugin = jalviewjs_j2s_plugin
+ jalviewjsStderrLaunchFilename = "${jalviewjsSiteDir}/"+(file(jalviewjs_stderr_launch).getName())
+ closureCompilerJar = "${jalviewDir}/${jalviewjs_closure_compiler}"
+
eclipseWorkspace = null
eclipseBinary = string("")
eclipseVersion = string("")
+ eclipseProductVersion = string("")
eclipseDebug = false
+
+ jalviewjsChromiumUserDir = "${jalviewjsBuildDir}/${jalviewjs_chromium_user_dir}"
+ jalviewjsChromiumProfileDir = "${ext.jalviewjsChromiumUserDir}/${jalviewjs_chromium_profile_name}"
+
// ENDEXT
}
}
}
}
+ // local eclipse settings
+ def localEclipsePropertiesFile = file("${jalviewDirAbsolutePath}/${localEclipseProperties}")
+ if (localEclipsePropertiesFile.exists()) {
+ def eclipse_prefs = new Properties()
+ def ins2 = new FileInputStream(localEclipsePropertiesFile)
+ println("Loading Eclipse Preferences from '${localEclipsePropertiesFile}'")
+ eclipse_prefs.load(ins2)
+ ins2.close()
+ eclipse_prefs.forEach { t, v ->
+ props.putAt(t, v)
+ }
+ } else {
+ println("No local Eclipse Preferences file '${localEclipsePropertiesFile}'")
+ }
}
}
// 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.compilerArgs += additional_compiler_args
options.encoding = "UTF-8"
doFirst {
print ("Setting target compatibility to "+compile_target_compatibility+"\n")
compileTestJava {
sourceCompatibility = compile_source_compatibility
targetCompatibility = compile_target_compatibility
- options.compilerArgs = additional_compiler_args
+ options.compilerArgs += additional_compiler_args
doFirst {
print ("Setting target compatibility to "+targetCompatibility+"\n")
}
compileJava.dependsOn prepare
run.dependsOn compileJava
-//run.dependsOn prepare
+compileTestJava.dependsOn compileJava
+
-//testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
test {
- dependsOn prepare
+ group = "Verification"
+ description = "Runs all testTaskN tasks)"
if (useClover) {
dependsOn cloverClasses
- } else { //?
- dependsOn compileJava //?
+ } 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 testng_groups
- excludeGroups testng_excluded_groups
+ includeGroups name
+ excludeGroups testng_excluded_groups.split(",")
preserveOrder true
useDefaultListeners=true
}
+}
- maxHeapSize = "4096m"
- jvmArgs '-Xmx4096m', '-Xms4096m'
- maxParallelForks = 1
- forkEvery = 1
+task testTask2(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
+ }
+}
+task testTask3(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
+ }
+}
-/* delete these!
- maxParallelForks = 1
- forkEvery = 1
- failFast = true
- jvmArgs '-Xmx2048m', '-Xms2048m'
+/* 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
+ if (test_output) {
+ showStandardStreams true
+ }
+ info.events = [ TestLogEvent.FAILED ]
+ }
+
+ if (OperatingSystem.current().isMacOsX()) {
+ testTask.systemProperty "apple.awt.UIElement", "true"
+ testTask.environment "JAVA_TOOL_OPTIONS", "-Dapple.awt.UIElement=true"
+ }
+
+
+ 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) {
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) {
}
+task launcherJar(type: Jar) {
+ manifest {
+ attributes (
+ "Main-Class": shadow_jar_main_class,
+ "Implementation-Version": JALVIEW_VERSION,
+ "Application-Name": applicationName
+ )
+ }
+}
+
shadowJar {
group = "distribution"
description = "Create a single jar file with all dependency libraries merged. Can be run with java -jar"
if (buildDist) {
dependsOn makeDist
}
- from ("${jalviewDir}/${libDistDir}") {
- include("*.jar")
- }
+
+ def jarFiles = fileTree(dir: "${jalviewDir}/${libDistDir}", include: "*.jar", exclude: "regex.jar").getFiles()
+ def groovyJars = jarFiles.findAll {it1 -> file(it1).getName().startsWith("groovy-swing")}
+ def otherJars = jarFiles.findAll {it2 -> !file(it2).getName().startsWith("groovy-swing")}
+ from groovyJars
+ from otherJars
+
manifest {
- attributes "Implementation-Version": JALVIEW_VERSION,
- "Application-Name": applicationName
+ // shadowJar manifest must inheritFrom another Jar task. Can't set attributes here.
+ inheritFrom(project.tasks.launcherJar.manifest)
+ }
+ // we need to include the groovy-swing Include-Package for it to run in the shadowJar
+ doFirst {
+ def jarFileManifests = []
+ groovyJars.each { jarFile ->
+ def mf = zipTree(jarFile).getFiles().find { it.getName().equals("MANIFEST.MF") }
+ if (mf != null) {
+ jarFileManifests += mf
+ }
+ }
+ manifest {
+ from (jarFileManifests) {
+ eachEntry { details ->
+ if (!details.key.equals("Import-Package")) {
+ details.exclude()
+ }
+ }
+ }
+ }
}
duplicatesStrategy "INCLUDE"
+ // this mainClassName is mandatory but gets ignored due to manifest created in doFirst{}. Set the Main-Class as an attribute in launcherJar instead
mainClassName = shadow_jar_main_class
mergeServiceFiles()
classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
dependsOn getdownImagesProcess
}
-task getdownWebsite() {
+task getdownWebsiteBuild() {
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"
+ description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer. No digest is created."
dependsOn getdownImages
if (buildDist) {
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", "${getdownImagesBuildDir}/${getdown_icon}")
- props.put("getdown_txt_ui.mac_dock_icon", "${getdownImagesBuildDir}/${getdown_mac_dock_icon}")
+ 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)
from s
into "${getdownAppBaseDir}/${getdown_wrapper_script_dir}"
}
- getdownTextLines += "resource = ${getdown_wrapper_script_dir}/${script}"
+ getdownTextLines += "xresource = ${getdown_wrapper_script_dir}/${script}"
}
}
task getdownDigest(type: JavaExec) {
group = "distribution"
description = "Digest the getdown website folder"
- dependsOn getdownWebsite
+
+ dependsOn getdownWebsiteBuild
+
doFirst {
classpath = files(getdownLauncher)
}
}
}
+task getdownWebsite {
+ group = "distribution"
+ description = "A task to create the whole getdown channel website dir including digest file"
+
+ dependsOn getdownWebsiteBuild
+ dependsOn getdownDigest
+}
task getdownArchiveBuild() {
group = "distribution"
description = "Put files in the archive dir to go on the website"
- dependsOn getdownWebsite
+ dependsOn getdownWebsiteBuild
def v = "v${JALVIEW_VERSION_UNDERSCORES}"
def vDir = "${getdownArchiveDir}/${v}"
'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,
into project.name
def EXCLUDE_FILES=[
+ "dist/*",
"build/*",
"bin/*",
"test-output/",
task jalviewjsSetEclipseWorkspace {
def propKey = "jalviewjs_eclipse_workspace"
def propVal = null
+ // see if jalviewjs_eclipse_workspace is set by a property
if (project.hasProperty(propKey)) {
propVal = project.getProperty(propKey)
if (propVal.startsWith("~/")) {
propVal = System.getProperty("user.home") + propVal.substring(1)
}
}
+ // else look for an existing build/jalviewjs/eclipse_workspace_location file
def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
def propsFile = file(propsFileName)
def eclipseWsDir = propVal
}
//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() }
+ //outputs.file(propsFileName) // don't want this to be deleted because of falsely "stale" task
+ outputs.upToDateWhen { eclipseWorkspace.exists() && (propsFile.exists() || !writeProps) }
}
task jalviewjsEclipsePaths {
- def eclipseProduct
+ def eclipseProductFile
+ def eclipseSetupLog
def eclipseRoot = jalviewjs_eclipse_root
if (eclipseRoot.startsWith("~/")) {
if (OperatingSystem.current().isMacOsX()) {
eclipseRoot += "/Eclipse.app"
eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
- eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
+ eclipseProductFile = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
+ eclipseSetupLog = "${eclipseRoot}/Contents/Eclipse/configuration/org.eclipse.oomph.setup/setup.log"
} 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"
+ eclipseProductFile = "${eclipseRoot}/.eclipseproduct"
+ eclipseSetupLog = "${eclipseRoot}/configuration/org.eclipse.oomph.setup/setup.log"
} 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"
+ eclipseProductFile = "${eclipseRoot}/.eclipseproduct"
+ eclipseSetupLog = "${eclipseRoot}/configuration/org.eclipse.oomph.setup/setup.log"
}
- eclipseVersion = "4.13" // default
+ eclipseVersion = "unknown" // default
def assumedVersion = true
- if (file(eclipseProduct).exists()) {
- def fis = new FileInputStream(eclipseProduct)
+ if (file(eclipseProductFile).exists()) {
+ def fis = new FileInputStream(eclipseProductFile)
def props = new Properties()
props.load(fis)
eclipseVersion = props.getProperty("version")
fis.close()
assumedVersion = false
}
+ if (file(eclipseSetupLog).exists()) {
+ def productRegex = /(?m)^\[[^\]]+\]\s+Product\s+(org\.eclipse.\S*)/
+ int lineCount = 0
+ file(eclipseSetupLog).eachLine { String line ->
+ def matcher = line =~ productRegex
+ if (matcher.size() > 0) {
+ eclipseProductVersion = matcher[0][1]
+ return true
+ }
+ if (lineCount >= 100) {
+ return true
+ }
+ lineCount++
+ }
+ }
def propKey = "eclipse_debug"
eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
if (!assumedVersion) {
println("ECLIPSE VERSION=${eclipseVersion}")
+ if (eclipseProductVersion.length() != 0) {
+ println("ECLIPSE PRODUCT=${eclipseProductVersion}")
+ }
}
}
}
*/
-task jalviewjsTransferUnzipSwingJs {
- def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
-
- doLast {
- copy {
- from zipTree(file_zip)
- into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
- }
- }
+task jalviewjsTransferUnzipSwingJs(type: Copy) {
+ def swingJsZipFile = "${jalviewDir}/${jalviewjs_swingjs_zip}"
+ from zipTree( "${jalviewDir}/${jalviewjs_swingjs_zip}" )
+ into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
- inputs.file file_zip
- outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
+ inputs.file swingJsZipFile
}
-task jalviewjsTransferUnzipLib {
- def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
+task jalviewjsTransferUnzipLib(type: Copy) {
+ def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip").sort()
- doLast {
- zipFiles.each { file_zip ->
- copy {
- from zipTree(file_zip)
- into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
+ zipFiles.each { file_zip ->
+ from zipTree(file_zip)
+
+ // The following replace() is needed due to a mismatch in Jmol calls to
+ // colorPtToFFRGB$javajs_util_T3d when only colorPtToFFRGB$javajs_util_T3 is defined
+ // in the SwingJS.zip (github or the one distributed with JSmol)
+ if (file_zip.getName().startsWith("Jmol-SwingJS")) {
+ filter { line ->
+ def l = ""
+ while(!line.equals(l)) {
+ line = line.replace('colorPtToFFRGB$javajs_util_T3d', 'colorPtToFFRGB$javajs_util_T3')
+ l = line
+ }
+ return line
}
}
- }
-
- inputs.files zipFiles
- outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
-}
-
-task jalviewjsTransferUnzipAllLibs {
- dependsOn jalviewjsTransferUnzipSwingJs
- dependsOn jalviewjsTransferUnzipLib
+ }
+ into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
}
if (! IN_ECLIPSE) {
inputs.properties(jalviewjsJ2sProps)
- outputs.file(jalviewjsJ2sAltSettingsFileName)
}
}
}
-task jalviewjsSyncAllLibs (type: Sync) {
- dependsOn jalviewjsTransferUnzipAllLibs
- def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
- inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
+task jalviewjsSyncLibs (type: Sync) {
+ dependsOn jalviewjsTransferUnzipLib
+ dependsOn jalviewjsTransferUnzipSwingJs
+
+ def inputDir = file("${jalviewDir}/${jalviewjsTransferSiteLibDir}")
+ def inputFiles = fileTree(dir: inputDir)
def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
from inputFiles
into outputDir
def outputFiles = []
- rename { filename ->
- outputFiles += "${outputDir}/${filename}"
- null
+ inputFiles.each{ file ->
+ def rfile = inputDir.toPath().relativize(file.toPath())
+ def ofile = new File("${outputDir}/${rfile}")
+ outputFiles += "${ofile}"
}
preserve {
- include "**"
+ include "**/*"
+ }
+
+ duplicatesStrategy "EXCLUDE"
+
+ outputs.files outputFiles
+ inputs.files inputFiles
+}
+
+task jalviewjsSyncSwingJS (type: Sync) {
+ dependsOn jalviewjsTransferUnzipSwingJs
+ mustRunAfter jalviewjsSyncLibs
+
+ def inputDir = file("${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
+ def inputFiles = fileTree(dir: inputDir)
+ def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
+
+ from inputFiles
+ into outputDir
+ def outputFiles = []
+ inputFiles.each{ file ->
+ def rfile = inputDir.toPath().relativize(file.toPath())
+ def ofile = new File("${outputDir}/${rfile}")
+ outputFiles += "${ofile}"
+ }
+ preserve {
+ include "**/*"
}
- // should this be exclude really ?
duplicatesStrategy "INCLUDE"
outputs.files outputFiles
inputs.files inputFiles
}
+task jalviewjsSyncAllLibs {
+ dependsOn jalviewjsSyncLibs
+ dependsOn jalviewjsSyncSwingJS
+}
+
task jalviewjsSyncResources (type: Sync) {
dependsOn buildResources
- def inputFiles = fileTree(dir: resourcesBuildDir)
+ def inputDir = file(resourcesBuildDir)
+ def inputFiles = fileTree(dir: inputDir)
def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
from inputFiles
into outputDir
def outputFiles = []
- rename { filename ->
- outputFiles += "${outputDir}/${filename}"
- null
+ inputFiles.each{ file ->
+ def rfile = inputDir.toPath().relativize(file.toPath())
+ def ofile = new File("${outputDir}/${rfile}")
+ outputFiles += "${ofile}"
}
preserve {
- include "**"
+ include "**/*"
}
outputs.files outputFiles
inputs.files inputFiles
task jalviewjsSyncSiteResources (type: Sync) {
- def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
+ def inputDir = file("${jalviewDir}/${jalviewjs_site_resource_dir}")
+ def inputFiles = fileTree(dir: inputDir)
def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
from inputFiles
into outputDir
def outputFiles = []
- rename { filename ->
- outputFiles += "${outputDir}/${filename}"
- null
+ inputFiles.each{ file ->
+ def rfile = inputDir.toPath().relativize(file.toPath())
+ def ofile = new File("${outputDir}/${rfile}")
+ outputFiles += "${ofile}"
}
preserve {
- include "**"
+ include "**/*"
}
+
outputs.files outputFiles
inputs.files inputFiles
}
task jalviewjsSyncBuildProperties (type: Sync) {
dependsOn createBuildProperties
- def inputFiles = [file(buildProperties)]
+
+ def f = file(buildProperties)
+ def inputDir = f.getParentFile()
+ def inputFiles = [f]
def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
from inputFiles
into outputDir
def outputFiles = []
- rename { filename ->
- outputFiles += "${outputDir}/${filename}"
- null
+ inputFiles.each{ file ->
+ def rfile = inputDir.toPath().relativize(file.toPath())
+ def ofile = new File("${outputDir}/${rfile}")
+ outputFiles += "${ofile}"
}
preserve {
- include "**"
+ include "**/*"
}
+
outputs.files outputFiles
inputs.files inputFiles
}
}
//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"
+ def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/${eclipse_project_name}"
+
executable(eclipseBinary)
args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
if (eclipseDebug) {
if (!IN_ECLIPSE) {
args += [ "-D${j2sHeadlessBuildProperty}=true" ]
args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
+ inputs.file("${jalviewjsJ2sAltSettingsFileName}")
}
- inputs.file("${jalviewDir}/.project")
- outputs.upToDateWhen {
- file(projdir).exists()
- }
+ outputs.upToDateWhen( {
+ if (IN_ECLIPSE) {
+ return true
+ }
+ def projDirExists = file(projdir).exists()
+ return projDirExists
+ } )
}
-
+// jalviewjs_eclipse_workspace_location_file
task jalviewjsTranspile(type: Exec) {
- dependsOn jalviewjsEclipseSetup
dependsOn jalviewjsProjectImport
- dependsOn jalviewjsEclipsePaths
+
if (!IN_ECLIPSE) {
dependsOn jalviewjsEnableAltFileProperty
}
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 info = """ROOT: ${jalviewjs_eclipse_root}
+ECLIPSE BINARY: ${eclipseBinary}
+ECLIPSE VERSION: ${eclipseVersion}
+ECLIPSE PRODUCT: ${eclipseProductVersion}
+ECLIPSE WORKSPACE: ${eclipseWorkspace}
+ECLIPSE DEBUG: ${eclipseDebug}
----
"""
def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
logErrFOS,
stderr)
}
+ standardOutput.write(string(info).getBytes("UTF-8"))
}
doLast {
- if (stdout.toString().contains("Error processing ")) {
+ def transpileError = false
+ def j2sIsActive = false
+ def j2sBuildStarting = false
+ def compilingLines = 0
+ def j2sBuildingJavascript = false
+ def j2sBuildingJavascriptRegex = /(?m)^J2S building JavaScript for (\d+) files/
+ def numFiles = 0
+ def transpilingLines = 0
+ stdout.toString().eachLine { String line ->
+ if (line.startsWith("J2S isActive true")) {
+ j2sIsActive = true
+ }
+ if (line.startsWith("J2S buildStarting")) {
+ j2sBuildStarting = true
+ }
+ if (line =~ / Compiling /) {
+ compilingLines++
+ }
+ if (!j2sBuildingJavascript) {
+ def matcher = line =~ j2sBuildingJavascriptRegex
+ if (matcher.size() > 0) {
+ numFiles = Integer.valueOf(matcher[0][1])
+ j2sBuildingJavascript = true
+ }
+ }
+ if (line.startsWith("J2S transpiling ")) {
+ transpilingLines++
+ }
+ if (line.contains("Error processing ")) {
+ transpileError = true
+ }
+ }
+
+ println("J2S IS ACTIVE=${j2sIsActive}")
+ println("J2S BUILD STARTING=${j2sBuildStarting}")
+ println("J2S BUILDING JAVASCRIPT=${j2sBuildingJavascript}")
+ println("NUM FILES=${numFiles}")
+ println("COMPILING LINES=${compilingLines}")
+ println("TRANSPILING LINES=${transpilingLines}")
+ println("TRANSPILE ERROR=${transpileError}")
+
+ if (!j2sIsActive
+ || transpileError
+ || (j2sBuildStarting && transpilingLines == 0)
+ || (transpilingLines < compilingLines)
+ || (transpilingLines != numFiles)
+ ) {
// 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}'")
}
}
+ if (IN_ECLIPSE) {
+ inputs.file(jalviewjsJ2sSettingsFileName)
+ } else {
+ inputs.file(jalviewjsJ2sAltSettingsFileName)
+ }
inputs.dir("${jalviewDir}/${sourceDir}")
- outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
- outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
+
+ def inputJavaDir = file("${jalviewDir}/${sourceDir}")
+ def inputJavaFiles = fileTree(dir: inputJavaDir)
+ def outputJsDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
+ def outputJsFiles = []
+ inputJavaFiles.each{ file ->
+ def rfile = inputJavaDir.toPath().relativize(file.toPath())
+ def ofile = new File("${outputJsDir}/${rfile}")
+ def ofilenamejs = ofile.getPath()
+ if (ofilenamejs.endsWith(".java")) {
+ ofilenamejs = ofilenamejs.substring(0,ofilenamejs.length()-4)+"js"
+ }
+ outputJsFiles += "${ofilenamejs}"
+ }
+
+ outputs.files outputJsFiles
+ outputs.file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}")
+}
+
+
+task jalviewjsTransferSiteMergeSiteJsDir (type: Copy) {
+ dependsOn jalviewjsTranspile
+
+ def inputDir = file("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
+ def outputDir = "${jalviewDir}/${jalviewjsTransferSiteMergeDir}"
+ into outputDir
+ from {
+ def inputFiles = fileTree(dir: inputDir)
+ return inputFiles
+ }
+
+ includeEmptyDirs = false
+ exclude "**/*.html"
+ exclude "**/*.htm"
+
+ // should this be exclude really ? No, swingjs dir should be transferred last (and overwrite)
+ duplicatesStrategy "INCLUDE"
+
+ // SiteJs files should take priority and write over existing files if different
+ // so we define the output files
+ outputs.upToDateWhen(
+ {
+ def transpiledFiles = jalviewjsTransferSiteMergeSiteJsDir.getOutputs().getFiles()
+ def inputFiles = fileTree(dir: inputDir)
+ if (inputFiles.size() < transpiledFiles.size()) {
+ return false
+ }
+ def retVal = ! inputFiles.any { file ->
+ def rfile = inputDir.toPath().relativize(file.toPath())
+ def ofile = new File("${outputDir}/${rfile}")
+ if (!ofile.exists() || ofile.lastModified() < file.lastModified()) {
+ return true // this is NOTted to false
+ }
+ }
+
+ return retVal
+ }
+ )
+
+ inputs.files jalviewjsTranspile
+}
+
+task jalviewjsTransferSiteMergeLibDir (type: Copy) {
+ dependsOn jalviewjsTransferUnzipLib
+
+ def outputDir = "${jalviewDir}/${jalviewjsTransferSiteMergeDir}"
+
+ // This takes the outputs of jalviewjsTransferUnzipLib
+ from jalviewjsTransferUnzipLib
+ into outputDir
+
+ includeEmptyDirs = false
+ exclude "**/*.html"
+ exclude "**/*.htm"
+
+ // don't overwrite files in the destination
+ // Note, this closure gets run at run stage not config stage
+ eachFile {
+ if (it.getRelativePath().getFile(file(outputDir)).exists()) {
+ it.exclude()
+ }
+ }
+
+ duplicatesStrategy "INCLUDE"
+}
+
+task jalviewjsTransferSiteMergeSwingJsDir (type: Copy) {
+ dependsOn jalviewjsTransferUnzipSwingJs
+
+ def outputDir = "${jalviewDir}/${jalviewjsTransferSiteMergeDir}"
+
+ // This takes the outputs of jalviewjsTransferUnzipSwingJs
+ from jalviewjsTransferUnzipSwingJs
+ into outputDir
+
+ includeEmptyDirs = false
+ exclude "**/*.html"
+ exclude "**/*.htm"
+
+ // DO overwrite files in the destination
+
+ // should this be exclude really ? No, swingjs dir should be transferred last (and overwrite)
+ duplicatesStrategy "INCLUDE"
+}
+
+// we run after SiteJs and exclude overwriting files
+jalviewjsTransferSiteMergeLibDir.mustRunAfter jalviewjsTransferSiteMergeSiteJsDir
+jalviewjsTransferSiteMergeLibDir.mustRunAfter jalviewjsTransferSiteMergeSwingJsDir
+// we run this last, overwriting files from sitejs and lib, to ensure a consistent SwingJS
+jalviewjsTransferSiteMergeSwingJsDir.mustRunAfter jalviewjsTransferSiteMergeSiteJsDir
+
+task jalviewjsTransferSiteMergeDirs {
+ dependsOn jalviewjsTransferSiteMergeLibDir
+ dependsOn jalviewjsTransferSiteMergeSwingJsDir
+ dependsOn jalviewjsTransferSiteMergeSiteJsDir
}
def coreTop = file(prefixFile)
def coreBottom = file(suffixFile)
+ def missingFiles = []
coreFile.getParentFile().mkdirs()
coreFile.createNewFile()
coreFile.write( coreTop.getText("UTF-8") )
msg = "...file '"+f.getPath()+"' does not exist, skipping"
println(msg)
logOutFile.append(msg+"\n")
+ missingFiles += f
}
}
coreFile.append( coreBottom.getText("UTF-8") )
def logErrFOS = logOutFOS
javaexec {
- classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
+ classpath = files([closureCompilerJar])
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"
+ args = [ "--compilation_level", jalviewjs_closure_compiler_optimization_level, "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
+ maxHeapSize = "4g"
msg = "\nRunning '"+commandLine.join(' ')+"'\n"
println(msg)
}
}
msg = "--"
+ if (missingFiles.size() > 0) {
+ msg += "\n!!! These files were listed but missing:\n"
+ missingFiles.each { file -> msg += "!!! " + file.getPath() + "\n" }
+ msg = "--"
+ }
println(msg)
logOutFile.append(msg+"\n")
}
-task jalviewjsBuildAllCores {
+task jalviewjsBuildCore {
group "JalviewJS"
description "Build the core js lib closures listed in the classlists dir"
- dependsOn jalviewjsTranspile
- dependsOn jalviewjsTransferUnzipSwingJs
+ dependsOn jalviewjsTransferSiteMergeDirs
- 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 j2sDir = "${jalviewDir}/${jalviewjsTransferSiteMergeDir}/${jalviewjs_j2s_subdir}"
+ def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteMergeDir}/${jalviewjs_j2s_subdir}"
+ def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteMergeDir}/${jalviewjs_j2s_subdir}"
+ def jsDir = "${jalviewDir}/${jalviewjsTransferSiteMergeDir}/${jalviewjs_js_subdir}"
def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
def prefixFile = "${jsDir}/core/coretop2.js"
def suffixFile = "${jsDir}/core/corebottom2.js"
]
}
- // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
- //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
+ // _jalview core
classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
jalviewjsCoreClasslists = []
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")
+ logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildCore\n----\n")
jalviewjsCoreClasslists.each {
jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
}
}
+ inputs.file(closureCompilerJar)
}
task jalviewjsPublishCoreTemplates {
- dependsOn jalviewjsBuildAllCores
+ dependsOn jalviewjsBuildCore
+
def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
def inputFile = file(inputFileName)
def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
task jalviewjsSyncCore (type: Sync) {
- dependsOn jalviewjsBuildAllCores
+ dependsOn jalviewjsBuildCore
dependsOn jalviewjsPublishCoreTemplates
- def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
+
+ def inputDir = file("${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
+ def inputFiles = fileTree(dir: inputDir)
def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
from inputFiles
into outputDir
def outputFiles = []
- rename { filename ->
- outputFiles += "${outputDir}/${filename}"
- null
+ inputFiles.each{ file ->
+ def rfile = inputDir.toPath().relativize(file.toPath())
+ def ofile = new File("${outputDir}/${rfile}")
+ outputFiles += "${ofile}"
}
preserve {
- include "**"
+ include "**/*"
}
+
outputs.files outputFiles
inputs.files inputFiles
}
// this Copy version of TransferSiteJs will delete anything else in the target dir
+task jalviewjsCopyTransferSiteMergeDir(type: Copy) {
+ dependsOn jalviewjsTransferSiteMergeDirs
+
+ from "${jalviewDir}/${jalviewjsTransferSiteMergeDir}"
+ into "${jalviewDir}/${jalviewjsSiteDir}"
+}
+
+
+// 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}"
}
include "**/*.*"
into "${jalviewDir}/${jalviewjsSiteDir}"
preserve {
- include "**"
+ include "**/*"
}
}
task jalviewjsPrepareSite {
group "JalviewJS"
description "Prepares the website folder including unzipping files and copying resources"
- dependsOn jalviewjsSyncAllLibs
+ //dependsOn jalviewjsSyncAllLibs // now using jalviewjsCopyTransferSiteMergeDir
dependsOn jalviewjsSyncResources
dependsOn jalviewjsSyncSiteResources
dependsOn jalviewjsSyncBuildProperties
task jalviewjsBuildSite {
group "JalviewJS"
description "Builds the whole website including transpiled code"
- dependsOn jalviewjsCopyTransferSiteJs
+ dependsOn jalviewjsCopyTransferSiteMergeDir
dependsOn jalviewjsPrepareSite
}
}
+task jalviewjsCopyStderrLaunchFile(type: Copy) {
+ from file(jalviewjs_stderr_launch)
+ into jalviewjsSiteDir
+
+ inputs.file jalviewjs_stderr_launch
+ outputs.file jalviewjsStderrLaunchFilename
+}
+
+task cleanJalviewjsChromiumUserDir {
+ doFirst {
+ delete jalviewjsChromiumUserDir
+ }
+ outputs.dir jalviewjsChromiumUserDir
+ // always run when depended on
+ outputs.upToDateWhen { !file(jalviewjsChromiumUserDir).exists() }
+}
+
+task jalviewjsChromiumProfile {
+ dependsOn cleanJalviewjsChromiumUserDir
+ mustRunAfter cleanJalviewjsChromiumUserDir
+
+ def firstRun = file("${jalviewjsChromiumUserDir}/First Run")
+
+ doFirst {
+ mkdir jalviewjsChromiumProfileDir
+ firstRun.text = ""
+ }
+ outputs.file firstRun
+}
+
+task jalviewjsLaunchTest {
+ group "Test"
+ description "Check JalviewJS opens in a browser"
+ dependsOn jalviewjsBuildSite
+ dependsOn jalviewjsCopyStderrLaunchFile
+ dependsOn jalviewjsChromiumProfile
+
+ def macOS = OperatingSystem.current().isMacOsX()
+ def chromiumBinary = macOS ? jalviewjs_macos_chromium_binary : jalviewjs_chromium_binary
+ if (chromiumBinary.startsWith("~/")) {
+ chromiumBinary = System.getProperty("user.home") + chromiumBinary.substring(1)
+ }
+
+ def stdout
+ def stderr
+ doFirst {
+ def timeoutms = Integer.valueOf(jalviewjs_chromium_overall_timeout) * 1000
+
+ def binary = file(chromiumBinary)
+ if (!binary.exists()) {
+ throw new StopExecutionException("Could not find chromium binary '${chromiumBinary}'. Cannot run task ${name}.")
+ }
+ stdout = new ByteArrayOutputStream()
+ stderr = new ByteArrayOutputStream()
+ def execStdout
+ def execStderr
+ if (jalviewjs_j2s_to_console.equals("true")) {
+ execStdout = new org.apache.tools.ant.util.TeeOutputStream(
+ stdout,
+ System.out)
+ execStderr = new org.apache.tools.ant.util.TeeOutputStream(
+ stderr,
+ System.err)
+ } else {
+ execStdout = stdout
+ execStderr = stderr
+ }
+ // macOS seems okay now with timeout arguments
+ def execArgs = [
+ "--virtual-time-budget=${timeoutms}",
+ "--timeout=${timeoutms}",
+ ]
+ execArgs += [
+ "--no-sandbox", // --no-sandbox IS USED BY THE THORIUM APPIMAGE ON THE BUILDSERVER
+ "--headless=new",
+ "--disable-gpu",
+ "--user-data-dir=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_chromium_user_dir}",
+ "--profile-directory=${jalviewjs_chromium_profile_name}",
+ "--allow-file-access-from-files",
+ "--enable-logging=stderr",
+ "file://${jalviewDirAbsolutePath}/${jalviewjsStderrLaunchFilename}"
+ ]
+
+ java.lang.Runnable runChrome = () -> {
+ exec {
+ standardOutput = execStdout
+ errorOutput = execStderr
+ executable(chromiumBinary)
+ args(execArgs)
+ println "COMMAND: '"+commandLine.join(" ")+"'"
+ }
+ }
+
+ if (macOS) {
+ // we create our own timeout executor as --timeout doesn't work on macOS
+ ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
+
+ Future f1 = executor.submit( runChrome )
+
+ def noChangeBytes = 0
+ def noChangeIterations = 0
+ executor.scheduleAtFixedRate(
+ () -> {
+ String stderrString = stderr.toString()
+ // shutdown the task if we have a success string
+ if (stderrString.contains(jalviewjs_desktop_init_string)) {
+ f1.cancel(true)
+ Thread.sleep(100)
+ executor.shutdownNow()
+ } else
+ // if no change in stderr for 10s then also end
+ if (noChangeIterations >= jalviewjs_chromium_idle_timeout) {
+ executor.shutdownNow()
+ }
+ if (stderrString.length() == noChangeBytes) {
+ noChangeIterations++
+ } else {
+ noChangeBytes = stderrString.length()
+ noChangeIterations = 0
+ }
+ },
+ 200, 200, TimeUnit.MILLISECONDS)
+
+ executor.schedule(new Runnable(){
+ public void run(){
+ f1.cancel(true)
+ executor.shutdownNow()
+ }
+ }, timeoutms, TimeUnit.MILLISECONDS)
+
+ executor.awaitTermination(timeoutms+200, TimeUnit.MILLISECONDS)
+ f1.cancel(true)
+ executor.shutdownNow()
+ } else {
+ // just run chrome and rely on --virtual-time-budget and --timeout
+ runChrome.run()
+ }
+
+ }
+
+ doLast {
+ def found = false
+ stderr.toString().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.")
+ }
+ }
+}
+
+
task jalviewjs {
group "JalviewJS"
- description "Build the site"
+ description "Build the JalviewJS site and run the launch test"
dependsOn jalviewjsBuildSite
+ dependsOn jalviewjsLaunchTest
}
-