1 /* Convention for properties. Read from gradle.properties, use lower_case_underlines for property names.
2 * For properties set within build.gradle, use camelCaseNoSpace.
4 import org.apache.tools.ant.filters.ReplaceTokens
5 import org.gradle.internal.os.OperatingSystem
6 import org.gradle.plugins.ide.internal.generator.PropertiesPersistableConfigurationObject
7 import org.gradle.api.internal.PropertiesTransformer
8 import org.gradle.util.ConfigureUtil
9 import org.gradle.plugins.ide.eclipse.model.Output
10 import org.gradle.plugins.ide.eclipse.model.Library
11 import java.security.MessageDigest
12 import groovy.transform.ExternalizeMethods
13 import groovy.util.XmlParser
14 import groovy.xml.XmlUtil
15 import groovy.json.JsonBuilder
16 import com.vladsch.flexmark.util.ast.Node
17 import com.vladsch.flexmark.html.HtmlRenderer
18 import com.vladsch.flexmark.parser.Parser
19 import com.vladsch.flexmark.util.data.MutableDataSet
20 import com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension
21 import com.vladsch.flexmark.ext.tables.TablesExtension
22 import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension
23 import com.vladsch.flexmark.ext.autolink.AutolinkExtension
24 import com.vladsch.flexmark.ext.anchorlink.AnchorLinkExtension
25 import com.vladsch.flexmark.ext.toc.TocExtension
26 import com.google.common.hash.HashCode
27 import com.google.common.hash.Hashing
28 import com.google.common.io.Files
29 import org.jsoup.Jsoup
30 import org.jsoup.nodes.Element
38 classpath "com.vladsch.flexmark:flexmark-all:0.62.0"
39 classpath "org.jsoup:jsoup:1.14.3"
48 id "com.diffplug.gradle.spotless" version "3.28.0"
49 id 'com.github.johnrengelman.shadow' version '4.0.3'
50 id 'com.install4j.gradle' version '9.0.6'
51 id 'com.dorongold.task-tree' version '2.1.0' // only needed to display task dependency tree with gradle task1 [task2 ...] taskTree
52 id 'com.palantir.git-version' version '0.13.0' apply false
63 // in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use
64 def string(Object o) {
65 return o == null ? "" : o.toString()
68 def overrideProperties(String propsFileName, boolean output = false) {
69 if (propsFileName == null) {
72 def propsFile = file(propsFileName)
73 if (propsFile != null && propsFile.exists()) {
74 println("Using properties from file '${propsFileName}'")
76 def p = new Properties()
77 def localPropsFIS = new FileInputStream(propsFile)
83 if (project.hasProperty(key)) {
84 oldval = project.findProperty(key)
85 project.setProperty(key, val)
87 println("Overriding property '${key}' ('${oldval}') with ${file(propsFile).getName()} value '${val}'")
90 ext.setProperty(key, val)
92 println("Setting ext property '${key}' with ${file(propsFile).getName()}s value '${val}'")
96 } catch (Exception e) {
97 println("Exception reading local.properties")
104 jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
105 jalviewDirRelativePath = jalviewDir
108 getdownChannelName = CHANNEL.toLowerCase()
109 // default to "default". Currently only has different cosmetics for "develop", "release", "default"
110 propertiesChannelName = ["develop", "release", "test-release", "jalviewjs", "jalviewjs-release" ].contains(getdownChannelName) ? getdownChannelName : "default"
111 // Import channel_properties
112 channelDir = string("${jalviewDir}/${channel_properties_dir}/${propertiesChannelName}")
113 channelGradleProperties = string("${channelDir}/channel_gradle.properties")
114 channelPropsFile = string("${channelDir}/${resource_dir}/${channel_props}")
115 overrideProperties(channelGradleProperties, false)
116 // local build environment properties
117 // can be "projectDir/local.properties"
118 overrideProperties("${projectDir}/local.properties", true)
119 // or "../projectDir_local.properties"
120 overrideProperties(projectDir.getParent() + "/" + projectDir.getName() + "_local.properties", true)
123 // Import releaseProps from the RELEASE file
124 // or a file specified via JALVIEW_RELEASE_FILE if defined
125 // Expect jalview.version and target release branch in jalview.release
126 releaseProps = new Properties();
127 def releasePropFile = findProperty("JALVIEW_RELEASE_FILE");
128 def defaultReleasePropFile = "${jalviewDirAbsolutePath}/RELEASE";
130 (new File(releasePropFile!=null ? releasePropFile : defaultReleasePropFile)).withInputStream {
131 releaseProps.load(it)
133 } catch (Exception fileLoadError) {
134 throw new Error("Couldn't load release properties file "+(releasePropFile==null ? defaultReleasePropFile : "from custom location: releasePropFile"),fileLoadError);
137 // Set JALVIEW_VERSION if it is not already set
138 if (findProperty("JALVIEW_VERSION")==null || "".equals(JALVIEW_VERSION)) {
139 JALVIEW_VERSION = releaseProps.get("jalview.version")
141 println("JALVIEW_VERSION is set to '${JALVIEW_VERSION}'")
143 // this property set when running Eclipse headlessly
144 j2sHeadlessBuildProperty = string("net.sf.j2s.core.headlessbuild")
145 // this property set by Eclipse
146 eclipseApplicationProperty = string("eclipse.application")
147 // CHECK IF RUNNING FROM WITHIN ECLIPSE
148 def eclipseApplicationPropertyVal = System.properties[eclipseApplicationProperty]
149 IN_ECLIPSE = eclipseApplicationPropertyVal != null && eclipseApplicationPropertyVal.startsWith("org.eclipse.ui.")
150 // BUT WITHOUT THE HEADLESS BUILD PROPERTY SET
151 if (System.properties[j2sHeadlessBuildProperty].equals("true")) {
152 println("Setting IN_ECLIPSE to ${IN_ECLIPSE} as System.properties['${j2sHeadlessBuildProperty}'] == '${System.properties[j2sHeadlessBuildProperty]}'")
156 println("WITHIN ECLIPSE IDE")
158 println("HEADLESS BUILD")
161 J2S_ENABLED = (project.hasProperty('j2s.compiler.status') && project['j2s.compiler.status'] != null && project['j2s.compiler.status'] == "enable")
163 println("J2S ENABLED")
166 System.properties.sort { it.key }.each {
167 key, val -> println("SYSTEM PROPERTY ${key}='${val}'")
170 if (false && IN_ECLIPSE) {
171 jalviewDir = jalviewDirAbsolutePath
176 buildDate = new Date().format("yyyyMMdd")
179 bareSourceDir = string(source_dir)
180 sourceDir = string("${jalviewDir}/${bareSourceDir}")
181 resourceDir = string("${jalviewDir}/${resource_dir}")
182 bareTestSourceDir = string(test_source_dir)
183 testDir = string("${jalviewDir}/${bareTestSourceDir}")
185 classesDir = string("${jalviewDir}/${classes_dir}")
188 useClover = clover.equals("true")
189 cloverBuildDir = "${buildDir}/clover"
190 cloverInstrDir = file("${cloverBuildDir}/clover-instr")
191 cloverClassesDir = file("${cloverBuildDir}/clover-classes")
192 cloverReportDir = file("${buildDir}/reports/clover")
193 cloverTestInstrDir = file("${cloverBuildDir}/clover-test-instr")
194 cloverTestClassesDir = file("${cloverBuildDir}/clover-test-classes")
195 //cloverTestClassesDir = cloverClassesDir
196 cloverDb = string("${cloverBuildDir}/clover.db")
198 testSourceDir = useClover ? cloverTestInstrDir : testDir
199 testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}"
201 getdownChannelDir = string("${getdown_website_dir}/${propertiesChannelName}")
202 getdownAppBaseDir = string("${jalviewDir}/${getdownChannelDir}/${JAVA_VERSION}")
203 getdownArchiveDir = string("${jalviewDir}/${getdown_archive_dir}")
204 getdownFullArchiveDir = null
205 getdownTextLines = []
206 getdownLaunchJvl = null
207 getdownVersionLaunchJvl = null
209 buildProperties = null
211 // the following values might be overridden by the CHANNEL switch
212 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
213 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
214 getdownArchiveAppBase = getdown_archive_base
215 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
216 getdownAppDistDir = getdown_app_dir_alt
217 getdownImagesDir = string("${jalviewDir}/${getdown_images_dir}")
218 getdownSetAppBaseProperty = false // whether to pass the appbase and appdistdir to the application
219 reportRsyncCommand = false
220 jvlChannelName = CHANNEL.toLowerCase()
221 install4jSuffix = CHANNEL.substring(0, 1).toUpperCase() + CHANNEL.substring(1).toLowerCase(); // BUILD -> Build
222 install4jDMGDSStore = "${install4j_images_dir}/${install4j_dmg_ds_store}"
223 install4jDMGBackgroundImage = "${install4j_images_dir}/${install4j_dmg_background}"
224 install4jInstallerName = "${jalview_name} Non-Release Installer"
225 install4jExecutableName = install4j_executable_name
226 install4jExtraScheme = "jalviewx"
227 install4jMacIconsFile = string("${install4j_images_dir}/${install4j_mac_icons_file}")
228 install4jWindowsIconsFile = string("${install4j_images_dir}/${install4j_windows_icons_file}")
229 install4jPngIconFile = string("${install4j_images_dir}/${install4j_png_icon_file}")
230 install4jBackground = string("${install4j_images_dir}/${install4j_background}")
231 install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
232 install4jCheckSums = true
234 applicationName = "${jalview_name}"
238 // TODO: get bamboo build artifact URL for getdown artifacts
239 getdown_channel_base = bamboo_channelbase
240 getdownChannelName = string("${bamboo_planKey}/${JAVA_VERSION}")
241 getdownAppBase = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
242 jvlChannelName += "_${getdownChannelName}"
243 // automatically add the test group Not-bamboo for exclusion
244 if ("".equals(testng_excluded_groups)) {
245 testng_excluded_groups = "Not-bamboo"
247 install4jExtraScheme = "jalviewb"
250 case [ "RELEASE", "JALVIEWJS-RELEASE" ]:
251 getdownAppDistDir = getdown_app_dir_release
252 getdownSetAppBaseProperty = true
253 reportRsyncCommand = true
255 install4jInstallerName = "${jalview_name} Installer"
259 getdownChannelName = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
260 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
261 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
262 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
263 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
265 package_dir = string("${ARCHIVEDIR}/${package_dir}")
266 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
269 reportRsyncCommand = true
270 install4jExtraScheme = "jalviewa"
274 getdownChannelName = string("archive/${JALVIEW_VERSION}")
275 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
276 getdownAppBase = file(getdownAppBaseDir).toURI().toString()
277 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
278 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
280 package_dir = string("${ARCHIVEDIR}/${package_dir}")
281 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
284 reportRsyncCommand = true
285 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
286 install4jSuffix = "Archive"
287 install4jExtraScheme = "jalviewa"
291 reportRsyncCommand = true
292 getdownSetAppBaseProperty = true
293 // DEVELOP-RELEASE is usually associated with a Jalview release series so set the version
294 JALVIEW_VERSION=JALVIEW_VERSION+"-d${buildDate}"
296 install4jSuffix = "Develop"
297 install4jExtraScheme = "jalviewd"
298 install4jInstallerName = "${jalview_name} Develop Installer"
302 reportRsyncCommand = true
303 getdownSetAppBaseProperty = true
304 // Don't ignore transpile errors for release build
305 if (jalviewjs_ignore_transpile_errors.equals("true")) {
306 jalviewjs_ignore_transpile_errors = "false"
307 println("Setting jalviewjs_ignore_transpile_errors to 'false'")
309 JALVIEW_VERSION = JALVIEW_VERSION+"-test"
310 install4jSuffix = "Test"
311 install4jExtraScheme = "jalviewt"
312 install4jInstallerName = "${jalview_name} Test Installer"
315 case ~/^SCRATCH(|-[-\w]*)$/:
316 getdownChannelName = CHANNEL
317 JALVIEW_VERSION = JALVIEW_VERSION+"-"+CHANNEL
319 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
320 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
321 reportRsyncCommand = true
322 install4jSuffix = "Scratch"
326 if (!file("${LOCALDIR}").exists()) {
327 throw new GradleException("Must provide a LOCALDIR value to produce a local distribution")
329 getdownAppBase = file(file("${LOCALDIR}").getAbsolutePath()).toURI().toString()
330 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
332 JALVIEW_VERSION = "TEST"
333 install4jSuffix = "Test-Local"
334 install4jExtraScheme = "jalviewt"
335 install4jInstallerName = "${jalview_name} Test Installer"
338 case [ "LOCAL", "JALVIEWJS" ]:
339 JALVIEW_VERSION = "TEST"
340 getdownAppBase = file(getdownAppBaseDir).toURI().toString()
341 getdownArchiveAppBase = file("${jalviewDir}/${getdown_archive_dir}").toURI().toString()
342 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
343 install4jExtraScheme = "jalviewl"
344 install4jCheckSums = false
347 default: // something wrong specified
348 throw new GradleException("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
352 JALVIEW_VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
353 hugoDataJsonFile = file("${jalviewDir}/${hugo_build_dir}/${hugo_data_installers_dir}/installers-${JALVIEW_VERSION_UNDERSCORES}.json")
354 hugoArchiveMdFile = file("${jalviewDir}/${hugo_build_dir}/${hugo_version_archive_dir}/Version-${JALVIEW_VERSION_UNDERSCORES}/_index.md")
355 // override getdownAppBase if requested
356 if (findProperty("getdown_appbase_override") != null) {
357 // revert to LOCAL if empty string
358 if (string(getdown_appbase_override) == "") {
359 getdownAppBase = file(getdownAppBaseDir).toURI().toString()
360 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
361 } else if (string(getdown_appbase_override).startsWith("file://")) {
362 getdownAppBase = string(getdown_appbase_override)
363 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
365 getdownAppBase = string(getdown_appbase_override)
367 println("Overriding getdown appbase with '${getdownAppBase}'")
369 // sanitise file name for jalview launcher file for this channel
370 jvlChannelName = jvlChannelName.replaceAll("[^\\w\\-]+", "_")
371 // install4j application and folder names
372 if (install4jSuffix == "") {
373 install4jBundleId = "${install4j_bundle_id}"
374 install4jWinApplicationId = install4j_release_win_application_id
376 applicationName = "${jalview_name} ${install4jSuffix}"
377 install4jBundleId = "${install4j_bundle_id}-" + install4jSuffix.toLowerCase()
378 // add int hash of install4jSuffix to the last part of the application_id
379 def id = install4j_release_win_application_id
380 def idsplitreverse = id.split("-").reverse()
381 idsplitreverse[0] = idsplitreverse[0].toInteger() + install4jSuffix.hashCode()
382 install4jWinApplicationId = idsplitreverse.reverse().join("-")
384 // sanitise folder and id names
385 // install4jApplicationFolder = e.g. "Jalview Build"
386 install4jApplicationFolder = applicationName
387 .replaceAll("[\"'~:/\\\\\\s]", "_") // replace all awkward filename chars " ' ~ : / \
388 .replaceAll("_+", "_") // collapse __
389 install4jInternalId = applicationName
391 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
392 .replaceAll("_+", "") // collapse __
393 //.replaceAll("_*-_*", "-") // collapse _-_
394 install4jUnixApplicationFolder = applicationName
396 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
397 .replaceAll("_+", "_") // collapse __
398 .replaceAll("_*-_*", "-") // collapse _-_
401 getdownWrapperLink = install4jUnixApplicationFolder // e.g. "jalview_local"
402 getdownAppDir = string("${getdownAppBaseDir}/${getdownAppDistDir}")
403 //getdownJ11libDir = "${getdownAppBaseDir}/${getdown_j11lib_dir}"
404 getdownResourceDir = string("${getdownAppBaseDir}/${getdown_resource_dir}")
405 getdownInstallDir = string("${getdownAppBaseDir}/${getdown_install_dir}")
406 getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
407 getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
408 /* compile without modules -- using classpath libraries
409 modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
410 modules_runtimeClasspath = modules_compileClasspath
416 apply plugin: "com.palantir.git-version"
417 def details = versionDetails()
418 gitHash = details.gitHash
419 gitBranch = details.branchName
420 } catch(org.gradle.api.internal.plugins.PluginApplicationException e) {
421 println("Not in a git repository. Using git values from RELEASE properties file.")
422 gitHash = releaseProps.getProperty("git.hash")
423 gitBranch = releaseProps.getProperty("git.branch")
424 } catch(java.lang.RuntimeException e1) {
425 throw new GradleException("Error with git-version plugin. Directory '.git' exists but versionDetails() cannot be found.")
428 println("Using a ${CHANNEL} profile.")
430 additional_compiler_args = []
431 // configure classpath/args for j8/j11 compilation
432 if (JAVA_VERSION.equals("1.8")) {
433 JAVA_INTEGER_VERSION = string("8")
436 libDistDir = j8libDir
437 compile_source_compatibility = 1.8
438 compile_target_compatibility = 1.8
439 // these are getdown.txt properties defined dependent on the JAVA_VERSION
440 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java8_min_version"))
441 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java8_max_version"))
442 // this property is assigned below and expanded to multiple lines in the getdown task
443 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java8_txt_multi_java_location"))
444 // this property is for the Java library used in eclipse
445 eclipseJavaRuntimeName = string("JavaSE-1.8")
446 } else if (JAVA_VERSION.equals("11")) {
447 JAVA_INTEGER_VERSION = string("11")
449 libDistDir = j11libDir
450 compile_source_compatibility = 11
451 compile_target_compatibility = 11
452 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
453 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
454 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
455 eclipseJavaRuntimeName = string("JavaSE-11")
456 /* compile without modules -- using classpath libraries
457 additional_compiler_args += [
458 '--module-path', modules_compileClasspath.asPath,
459 '--add-modules', j11modules
462 } else if (JAVA_VERSION.equals("17")) {
463 JAVA_INTEGER_VERSION = string("17")
465 libDistDir = j17libDir
466 compile_source_compatibility = 17
467 compile_target_compatibility = 17
468 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
469 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
470 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
471 eclipseJavaRuntimeName = string("JavaSE-17")
472 /* compile without modules -- using classpath libraries
473 additional_compiler_args += [
474 '--module-path', modules_compileClasspath.asPath,
475 '--add-modules', j11modules
479 throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
484 JAVA_MIN_VERSION = JAVA_VERSION
485 JAVA_MAX_VERSION = JAVA_VERSION
486 def jreInstallsDir = string(jre_installs_dir)
487 if (jreInstallsDir.startsWith("~/")) {
488 jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1)
490 macosJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-mac-x64/jre")
491 windowsJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-windows-x64/jre")
492 linuxJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-linux-x64/jre")
493 macosJavaVMTgz = string("${jreInstallsDir}/tgz/jre_${JAVA_INTEGER_VERSION}_mac_x64.tar.gz")
494 windowsJavaVMTgz = string("${jreInstallsDir}/tgz/jre_${JAVA_INTEGER_VERSION}_windows_x64.tar.gz")
495 linuxJavaVMTgz = string("${jreInstallsDir}/tgz/jre_${JAVA_INTEGER_VERSION}_linux_x64.tar.gz")
496 install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
497 install4jConfFileName = string("jalview-install4j-conf.install4j")
498 install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
499 install4jHomeDir = install4j_home_dir
500 if (install4jHomeDir.startsWith("~/")) {
501 install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1)
504 resourceBuildDir = string("${buildDir}/resources")
505 resourcesBuildDir = string("${resourceBuildDir}/resources_build")
506 helpBuildDir = string("${resourceBuildDir}/help_build")
507 docBuildDir = string("${resourceBuildDir}/doc_build")
509 if (buildProperties == null) {
510 buildProperties = string("${resourcesBuildDir}/${build_properties_file}")
512 buildingHTML = string("${jalviewDir}/${doc_dir}/building.html")
513 helpParentDir = string("${jalviewDir}/${help_parent_dir}")
514 helpSourceDir = string("${helpParentDir}/${help_dir}")
515 helpFile = string("${helpBuildDir}/${help_dir}/help.jhm")
518 relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
519 jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
520 jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}")
522 jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
524 jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
526 jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
527 jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
528 jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
529 jalviewjsJalviewCoreHtmlFile = string("")
530 jalviewjsJalviewCoreName = string(jalviewjs_core_name)
531 jalviewjsCoreClasslists = []
532 jalviewjsJalviewTemplateName = string(jalviewjs_name)
533 jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
534 jalviewjsJ2sAltSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_alt_settings}")
535 jalviewjsJ2sProps = null
536 jalviewjsJ2sPlugin = jalviewjs_j2s_plugin
538 eclipseWorkspace = null
539 eclipseBinary = string("")
540 eclipseVersion = string("")
550 outputDir = file(classesDir)
554 srcDirs = [ resourcesBuildDir, docBuildDir, helpBuildDir ]
557 compileClasspath = files(sourceSets.main.java.outputDir)
558 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
560 runtimeClasspath = compileClasspath
561 runtimeClasspath += files(sourceSets.main.resources.srcDirs)
566 srcDirs cloverInstrDir
567 outputDir = cloverClassesDir
571 srcDirs = sourceSets.main.resources.srcDirs
574 compileClasspath = files( sourceSets.clover.java.outputDir )
575 //compileClasspath += files( testClassesDir )
576 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
577 compileClasspath += fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
578 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
580 runtimeClasspath = compileClasspath
585 srcDirs testSourceDir
586 outputDir = file(testClassesDir)
590 srcDirs = useClover ? sourceSets.clover.resources.srcDirs : sourceSets.main.resources.srcDirs
593 compileClasspath = files( sourceSets.test.java.outputDir )
594 compileClasspath += useClover ? sourceSets.clover.compileClasspath : sourceSets.main.compileClasspath
595 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
597 runtimeClasspath = compileClasspath
598 runtimeClasspath += files(sourceSets.test.resources.srcDirs)
604 // eclipse project and settings files creation, also used by buildship
607 name = eclipse_project_name
609 natures 'org.eclipse.jdt.core.javanature',
610 'org.eclipse.jdt.groovy.core.groovyNature',
611 'org.eclipse.buildship.core.gradleprojectnature'
613 buildCommand 'org.eclipse.jdt.core.javabuilder'
614 buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
618 //defaultOutputDir = sourceSets.main.java.outputDir
619 configurations.each{ c->
620 if (c.isCanBeResolved()) {
621 minusConfigurations += [c]
625 plusConfigurations = [ ]
629 def removeTheseToo = []
630 HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
631 cp.entries.each { entry ->
632 // This conditional removes all src classpathentries that a) have already been added or b) aren't "src" or "test".
633 // e.g. this removes the resources dir being copied into bin/main, bin/test AND bin/clover
634 // we add the resources and help/help dirs in as libs afterwards (see below)
635 if (entry.kind == 'src') {
636 if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) {
637 removeTheseToo += entry
639 alreadyAddedSrcPath.putAt(entry.path, true)
644 cp.entries.removeAll(removeTheseToo)
646 //cp.entries += new Output("${eclipse_bin_dir}/main")
647 if (file(helpParentDir).isDirectory()) {
648 cp.entries += new Library(fileReference(helpParentDir))
650 if (file(resourceDir).isDirectory()) {
651 cp.entries += new Library(fileReference(resourceDir))
654 HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
656 sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
657 //don't want to add outputDir as eclipse is using its own output dir in bin/main
658 if (it.isDirectory() || ! it.exists()) {
659 // don't add dirs to classpath, especially if they don't exist
660 return false // groovy "continue" in .any closure
662 def itPath = it.toString()
663 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
664 // make relative path
665 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
667 if (alreadyAddedLibPath.get(itPath)) {
668 //println("Not adding duplicate entry "+itPath)
670 //println("Adding entry "+itPath)
671 cp.entries += new Library(fileReference(itPath))
672 alreadyAddedLibPath.put(itPath, true)
676 sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
677 //no longer want to add outputDir as eclipse is using its own output dir in bin/main
678 if (it.isDirectory() || ! it.exists()) {
679 // don't add dirs to classpath
680 return false // groovy "continue" in .any closure
683 def itPath = it.toString()
684 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
685 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
687 if (alreadyAddedLibPath.get(itPath)) {
690 def lib = new Library(fileReference(itPath))
691 lib.entryAttributes["test"] = "true"
693 alreadyAddedLibPath.put(itPath, true)
701 containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
706 // for the IDE, use java 11 compatibility
707 sourceCompatibility = compile_source_compatibility
708 targetCompatibility = compile_target_compatibility
709 javaRuntimeName = eclipseJavaRuntimeName
711 // add in jalview project specific properties/preferences into eclipse core preferences
713 withProperties { props ->
714 def jalview_prefs = new Properties()
715 def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
716 jalview_prefs.load(ins)
718 jalview_prefs.forEach { t, v ->
719 if (props.getAt(t) == null) {
723 // codestyle file -- overrides previous formatter prefs
724 def csFile = file("${jalviewDirAbsolutePath}/${eclipse_codestyle_file}")
725 if (csFile.exists()) {
726 XmlParser parser = new XmlParser()
727 def profiles = parser.parse(csFile)
728 def profile = profiles.'profile'.find { p -> (p.'@kind' == "CodeFormatterProfile" && p.'@name' == "Jalview") }
729 if (profile != null) {
730 profile.'setting'.each { s ->
732 def value = s.'@value'
733 if (id != null && value != null) {
734 props.putAt(id, value)
745 // Don't want these to be activated if in headless build
746 synchronizationTasks "eclipseSynchronizationTask"
747 //autoBuildTasks "eclipseAutoBuildTask"
753 /* hack to change eclipse prefs in .settings files other than org.eclipse.jdt.core.prefs */
754 // Class to allow updating arbitrary properties files
755 class PropertiesFile extends PropertiesPersistableConfigurationObject {
756 public PropertiesFile(PropertiesTransformer t) { super(t); }
757 @Override protected void load(Properties properties) { }
758 @Override protected void store(Properties properties) { }
759 @Override protected String getDefaultResourceName() { return ""; }
760 // This is necessary, because PropertiesPersistableConfigurationObject fails
761 // if no default properties file exists.
762 @Override public void loadDefaults() { load(new StringBufferInputStream("")); }
765 // Task to update arbitrary properties files (set outputFile)
766 class PropertiesFileTask extends PropertiesGeneratorTask<PropertiesFile> {
767 private final PropertiesFileContentMerger file;
768 public PropertiesFileTask() { file = new PropertiesFileContentMerger(getTransformer()); }
769 protected PropertiesFile create() { return new PropertiesFile(getTransformer()); }
770 protected void configure(PropertiesFile props) {
771 file.getBeforeMerged().execute(props); file.getWhenMerged().execute(props);
773 public void file(Closure closure) { ConfigureUtil.configure(closure, file); }
776 task eclipseUIPreferences(type: PropertiesFileTask) {
777 description = "Generate Eclipse additional settings"
778 def filename = "org.eclipse.jdt.ui.prefs"
779 outputFile = "$projectDir/.settings/${filename}" as File
782 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
787 task eclipseGroovyCorePreferences(type: PropertiesFileTask) {
788 description = "Generate Eclipse additional settings"
789 def filename = "org.eclipse.jdt.groovy.core.prefs"
790 outputFile = "$projectDir/.settings/${filename}" as File
793 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
798 task eclipseAllPreferences {
800 dependsOn eclipseUIPreferences
801 dependsOn eclipseGroovyCorePreferences
804 eclipseUIPreferences.mustRunAfter eclipseJdt
805 eclipseGroovyCorePreferences.mustRunAfter eclipseJdt
807 /* end of eclipse preferences hack */
815 delete cloverBuildDir
816 delete cloverReportDir
821 task cloverInstrJava(type: JavaExec) {
822 group = "Verification"
823 description = "Create clover instrumented source java files"
825 dependsOn cleanClover
827 inputs.files(sourceSets.main.allJava)
828 outputs.dir(cloverInstrDir)
830 //classpath = fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
831 classpath = sourceSets.clover.compileClasspath
832 main = "com.atlassian.clover.CloverInstr"
840 cloverInstrDir.getPath(),
842 def srcFiles = sourceSets.main.allJava.files
845 { file -> file.absolutePath }
848 args argsList.toArray()
851 delete cloverInstrDir
852 println("Clover: About to instrument "+srcFiles.size() +" files")
857 task cloverInstrTests(type: JavaExec) {
858 group = "Verification"
859 description = "Create clover instrumented source test files"
861 dependsOn cleanClover
863 inputs.files(testDir)
864 outputs.dir(cloverTestInstrDir)
866 classpath = sourceSets.clover.compileClasspath
867 main = "com.atlassian.clover.CloverInstr"
877 cloverTestInstrDir.getPath(),
879 args argsList.toArray()
882 delete cloverTestInstrDir
883 println("Clover: About to instrument test files")
889 group = "Verification"
890 description = "Create clover instrumented all source files"
892 dependsOn cloverInstrJava
893 dependsOn cloverInstrTests
897 cloverClasses.dependsOn cloverInstr
900 task cloverConsoleReport(type: JavaExec) {
901 group = "Verification"
902 description = "Creates clover console report"
905 file(cloverDb).exists()
908 inputs.dir cloverClassesDir
910 classpath = sourceSets.clover.runtimeClasspath
911 main = "com.atlassian.clover.reporters.console.ConsoleReporter"
913 if (cloverreport_mem.length() > 0) {
914 maxHeapSize = cloverreport_mem
916 if (cloverreport_jvmargs.length() > 0) {
917 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
927 args argsList.toArray()
931 task cloverHtmlReport(type: JavaExec) {
932 group = "Verification"
933 description = "Creates clover HTML report"
936 file(cloverDb).exists()
939 def cloverHtmlDir = cloverReportDir
940 inputs.dir cloverClassesDir
941 outputs.dir cloverHtmlDir
943 classpath = sourceSets.clover.runtimeClasspath
944 main = "com.atlassian.clover.reporters.html.HtmlReporter"
946 if (cloverreport_mem.length() > 0) {
947 maxHeapSize = cloverreport_mem
949 if (cloverreport_jvmargs.length() > 0) {
950 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
961 if (cloverreport_html_options.length() > 0) {
962 argsList += cloverreport_html_options.split(" ")
965 args argsList.toArray()
969 task cloverXmlReport(type: JavaExec) {
970 group = "Verification"
971 description = "Creates clover XML report"
974 file(cloverDb).exists()
977 def cloverXmlFile = "${cloverReportDir}/clover.xml"
978 inputs.dir cloverClassesDir
979 outputs.file cloverXmlFile
981 classpath = sourceSets.clover.runtimeClasspath
982 main = "com.atlassian.clover.reporters.xml.XMLReporter"
984 if (cloverreport_mem.length() > 0) {
985 maxHeapSize = cloverreport_mem
987 if (cloverreport_jvmargs.length() > 0) {
988 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
999 if (cloverreport_xml_options.length() > 0) {
1000 argsList += cloverreport_xml_options.split(" ")
1003 args argsList.toArray()
1008 group = "Verification"
1009 description = "Creates clover reports"
1011 dependsOn cloverXmlReport
1012 dependsOn cloverHtmlReport
1019 sourceCompatibility = compile_source_compatibility
1020 targetCompatibility = compile_target_compatibility
1021 options.compilerArgs += additional_compiler_args
1022 print ("Setting target compatibility to "+targetCompatibility+"\n")
1024 //classpath += configurations.cloverRuntime
1030 // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ?
1031 sourceCompatibility = compile_source_compatibility
1032 targetCompatibility = compile_target_compatibility
1033 options.compilerArgs = additional_compiler_args
1034 options.encoding = "UTF-8"
1036 print ("Setting target compatibility to "+compile_target_compatibility+"\n")
1043 sourceCompatibility = compile_source_compatibility
1044 targetCompatibility = compile_target_compatibility
1045 options.compilerArgs = additional_compiler_args
1047 print ("Setting target compatibility to "+targetCompatibility+"\n")
1054 delete sourceSets.main.java.outputDir
1060 dependsOn cleanClover
1062 delete sourceSets.test.java.outputDir
1067 // format is a string like date.format("dd MMMM yyyy")
1068 def getDate(format) {
1069 return date.format(format)
1073 def convertMdToHtml (FileTree mdFiles, File cssFile) {
1074 MutableDataSet options = new MutableDataSet()
1076 def extensions = new ArrayList<>()
1077 extensions.add(AnchorLinkExtension.create())
1078 extensions.add(AutolinkExtension.create())
1079 extensions.add(StrikethroughExtension.create())
1080 extensions.add(TaskListExtension.create())
1081 extensions.add(TablesExtension.create())
1082 extensions.add(TocExtension.create())
1084 options.set(Parser.EXTENSIONS, extensions)
1086 // set GFM table parsing options
1087 options.set(TablesExtension.WITH_CAPTION, false)
1088 options.set(TablesExtension.COLUMN_SPANS, false)
1089 options.set(TablesExtension.MIN_HEADER_ROWS, 1)
1090 options.set(TablesExtension.MAX_HEADER_ROWS, 1)
1091 options.set(TablesExtension.APPEND_MISSING_COLUMNS, true)
1092 options.set(TablesExtension.DISCARD_EXTRA_COLUMNS, true)
1093 options.set(TablesExtension.HEADER_SEPARATOR_COLUMN_MATCH, true)
1095 options.set(AnchorLinkExtension.ANCHORLINKS_SET_ID, false)
1096 options.set(AnchorLinkExtension.ANCHORLINKS_ANCHOR_CLASS, "anchor")
1097 options.set(AnchorLinkExtension.ANCHORLINKS_SET_NAME, true)
1098 options.set(AnchorLinkExtension.ANCHORLINKS_TEXT_PREFIX, "<span class=\"octicon octicon-link\"></span>")
1100 Parser parser = Parser.builder(options).build()
1101 HtmlRenderer renderer = HtmlRenderer.builder(options).build()
1103 mdFiles.each { mdFile ->
1104 // add table of contents
1105 def mdText = "[TOC]\n"+mdFile.text
1107 // grab the first top-level title
1109 def titleRegex = /(?m)^#(\s+|([^#]))(.*)/
1110 def matcher = mdText =~ titleRegex
1111 if (matcher.size() > 0) {
1112 // matcher[0][2] is the first character of the title if there wasn't any whitespace after the #
1113 title = (matcher[0][2] != null ? matcher[0][2] : "")+matcher[0][3]
1115 // or use the filename if none found
1116 if (title == null) {
1117 title = mdFile.getName()
1120 Node document = parser.parse(mdText)
1121 String htmlBody = renderer.render(document)
1122 def htmlText = '''<html>
1123 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1124 <html xmlns="http://www.w3.org/1999/xhtml">
1126 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1127 <meta http-equiv="Content-Style-Type" content="text/css" />
1128 <meta name="generator" content="flexmark" />
1130 htmlText += ((title != null) ? " <title>${title}</title>" : '' )
1132 <style type="text/css">code{white-space: pre;}</style>
1134 htmlText += ((cssFile != null) ? cssFile.text : '')
1135 htmlText += '''</head>
1138 htmlText += htmlBody
1144 def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
1145 def htmlFile = file(htmlFilePath)
1146 println("Creating ${htmlFilePath}")
1147 htmlFile.text = htmlText
1152 task copyDocs(type: Copy) {
1153 def inputDir = "${jalviewDir}/${doc_dir}"
1154 def outputDir = "${docBuildDir}/${doc_dir}"
1158 include('**/*.html')
1160 filter(ReplaceTokens,
1164 'Version-Rel': JALVIEW_VERSION,
1165 'Year-Rel': getDate("yyyy")
1172 exclude('**/*.html')
1177 inputs.dir(inputDir)
1178 outputs.dir(outputDir)
1182 task convertMdFiles {
1184 def mdFiles = fileTree(dir: docBuildDir, include: "**/*.md")
1185 def cssFile = file("${jalviewDir}/${flexmark_css}")
1188 convertMdToHtml(mdFiles, cssFile)
1191 inputs.files(mdFiles)
1192 inputs.file(cssFile)
1195 mdFiles.each { mdFile ->
1196 def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
1197 htmlFiles.add(file(htmlFilePath))
1199 outputs.files(htmlFiles)
1203 def hugoTemplateSubstitutions(String input, Map extras=null) {
1204 def replacements = [
1205 DATE: getDate("yyyy-MM-dd"),
1206 CHANNEL: propertiesChannelName,
1207 APPLICATION_NAME: applicationName,
1209 GIT_BRANCH: gitBranch,
1210 VERSION: JALVIEW_VERSION,
1211 JAVA_VERSION: JAVA_VERSION,
1212 VERSION_UNDERSCORES: JALVIEW_VERSION_UNDERSCORES,
1217 if (extras != null) {
1218 extras.each{ k, v ->
1219 output = output.replaceAll("__${k}__", ((v == null)?"":v))
1222 replacements.each{ k, v ->
1223 output = output.replaceAll("__${k}__", ((v == null)?"":v))
1228 def mdFileComponents(File mdFile, def dateOnly=false) {
1231 if (mdFile.exists()) {
1232 def inFrontMatter = false
1233 def firstLine = true
1234 mdFile.eachLine { line ->
1235 if (line.matches("---")) {
1236 def prev = inFrontMatter
1237 inFrontMatter = firstLine
1238 if (inFrontMatter != prev)
1241 if (inFrontMatter) {
1243 if (m = line =~ /^date:\s*(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/) {
1244 map["date"] = new Date().parse("yyyy-MM-dd HH:mm:ss", m[0][1])
1245 } else if (m = line =~ /^date:\s*(\d{4}-\d{2}-\d{2})/) {
1246 map["date"] = new Date().parse("yyyy-MM-dd", m[0][1])
1247 } else if (m = line =~ /^channel:\s*(\S+)/) {
1248 map["channel"] = m[0][1]
1249 } else if (m = line =~ /^version:\s*(\S+)/) {
1250 map["version"] = m[0][1]
1251 } else if (m = line =~ /^\s*([^:]+)\s*:\s*(\S.*)/) {
1252 map[ m[0][1] ] = m[0][2]
1254 if (dateOnly && map["date"] != null) {
1260 content += line+"\n"
1265 return dateOnly ? map["date"] : [map, content]
1268 task hugoTemplates {
1270 description "Create partially populated md pages for hugo website build"
1272 def hugoTemplatesDir = file("${jalviewDir}/${hugo_templates_dir}")
1273 def hugoBuildDir = "${jalviewDir}/${hugo_build_dir}"
1274 def templateFiles = fileTree(dir: hugoTemplatesDir)
1275 def releaseMdFile = file("${jalviewDir}/${releases_dir}/release-${JALVIEW_VERSION_UNDERSCORES}.md")
1276 def whatsnewMdFile = file("${jalviewDir}/${whatsnew_dir}/whatsnew-${JALVIEW_VERSION_UNDERSCORES}.md")
1277 def oldJvlFile = file("${jalviewDir}/${hugo_old_jvl}")
1278 def jalviewjsFile = file("${jalviewDir}/${hugo_jalviewjs}")
1281 // specific release template for version archive
1284 def givenDate = null
1285 def givenChannel = null
1286 def givenVersion = null
1287 if (CHANNEL == "RELEASE") {
1288 def (map, content) = mdFileComponents(releaseMdFile)
1289 givenDate = map.date
1290 givenChannel = map.channel
1291 givenVersion = map.version
1293 if (givenVersion != null && givenVersion != JALVIEW_VERSION) {
1294 throw new GradleException("'version' header (${givenVersion}) found in ${releaseMdFile} does not match JALVIEW_VERSION (${JALVIEW_VERSION})")
1297 if (whatsnewMdFile.exists())
1298 whatsnew = whatsnewMdFile.text
1301 def oldJvl = oldJvlFile.exists() ? oldJvlFile.collect{it} : []
1302 def jalviewjsLink = jalviewjsFile.exists() ? jalviewjsFile.collect{it} : []
1304 def changesHugo = null
1305 if (changes != null) {
1306 changesHugo = '<div class="release_notes">\n\n'
1307 def inSection = false
1308 changes.eachLine { line ->
1310 if (m = line =~ /^##([^#].*)$/) {
1312 changesHugo += "</div>\n\n"
1314 def section = m[0][1].trim()
1315 section = section.toLowerCase()
1316 section = section.replaceAll(/ +/, "_")
1317 section = section.replaceAll(/[^a-z0-9_\-]/, "")
1318 changesHugo += "<div class=\"${section}\">\n\n"
1320 } else if (m = line =~ /^(\s*-\s*)<!--([^>]+)-->(.*?)(<br\/?>)?\s*$/) {
1321 def comment = m[0][2].trim()
1322 if (comment != "") {
1323 comment = comment.replaceAll('"', """)
1325 comment.eachMatch(/JAL-\d+/) { jal -> issuekeys += jal }
1326 def newline = m[0][1]
1327 if (comment.trim() != "")
1328 newline += "{{<comment>}}${comment}{{</comment>}} "
1329 newline += m[0][3].trim()
1330 if (issuekeys.size() > 0)
1331 newline += " {{< jal issue=\"${issuekeys.join(",")}\" alt=\"${comment}\" >}}"
1332 if (m[0][4] != null)
1337 changesHugo += line+"\n"
1340 changesHugo += "\n</div>\n\n"
1342 changesHugo += '</div>'
1345 templateFiles.each{ templateFile ->
1346 def newFileName = string(hugoTemplateSubstitutions(templateFile.getName()))
1347 def relPath = hugoTemplatesDir.toPath().relativize(templateFile.toPath()).getParent()
1348 def newRelPathName = hugoTemplateSubstitutions( relPath.toString() )
1350 def outPathName = string("${hugoBuildDir}/$newRelPathName")
1354 rename(templateFile.getName(), newFileName)
1358 def newFile = file("${outPathName}/${newFileName}".toString())
1359 def content = newFile.text
1360 newFile.text = hugoTemplateSubstitutions(content,
1363 CHANGES: changesHugo,
1364 DATE: givenDate == null ? "" : givenDate.format("yyyy-MM-dd"),
1365 DRAFT: givenDate == null ? "true" : "false",
1366 JALVIEWJSLINK: jalviewjsLink.contains(JALVIEW_VERSION) ? "true" : "false",
1367 JVL_HEADER: oldJvl.contains(JALVIEW_VERSION) ? "jvl: true" : ""
1374 inputs.file(oldJvlFile)
1375 inputs.dir(hugoTemplatesDir)
1376 inputs.property("JALVIEW_VERSION", { JALVIEW_VERSION })
1377 inputs.property("CHANNEL", { CHANNEL })
1380 def getMdDate(File mdFile) {
1381 return mdFileComponents(mdFile, true)
1384 def getMdSections(String content) {
1386 def sectionContent = ""
1387 def sectionName = null
1388 content.eachLine { line ->
1390 if (m = line =~ /^##([^#].*)$/) {
1391 if (sectionName != null) {
1392 sections[sectionName] = sectionContent
1396 sectionName = m[0][1].trim()
1397 sectionName = sectionName.toLowerCase()
1398 sectionName = sectionName.replaceAll(/ +/, "_")
1399 sectionName = sectionName.replaceAll(/[^a-z0-9_\-]/, "")
1400 } else if (sectionName != null) {
1401 sectionContent += line+"\n"
1404 if (sectionContent != null) {
1405 sections[sectionName] = sectionContent
1411 task copyHelp(type: Copy) {
1412 def inputDir = helpSourceDir
1413 def outputDir = "${helpBuildDir}/${help_dir}"
1417 include('**/*.html')
1421 filter(ReplaceTokens,
1425 'Version-Rel': JALVIEW_VERSION,
1426 'Year-Rel': getDate("yyyy")
1433 exclude('**/*.html')
1440 inputs.dir(inputDir)
1441 outputs.files(helpFile)
1442 outputs.dir(outputDir)
1446 task releasesTemplates {
1448 description "Recreate whatsNew.html and releases.html from markdown files and templates in help"
1452 def releasesTemplateFile = file("${jalviewDir}/${releases_template}")
1453 def whatsnewTemplateFile = file("${jalviewDir}/${whatsnew_template}")
1454 def releasesHtmlFile = file("${helpBuildDir}/${help_dir}/${releases_html}")
1455 def whatsnewHtmlFile = file("${helpBuildDir}/${help_dir}/${whatsnew_html}")
1456 def releasesMdDir = "${jalviewDir}/${releases_dir}"
1457 def whatsnewMdDir = "${jalviewDir}/${whatsnew_dir}"
1460 def releaseMdFile = file("${releasesMdDir}/release-${JALVIEW_VERSION_UNDERSCORES}.md")
1461 def whatsnewMdFile = file("${whatsnewMdDir}/whatsnew-${JALVIEW_VERSION_UNDERSCORES}.md")
1463 if (CHANNEL == "RELEASE") {
1464 if (!releaseMdFile.exists()) {
1465 throw new GradleException("File ${releaseMdFile} must be created for RELEASE")
1467 if (!whatsnewMdFile.exists()) {
1468 throw new GradleException("File ${whatsnewMdFile} must be created for RELEASE")
1472 def releaseFiles = fileTree(dir: releasesMdDir, include: "release-*.md")
1473 def releaseFilesDates = releaseFiles.collectEntries {
1474 [(it): getMdDate(it)]
1476 releaseFiles = releaseFiles.sort { a,b -> releaseFilesDates[a].compareTo(releaseFilesDates[b]) }
1478 def releasesTemplate = releasesTemplateFile.text
1479 def m = releasesTemplate =~ /(?s)__VERSION_LOOP_START__(.*)__VERSION_LOOP_END__/
1480 def versionTemplate = m[0][1]
1482 MutableDataSet options = new MutableDataSet()
1484 def extensions = new ArrayList<>()
1485 options.set(Parser.EXTENSIONS, extensions)
1486 options.set(Parser.HTML_BLOCK_COMMENT_ONLY_FULL_LINE, true)
1488 Parser parser = Parser.builder(options).build()
1489 HtmlRenderer renderer = HtmlRenderer.builder(options).build()
1491 def actualVersions = releaseFiles.collect { rf ->
1492 def (rfMap, rfContent) = mdFileComponents(rf)
1493 return rfMap.version
1495 def versionsHtml = ""
1496 def linkedVersions = []
1497 releaseFiles.reverse().each { rFile ->
1498 def (rMap, rContent) = mdFileComponents(rFile)
1500 def versionLink = ""
1501 def partialVersion = ""
1502 def firstPart = true
1503 rMap.version.split("\\.").each { part ->
1504 def displayPart = ( firstPart ? "" : "." ) + part
1505 partialVersion += displayPart
1507 linkedVersions.contains(partialVersion)
1508 || ( actualVersions.contains(partialVersion) && partialVersion != rMap.version )
1510 versionLink += displayPart
1512 versionLink += "<a id=\"Jalview.${partialVersion}\">${displayPart}</a>"
1513 linkedVersions += partialVersion
1517 def displayDate = releaseFilesDates[rFile].format("dd/MM/yyyy")
1520 def rContentProcessed = ""
1521 rContent.eachLine { line ->
1522 if (lm = line =~ /^(\s*-)(\s*<!--[^>]*?-->)(.*)$/) {
1523 line = "${lm[0][1]}${lm[0][3]}${lm[0][2]}"
1524 } else if (lm = line =~ /^###([^#]+.*)$/) {
1525 line = "_${lm[0][1].trim()}_"
1527 rContentProcessed += line + "\n"
1530 def rContentSections = getMdSections(rContentProcessed)
1531 def rVersion = versionTemplate
1532 if (rVersion != "") {
1533 def rNewFeatures = rContentSections["new_features"]
1534 def rIssuesResolved = rContentSections["issues_resolved"]
1535 Node newFeaturesNode = parser.parse(rNewFeatures)
1536 String newFeaturesHtml = renderer.render(newFeaturesNode)
1537 Node issuesResolvedNode = parser.parse(rIssuesResolved)
1538 String issuesResolvedHtml = renderer.render(issuesResolvedNode)
1539 rVersion = hugoTemplateSubstitutions(rVersion,
1541 VERSION: rMap.version,
1542 VERSION_LINK: versionLink,
1543 DISPLAY_DATE: displayDate,
1544 NEW_FEATURES: newFeaturesHtml,
1545 ISSUES_RESOLVED: issuesResolvedHtml
1548 versionsHtml += rVersion
1552 releasesTemplate = releasesTemplate.replaceAll("(?s)__VERSION_LOOP_START__.*__VERSION_LOOP_END__", versionsHtml)
1553 releasesTemplate = hugoTemplateSubstitutions(releasesTemplate)
1554 releasesHtmlFile.text = releasesTemplate
1556 if (whatsnewMdFile.exists()) {
1557 def wnDisplayDate = releaseFilesDates[releaseMdFile] != null ? releaseFilesDates[releaseMdFile].format("dd MMMM yyyy") : ""
1558 def whatsnewMd = hugoTemplateSubstitutions(whatsnewMdFile.text)
1559 Node whatsnewNode = parser.parse(whatsnewMd)
1560 String whatsnewHtml = renderer.render(whatsnewNode)
1561 whatsnewHtml = whatsnewTemplateFile.text.replaceAll("__WHATS_NEW__", whatsnewHtml)
1562 whatsnewHtmlFile.text = hugoTemplateSubstitutions(whatsnewHtml,
1564 VERSION: JALVIEW_VERSION,
1565 DISPLAY_DATE: wnDisplayDate
1568 } else if (gradle.taskGraph.hasTask(":linkCheck")) {
1569 whatsnewHtmlFile.text = "Development build " + getDate("yyyy-MM-dd HH:mm:ss")
1574 inputs.file(releasesTemplateFile)
1575 inputs.file(whatsnewTemplateFile)
1576 inputs.dir(releasesMdDir)
1577 inputs.dir(whatsnewMdDir)
1578 outputs.file(releasesHtmlFile)
1579 outputs.file(whatsnewHtmlFile)
1583 task copyResources(type: Copy) {
1585 description = "Copy (and make text substitutions in) the resources dir to the build area"
1587 def inputDir = resourceDir
1588 def outputDir = resourcesBuildDir
1592 include('**/*.html')
1594 filter(ReplaceTokens,
1598 'Version-Rel': JALVIEW_VERSION,
1599 'Year-Rel': getDate("yyyy")
1606 exclude('**/*.html')
1611 inputs.dir(inputDir)
1612 outputs.dir(outputDir)
1615 task copyChannelResources(type: Copy) {
1616 dependsOn copyResources
1618 description = "Copy the channel resources dir to the build resources area"
1620 def inputDir = "${channelDir}/${resource_dir}"
1621 def outputDir = resourcesBuildDir
1625 inputs.dir(inputDir)
1626 outputs.dir(outputDir)
1629 task createBuildProperties(type: WriteProperties) {
1630 dependsOn copyResources
1632 description = "Create the ${buildProperties} file"
1634 inputs.dir(sourceDir)
1635 inputs.dir(resourcesBuildDir)
1636 outputFile (buildProperties)
1637 // taking time specific comment out to allow better incremental builds
1638 comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
1639 //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
1640 property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
1641 property "VERSION", JALVIEW_VERSION
1642 property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
1643 property "JAVA_COMPILE_VERSION", JAVA_INTEGER_VERSION
1644 if (getdownSetAppBaseProperty) {
1645 property "GETDOWNAPPBASE", getdownAppBase
1646 property "GETDOWNAPPDISTDIR", getdownAppDistDir
1648 outputs.file(outputFile)
1652 task buildIndices(type: JavaExec) {
1654 classpath = sourceSets.main.compileClasspath
1655 main = "com.sun.java.help.search.Indexer"
1656 workingDir = "${helpBuildDir}/${help_dir}"
1659 inputs.dir("${workingDir}/${argDir}")
1661 outputs.dir("${classesDir}/doc")
1662 outputs.dir("${classesDir}/help")
1663 outputs.file("${workingDir}/JavaHelpSearch/DOCS")
1664 outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
1665 outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
1666 outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
1667 outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
1668 outputs.file("${workingDir}/JavaHelpSearch/TMAP")
1671 task buildResources {
1672 dependsOn copyResources
1673 dependsOn copyChannelResources
1674 dependsOn createBuildProperties
1678 dependsOn buildResources
1681 dependsOn releasesTemplates
1682 dependsOn convertMdFiles
1683 dependsOn buildIndices
1687 compileJava.dependsOn prepare
1688 run.dependsOn compileJava
1689 //run.dependsOn prepare
1692 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
1697 dependsOn cloverClasses
1699 dependsOn compileJava //?
1703 includeGroups testng_groups
1704 excludeGroups testng_excluded_groups
1706 useDefaultListeners=true
1709 maxHeapSize = "1024m"
1711 workingDir = jalviewDir
1712 def testLaf = project.findProperty("test_laf")
1713 if (testLaf != null) {
1714 println("Setting Test LaF to '${testLaf}'")
1715 systemProperty "laf", testLaf
1717 def testHiDPIScale = project.findProperty("test_HiDPIScale")
1718 if (testHiDPIScale != null) {
1719 println("Setting Test HiDPI Scale to '${testHiDPIScale}'")
1720 systemProperty "sun.java2d.uiScale", testHiDPIScale
1722 sourceCompatibility = compile_source_compatibility
1723 targetCompatibility = compile_target_compatibility
1724 jvmArgs += additional_compiler_args
1728 println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
1734 task compileLinkCheck(type: JavaCompile) {
1736 classpath = files("${jalviewDir}/${utils_dir}")
1737 destinationDir = file("${jalviewDir}/${utils_dir}")
1738 source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
1740 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1741 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1742 outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
1743 outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
1747 task linkCheck(type: JavaExec) {
1749 dependsOn compileLinkCheck
1751 def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
1752 classpath = files("${jalviewDir}/${utils_dir}")
1753 main = "HelpLinksChecker"
1754 workingDir = "${helpBuildDir}"
1755 args = [ "${helpBuildDir}/${help_dir}", "-nointernet" ]
1757 def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
1758 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1761 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1765 inputs.dir(helpBuildDir)
1766 outputs.file(helpLinksCheckerOutFile)
1770 // import the pubhtmlhelp target
1771 ant.properties.basedir = "${jalviewDir}"
1772 ant.properties.helpBuildDir = "${helpBuildDir}/${help_dir}"
1773 ant.importBuild "${utils_dir}/publishHelp.xml"
1776 task cleanPackageDir(type: Delete) {
1778 delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
1788 attributes "Main-Class": main_class,
1789 "Permissions": "all-permissions",
1790 "Application-Name": applicationName,
1791 "Codebase": application_codebase,
1792 "Implementation-Version": JALVIEW_VERSION
1795 def outputDir = "${jalviewDir}/${package_dir}"
1796 destinationDirectory = file(outputDir)
1797 archiveFileName = rootProject.name+".jar"
1798 duplicatesStrategy "EXCLUDE"
1805 exclude "**/*.jar.*"
1807 inputs.dir(sourceSets.main.java.outputDir)
1808 sourceSets.main.resources.srcDirs.each{ dir ->
1811 outputs.file("${outputDir}/${archiveFileName}")
1815 task copyJars(type: Copy) {
1816 from fileTree(dir: classesDir, include: "**/*.jar").files
1817 into "${jalviewDir}/${package_dir}"
1821 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
1822 task syncJars(type: Sync) {
1824 from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
1825 into "${jalviewDir}/${package_dir}"
1827 include jar.archiveFileName.getOrNull()
1834 description = "Put all required libraries in dist"
1835 // order of "cleanPackageDir", "copyJars", "jar" important!
1836 jar.mustRunAfter cleanPackageDir
1837 syncJars.mustRunAfter cleanPackageDir
1838 dependsOn cleanPackageDir
1841 outputs.dir("${jalviewDir}/${package_dir}")
1846 dependsOn cleanPackageDir
1853 group = "distribution"
1854 description = "Create a single jar file with all dependency libraries merged. Can be run with java -jar"
1858 from ("${jalviewDir}/${libDistDir}") {
1862 attributes "Implementation-Version": JALVIEW_VERSION,
1863 "Application-Name": applicationName
1866 duplicatesStrategy "INCLUDE"
1868 mainClassName = shadow_jar_main_class
1870 classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
1875 task getdownWebsite() {
1876 group = "distribution"
1877 description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
1882 def getdownWebsiteResourceFilenames = []
1883 def getdownResourceDir = getdownResourceDir
1884 def getdownResourceFilenames = []
1887 // clean the getdown website and files dir before creating getdown folders
1888 delete getdownAppBaseDir
1889 delete getdownFilesDir
1892 from buildProperties
1893 rename(file(buildProperties).getName(), getdown_build_properties)
1896 getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
1899 from channelPropsFile
1900 into getdownAppBaseDir
1902 getdownWebsiteResourceFilenames += file(channelPropsFile).getName()
1904 // set some getdownTxt_ properties then go through all properties looking for getdownTxt_...
1905 def props = project.properties.sort { it.key }
1906 if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
1907 props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
1909 if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) {
1910 props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion)
1912 if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
1913 props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
1915 if (getdownImagesDir != null && file(getdownImagesDir).exists()) {
1916 props.put("getdown_txt_ui.background_image", "${getdownImagesDir}/${getdown_background_image}")
1917 props.put("getdown_txt_ui.instant_background_image", "${getdownImagesDir}/${getdown_instant_background_image}")
1918 props.put("getdown_txt_ui.error_background", "${getdownImagesDir}/${getdown_error_background}")
1919 props.put("getdown_txt_ui.progress_image", "${getdownImagesDir}/${getdown_progress_image}")
1920 props.put("getdown_txt_ui.icon", "${getdownImagesDir}/${getdown_icon}")
1921 props.put("getdown_txt_ui.mac_dock_icon", "${getdownImagesDir}/${getdown_mac_dock_icon}")
1924 props.put("getdown_txt_title", jalview_name)
1925 props.put("getdown_txt_ui.name", applicationName)
1927 // start with appbase
1928 getdownTextLines += "appbase = ${getdownAppBase}"
1929 props.each{ prop, val ->
1930 if (prop.startsWith("getdown_txt_") && val != null) {
1931 if (prop.startsWith("getdown_txt_multi_")) {
1932 def key = prop.substring(18)
1933 val.split(",").each{ v ->
1934 def line = "${key} = ${v}"
1935 getdownTextLines += line
1938 // file values rationalised
1939 if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1941 if (val.indexOf('/') == 0) {
1944 } else if (val.indexOf('/') > 0) {
1945 // relative path (relative to jalviewDir)
1946 r = file( "${jalviewDir}/${val}" )
1949 val = "${getdown_resource_dir}/" + r.getName()
1950 getdownWebsiteResourceFilenames += val
1951 getdownResourceFilenames += r.getPath()
1954 if (! prop.startsWith("getdown_txt_resource")) {
1955 def line = prop.substring(12) + " = ${val}"
1956 getdownTextLines += line
1962 getdownWebsiteResourceFilenames.each{ filename ->
1963 getdownTextLines += "resource = ${filename}"
1965 getdownResourceFilenames.each{ filename ->
1968 into getdownResourceDir
1972 def getdownWrapperScripts = [ getdown_bash_wrapper_script, getdown_powershell_wrapper_script, getdown_batch_wrapper_script ]
1973 getdownWrapperScripts.each{ script ->
1974 def s = file( "${jalviewDir}/utils/getdown/${getdown_wrapper_script_dir}/${script}" )
1978 into "${getdownAppBaseDir}/${getdown_wrapper_script_dir}"
1980 getdownTextLines += "resource = ${getdown_wrapper_script_dir}/${script}"
1985 fileTree(file(package_dir)).each{ f ->
1986 if (f.isDirectory()) {
1987 def files = fileTree(dir: f, include: ["*"]).getFiles()
1989 } else if (f.exists()) {
1993 def jalviewJar = jar.archiveFileName.getOrNull()
1994 // put jalview.jar first for CLASSPATH and .properties files reasons
1995 codeFiles.sort{a, b -> ( a.getName() == jalviewJar ? -1 : ( b.getName() == jalviewJar ? 1 : a <=> b ) ) }.each{f ->
1996 def name = f.getName()
1997 def line = "code = ${getdownAppDistDir}/${name}"
1998 getdownTextLines += line
2005 // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
2007 if (JAVA_VERSION.equals("11")) {
2008 def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
2009 j11libFiles.sort().each{f ->
2010 def name = f.getName()
2011 def line = "code = ${getdown_j11lib_dir}/${name}"
2012 getdownTextLines += line
2015 into getdownJ11libDir
2021 // 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.
2022 //getdownTextLines += "class = " + file(getdownLauncher).getName()
2023 getdownTextLines += "resource = ${getdown_launcher_new}"
2024 getdownTextLines += "class = ${main_class}"
2025 // Not setting these properties in general so that getdownappbase and getdowndistdir will default to release version in jalview.bin.Cache
2026 if (getdownSetAppBaseProperty) {
2027 getdownTextLines += "jvmarg = -Dgetdowndistdir=${getdownAppDistDir}"
2028 getdownTextLines += "jvmarg = -Dgetdownappbase=${getdownAppBase}"
2031 def getdownTxt = file("${getdownAppBaseDir}/getdown.txt")
2032 getdownTxt.write(getdownTextLines.join("\n"))
2034 getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
2035 def launchJvl = file("${getdownAppBaseDir}/${getdownLaunchJvl}")
2036 launchJvl.write("appbase=${getdownAppBase}")
2038 // files going into the getdown website dir: getdown-launcher.jar
2040 from getdownLauncher
2041 rename(file(getdownLauncher).getName(), getdown_launcher_new)
2042 into getdownAppBaseDir
2045 // files going into the getdown website dir: getdown-launcher(-local).jar
2047 from getdownLauncher
2048 if (file(getdownLauncher).getName() != getdown_launcher) {
2049 rename(file(getdownLauncher).getName(), getdown_launcher)
2051 into getdownAppBaseDir
2054 // files going into the getdown website dir: ./install dir and files
2055 if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
2058 from getdownLauncher
2059 from "${getdownAppDir}/${getdown_build_properties}"
2060 if (file(getdownLauncher).getName() != getdown_launcher) {
2061 rename(file(getdownLauncher).getName(), getdown_launcher)
2063 into getdownInstallDir
2066 // and make a copy in the getdown files dir (these are not downloaded by getdown)
2068 from getdownInstallDir
2069 into getdownFilesInstallDir
2073 // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties
2077 from getdownLauncher
2078 from "${getdownAppBaseDir}/${getdown_build_properties}"
2079 from "${getdownAppBaseDir}/${channel_props}"
2080 if (file(getdownLauncher).getName() != getdown_launcher) {
2081 rename(file(getdownLauncher).getName(), getdown_launcher)
2083 into getdownFilesDir
2086 // and ./resource (not all downloaded by getdown)
2088 from getdownResourceDir
2089 into "${getdownFilesDir}/${getdown_resource_dir}"
2094 inputs.dir("${jalviewDir}/${package_dir}")
2096 outputs.dir(getdownAppBaseDir)
2097 outputs.dir(getdownFilesDir)
2101 // a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
2102 task getdownDigestDir(type: JavaExec) {
2104 description "A task to run a getdown Digest on a dir with getdown.txt. Provide a DIGESTDIR property via -PDIGESTDIR=..."
2106 def digestDirPropertyName = "DIGESTDIR"
2108 classpath = files(getdownLauncher)
2109 def digestDir = findProperty(digestDirPropertyName)
2110 if (digestDir == null) {
2111 throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest")
2115 main = "com.threerings.getdown.tools.Digester"
2119 task getdownDigest(type: JavaExec) {
2120 group = "distribution"
2121 description = "Digest the getdown website folder"
2122 dependsOn getdownWebsite
2124 classpath = files(getdownLauncher)
2126 main = "com.threerings.getdown.tools.Digester"
2127 args getdownAppBaseDir
2128 inputs.dir(getdownAppBaseDir)
2129 outputs.file("${getdownAppBaseDir}/digest2.txt")
2134 group = "distribution"
2135 description = "Create the minimal and full getdown app folder for installers and website and create digest file"
2136 dependsOn getdownDigest
2138 if (reportRsyncCommand) {
2139 def fromDir = getdownAppBaseDir + (getdownAppBaseDir.endsWith('/')?'':'/')
2140 def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
2141 println "LIKELY RSYNC COMMAND:"
2142 println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
2143 if (RUNRSYNC == "true") {
2145 commandLine "mkdir", "-p", toDir
2148 commandLine "rsync", "-avh", "--delete", fromDir, toDir
2156 task getdownArchiveBuild() {
2157 group = "distribution"
2158 description = "Put files in the archive dir to go on the website"
2160 dependsOn getdownWebsite
2162 def v = "v${JALVIEW_VERSION_UNDERSCORES}"
2163 def vDir = "${getdownArchiveDir}/${v}"
2164 getdownFullArchiveDir = "${vDir}/getdown"
2165 getdownVersionLaunchJvl = "${vDir}/jalview-${v}.jvl"
2167 def vAltDir = "alt_${v}"
2168 def archiveImagesDir = "${jalviewDir}/${channel_properties_dir}/old/images"
2171 // cleanup old "old" dir
2172 delete getdownArchiveDir
2174 def getdownArchiveTxt = file("${getdownFullArchiveDir}/getdown.txt")
2175 getdownArchiveTxt.getParentFile().mkdirs()
2176 def getdownArchiveTextLines = []
2177 def getdownFullArchiveAppBase = "${getdownArchiveAppBase}${getdownArchiveAppBase.endsWith("/")?"":"/"}${v}/getdown/"
2181 from "${getdownAppBaseDir}/${getdownAppDistDir}"
2182 into "${getdownFullArchiveDir}/${vAltDir}"
2185 getdownTextLines.each { line ->
2186 line = line.replaceAll("^(?<s>appbase\\s*=\\s*).*", '${s}'+getdownFullArchiveAppBase)
2187 line = line.replaceAll("^(?<s>(resource|code)\\s*=\\s*)${getdownAppDistDir}/", '${s}'+vAltDir+"/")
2188 line = line.replaceAll("^(?<s>ui.background_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background.png")
2189 line = line.replaceAll("^(?<s>ui.instant_background_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background_initialising.png")
2190 line = line.replaceAll("^(?<s>ui.error_background\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background_error.png")
2191 line = line.replaceAll("^(?<s>ui.progress_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_progress_bar.png")
2192 // remove the existing resource = resource/ or bin/ lines
2193 if (! line.matches("resource\\s*=\\s*(resource|bin)/.*")) {
2194 getdownArchiveTextLines += line
2198 // the resource dir -- add these files as resource lines in getdown.txt
2200 from "${archiveImagesDir}"
2201 into "${getdownFullArchiveDir}/${getdown_resource_dir}"
2203 getdownArchiveTextLines += "resource = ${getdown_resource_dir}/${file.getName()}"
2207 getdownArchiveTxt.write(getdownArchiveTextLines.join("\n"))
2209 def vLaunchJvl = file(getdownVersionLaunchJvl)
2210 vLaunchJvl.getParentFile().mkdirs()
2211 vLaunchJvl.write("appbase=${getdownFullArchiveAppBase}\n")
2212 def vLaunchJvlPath = vLaunchJvl.toPath().toAbsolutePath()
2213 def jvlLinkPath = file("${vDir}/jalview.jvl").toPath().toAbsolutePath()
2214 // for some reason filepath.relativize(fileInSameDirPath) gives a path to "../" which is wrong
2215 //java.nio.file.Files.createSymbolicLink(jvlLinkPath, jvlLinkPath.relativize(vLaunchJvlPath));
2216 java.nio.file.Files.createSymbolicLink(jvlLinkPath, java.nio.file.Paths.get(".",vLaunchJvl.getName()));
2218 // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties
2220 from getdownLauncher
2221 from "${getdownAppBaseDir}/${getdownLaunchJvl}"
2222 from "${getdownAppBaseDir}/${getdown_launcher_new}"
2223 from "${getdownAppBaseDir}/${channel_props}"
2224 if (file(getdownLauncher).getName() != getdown_launcher) {
2225 rename(file(getdownLauncher).getName(), getdown_launcher)
2227 into getdownFullArchiveDir
2233 task getdownArchiveDigest(type: JavaExec) {
2234 group = "distribution"
2235 description = "Digest the getdown archive folder"
2237 dependsOn getdownArchiveBuild
2240 classpath = files(getdownLauncher)
2241 args getdownFullArchiveDir
2243 main = "com.threerings.getdown.tools.Digester"
2244 inputs.dir(getdownFullArchiveDir)
2245 outputs.file("${getdownFullArchiveDir}/digest2.txt")
2248 task getdownArchive() {
2249 group = "distribution"
2250 description = "Build the website archive dir with getdown digest"
2252 dependsOn getdownArchiveBuild
2253 dependsOn getdownArchiveDigest
2256 tasks.withType(JavaCompile) {
2257 options.encoding = 'UTF-8'
2263 delete getdownAppBaseDir
2264 delete getdownFilesDir
2265 delete getdownArchiveDir
2271 if (file(install4jHomeDir).exists()) {
2273 } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
2274 install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
2275 } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
2276 install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
2278 installDir(file(install4jHomeDir))
2280 mediaTypes = Arrays.asList(install4j_media_types.split(","))
2284 task copyInstall4jTemplate {
2285 def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
2286 def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
2287 inputs.file(install4jTemplateFile)
2288 inputs.file(install4jFileAssociationsFile)
2289 inputs.property("CHANNEL", { CHANNEL })
2290 outputs.file(install4jConfFile)
2293 def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
2295 // turn off code signing if no OSX_KEYPASS
2296 if (OSX_KEYPASS == "") {
2297 install4jConfigXml.'**'.codeSigning.each { codeSigning ->
2298 codeSigning.'@macEnabled' = "false"
2300 install4jConfigXml.'**'.windows.each { windows ->
2301 windows.'@runPostProcessor' = "false"
2305 // disable install screen for OSX dmg (for 2.11.2.0)
2306 install4jConfigXml.'**'.macosArchive.each { macosArchive ->
2307 macosArchive.attributes().remove('executeSetupApp')
2308 macosArchive.attributes().remove('setupAppId')
2311 // turn off checksum creation for LOCAL channel
2312 def e = install4jConfigXml.application[0]
2313 e.'@createChecksums' = string(install4jCheckSums)
2315 // put file association actions where placeholder action is
2316 def install4jFileAssociationsText = install4jFileAssociationsFile.text
2317 def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
2318 install4jConfigXml.'**'.action.any { a -> // .any{} stops after the first one that returns true
2319 if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
2320 def parent = a.parent()
2322 fileAssociationActions.each { faa ->
2325 // don't need to continue in .any loop once replacements have been made
2330 // use Windows Program Group with Examples folder for RELEASE, and Program Group without Examples for everything else
2331 // NB we're deleting the /other/ one!
2332 // Also remove the examples subdir from non-release versions
2333 def customizedIdToDelete = "PROGRAM_GROUP_RELEASE"
2334 // 2.11.1.0 NOT releasing with the Examples folder in the Program Group
2335 if (false && CHANNEL=="RELEASE") { // remove 'false && ' to include Examples folder in RELEASE channel
2336 customizedIdToDelete = "PROGRAM_GROUP_NON_RELEASE"
2338 // remove the examples subdir from Full File Set
2339 def files = install4jConfigXml.files[0]
2340 def fileset = files.filesets.fileset.find { fs -> fs.'@customizedId' == "FULL_FILE_SET" }
2341 def root = files.roots.root.find { r -> r.'@fileset' == fileset.'@id' }
2342 def mountPoint = files.mountPoints.mountPoint.find { mp -> mp.'@root' == root.'@id' }
2343 def dirEntry = files.entries.dirEntry.find { de -> de.'@mountPoint' == mountPoint.'@id' && de.'@subDirectory' == "examples" }
2344 dirEntry.parent().remove(dirEntry)
2346 install4jConfigXml.'**'.action.any { a ->
2347 if (a.'@customizedId' == customizedIdToDelete) {
2348 def parent = a.parent()
2354 // write install4j file
2355 install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
2362 delete install4jConfFile
2366 task cleanInstallersDataFiles {
2367 def installersOutputTxt = file("${jalviewDir}/${install4jBuildDir}/output.txt")
2368 def installersSha256 = file("${jalviewDir}/${install4jBuildDir}/sha256sums")
2369 def hugoDataJsonFile = file("${jalviewDir}/${install4jBuildDir}/installers-${JALVIEW_VERSION_UNDERSCORES}.json")
2371 delete installersOutputTxt
2372 delete installersSha256
2373 delete hugoDataJsonFile
2377 task installerFiles(type: com.install4j.gradle.Install4jTask) {
2378 group = "distribution"
2379 description = "Create the install4j installers"
2381 dependsOn copyInstall4jTemplate
2382 dependsOn cleanInstallersDataFiles
2384 projectFile = install4jConfFile
2386 // create an md5 for the input files to use as version for install4j conf file
2387 def digest = MessageDigest.getInstance("MD5")
2389 (file("${install4jDir}/${install4j_template}").text +
2390 file("${install4jDir}/${install4j_info_plist_file_associations}").text +
2391 file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
2392 def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
2393 if (filesMd5.length() >= 8) {
2394 filesMd5 = filesMd5.substring(0,8)
2396 def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
2399 'JALVIEW_NAME': jalview_name,
2400 'JALVIEW_APPLICATION_NAME': applicationName,
2401 'JALVIEW_DIR': "../..",
2402 'OSX_KEYSTORE': OSX_KEYSTORE,
2403 'OSX_APPLEID': OSX_APPLEID,
2404 'OSX_ALTOOLPASS': OSX_ALTOOLPASS,
2405 'JSIGN_SH': JSIGN_SH,
2406 'JRE_DIR': getdown_app_dir_java,
2407 'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
2408 'JALVIEW_VERSION': JALVIEW_VERSION,
2409 'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
2410 'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
2411 'JAVA_VERSION': JAVA_VERSION,
2412 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
2413 'VERSION': JALVIEW_VERSION,
2414 'MACOS_JAVA_VM_DIR': macosJavaVMDir,
2415 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
2416 'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
2417 'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
2418 'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
2419 'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
2420 'COPYRIGHT_MESSAGE': install4j_copyright_message,
2421 'BUNDLE_ID': install4jBundleId,
2422 'INTERNAL_ID': install4jInternalId,
2423 'WINDOWS_APPLICATION_ID': install4jWinApplicationId,
2424 'MACOS_DMG_DS_STORE': install4jDMGDSStore,
2425 'MACOS_DMG_BG_IMAGE': install4jDMGBackgroundImage,
2426 'WRAPPER_LINK': getdownWrapperLink,
2427 'BASH_WRAPPER_SCRIPT': getdown_bash_wrapper_script,
2428 'POWERSHELL_WRAPPER_SCRIPT': getdown_powershell_wrapper_script,
2429 'WRAPPER_SCRIPT_BIN_DIR': getdown_wrapper_script_dir,
2430 'INSTALLER_NAME': install4jInstallerName,
2431 'INSTALL4J_UTILS_DIR': install4j_utils_dir,
2432 'GETDOWN_CHANNEL_DIR': getdownChannelDir,
2433 'GETDOWN_FILES_DIR': getdown_files_dir,
2434 'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
2435 'GETDOWN_DIST_DIR': getdownAppDistDir,
2436 'GETDOWN_ALT_DIR': getdown_app_dir_alt,
2437 'GETDOWN_INSTALL_DIR': getdown_install_dir,
2438 'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
2439 'BUILD_DIR': install4jBuildDir,
2440 'APPLICATION_CATEGORIES': install4j_application_categories,
2441 'APPLICATION_FOLDER': install4jApplicationFolder,
2442 'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder,
2443 'EXECUTABLE_NAME': install4jExecutableName,
2444 'EXTRA_SCHEME': install4jExtraScheme,
2445 'MAC_ICONS_FILE': install4jMacIconsFile,
2446 'WINDOWS_ICONS_FILE': install4jWindowsIconsFile,
2447 'PNG_ICON_FILE': install4jPngIconFile,
2448 'BACKGROUND': install4jBackground,
2452 //println("INSTALL4J VARIABLES:")
2453 //variables.each{k,v->println("${k}=${v}")}
2455 destination = "${jalviewDir}/${install4jBuildDir}"
2456 buildSelected = true
2458 if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
2460 disableSigning = true
2461 disableNotarization = true
2465 macKeystorePassword = OSX_KEYPASS
2468 if (OSX_ALTOOLPASS) {
2469 appleIdPassword = OSX_ALTOOLPASS
2470 disableNotarization = false
2472 disableNotarization = true
2476 println("Using projectFile "+projectFile)
2477 if (!disableNotarization) { println("Will notarize OSX App DMG") }
2481 inputs.dir(getdownAppBaseDir)
2482 inputs.file(install4jConfFile)
2483 inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
2484 inputs.dir(macosJavaVMDir)
2485 inputs.dir(windowsJavaVMDir)
2486 outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
2489 def getDataHash(File myFile) {
2490 HashCode hash = Files.asByteSource(myFile).hash(Hashing.sha256())
2491 return myFile.exists()
2493 "file" : myFile.getName(),
2494 "filesize" : myFile.length(),
2495 "sha256" : hash.toString()
2500 def writeDataJsonFile(File installersOutputTxt, File installersSha256, File dataJsonFile) {
2502 "channel" : getdownChannelName,
2503 "date" : getDate("yyyy-MM-dd HH:mm:ss"),
2504 "git-commit" : "${gitHash} [${gitBranch}]",
2505 "version" : JALVIEW_VERSION
2507 // install4j installer files
2508 if (installersOutputTxt.exists()) {
2510 installersOutputTxt.readLines().each { def line ->
2511 if (line.startsWith("#")) {
2514 line.replaceAll("\n","")
2515 def vals = line.split("\t")
2516 def filename = vals[3]
2517 def filesize = file(filename).length()
2518 filename = filename.replaceAll(/^.*\//, "")
2519 hash[vals[0]] = [ "id" : vals[0], "os" : vals[1], "name" : vals[2], "file" : filename, "filesize" : filesize ]
2520 idHash."${filename}" = vals[0]
2522 if (install4jCheckSums && installersSha256.exists()) {
2523 installersSha256.readLines().each { def line ->
2524 if (line.startsWith("#")) {
2527 line.replaceAll("\n","")
2528 def vals = line.split(/\s+\*?/)
2529 def filename = vals[1]
2530 def innerHash = (hash.(idHash."${filename}"))."sha256" = vals[0]
2536 "JAR": shadowJar.archiveFile, // executable JAR
2537 "JVL": getdownVersionLaunchJvl, // version JVL
2538 "SOURCE": sourceDist.archiveFile // source TGZ
2539 ].each { key, value ->
2540 def file = file(value)
2541 if (file.exists()) {
2542 def fileHash = getDataHash(file)
2543 if (fileHash != null) {
2544 hash."${key}" = fileHash;
2548 return dataJsonFile.write(new JsonBuilder(hash).toPrettyString())
2551 task staticMakeInstallersJsonFile {
2553 def output = findProperty("i4j_output")
2554 def sha256 = findProperty("i4j_sha256")
2555 def json = findProperty("i4j_json")
2556 if (output == null || sha256 == null || json == null) {
2557 throw new GradleException("Must provide paths to all of output.txt, sha256sums, and output.json with '-Pi4j_output=... -Pi4j_sha256=... -Pi4j_json=...")
2559 writeDataJsonFile(file(output), file(sha256), file(json))
2564 dependsOn installerFiles
2570 eclipse().configFile(eclipse_codestyle_file)
2574 task createSourceReleaseProperties(type: WriteProperties) {
2575 group = "distribution"
2576 description = "Create the source RELEASE properties file"
2578 def sourceTarBuildDir = "${buildDir}/sourceTar"
2579 def sourceReleasePropertiesFile = "${sourceTarBuildDir}/RELEASE"
2580 outputFile (sourceReleasePropertiesFile)
2583 releaseProps.each{ key, val -> property key, val }
2584 property "git.branch", gitBranch
2585 property "git.hash", gitHash
2588 outputs.file(outputFile)
2591 task sourceDist(type: Tar) {
2592 group "distribution"
2593 description "Create a source .tar.gz file for distribution"
2595 dependsOn createBuildProperties
2596 dependsOn convertMdFiles
2597 dependsOn eclipseAllPreferences
2598 dependsOn createSourceReleaseProperties
2601 def outputFileName = "${project.name}_${JALVIEW_VERSION_UNDERSCORES}.tar.gz"
2602 archiveFileName = outputFileName
2604 compression Compression.GZIP
2619 "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
2621 "utils/InstallAnywhere",
2636 "gradle.properties",
2648 ".settings/org.eclipse.buildship.core.prefs",
2649 ".settings/org.eclipse.jdt.core.prefs"
2653 exclude (EXCLUDE_FILES)
2654 include (PROCESS_FILES)
2655 filter(ReplaceTokens,
2659 'Version-Rel': JALVIEW_VERSION,
2660 'Year-Rel': getDate("yyyy")
2665 exclude (EXCLUDE_FILES)
2666 exclude (PROCESS_FILES)
2667 exclude ("appletlib")
2668 exclude ("**/*locales")
2669 exclude ("*locales/**")
2670 exclude ("utils/InstallAnywhere")
2672 exclude (getdown_files_dir)
2673 // getdown_website_dir and getdown_archive_dir moved to build/website/docroot/getdown
2674 //exclude (getdown_website_dir)
2675 //exclude (getdown_archive_dir)
2677 // exluding these as not using jars as modules yet
2678 exclude ("${j11modDir}/**/*.jar")
2681 include(INCLUDE_FILES)
2683 // from (jalviewDir) {
2684 // // explicit includes for stuff that seemed to not get included
2685 // include(fileTree("test/**/*."))
2686 // exclude(EXCLUDE_FILES)
2687 // exclude(PROCESS_FILES)
2690 from(file(buildProperties).getParent()) {
2691 include(file(buildProperties).getName())
2692 rename(file(buildProperties).getName(), "build_properties")
2694 line.replaceAll("^INSTALLATION=.*\$","INSTALLATION=Source Release"+" git-commit\\\\:"+gitHash+" ["+gitBranch+"]")
2698 def sourceTarBuildDir = "${buildDir}/sourceTar"
2699 from(sourceTarBuildDir) {
2700 // this includes the appended RELEASE properties file
2704 task dataInstallersJson {
2706 description "Create the installers-VERSION.json data file for installer files created"
2708 mustRunAfter installers
2709 mustRunAfter shadowJar
2710 mustRunAfter sourceDist
2711 mustRunAfter getdownArchive
2713 def installersOutputTxt = file("${jalviewDir}/${install4jBuildDir}/output.txt")
2714 def installersSha256 = file("${jalviewDir}/${install4jBuildDir}/sha256sums")
2716 if (installersOutputTxt.exists()) {
2717 inputs.file(installersOutputTxt)
2719 if (install4jCheckSums && installersSha256.exists()) {
2720 inputs.file(installersSha256)
2723 shadowJar.archiveFile, // executable JAR
2724 getdownVersionLaunchJvl, // version JVL
2725 sourceDist.archiveFile // source TGZ
2726 ].each { fileName ->
2727 if (file(fileName).exists()) {
2728 inputs.file(fileName)
2732 outputs.file(hugoDataJsonFile)
2735 writeDataJsonFile(installersOutputTxt, installersSha256, hugoDataJsonFile)
2741 description "Copies all help pages to build dir. Runs ant task 'pubhtmlhelp'."
2744 dependsOn pubhtmlhelp
2746 inputs.dir("${helpBuildDir}/${help_dir}")
2747 outputs.dir("${buildDir}/distributions/${help_dir}")
2751 task j2sSetHeadlessBuild {
2758 task jalviewjsEnableAltFileProperty(type: WriteProperties) {
2760 description "Enable the alternative J2S Config file for headless build"
2762 outputFile = jalviewjsJ2sSettingsFileName
2763 def j2sPropsFile = file(jalviewjsJ2sSettingsFileName)
2764 def j2sProps = new Properties()
2765 if (j2sPropsFile.exists()) {
2767 def j2sPropsFileFIS = new FileInputStream(j2sPropsFile)
2768 j2sProps.load(j2sPropsFileFIS)
2769 j2sPropsFileFIS.close()
2771 j2sProps.each { prop, val ->
2774 } catch (Exception e) {
2775 println("Exception reading ${jalviewjsJ2sSettingsFileName}")
2779 if (! j2sProps.stringPropertyNames().contains(jalviewjs_j2s_alt_file_property_config)) {
2780 property(jalviewjs_j2s_alt_file_property_config, jalviewjs_j2s_alt_file_property)
2785 task jalviewjsSetEclipseWorkspace {
2786 def propKey = "jalviewjs_eclipse_workspace"
2788 if (project.hasProperty(propKey)) {
2789 propVal = project.getProperty(propKey)
2790 if (propVal.startsWith("~/")) {
2791 propVal = System.getProperty("user.home") + propVal.substring(1)
2794 def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
2795 def propsFile = file(propsFileName)
2796 def eclipseWsDir = propVal
2797 def props = new Properties()
2799 def writeProps = true
2800 if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
2801 def ins = new FileInputStream(propsFileName)
2804 if (props.getProperty(propKey, null) != null) {
2805 eclipseWsDir = props.getProperty(propKey)
2810 if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
2811 def tempDir = File.createTempDir()
2812 eclipseWsDir = tempDir.getAbsolutePath()
2815 eclipseWorkspace = file(eclipseWsDir)
2818 // do not run a headless transpile when we claim to be in Eclipse
2820 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2821 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2823 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2827 props.setProperty(propKey, eclipseWsDir)
2828 propsFile.parentFile.mkdirs()
2829 def bytes = new ByteArrayOutputStream()
2830 props.store(bytes, null)
2831 def propertiesString = bytes.toString()
2832 propsFile.text = propertiesString
2838 println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
2841 //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
2842 outputs.file(propsFileName)
2843 outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
2847 task jalviewjsEclipsePaths {
2850 def eclipseRoot = jalviewjs_eclipse_root
2851 if (eclipseRoot.startsWith("~/")) {
2852 eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
2854 if (OperatingSystem.current().isMacOsX()) {
2855 eclipseRoot += "/Eclipse.app"
2856 eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
2857 eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
2858 } else if (OperatingSystem.current().isWindows()) { // check these paths!!
2859 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2860 eclipseRoot += "/eclipse"
2862 eclipseBinary = "${eclipseRoot}/eclipse.exe"
2863 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2864 } else { // linux or unix
2865 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2866 eclipseRoot += "/eclipse"
2867 println("eclipseDir exists")
2869 eclipseBinary = "${eclipseRoot}/eclipse"
2870 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2873 eclipseVersion = "4.13" // default
2874 def assumedVersion = true
2875 if (file(eclipseProduct).exists()) {
2876 def fis = new FileInputStream(eclipseProduct)
2877 def props = new Properties()
2879 eclipseVersion = props.getProperty("version")
2881 assumedVersion = false
2884 def propKey = "eclipse_debug"
2885 eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
2888 // do not run a headless transpile when we claim to be in Eclipse
2890 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2891 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2893 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2896 if (!assumedVersion) {
2897 println("ECLIPSE VERSION=${eclipseVersion}")
2903 task printProperties {
2905 description "Output to console all System.properties"
2907 System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
2913 dependsOn eclipseProject
2914 dependsOn eclipseClasspath
2915 dependsOn eclipseJdt
2919 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
2920 task jalviewjsEclipseCopyDropins(type: Copy) {
2921 dependsOn jalviewjsEclipsePaths
2923 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
2924 inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
2925 def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
2932 // this eclipse -clean doesn't actually work
2933 task jalviewjsCleanEclipse(type: Exec) {
2934 dependsOn eclipseSetup
2935 dependsOn jalviewjsEclipsePaths
2936 dependsOn jalviewjsEclipseCopyDropins
2938 executable(eclipseBinary)
2939 args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
2945 def inputString = """exit
2948 def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
2949 standardInput = inputByteStream
2952 /* not really working yet
2953 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
2957 task jalviewjsTransferUnzipSwingJs {
2958 def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
2962 from zipTree(file_zip)
2963 into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2967 inputs.file file_zip
2968 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2972 task jalviewjsTransferUnzipLib {
2973 def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
2976 zipFiles.each { file_zip ->
2978 from zipTree(file_zip)
2979 into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2984 inputs.files zipFiles
2985 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2989 task jalviewjsTransferUnzipAllLibs {
2990 dependsOn jalviewjsTransferUnzipSwingJs
2991 dependsOn jalviewjsTransferUnzipLib
2995 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
2997 description "Create the alternative j2s file from the j2s.* properties"
2999 jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
3000 def siteDirProperty = "j2s.site.directory"
3001 def setSiteDir = false
3002 jalviewjsJ2sProps.each { prop, val ->
3004 if (prop == siteDirProperty) {
3005 if (!(val.startsWith('/') || val.startsWith("file://") )) {
3006 val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
3012 if (!setSiteDir) { // default site location, don't override specifically set property
3013 property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
3016 outputFile = jalviewjsJ2sAltSettingsFileName
3019 inputs.properties(jalviewjsJ2sProps)
3020 outputs.file(jalviewjsJ2sAltSettingsFileName)
3025 task jalviewjsEclipseSetup {
3026 dependsOn jalviewjsEclipseCopyDropins
3027 dependsOn jalviewjsSetEclipseWorkspace
3028 dependsOn jalviewjsCreateJ2sSettings
3032 task jalviewjsSyncAllLibs (type: Sync) {
3033 dependsOn jalviewjsTransferUnzipAllLibs
3034 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
3035 inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
3036 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
3040 def outputFiles = []
3041 rename { filename ->
3042 outputFiles += "${outputDir}/${filename}"
3049 // should this be exclude really ?
3050 duplicatesStrategy "INCLUDE"
3052 outputs.files outputFiles
3053 inputs.files inputFiles
3057 task jalviewjsSyncResources (type: Sync) {
3058 dependsOn buildResources
3060 def inputFiles = fileTree(dir: resourcesBuildDir)
3061 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
3065 def outputFiles = []
3066 rename { filename ->
3067 outputFiles += "${outputDir}/${filename}"
3073 outputs.files outputFiles
3074 inputs.files inputFiles
3078 task jalviewjsSyncSiteResources (type: Sync) {
3079 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
3080 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
3084 def outputFiles = []
3085 rename { filename ->
3086 outputFiles += "${outputDir}/${filename}"
3092 outputs.files outputFiles
3093 inputs.files inputFiles
3097 task jalviewjsSyncBuildProperties (type: Sync) {
3098 dependsOn createBuildProperties
3099 def inputFiles = [file(buildProperties)]
3100 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
3104 def outputFiles = []
3105 rename { filename ->
3106 outputFiles += "${outputDir}/${filename}"
3112 outputs.files outputFiles
3113 inputs.files inputFiles
3117 task jalviewjsProjectImport(type: Exec) {
3118 dependsOn eclipseSetup
3119 dependsOn jalviewjsEclipsePaths
3120 dependsOn jalviewjsEclipseSetup
3123 // do not run a headless import when we claim to be in Eclipse
3125 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
3126 throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
3128 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
3132 //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
3133 def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
3134 executable(eclipseBinary)
3135 args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
3139 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
3141 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
3142 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
3145 inputs.file("${jalviewDir}/.project")
3146 outputs.upToDateWhen {
3147 file(projdir).exists()
3152 task jalviewjsTranspile(type: Exec) {
3153 dependsOn jalviewjsEclipseSetup
3154 dependsOn jalviewjsProjectImport
3155 dependsOn jalviewjsEclipsePaths
3157 dependsOn jalviewjsEnableAltFileProperty
3161 // do not run a headless transpile when we claim to be in Eclipse
3163 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
3164 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
3166 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
3170 executable(eclipseBinary)
3171 args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
3175 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
3177 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
3178 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
3184 stdout = new ByteArrayOutputStream()
3185 stderr = new ByteArrayOutputStream()
3187 def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
3188 def logOutFile = file(logOutFileName)
3189 logOutFile.createNewFile()
3190 logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
3191 BINARY: ${eclipseBinary}
3192 VERSION: ${eclipseVersion}
3193 WORKSPACE: ${eclipseWorkspace}
3194 DEBUG: ${eclipseDebug}
3197 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
3198 // combine stdout and stderr
3199 def logErrFOS = logOutFOS
3201 if (jalviewjs_j2s_to_console.equals("true")) {
3202 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
3203 new org.apache.tools.ant.util.TeeOutputStream(
3207 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
3208 new org.apache.tools.ant.util.TeeOutputStream(
3213 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
3216 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
3223 if (stdout.toString().contains("Error processing ")) {
3224 // j2s did not complete transpile
3225 //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
3226 if (jalviewjs_ignore_transpile_errors.equals("true")) {
3227 println("IGNORING TRANSPILE ERRORS")
3228 println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
3230 throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
3235 inputs.dir("${jalviewDir}/${sourceDir}")
3236 outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
3237 outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
3241 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
3243 def stdout = new ByteArrayOutputStream()
3244 def stderr = new ByteArrayOutputStream()
3246 def coreFile = file(jsfile)
3248 msg = "Creating core for ${name}...\nGenerating ${jsfile}"
3250 logOutFile.createNewFile()
3251 logOutFile.append(msg+"\n")
3253 def coreTop = file(prefixFile)
3254 def coreBottom = file(suffixFile)
3255 coreFile.getParentFile().mkdirs()
3256 coreFile.createNewFile()
3257 coreFile.write( coreTop.getText("UTF-8") )
3261 def t = f.getText("UTF-8")
3262 t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
3263 coreFile.append( t )
3265 msg = "...file '"+f.getPath()+"' does not exist, skipping"
3267 logOutFile.append(msg+"\n")
3270 coreFile.append( coreBottom.getText("UTF-8") )
3272 msg = "Generating ${zjsfile}"
3274 logOutFile.append(msg+"\n")
3275 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
3276 def logErrFOS = logOutFOS
3279 classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
3280 main = "com.google.javascript.jscomp.CommandLineRunner"
3281 jvmArgs = [ "-Dfile.encoding=UTF-8" ]
3282 args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
3285 msg = "\nRunning '"+commandLine.join(' ')+"'\n"
3287 logOutFile.append(msg+"\n")
3289 if (logOutConsole) {
3290 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
3291 new org.apache.tools.ant.util.TeeOutputStream(
3295 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
3296 new org.apache.tools.ant.util.TeeOutputStream(
3301 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
3304 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
3311 logOutFile.append(msg+"\n")
3315 task jalviewjsBuildAllCores {
3317 description "Build the core js lib closures listed in the classlists dir"
3318 dependsOn jalviewjsTranspile
3319 dependsOn jalviewjsTransferUnzipSwingJs
3321 def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
3322 def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
3323 def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
3324 def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
3325 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
3326 def prefixFile = "${jsDir}/core/coretop2.js"
3327 def suffixFile = "${jsDir}/core/corebottom2.js"
3329 inputs.file prefixFile
3330 inputs.file suffixFile
3332 def classlistFiles = []
3333 // add the classlists found int the jalviewjs_classlists_dir
3334 fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
3336 def name = file.getName() - ".txt"
3343 // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
3344 //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
3345 classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
3347 jalviewjsCoreClasslists = []
3349 classlistFiles.each {
3352 def file = hash['file']
3353 if (! file.exists()) {
3354 //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
3355 return false // this is a "continue" in groovy .each closure
3357 def name = hash['name']
3359 name = file.getName() - ".txt"
3367 def list = fileTree(dir: j2sDir, includes: filelist)
3369 def jsfile = "${outputDir}/core${name}.js"
3370 def zjsfile = "${outputDir}/core${name}.z.js"
3372 jalviewjsCoreClasslists += [
3381 outputs.file(jsfile)
3382 outputs.file(zjsfile)
3385 // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
3386 def stevesoftClasslistName = "_stevesoft"
3387 def stevesoftClasslist = [
3388 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
3389 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
3390 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
3391 'name': stevesoftClasslistName
3393 jalviewjsCoreClasslists += stevesoftClasslist
3394 inputs.files(stevesoftClasslist['list'])
3395 outputs.file(stevesoftClasslist['jsfile'])
3396 outputs.file(stevesoftClasslist['zjsfile'])
3399 def allClasslistName = "_all"
3400 def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
3401 allJsFiles += fileTree(
3405 // these exlusions are files that the closure-compiler produces errors for. Should fix them
3406 "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
3407 "**/org/jmol/export/JSExporter.js"
3410 allJsFiles += fileTree(
3414 // these exlusions are files that the closure-compiler produces errors for. Should fix them
3415 "**/sun/misc/Unsafe.js",
3416 "**/swingjs/jquery/jquery-editable-select.js",
3417 "**/swingjs/jquery/j2sComboBox.js",
3418 "**/sun/misc/FloatingDecimal.js"
3421 def allClasslist = [
3422 'jsfile': "${outputDir}/core${allClasslistName}.js",
3423 'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
3425 'name': allClasslistName
3427 // not including this version of "all" core at the moment
3428 //jalviewjsCoreClasslists += allClasslist
3429 inputs.files(allClasslist['list'])
3430 outputs.file(allClasslist['jsfile'])
3431 outputs.file(allClasslist['zjsfile'])
3434 def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
3435 logOutFile.getParentFile().mkdirs()
3436 logOutFile.createNewFile()
3437 logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
3439 jalviewjsCoreClasslists.each {
3440 jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
3447 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
3450 into file(outputFile).getParentFile()
3451 rename { filename ->
3452 if (filename.equals(inputFile.getName())) {
3453 return file(outputFile).getName()
3457 filter(ReplaceTokens,
3461 'MAIN': '"'+main_class+'"',
3463 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
3464 'COREKEY': jalviewjs_core_key,
3465 'CORENAME': coreName
3472 task jalviewjsPublishCoreTemplates {
3473 dependsOn jalviewjsBuildAllCores
3474 def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
3475 def inputFile = file(inputFileName)
3476 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
3478 def outputFiles = []
3479 jalviewjsCoreClasslists.each { cl ->
3480 def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
3481 cl['outputfile'] = outputFile
3482 outputFiles += outputFile
3486 jalviewjsCoreClasslists.each { cl ->
3487 jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
3490 inputs.file(inputFile)
3491 outputs.files(outputFiles)
3495 task jalviewjsSyncCore (type: Sync) {
3496 dependsOn jalviewjsBuildAllCores
3497 dependsOn jalviewjsPublishCoreTemplates
3498 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
3499 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
3503 def outputFiles = []
3504 rename { filename ->
3505 outputFiles += "${outputDir}/${filename}"
3511 outputs.files outputFiles
3512 inputs.files inputFiles
3516 // this Copy version of TransferSiteJs will delete anything else in the target dir
3517 task jalviewjsCopyTransferSiteJs(type: Copy) {
3518 dependsOn jalviewjsTranspile
3519 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
3520 into "${jalviewDir}/${jalviewjsSiteDir}"
3524 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
3525 task jalviewjsSyncTransferSiteJs(type: Sync) {
3526 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
3528 into "${jalviewDir}/${jalviewjsSiteDir}"
3535 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
3536 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
3537 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
3538 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
3540 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
3541 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
3542 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
3543 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
3546 task jalviewjsPrepareSite {
3548 description "Prepares the website folder including unzipping files and copying resources"
3549 dependsOn jalviewjsSyncAllLibs
3550 dependsOn jalviewjsSyncResources
3551 dependsOn jalviewjsSyncSiteResources
3552 dependsOn jalviewjsSyncBuildProperties
3553 dependsOn jalviewjsSyncCore
3557 task jalviewjsBuildSite {
3559 description "Builds the whole website including transpiled code"
3560 dependsOn jalviewjsCopyTransferSiteJs
3561 dependsOn jalviewjsPrepareSite
3565 task cleanJalviewjsTransferSite {
3567 delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
3568 delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
3569 delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
3570 delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
3575 task cleanJalviewjsSite {
3576 dependsOn cleanJalviewjsTransferSite
3578 delete "${jalviewDir}/${jalviewjsSiteDir}"
3583 task jalviewjsSiteTar(type: Tar) {
3585 description "Creates a tar.gz file for the website"
3586 dependsOn jalviewjsBuildSite
3587 def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
3588 archiveFileName = outputFilename
3590 compression Compression.GZIP
3592 from "${jalviewDir}/${jalviewjsSiteDir}"
3593 into jalviewjs_site_dir // this is inside the tar file
3595 inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
3599 task jalviewjsServer {
3601 def filename = "jalviewjsTest.html"
3602 description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
3603 def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
3608 def f = Class.forName("org.gradle.plugins.javascript.envjs.http.simple.SimpleHttpFileServerFactory")
3609 factory = f.newInstance()
3610 } catch (ClassNotFoundException e) {
3611 throw new GradleException("Unable to create SimpleHttpFileServerFactory")
3613 def port = Integer.valueOf(jalviewjs_server_port)
3618 while(port < start+1000 && !running) {
3620 def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
3621 jalviewjsServer = factory.start(doc_root, port)
3623 url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
3624 println("SERVER STARTED with document root ${doc_root}.")
3625 println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).")
3626 println("For debug: "+url+"?j2sdebug")
3627 println("For verbose: "+url+"?j2sverbose")
3628 } catch (Exception e) {
3633 <p><a href="${url}">JalviewJS Test. <${url}></a></p>
3634 <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
3635 <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
3637 jalviewjsCoreClasslists.each { cl ->
3638 def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
3640 <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></a></p>
3642 println("For core ${cl.name}: "+urlcore)
3645 file(htmlFile).text = htmlText
3648 outputs.file(htmlFile)
3649 outputs.upToDateWhen({false})
3653 task cleanJalviewjsAll {
3655 description "Delete all configuration and build artifacts to do with JalviewJS build"
3656 dependsOn cleanJalviewjsSite
3657 dependsOn jalviewjsEclipsePaths
3660 delete "${jalviewDir}/${jalviewjsBuildDir}"
3661 delete "${jalviewDir}/${eclipse_bin_dir}"
3662 if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
3663 delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
3665 delete jalviewjsJ2sAltSettingsFileName
3668 outputs.upToDateWhen( { false } )
3672 task jalviewjsIDE_checkJ2sPlugin {
3673 group "00 JalviewJS in Eclipse"
3674 description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
3677 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3678 def j2sPluginFile = file(j2sPlugin)
3679 def eclipseHome = System.properties["eclipse.home.location"]
3680 if (eclipseHome == null || ! IN_ECLIPSE) {
3681 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
3683 def eclipseJ2sPluginDirs = [ "${eclipseHome}/dropins" ]
3684 def altPluginsDir = System.properties["org.eclipse.equinox.p2.reconciler.dropins.directory"]
3685 if (altPluginsDir != null && file(altPluginsDir).exists()) {
3686 eclipseJ2sPluginDirs += altPluginsDir
3688 def foundPlugin = false
3689 def j2sPluginFileName = j2sPluginFile.getName()
3690 def eclipseJ2sPlugin
3691 def eclipseJ2sPluginFile
3692 eclipseJ2sPluginDirs.any { dir ->
3693 eclipseJ2sPlugin = "${dir}/${j2sPluginFileName}"
3694 eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3695 if (eclipseJ2sPluginFile.exists()) {
3701 def msg = "Eclipse J2S Plugin is not installed (could not find '${j2sPluginFileName}' in\n"+eclipseJ2sPluginDirs.join("\n")+"\n)\nTry running task jalviewjsIDE_copyJ2sPlugin"
3702 System.err.println(msg)
3703 throw new StopExecutionException(msg)
3706 def digest = MessageDigest.getInstance("MD5")
3708 digest.update(j2sPluginFile.text.bytes)
3709 def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3711 digest.update(eclipseJ2sPluginFile.text.bytes)
3712 def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3714 if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
3715 def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
3716 System.err.println(msg)
3717 throw new StopExecutionException(msg)
3719 def msg = "Eclipse J2S Plugin '${eclipseJ2sPlugin}' is the same as '${j2sPlugin}' (this is good)"
3725 task jalviewjsIDE_copyJ2sPlugin {
3726 group "00 JalviewJS in Eclipse"
3727 description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
3730 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3731 def j2sPluginFile = file(j2sPlugin)
3732 def eclipseHome = System.properties["eclipse.home.location"]
3733 if (eclipseHome == null || ! IN_ECLIPSE) {
3734 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
3736 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
3737 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3738 def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
3739 System.err.println(msg)
3742 eclipseJ2sPluginFile.getParentFile().mkdirs()
3743 into eclipseJ2sPluginFile.getParent()
3749 task jalviewjsIDE_j2sFile {
3750 group "00 JalviewJS in Eclipse"
3751 description "Creates the .j2s file"
3752 dependsOn jalviewjsCreateJ2sSettings
3756 task jalviewjsIDE_SyncCore {
3757 group "00 JalviewJS in Eclipse"
3758 description "Build the core js lib closures listed in the classlists dir and publish core html from template"
3759 dependsOn jalviewjsSyncCore
3763 task jalviewjsIDE_SyncSiteAll {
3764 dependsOn jalviewjsSyncAllLibs
3765 dependsOn jalviewjsSyncResources
3766 dependsOn jalviewjsSyncSiteResources
3767 dependsOn jalviewjsSyncBuildProperties
3771 cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
3774 task jalviewjsIDE_PrepareSite {
3775 group "00 JalviewJS in Eclipse"
3776 description "Sync libs and resources to site dir, but not closure cores"
3778 dependsOn jalviewjsIDE_SyncSiteAll
3779 //dependsOn cleanJalviewjsTransferSite // not sure why this clean is here -- will slow down a re-run of this task
3783 task jalviewjsIDE_AssembleSite {
3784 group "00 JalviewJS in Eclipse"
3785 description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
3786 dependsOn jalviewjsPrepareSite
3790 task jalviewjsIDE_SiteClean {
3791 group "00 JalviewJS in Eclipse"
3792 description "Deletes the Eclipse transpiled site"
3793 dependsOn cleanJalviewjsSite
3797 task jalviewjsIDE_Server {
3798 group "00 JalviewJS in Eclipse"
3799 description "Starts a webserver on localhost to test the website"
3800 dependsOn jalviewjsServer
3804 // buildship runs this at import or gradle refresh
3805 task eclipseSynchronizationTask {
3806 //dependsOn eclipseSetup
3807 dependsOn createBuildProperties
3809 dependsOn jalviewjsIDE_j2sFile
3810 dependsOn jalviewjsIDE_checkJ2sPlugin
3811 dependsOn jalviewjsIDE_PrepareSite
3816 // buildship runs this at build time or project refresh
3817 task eclipseAutoBuildTask {
3818 //dependsOn jalviewjsIDE_checkJ2sPlugin
3819 //dependsOn jalviewjsIDE_PrepareSite
3825 description "Build the site"
3826 dependsOn jalviewjsBuildSite