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
37 classpath "com.vladsch.flexmark:flexmark-all:0.62.0"
38 classpath "org.jsoup:jsoup:1.14.3"
47 id "com.diffplug.gradle.spotless" version "3.28.0"
48 id 'com.github.johnrengelman.shadow' version '4.0.3'
49 id 'com.install4j.gradle' version '9.0.6'
50 id 'com.dorongold.task-tree' version '1.5' // only needed to display task dependency tree with gradle task1 [task2 ...] taskTree
51 id 'com.palantir.git-version' version '0.13.0' apply false
62 // in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use
63 def string(Object o) {
64 return o == null ? "" : o.toString()
67 def overrideProperties(String propsFileName, boolean output = false) {
68 if (propsFileName == null) {
71 def propsFile = file(propsFileName)
72 if (propsFile != null && propsFile.exists()) {
73 println("Using properties from file '${propsFileName}'")
75 def p = new Properties()
76 def localPropsFIS = new FileInputStream(propsFile)
82 if (project.hasProperty(key)) {
83 oldval = project.findProperty(key)
84 project.setProperty(key, val)
86 println("Overriding property '${key}' ('${oldval}') with ${file(propsFile).getName()} value '${val}'")
89 ext.setProperty(key, val)
91 println("Setting ext property '${key}' with ${file(propsFile).getName()}s value '${val}'")
95 } catch (Exception e) {
96 println("Exception reading local.properties")
103 jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
104 jalviewDirRelativePath = jalviewDir
107 getdownChannelName = CHANNEL.toLowerCase()
108 // default to "default". Currently only has different cosmetics for "develop", "release", "default"
109 propertiesChannelName = ["develop", "release", "test-release", "jalviewjs", "jalviewjs-release" ].contains(getdownChannelName) ? getdownChannelName : "default"
110 // Import channel_properties
111 channelDir = string("${jalviewDir}/${channel_properties_dir}/${propertiesChannelName}")
112 channelGradleProperties = string("${channelDir}/channel_gradle.properties")
113 channelPropsFile = string("${channelDir}/${resource_dir}/${channel_props}")
114 overrideProperties(channelGradleProperties, false)
115 // local build environment properties
116 // can be "projectDir/local.properties"
117 overrideProperties("${projectDir}/local.properties", true)
118 // or "../projectDir_local.properties"
119 overrideProperties(projectDir.getParent() + "/" + projectDir.getName() + "_local.properties", true)
122 // Import releaseProps from the RELEASE file
123 // or a file specified via JALVIEW_RELEASE_FILE if defined
124 // Expect jalview.version and target release branch in jalview.release
125 releaseProps = new Properties();
126 def releasePropFile = findProperty("JALVIEW_RELEASE_FILE");
127 def defaultReleasePropFile = "${jalviewDirAbsolutePath}/RELEASE";
129 (new File(releasePropFile!=null ? releasePropFile : defaultReleasePropFile)).withInputStream {
130 releaseProps.load(it)
132 } catch (Exception fileLoadError) {
133 throw new Error("Couldn't load release properties file "+(releasePropFile==null ? defaultReleasePropFile : "from custom location: releasePropFile"),fileLoadError);
136 // Set JALVIEW_VERSION if it is not already set
137 if (findProperty("JALVIEW_VERSION")==null || "".equals(JALVIEW_VERSION)) {
138 JALVIEW_VERSION = releaseProps.get("jalview.version")
141 // this property set when running Eclipse headlessly
142 j2sHeadlessBuildProperty = string("net.sf.j2s.core.headlessbuild")
143 // this property set by Eclipse
144 eclipseApplicationProperty = string("eclipse.application")
145 // CHECK IF RUNNING FROM WITHIN ECLIPSE
146 def eclipseApplicationPropertyVal = System.properties[eclipseApplicationProperty]
147 IN_ECLIPSE = eclipseApplicationPropertyVal != null && eclipseApplicationPropertyVal.startsWith("org.eclipse.ui.")
148 // BUT WITHOUT THE HEADLESS BUILD PROPERTY SET
149 if (System.properties[j2sHeadlessBuildProperty].equals("true")) {
150 println("Setting IN_ECLIPSE to ${IN_ECLIPSE} as System.properties['${j2sHeadlessBuildProperty}'] == '${System.properties[j2sHeadlessBuildProperty]}'")
154 println("WITHIN ECLIPSE IDE")
156 println("HEADLESS BUILD")
159 J2S_ENABLED = (project.hasProperty('j2s.compiler.status') && project['j2s.compiler.status'] != null && project['j2s.compiler.status'] == "enable")
161 println("J2S ENABLED")
164 System.properties.sort { it.key }.each {
165 key, val -> println("SYSTEM PROPERTY ${key}='${val}'")
168 if (false && IN_ECLIPSE) {
169 jalviewDir = jalviewDirAbsolutePath
174 buildDate = new Date().format("yyyyMMdd")
177 bareSourceDir = string(source_dir)
178 sourceDir = string("${jalviewDir}/${bareSourceDir}")
179 resourceDir = string("${jalviewDir}/${resource_dir}")
180 bareTestSourceDir = string(test_source_dir)
181 testDir = string("${jalviewDir}/${bareTestSourceDir}")
183 classesDir = string("${jalviewDir}/${classes_dir}")
186 useClover = clover.equals("true")
187 cloverBuildDir = "${buildDir}/clover"
188 cloverInstrDir = file("${cloverBuildDir}/clover-instr")
189 cloverClassesDir = file("${cloverBuildDir}/clover-classes")
190 cloverReportDir = file("${buildDir}/reports/clover")
191 cloverTestInstrDir = file("${cloverBuildDir}/clover-test-instr")
192 cloverTestClassesDir = file("${cloverBuildDir}/clover-test-classes")
193 //cloverTestClassesDir = cloverClassesDir
194 cloverDb = string("${cloverBuildDir}/clover.db")
196 testSourceDir = useClover ? cloverTestInstrDir : testDir
197 testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}"
199 getdownChannelDir = string("${getdown_website_dir}/${propertiesChannelName}")
200 getdownAppBaseDir = string("${jalviewDir}/${getdownChannelDir}/${JAVA_VERSION}")
201 getdownArchiveDir = string("${jalviewDir}/${getdown_archive_dir}")
202 getdownFullArchiveDir = null
203 getdownTextLines = []
204 getdownLaunchJvl = null
205 getdownVersionLaunchJvl = null
207 buildProperties = null
209 // the following values might be overridden by the CHANNEL switch
210 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
211 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
212 getdownArchiveAppBase = getdown_archive_base
213 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
214 getdownAppDistDir = getdown_app_dir_alt
215 getdownImagesDir = string("${jalviewDir}/${getdown_images_dir}")
216 getdownSetAppBaseProperty = false // whether to pass the appbase and appdistdir to the application
217 reportRsyncCommand = false
218 jvlChannelName = CHANNEL.toLowerCase()
219 install4jSuffix = CHANNEL.substring(0, 1).toUpperCase() + CHANNEL.substring(1).toLowerCase(); // BUILD -> Build
220 install4jDMGDSStore = "${install4j_images_dir}/${install4j_dmg_ds_store}"
221 install4jDMGBackgroundImage = "${install4j_images_dir}/${install4j_dmg_background}"
222 install4jInstallerName = "${jalview_name} Non-Release Installer"
223 install4jExecutableName = install4j_executable_name
224 install4jExtraScheme = "jalviewx"
225 install4jMacIconsFile = string("${install4j_images_dir}/${install4j_mac_icons_file}")
226 install4jWindowsIconsFile = string("${install4j_images_dir}/${install4j_windows_icons_file}")
227 install4jPngIconFile = string("${install4j_images_dir}/${install4j_png_icon_file}")
228 install4jBackground = string("${install4j_images_dir}/${install4j_background}")
229 install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
230 install4jCheckSums = true
232 applicationName = "${jalview_name}"
236 // TODO: get bamboo build artifact URL for getdown artifacts
237 getdown_channel_base = bamboo_channelbase
238 getdownChannelName = string("${bamboo_planKey}/${JAVA_VERSION}")
239 getdownAppBase = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
240 jvlChannelName += "_${getdownChannelName}"
241 // automatically add the test group Not-bamboo for exclusion
242 if ("".equals(testng_excluded_groups)) {
243 testng_excluded_groups = "Not-bamboo"
245 install4jExtraScheme = "jalviewb"
248 case [ "RELEASE", "JALVIEWJS-RELEASE" ]:
249 getdownAppDistDir = getdown_app_dir_release
250 getdownSetAppBaseProperty = true
251 reportRsyncCommand = true
253 install4jInstallerName = "${jalview_name} Installer"
257 getdownChannelName = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
258 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
259 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
260 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
261 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
263 package_dir = string("${ARCHIVEDIR}/${package_dir}")
264 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
267 reportRsyncCommand = true
268 install4jExtraScheme = "jalviewa"
272 getdownChannelName = string("archive/${JALVIEW_VERSION}")
273 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
274 getdownAppBase = file(getdownAppBaseDir).toURI().toString()
275 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
276 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
278 package_dir = string("${ARCHIVEDIR}/${package_dir}")
279 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
282 reportRsyncCommand = true
283 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
284 install4jSuffix = "Archive"
285 install4jExtraScheme = "jalviewa"
289 reportRsyncCommand = true
290 getdownSetAppBaseProperty = true
291 // DEVELOP-RELEASE is usually associated with a Jalview release series so set the version
292 JALVIEW_VERSION=JALVIEW_VERSION+"-d${buildDate}"
294 install4jSuffix = "Develop"
295 install4jExtraScheme = "jalviewd"
296 install4jInstallerName = "${jalview_name} Develop Installer"
300 reportRsyncCommand = true
301 getdownSetAppBaseProperty = true
302 // Don't ignore transpile errors for release build
303 if (jalviewjs_ignore_transpile_errors.equals("true")) {
304 jalviewjs_ignore_transpile_errors = "false"
305 println("Setting jalviewjs_ignore_transpile_errors to 'false'")
307 JALVIEW_VERSION = JALVIEW_VERSION+"-test"
308 install4jSuffix = "Test"
309 install4jExtraScheme = "jalviewt"
310 install4jInstallerName = "${jalview_name} Test Installer"
313 case ~/^SCRATCH(|-[-\w]*)$/:
314 getdownChannelName = CHANNEL
315 JALVIEW_VERSION = JALVIEW_VERSION+"-"+CHANNEL
317 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
318 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
319 reportRsyncCommand = true
320 install4jSuffix = "Scratch"
324 if (!file("${LOCALDIR}").exists()) {
325 throw new GradleException("Must provide a LOCALDIR value to produce a local distribution")
327 getdownAppBase = file(file("${LOCALDIR}").getAbsolutePath()).toURI().toString()
328 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
330 JALVIEW_VERSION = "TEST"
331 install4jSuffix = "Test-Local"
332 install4jExtraScheme = "jalviewt"
333 install4jInstallerName = "${jalview_name} Test Installer"
336 case [ "LOCAL", "JALVIEWJS" ]:
337 JALVIEW_VERSION = "TEST"
338 getdownAppBase = file(getdownAppBaseDir).toURI().toString()
339 getdownArchiveAppBase = file("${jalviewDir}/${getdown_archive_dir}").toURI().toString()
340 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
341 install4jExtraScheme = "jalviewl"
342 install4jCheckSums = false
345 default: // something wrong specified
346 throw new GradleException("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
350 JALVIEW_VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
351 hugoDataJsonFile = file("${jalviewDir}/${hugo_build_dir}/${hugo_data_installers_dir}/installers-${JALVIEW_VERSION_UNDERSCORES}.json")
352 hugoArchiveMdFile = file("${jalviewDir}/${hugo_build_dir}/${hugo_version_archive_dir}/Version-${JALVIEW_VERSION_UNDERSCORES}/_index.md")
353 // override getdownAppBase if requested
354 if (findProperty("getdown_appbase_override") != null) {
355 // revert to LOCAL if empty string
356 if (string(getdown_appbase_override) == "") {
357 getdownAppBase = file(getdownAppBaseDir).toURI().toString()
358 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
359 } else if (string(getdown_appbase_override).startsWith("file://")) {
360 getdownAppBase = string(getdown_appbase_override)
361 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
363 getdownAppBase = string(getdown_appbase_override)
365 println("Overriding getdown appbase with '${getdownAppBase}'")
367 // sanitise file name for jalview launcher file for this channel
368 jvlChannelName = jvlChannelName.replaceAll("[^\\w\\-]+", "_")
369 // install4j application and folder names
370 if (install4jSuffix == "") {
371 install4jBundleId = "${install4j_bundle_id}"
372 install4jWinApplicationId = install4j_release_win_application_id
374 applicationName = "${jalview_name} ${install4jSuffix}"
375 install4jBundleId = "${install4j_bundle_id}-" + install4jSuffix.toLowerCase()
376 // add int hash of install4jSuffix to the last part of the application_id
377 def id = install4j_release_win_application_id
378 def idsplitreverse = id.split("-").reverse()
379 idsplitreverse[0] = idsplitreverse[0].toInteger() + install4jSuffix.hashCode()
380 install4jWinApplicationId = idsplitreverse.reverse().join("-")
382 // sanitise folder and id names
383 // install4jApplicationFolder = e.g. "Jalview Build"
384 install4jApplicationFolder = applicationName
385 .replaceAll("[\"'~:/\\\\\\s]", "_") // replace all awkward filename chars " ' ~ : / \
386 .replaceAll("_+", "_") // collapse __
387 install4jInternalId = applicationName
389 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
390 .replaceAll("_+", "") // collapse __
391 //.replaceAll("_*-_*", "-") // collapse _-_
392 install4jUnixApplicationFolder = applicationName
394 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
395 .replaceAll("_+", "_") // collapse __
396 .replaceAll("_*-_*", "-") // collapse _-_
399 getdownWrapperLink = install4jUnixApplicationFolder // e.g. "jalview_local"
400 getdownAppDir = string("${getdownAppBaseDir}/${getdownAppDistDir}")
401 //getdownJ11libDir = "${getdownAppBaseDir}/${getdown_j11lib_dir}"
402 getdownResourceDir = string("${getdownAppBaseDir}/${getdown_resource_dir}")
403 getdownInstallDir = string("${getdownAppBaseDir}/${getdown_install_dir}")
404 getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
405 getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
406 /* compile without modules -- using classpath libraries
407 modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
408 modules_runtimeClasspath = modules_compileClasspath
414 apply plugin: "com.palantir.git-version"
415 def details = versionDetails()
416 gitHash = details.gitHash
417 gitBranch = details.branchName
418 } catch(org.gradle.api.internal.plugins.PluginApplicationException e) {
419 println("Not in a git repository. Using git values from RELEASE properties file.")
420 gitHash = releaseProps.getProperty("git.hash")
421 gitBranch = releaseProps.getProperty("git.branch")
422 } catch(java.lang.RuntimeException e1) {
423 throw new GradleException("Error with git-version plugin. Directory '.git' exists but versionDetails() cannot be found.")
426 println("Using a ${CHANNEL} profile.")
428 additional_compiler_args = []
429 // configure classpath/args for j8/j11 compilation
430 if (JAVA_VERSION.equals("1.8")) {
431 JAVA_INTEGER_VERSION = string("8")
434 libDistDir = j8libDir
435 compile_source_compatibility = 1.8
436 compile_target_compatibility = 1.8
437 // these are getdown.txt properties defined dependent on the JAVA_VERSION
438 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java8_min_version"))
439 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java8_max_version"))
440 // this property is assigned below and expanded to multiple lines in the getdown task
441 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java8_txt_multi_java_location"))
442 // this property is for the Java library used in eclipse
443 eclipseJavaRuntimeName = string("JavaSE-1.8")
444 } else if (JAVA_VERSION.equals("11")) {
445 JAVA_INTEGER_VERSION = string("11")
447 libDistDir = j11libDir
448 compile_source_compatibility = 11
449 compile_target_compatibility = 11
450 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
451 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
452 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
453 eclipseJavaRuntimeName = string("JavaSE-11")
454 /* compile without modules -- using classpath libraries
455 additional_compiler_args += [
456 '--module-path', modules_compileClasspath.asPath,
457 '--add-modules', j11modules
460 } else if (JAVA_VERSION.equals("17")) {
461 JAVA_INTEGER_VERSION = string("17")
463 libDistDir = j17libDir
464 compile_source_compatibility = 17
465 compile_target_compatibility = 17
466 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
467 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
468 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
469 eclipseJavaRuntimeName = string("JavaSE-17")
470 /* compile without modules -- using classpath libraries
471 additional_compiler_args += [
472 '--module-path', modules_compileClasspath.asPath,
473 '--add-modules', j11modules
477 throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
482 JAVA_MIN_VERSION = JAVA_VERSION
483 JAVA_MAX_VERSION = JAVA_VERSION
484 def jreInstallsDir = string(jre_installs_dir)
485 if (jreInstallsDir.startsWith("~/")) {
486 jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1)
488 macosJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-mac-x64/jre")
489 windowsJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-windows-x64/jre")
490 linuxJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-linux-x64/jre")
491 macosJavaVMTgz = string("${jreInstallsDir}/tgz/jre_${JAVA_INTEGER_VERSION}_mac_x64.tar.gz")
492 windowsJavaVMTgz = string("${jreInstallsDir}/tgz/jre_${JAVA_INTEGER_VERSION}_windows_x64.tar.gz")
493 linuxJavaVMTgz = string("${jreInstallsDir}/tgz/jre_${JAVA_INTEGER_VERSION}_linux_x64.tar.gz")
494 install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
495 install4jConfFileName = string("jalview-install4j-conf.install4j")
496 install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
497 install4jHomeDir = install4j_home_dir
498 if (install4jHomeDir.startsWith("~/")) {
499 install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1)
502 resourceBuildDir = string("${buildDir}/resources")
503 resourcesBuildDir = string("${resourceBuildDir}/resources_build")
504 helpBuildDir = string("${resourceBuildDir}/help_build")
505 docBuildDir = string("${resourceBuildDir}/doc_build")
507 if (buildProperties == null) {
508 buildProperties = string("${resourcesBuildDir}/${build_properties_file}")
510 buildingHTML = string("${jalviewDir}/${doc_dir}/building.html")
511 helpParentDir = string("${jalviewDir}/${help_parent_dir}")
512 helpSourceDir = string("${helpParentDir}/${help_dir}")
513 helpFile = string("${helpBuildDir}/${help_dir}/help.jhm")
516 relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
517 jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
518 jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}")
520 jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
522 jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
524 jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
525 jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
526 jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
527 jalviewjsJalviewCoreHtmlFile = string("")
528 jalviewjsJalviewCoreName = string(jalviewjs_core_name)
529 jalviewjsCoreClasslists = []
530 jalviewjsJalviewTemplateName = string(jalviewjs_name)
531 jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
532 jalviewjsJ2sAltSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_alt_settings}")
533 jalviewjsJ2sProps = null
534 jalviewjsJ2sPlugin = jalviewjs_j2s_plugin
536 eclipseWorkspace = null
537 eclipseBinary = string("")
538 eclipseVersion = string("")
548 outputDir = file(classesDir)
552 srcDirs = [ resourcesBuildDir, docBuildDir, helpBuildDir ]
555 compileClasspath = files(sourceSets.main.java.outputDir)
556 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
558 runtimeClasspath = compileClasspath
559 runtimeClasspath += files(sourceSets.main.resources.srcDirs)
564 srcDirs cloverInstrDir
565 outputDir = cloverClassesDir
569 srcDirs = sourceSets.main.resources.srcDirs
572 compileClasspath = files( sourceSets.clover.java.outputDir )
573 //compileClasspath += files( testClassesDir )
574 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
575 compileClasspath += fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
576 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
578 runtimeClasspath = compileClasspath
583 srcDirs testSourceDir
584 outputDir = file(testClassesDir)
588 srcDirs = useClover ? sourceSets.clover.resources.srcDirs : sourceSets.main.resources.srcDirs
591 compileClasspath = files( sourceSets.test.java.outputDir )
592 compileClasspath += useClover ? sourceSets.clover.compileClasspath : sourceSets.main.compileClasspath
593 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
595 runtimeClasspath = compileClasspath
596 runtimeClasspath += files(sourceSets.test.resources.srcDirs)
602 // eclipse project and settings files creation, also used by buildship
605 name = eclipse_project_name
607 natures 'org.eclipse.jdt.core.javanature',
608 'org.eclipse.jdt.groovy.core.groovyNature',
609 'org.eclipse.buildship.core.gradleprojectnature'
611 buildCommand 'org.eclipse.jdt.core.javabuilder'
612 buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
616 //defaultOutputDir = sourceSets.main.java.outputDir
617 configurations.each{ c->
618 if (c.isCanBeResolved()) {
619 minusConfigurations += [c]
623 plusConfigurations = [ ]
627 def removeTheseToo = []
628 HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
629 cp.entries.each { entry ->
630 // This conditional removes all src classpathentries that a) have already been added or b) aren't "src" or "test".
631 // e.g. this removes the resources dir being copied into bin/main, bin/test AND bin/clover
632 // we add the resources and help/help dirs in as libs afterwards (see below)
633 if (entry.kind == 'src') {
634 if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) {
635 removeTheseToo += entry
637 alreadyAddedSrcPath.putAt(entry.path, true)
642 cp.entries.removeAll(removeTheseToo)
644 //cp.entries += new Output("${eclipse_bin_dir}/main")
645 if (file(helpParentDir).isDirectory()) {
646 cp.entries += new Library(fileReference(helpParentDir))
648 if (file(resourceDir).isDirectory()) {
649 cp.entries += new Library(fileReference(resourceDir))
652 HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
654 sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
655 //don't want to add outputDir as eclipse is using its own output dir in bin/main
656 if (it.isDirectory() || ! it.exists()) {
657 // don't add dirs to classpath, especially if they don't exist
658 return false // groovy "continue" in .any closure
660 def itPath = it.toString()
661 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
662 // make relative path
663 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
665 if (alreadyAddedLibPath.get(itPath)) {
666 //println("Not adding duplicate entry "+itPath)
668 //println("Adding entry "+itPath)
669 cp.entries += new Library(fileReference(itPath))
670 alreadyAddedLibPath.put(itPath, true)
674 sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
675 //no longer want to add outputDir as eclipse is using its own output dir in bin/main
676 if (it.isDirectory() || ! it.exists()) {
677 // don't add dirs to classpath
678 return false // groovy "continue" in .any closure
681 def itPath = it.toString()
682 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
683 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
685 if (alreadyAddedLibPath.get(itPath)) {
688 def lib = new Library(fileReference(itPath))
689 lib.entryAttributes["test"] = "true"
691 alreadyAddedLibPath.put(itPath, true)
699 containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
704 // for the IDE, use java 11 compatibility
705 sourceCompatibility = compile_source_compatibility
706 targetCompatibility = compile_target_compatibility
707 javaRuntimeName = eclipseJavaRuntimeName
709 // add in jalview project specific properties/preferences into eclipse core preferences
711 withProperties { props ->
712 def jalview_prefs = new Properties()
713 def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
714 jalview_prefs.load(ins)
716 jalview_prefs.forEach { t, v ->
717 if (props.getAt(t) == null) {
721 // codestyle file -- overrides previous formatter prefs
722 def csFile = file("${jalviewDirAbsolutePath}/${eclipse_codestyle_file}")
723 if (csFile.exists()) {
724 XmlParser parser = new XmlParser()
725 def profiles = parser.parse(csFile)
726 def profile = profiles.'profile'.find { p -> (p.'@kind' == "CodeFormatterProfile" && p.'@name' == "Jalview") }
727 if (profile != null) {
728 profile.'setting'.each { s ->
730 def value = s.'@value'
731 if (id != null && value != null) {
732 props.putAt(id, value)
743 // Don't want these to be activated if in headless build
744 synchronizationTasks "eclipseSynchronizationTask"
745 //autoBuildTasks "eclipseAutoBuildTask"
751 /* hack to change eclipse prefs in .settings files other than org.eclipse.jdt.core.prefs */
752 // Class to allow updating arbitrary properties files
753 class PropertiesFile extends PropertiesPersistableConfigurationObject {
754 public PropertiesFile(PropertiesTransformer t) { super(t); }
755 @Override protected void load(Properties properties) { }
756 @Override protected void store(Properties properties) { }
757 @Override protected String getDefaultResourceName() { return ""; }
758 // This is necessary, because PropertiesPersistableConfigurationObject fails
759 // if no default properties file exists.
760 @Override public void loadDefaults() { load(new StringBufferInputStream("")); }
763 // Task to update arbitrary properties files (set outputFile)
764 class PropertiesFileTask extends PropertiesGeneratorTask<PropertiesFile> {
765 private final PropertiesFileContentMerger file;
766 public PropertiesFileTask() { file = new PropertiesFileContentMerger(getTransformer()); }
767 protected PropertiesFile create() { return new PropertiesFile(getTransformer()); }
768 protected void configure(PropertiesFile props) {
769 file.getBeforeMerged().execute(props); file.getWhenMerged().execute(props);
771 public void file(Closure closure) { ConfigureUtil.configure(closure, file); }
774 task eclipseUIPreferences(type: PropertiesFileTask) {
775 description = "Generate Eclipse additional settings"
776 def filename = "org.eclipse.jdt.ui.prefs"
777 outputFile = "$projectDir/.settings/${filename}" as File
780 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
785 task eclipseGroovyCorePreferences(type: PropertiesFileTask) {
786 description = "Generate Eclipse additional settings"
787 def filename = "org.eclipse.jdt.groovy.core.prefs"
788 outputFile = "$projectDir/.settings/${filename}" as File
791 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
796 task eclipseAllPreferences {
798 dependsOn eclipseUIPreferences
799 dependsOn eclipseGroovyCorePreferences
802 eclipseUIPreferences.mustRunAfter eclipseJdt
803 eclipseGroovyCorePreferences.mustRunAfter eclipseJdt
805 /* end of eclipse preferences hack */
813 delete cloverBuildDir
814 delete cloverReportDir
819 task cloverInstrJava(type: JavaExec) {
820 group = "Verification"
821 description = "Create clover instrumented source java files"
823 dependsOn cleanClover
825 inputs.files(sourceSets.main.allJava)
826 outputs.dir(cloverInstrDir)
828 //classpath = fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
829 classpath = sourceSets.clover.compileClasspath
830 main = "com.atlassian.clover.CloverInstr"
838 cloverInstrDir.getPath(),
840 def srcFiles = sourceSets.main.allJava.files
843 { file -> file.absolutePath }
846 args argsList.toArray()
849 delete cloverInstrDir
850 println("Clover: About to instrument "+srcFiles.size() +" files")
855 task cloverInstrTests(type: JavaExec) {
856 group = "Verification"
857 description = "Create clover instrumented source test files"
859 dependsOn cleanClover
861 inputs.files(testDir)
862 outputs.dir(cloverTestInstrDir)
864 classpath = sourceSets.clover.compileClasspath
865 main = "com.atlassian.clover.CloverInstr"
875 cloverTestInstrDir.getPath(),
877 args argsList.toArray()
880 delete cloverTestInstrDir
881 println("Clover: About to instrument test files")
887 group = "Verification"
888 description = "Create clover instrumented all source files"
890 dependsOn cloverInstrJava
891 dependsOn cloverInstrTests
895 cloverClasses.dependsOn cloverInstr
898 task cloverConsoleReport(type: JavaExec) {
899 group = "Verification"
900 description = "Creates clover console report"
903 file(cloverDb).exists()
906 inputs.dir cloverClassesDir
908 classpath = sourceSets.clover.runtimeClasspath
909 main = "com.atlassian.clover.reporters.console.ConsoleReporter"
911 if (cloverreport_mem.length() > 0) {
912 maxHeapSize = cloverreport_mem
914 if (cloverreport_jvmargs.length() > 0) {
915 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
925 args argsList.toArray()
929 task cloverHtmlReport(type: JavaExec) {
930 group = "Verification"
931 description = "Creates clover HTML report"
934 file(cloverDb).exists()
937 def cloverHtmlDir = cloverReportDir
938 inputs.dir cloverClassesDir
939 outputs.dir cloverHtmlDir
941 classpath = sourceSets.clover.runtimeClasspath
942 main = "com.atlassian.clover.reporters.html.HtmlReporter"
944 if (cloverreport_mem.length() > 0) {
945 maxHeapSize = cloverreport_mem
947 if (cloverreport_jvmargs.length() > 0) {
948 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
959 if (cloverreport_html_options.length() > 0) {
960 argsList += cloverreport_html_options.split(" ")
963 args argsList.toArray()
967 task cloverXmlReport(type: JavaExec) {
968 group = "Verification"
969 description = "Creates clover XML report"
972 file(cloverDb).exists()
975 def cloverXmlFile = "${cloverReportDir}/clover.xml"
976 inputs.dir cloverClassesDir
977 outputs.file cloverXmlFile
979 classpath = sourceSets.clover.runtimeClasspath
980 main = "com.atlassian.clover.reporters.xml.XMLReporter"
982 if (cloverreport_mem.length() > 0) {
983 maxHeapSize = cloverreport_mem
985 if (cloverreport_jvmargs.length() > 0) {
986 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
997 if (cloverreport_xml_options.length() > 0) {
998 argsList += cloverreport_xml_options.split(" ")
1001 args argsList.toArray()
1006 group = "Verification"
1007 description = "Creates clover reports"
1009 dependsOn cloverXmlReport
1010 dependsOn cloverHtmlReport
1017 sourceCompatibility = compile_source_compatibility
1018 targetCompatibility = compile_target_compatibility
1019 options.compilerArgs += additional_compiler_args
1020 print ("Setting target compatibility to "+targetCompatibility+"\n")
1022 //classpath += configurations.cloverRuntime
1028 // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ?
1029 sourceCompatibility = compile_source_compatibility
1030 targetCompatibility = compile_target_compatibility
1031 options.compilerArgs = additional_compiler_args
1032 options.encoding = "UTF-8"
1034 print ("Setting target compatibility to "+compile_target_compatibility+"\n")
1041 sourceCompatibility = compile_source_compatibility
1042 targetCompatibility = compile_target_compatibility
1043 options.compilerArgs = additional_compiler_args
1045 print ("Setting target compatibility to "+targetCompatibility+"\n")
1052 delete sourceSets.main.java.outputDir
1058 dependsOn cleanClover
1060 delete sourceSets.test.java.outputDir
1065 // format is a string like date.format("dd MMMM yyyy")
1066 def getDate(format) {
1067 return date.format(format)
1071 def convertMdToHtml (FileTree mdFiles, File cssFile) {
1072 MutableDataSet options = new MutableDataSet()
1074 def extensions = new ArrayList<>()
1075 extensions.add(AnchorLinkExtension.create())
1076 extensions.add(AutolinkExtension.create())
1077 extensions.add(StrikethroughExtension.create())
1078 extensions.add(TaskListExtension.create())
1079 extensions.add(TablesExtension.create())
1080 extensions.add(TocExtension.create())
1082 options.set(Parser.EXTENSIONS, extensions)
1084 // set GFM table parsing options
1085 options.set(TablesExtension.WITH_CAPTION, false)
1086 options.set(TablesExtension.COLUMN_SPANS, false)
1087 options.set(TablesExtension.MIN_HEADER_ROWS, 1)
1088 options.set(TablesExtension.MAX_HEADER_ROWS, 1)
1089 options.set(TablesExtension.APPEND_MISSING_COLUMNS, true)
1090 options.set(TablesExtension.DISCARD_EXTRA_COLUMNS, true)
1091 options.set(TablesExtension.HEADER_SEPARATOR_COLUMN_MATCH, true)
1093 options.set(AnchorLinkExtension.ANCHORLINKS_SET_ID, false)
1094 options.set(AnchorLinkExtension.ANCHORLINKS_ANCHOR_CLASS, "anchor")
1095 options.set(AnchorLinkExtension.ANCHORLINKS_SET_NAME, true)
1096 options.set(AnchorLinkExtension.ANCHORLINKS_TEXT_PREFIX, "<span class=\"octicon octicon-link\"></span>")
1098 Parser parser = Parser.builder(options).build()
1099 HtmlRenderer renderer = HtmlRenderer.builder(options).build()
1101 mdFiles.each { mdFile ->
1102 // add table of contents
1103 def mdText = "[TOC]\n"+mdFile.text
1105 // grab the first top-level title
1107 def titleRegex = /(?m)^#(\s+|([^#]))(.*)/
1108 def matcher = mdText =~ titleRegex
1109 if (matcher.size() > 0) {
1110 // matcher[0][2] is the first character of the title if there wasn't any whitespace after the #
1111 title = (matcher[0][2] != null ? matcher[0][2] : "")+matcher[0][3]
1113 // or use the filename if none found
1114 if (title == null) {
1115 title = mdFile.getName()
1118 Node document = parser.parse(mdText)
1119 String htmlBody = renderer.render(document)
1120 def htmlText = '''<html>
1121 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1122 <html xmlns="http://www.w3.org/1999/xhtml">
1124 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1125 <meta http-equiv="Content-Style-Type" content="text/css" />
1126 <meta name="generator" content="flexmark" />
1128 htmlText += ((title != null) ? " <title>${title}</title>" : '' )
1130 <style type="text/css">code{white-space: pre;}</style>
1132 htmlText += ((cssFile != null) ? cssFile.text : '')
1133 htmlText += '''</head>
1136 htmlText += htmlBody
1142 def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
1143 def htmlFile = file(htmlFilePath)
1144 println("Creating ${htmlFilePath}")
1145 htmlFile.text = htmlText
1150 task copyDocs(type: Copy) {
1151 def inputDir = "${jalviewDir}/${doc_dir}"
1152 def outputDir = "${docBuildDir}/${doc_dir}"
1156 include('**/*.html')
1158 filter(ReplaceTokens,
1162 'Version-Rel': JALVIEW_VERSION,
1163 'Year-Rel': getDate("yyyy")
1170 exclude('**/*.html')
1175 inputs.dir(inputDir)
1176 outputs.dir(outputDir)
1180 task convertMdFiles {
1182 def mdFiles = fileTree(dir: docBuildDir, include: "**/*.md")
1183 def cssFile = file("${jalviewDir}/${flexmark_css}")
1186 convertMdToHtml(mdFiles, cssFile)
1189 inputs.files(mdFiles)
1190 inputs.file(cssFile)
1193 mdFiles.each { mdFile ->
1194 def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
1195 htmlFiles.add(file(htmlFilePath))
1197 outputs.files(htmlFiles)
1201 task copyHelp(type: Copy) {
1202 def inputDir = helpSourceDir
1203 def outputDir = "${helpBuildDir}/${help_dir}"
1207 include('**/*.html')
1211 filter(ReplaceTokens,
1215 'Version-Rel': JALVIEW_VERSION,
1216 'Year-Rel': getDate("yyyy")
1223 exclude('**/*.html')
1230 inputs.dir(inputDir)
1231 outputs.files(helpFile)
1232 outputs.dir(outputDir)
1236 task copyResources(type: Copy) {
1238 description = "Copy (and make text substitutions in) the resources dir to the build area"
1240 def inputDir = resourceDir
1241 def outputDir = resourcesBuildDir
1245 include('**/*.html')
1247 filter(ReplaceTokens,
1251 'Version-Rel': JALVIEW_VERSION,
1252 'Year-Rel': getDate("yyyy")
1259 exclude('**/*.html')
1264 inputs.dir(inputDir)
1265 outputs.dir(outputDir)
1268 task copyChannelResources(type: Copy) {
1269 dependsOn copyResources
1271 description = "Copy the channel resources dir to the build resources area"
1273 def inputDir = "${channelDir}/${resource_dir}"
1274 def outputDir = resourcesBuildDir
1278 inputs.dir(inputDir)
1279 outputs.dir(outputDir)
1282 task createBuildProperties(type: WriteProperties) {
1283 dependsOn copyResources
1285 description = "Create the ${buildProperties} file"
1287 inputs.dir(sourceDir)
1288 inputs.dir(resourcesBuildDir)
1289 outputFile (buildProperties)
1290 // taking time specific comment out to allow better incremental builds
1291 comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
1292 //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
1293 property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
1294 property "VERSION", JALVIEW_VERSION
1295 property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
1296 if (getdownSetAppBaseProperty) {
1297 property "GETDOWNAPPBASE", getdownAppBase
1298 property "GETDOWNAPPDISTDIR", getdownAppDistDir
1300 outputs.file(outputFile)
1304 task buildIndices(type: JavaExec) {
1306 classpath = sourceSets.main.compileClasspath
1307 main = "com.sun.java.help.search.Indexer"
1308 workingDir = "${helpBuildDir}/${help_dir}"
1311 inputs.dir("${workingDir}/${argDir}")
1313 outputs.dir("${classesDir}/doc")
1314 outputs.dir("${classesDir}/help")
1315 outputs.file("${workingDir}/JavaHelpSearch/DOCS")
1316 outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
1317 outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
1318 outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
1319 outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
1320 outputs.file("${workingDir}/JavaHelpSearch/TMAP")
1323 task buildResources {
1324 dependsOn copyResources
1325 dependsOn copyChannelResources
1326 dependsOn createBuildProperties
1330 dependsOn buildResources
1333 dependsOn convertMdFiles
1334 dependsOn buildIndices
1338 compileJava.dependsOn prepare
1339 run.dependsOn compileJava
1340 //run.dependsOn prepare
1343 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
1348 dependsOn cloverClasses
1350 dependsOn compileJava //?
1354 includeGroups testng_groups
1355 excludeGroups testng_excluded_groups
1357 useDefaultListeners=true
1360 maxHeapSize = "1024m"
1362 workingDir = jalviewDir
1363 def testLaf = project.findProperty("test_laf")
1364 if (testLaf != null) {
1365 println("Setting Test LaF to '${testLaf}'")
1366 systemProperty "laf", testLaf
1368 def testHiDPIScale = project.findProperty("test_HiDPIScale")
1369 if (testHiDPIScale != null) {
1370 println("Setting Test HiDPI Scale to '${testHiDPIScale}'")
1371 systemProperty "sun.java2d.uiScale", testHiDPIScale
1373 sourceCompatibility = compile_source_compatibility
1374 targetCompatibility = compile_target_compatibility
1375 jvmArgs += additional_compiler_args
1379 println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
1385 task compileLinkCheck(type: JavaCompile) {
1387 classpath = files("${jalviewDir}/${utils_dir}")
1388 destinationDir = file("${jalviewDir}/${utils_dir}")
1389 source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
1391 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1392 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1393 outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
1394 outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
1398 task linkCheck(type: JavaExec) {
1400 dependsOn compileLinkCheck
1402 def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
1403 classpath = files("${jalviewDir}/${utils_dir}")
1404 main = "HelpLinksChecker"
1405 workingDir = jalviewDir
1406 args = [ "${helpBuildDir}/${help_dir}", "-nointernet" ]
1408 def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
1409 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1412 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1416 inputs.dir(helpBuildDir)
1417 outputs.file(helpLinksCheckerOutFile)
1421 // import the pubhtmlhelp target
1422 ant.properties.basedir = "${jalviewDir}"
1423 ant.properties.helpBuildDir = "${helpBuildDir}/${help_dir}"
1424 ant.importBuild "${utils_dir}/publishHelp.xml"
1427 task cleanPackageDir(type: Delete) {
1429 delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
1439 attributes "Main-Class": main_class,
1440 "Permissions": "all-permissions",
1441 "Application-Name": applicationName,
1442 "Codebase": application_codebase,
1443 "Implementation-Version": JALVIEW_VERSION
1446 def outputDir = "${jalviewDir}/${package_dir}"
1447 destinationDirectory = file(outputDir)
1448 archiveFileName = rootProject.name+".jar"
1449 duplicatesStrategy "EXCLUDE"
1456 exclude "**/*.jar.*"
1458 inputs.dir(sourceSets.main.java.outputDir)
1459 sourceSets.main.resources.srcDirs.each{ dir ->
1462 outputs.file("${outputDir}/${archiveFileName}")
1466 task copyJars(type: Copy) {
1467 from fileTree(dir: classesDir, include: "**/*.jar").files
1468 into "${jalviewDir}/${package_dir}"
1472 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
1473 task syncJars(type: Sync) {
1475 from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
1476 into "${jalviewDir}/${package_dir}"
1478 include jar.archiveFileName.getOrNull()
1485 description = "Put all required libraries in dist"
1486 // order of "cleanPackageDir", "copyJars", "jar" important!
1487 jar.mustRunAfter cleanPackageDir
1488 syncJars.mustRunAfter cleanPackageDir
1489 dependsOn cleanPackageDir
1492 outputs.dir("${jalviewDir}/${package_dir}")
1497 dependsOn cleanPackageDir
1504 group = "distribution"
1505 description = "Create a single jar file with all dependency libraries merged. Can be run with java -jar"
1509 from ("${jalviewDir}/${libDistDir}") {
1513 attributes "Implementation-Version": JALVIEW_VERSION,
1514 "Application-Name": applicationName
1517 duplicatesStrategy "INCLUDE"
1519 mainClassName = shadow_jar_main_class
1521 classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
1526 task getdownWebsite() {
1527 group = "distribution"
1528 description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
1533 def getdownWebsiteResourceFilenames = []
1534 def getdownResourceDir = getdownResourceDir
1535 def getdownResourceFilenames = []
1538 // clean the getdown website and files dir before creating getdown folders
1539 delete getdownAppBaseDir
1540 delete getdownFilesDir
1543 from buildProperties
1544 rename(file(buildProperties).getName(), getdown_build_properties)
1547 getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
1550 from channelPropsFile
1551 into getdownAppBaseDir
1553 getdownWebsiteResourceFilenames += file(channelPropsFile).getName()
1555 // set some getdownTxt_ properties then go through all properties looking for getdownTxt_...
1556 def props = project.properties.sort { it.key }
1557 if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
1558 props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
1560 if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) {
1561 props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion)
1563 if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
1564 props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
1566 if (getdownImagesDir != null && file(getdownImagesDir).exists()) {
1567 props.put("getdown_txt_ui.background_image", "${getdownImagesDir}/${getdown_background_image}")
1568 props.put("getdown_txt_ui.instant_background_image", "${getdownImagesDir}/${getdown_instant_background_image}")
1569 props.put("getdown_txt_ui.error_background", "${getdownImagesDir}/${getdown_error_background}")
1570 props.put("getdown_txt_ui.progress_image", "${getdownImagesDir}/${getdown_progress_image}")
1571 props.put("getdown_txt_ui.icon", "${getdownImagesDir}/${getdown_icon}")
1572 props.put("getdown_txt_ui.mac_dock_icon", "${getdownImagesDir}/${getdown_mac_dock_icon}")
1575 props.put("getdown_txt_title", jalview_name)
1576 props.put("getdown_txt_ui.name", applicationName)
1578 // start with appbase
1579 getdownTextLines += "appbase = ${getdownAppBase}"
1580 props.each{ prop, val ->
1581 if (prop.startsWith("getdown_txt_") && val != null) {
1582 if (prop.startsWith("getdown_txt_multi_")) {
1583 def key = prop.substring(18)
1584 val.split(",").each{ v ->
1585 def line = "${key} = ${v}"
1586 getdownTextLines += line
1589 // file values rationalised
1590 if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1592 if (val.indexOf('/') == 0) {
1595 } else if (val.indexOf('/') > 0) {
1596 // relative path (relative to jalviewDir)
1597 r = file( "${jalviewDir}/${val}" )
1600 val = "${getdown_resource_dir}/" + r.getName()
1601 getdownWebsiteResourceFilenames += val
1602 getdownResourceFilenames += r.getPath()
1605 if (! prop.startsWith("getdown_txt_resource")) {
1606 def line = prop.substring(12) + " = ${val}"
1607 getdownTextLines += line
1613 getdownWebsiteResourceFilenames.each{ filename ->
1614 getdownTextLines += "resource = ${filename}"
1616 getdownResourceFilenames.each{ filename ->
1619 into getdownResourceDir
1623 def getdownWrapperScripts = [ getdown_bash_wrapper_script, getdown_powershell_wrapper_script, getdown_batch_wrapper_script ]
1624 getdownWrapperScripts.each{ script ->
1625 def s = file( "${jalviewDir}/utils/getdown/${getdown_wrapper_script_dir}/${script}" )
1629 into "${getdownAppBaseDir}/${getdown_wrapper_script_dir}"
1631 getdownTextLines += "resource = ${getdown_wrapper_script_dir}/${script}"
1636 fileTree(file(package_dir)).each{ f ->
1637 if (f.isDirectory()) {
1638 def files = fileTree(dir: f, include: ["*"]).getFiles()
1640 } else if (f.exists()) {
1644 def jalviewJar = jar.archiveFileName.getOrNull()
1645 // put jalview.jar first for CLASSPATH and .properties files reasons
1646 codeFiles.sort{a, b -> ( a.getName() == jalviewJar ? -1 : ( b.getName() == jalviewJar ? 1 : a <=> b ) ) }.each{f ->
1647 def name = f.getName()
1648 def line = "code = ${getdownAppDistDir}/${name}"
1649 getdownTextLines += line
1656 // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
1658 if (JAVA_VERSION.equals("11")) {
1659 def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
1660 j11libFiles.sort().each{f ->
1661 def name = f.getName()
1662 def line = "code = ${getdown_j11lib_dir}/${name}"
1663 getdownTextLines += line
1666 into getdownJ11libDir
1672 // 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.
1673 //getdownTextLines += "class = " + file(getdownLauncher).getName()
1674 getdownTextLines += "resource = ${getdown_launcher_new}"
1675 getdownTextLines += "class = ${main_class}"
1676 // Not setting these properties in general so that getdownappbase and getdowndistdir will default to release version in jalview.bin.Cache
1677 if (getdownSetAppBaseProperty) {
1678 getdownTextLines += "jvmarg = -Dgetdowndistdir=${getdownAppDistDir}"
1679 getdownTextLines += "jvmarg = -Dgetdownappbase=${getdownAppBase}"
1682 def getdownTxt = file("${getdownAppBaseDir}/getdown.txt")
1683 getdownTxt.write(getdownTextLines.join("\n"))
1685 getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
1686 def launchJvl = file("${getdownAppBaseDir}/${getdownLaunchJvl}")
1687 launchJvl.write("appbase=${getdownAppBase}")
1689 // files going into the getdown website dir: getdown-launcher.jar
1691 from getdownLauncher
1692 rename(file(getdownLauncher).getName(), getdown_launcher_new)
1693 into getdownAppBaseDir
1696 // files going into the getdown website dir: getdown-launcher(-local).jar
1698 from getdownLauncher
1699 if (file(getdownLauncher).getName() != getdown_launcher) {
1700 rename(file(getdownLauncher).getName(), getdown_launcher)
1702 into getdownAppBaseDir
1705 // files going into the getdown website dir: ./install dir and files
1706 if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
1709 from getdownLauncher
1710 from "${getdownAppDir}/${getdown_build_properties}"
1711 if (file(getdownLauncher).getName() != getdown_launcher) {
1712 rename(file(getdownLauncher).getName(), getdown_launcher)
1714 into getdownInstallDir
1717 // and make a copy in the getdown files dir (these are not downloaded by getdown)
1719 from getdownInstallDir
1720 into getdownFilesInstallDir
1724 // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties
1728 from getdownLauncher
1729 from "${getdownAppBaseDir}/${getdown_build_properties}"
1730 from "${getdownAppBaseDir}/${channel_props}"
1731 if (file(getdownLauncher).getName() != getdown_launcher) {
1732 rename(file(getdownLauncher).getName(), getdown_launcher)
1734 into getdownFilesDir
1737 // and ./resource (not all downloaded by getdown)
1739 from getdownResourceDir
1740 into "${getdownFilesDir}/${getdown_resource_dir}"
1745 inputs.dir("${jalviewDir}/${package_dir}")
1747 outputs.dir(getdownAppBaseDir)
1748 outputs.dir(getdownFilesDir)
1752 // a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
1753 task getdownDigestDir(type: JavaExec) {
1755 description "A task to run a getdown Digest on a dir with getdown.txt. Provide a DIGESTDIR property via -PDIGESTDIR=..."
1757 def digestDirPropertyName = "DIGESTDIR"
1759 classpath = files(getdownLauncher)
1760 def digestDir = findProperty(digestDirPropertyName)
1761 if (digestDir == null) {
1762 throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest")
1766 main = "com.threerings.getdown.tools.Digester"
1770 task getdownDigest(type: JavaExec) {
1771 group = "distribution"
1772 description = "Digest the getdown website folder"
1773 dependsOn getdownWebsite
1775 classpath = files(getdownLauncher)
1777 main = "com.threerings.getdown.tools.Digester"
1778 args getdownAppBaseDir
1779 inputs.dir(getdownAppBaseDir)
1780 outputs.file("${getdownAppBaseDir}/digest2.txt")
1785 group = "distribution"
1786 description = "Create the minimal and full getdown app folder for installers and website and create digest file"
1787 dependsOn getdownDigest
1789 if (reportRsyncCommand) {
1790 def fromDir = getdownAppBaseDir + (getdownAppBaseDir.endsWith('/')?'':'/')
1791 def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
1792 println "LIKELY RSYNC COMMAND:"
1793 println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
1794 if (RUNRSYNC == "true") {
1796 commandLine "mkdir", "-p", toDir
1799 commandLine "rsync", "-avh", "--delete", fromDir, toDir
1807 task getdownArchiveBuild() {
1808 group = "distribution"
1809 description = "Put files in the archive dir to go on the website"
1811 dependsOn getdownWebsite
1813 def v = "v${JALVIEW_VERSION_UNDERSCORES}"
1814 def vDir = "${getdownArchiveDir}/${v}"
1815 getdownFullArchiveDir = "${vDir}/getdown"
1816 getdownVersionLaunchJvl = "${vDir}/jalview-${v}.jvl"
1818 def vAltDir = "alt_${v}"
1819 def archiveImagesDir = "${jalviewDir}/${channel_properties_dir}/old/images"
1822 // cleanup old "old" dir
1823 delete getdownArchiveDir
1825 def getdownArchiveTxt = file("${getdownFullArchiveDir}/getdown.txt")
1826 getdownArchiveTxt.getParentFile().mkdirs()
1827 def getdownArchiveTextLines = []
1828 def getdownFullArchiveAppBase = "${getdownArchiveAppBase}${getdownArchiveAppBase.endsWith("/")?"":"/"}${v}/getdown/"
1832 from "${getdownAppBaseDir}/${getdownAppDistDir}"
1833 into "${getdownFullArchiveDir}/${vAltDir}"
1836 getdownTextLines.each { line ->
1837 line = line.replaceAll("^(?<s>appbase\\s*=\\s*).*", '${s}'+getdownFullArchiveAppBase)
1838 line = line.replaceAll("^(?<s>(resource|code)\\s*=\\s*)${getdownAppDistDir}/", '${s}'+vAltDir+"/")
1839 line = line.replaceAll("^(?<s>ui.background_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background.png")
1840 line = line.replaceAll("^(?<s>ui.instant_background_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background_initialising.png")
1841 line = line.replaceAll("^(?<s>ui.error_background\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background_error.png")
1842 line = line.replaceAll("^(?<s>ui.progress_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_progress_bar.png")
1843 // remove the existing resource = resource/ or bin/ lines
1844 if (! line.matches("resource\\s*=\\s*(resource|bin)/.*")) {
1845 getdownArchiveTextLines += line
1849 // the resource dir -- add these files as resource lines in getdown.txt
1851 from "${archiveImagesDir}"
1852 into "${getdownFullArchiveDir}/${getdown_resource_dir}"
1854 getdownArchiveTextLines += "resource = ${getdown_resource_dir}/${file.getName()}"
1858 getdownArchiveTxt.write(getdownArchiveTextLines.join("\n"))
1860 def vLaunchJvl = file(getdownVersionLaunchJvl)
1861 vLaunchJvl.getParentFile().mkdirs()
1862 vLaunchJvl.write("appbase=${getdownFullArchiveAppBase}\n")
1863 def vLaunchJvlPath = vLaunchJvl.toPath().toAbsolutePath()
1864 def jvlLinkPath = file("${vDir}/jalview.jvl").toPath().toAbsolutePath()
1865 // for some reason filepath.relativize(fileInSameDirPath) gives a path to "../" which is wrong
1866 //java.nio.file.Files.createSymbolicLink(jvlLinkPath, jvlLinkPath.relativize(vLaunchJvlPath));
1867 java.nio.file.Files.createSymbolicLink(jvlLinkPath, java.nio.file.Paths.get(".",vLaunchJvl.getName()));
1869 // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties
1871 from getdownLauncher
1872 from "${getdownAppBaseDir}/${getdownLaunchJvl}"
1873 from "${getdownAppBaseDir}/${getdown_launcher_new}"
1874 from "${getdownAppBaseDir}/${channel_props}"
1875 if (file(getdownLauncher).getName() != getdown_launcher) {
1876 rename(file(getdownLauncher).getName(), getdown_launcher)
1878 into getdownFullArchiveDir
1884 task getdownArchiveDigest(type: JavaExec) {
1885 group = "distribution"
1886 description = "Digest the getdown archive folder"
1888 dependsOn getdownArchiveBuild
1891 classpath = files(getdownLauncher)
1892 args getdownFullArchiveDir
1894 main = "com.threerings.getdown.tools.Digester"
1895 inputs.dir(getdownFullArchiveDir)
1896 outputs.file("${getdownFullArchiveDir}/digest2.txt")
1899 task getdownArchive() {
1900 group = "distribution"
1901 description = "Build the website archive dir with getdown digest"
1903 dependsOn getdownArchiveBuild
1904 dependsOn getdownArchiveDigest
1907 tasks.withType(JavaCompile) {
1908 options.encoding = 'UTF-8'
1914 delete getdownAppBaseDir
1915 delete getdownFilesDir
1916 delete getdownArchiveDir
1922 if (file(install4jHomeDir).exists()) {
1924 } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
1925 install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1926 } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
1927 install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
1929 installDir(file(install4jHomeDir))
1931 mediaTypes = Arrays.asList(install4j_media_types.split(","))
1935 task copyInstall4jTemplate {
1936 def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
1937 def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
1938 inputs.file(install4jTemplateFile)
1939 inputs.file(install4jFileAssociationsFile)
1940 inputs.property("CHANNEL", { CHANNEL })
1941 outputs.file(install4jConfFile)
1944 def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
1946 // turn off code signing if no OSX_KEYPASS
1947 if (OSX_KEYPASS == "") {
1948 install4jConfigXml.'**'.codeSigning.each { codeSigning ->
1949 codeSigning.'@macEnabled' = "false"
1951 install4jConfigXml.'**'.windows.each { windows ->
1952 windows.'@runPostProcessor' = "false"
1956 // disable install screen for OSX dmg (for 2.11.2.0)
1957 install4jConfigXml.'**'.macosArchive.each { macosArchive ->
1958 macosArchive.attributes().remove('executeSetupApp')
1959 macosArchive.attributes().remove('setupAppId')
1962 // turn off checksum creation for LOCAL channel
1963 def e = install4jConfigXml.application[0]
1964 e.'@createChecksums' = string(install4jCheckSums)
1966 // put file association actions where placeholder action is
1967 def install4jFileAssociationsText = install4jFileAssociationsFile.text
1968 def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
1969 install4jConfigXml.'**'.action.any { a -> // .any{} stops after the first one that returns true
1970 if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
1971 def parent = a.parent()
1973 fileAssociationActions.each { faa ->
1976 // don't need to continue in .any loop once replacements have been made
1981 // use Windows Program Group with Examples folder for RELEASE, and Program Group without Examples for everything else
1982 // NB we're deleting the /other/ one!
1983 // Also remove the examples subdir from non-release versions
1984 def customizedIdToDelete = "PROGRAM_GROUP_RELEASE"
1985 // 2.11.1.0 NOT releasing with the Examples folder in the Program Group
1986 if (false && CHANNEL=="RELEASE") { // remove 'false && ' to include Examples folder in RELEASE channel
1987 customizedIdToDelete = "PROGRAM_GROUP_NON_RELEASE"
1989 // remove the examples subdir from Full File Set
1990 def files = install4jConfigXml.files[0]
1991 def fileset = files.filesets.fileset.find { fs -> fs.'@customizedId' == "FULL_FILE_SET" }
1992 def root = files.roots.root.find { r -> r.'@fileset' == fileset.'@id' }
1993 def mountPoint = files.mountPoints.mountPoint.find { mp -> mp.'@root' == root.'@id' }
1994 def dirEntry = files.entries.dirEntry.find { de -> de.'@mountPoint' == mountPoint.'@id' && de.'@subDirectory' == "examples" }
1995 dirEntry.parent().remove(dirEntry)
1997 install4jConfigXml.'**'.action.any { a ->
1998 if (a.'@customizedId' == customizedIdToDelete) {
1999 def parent = a.parent()
2005 // write install4j file
2006 install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
2013 delete install4jConfFile
2017 task cleanInstallersDataFiles {
2018 def installersOutputTxt = file("${jalviewDir}/${install4jBuildDir}/output.txt")
2019 def installersSha256 = file("${jalviewDir}/${install4jBuildDir}/sha256sums")
2020 def hugoDataJsonFile = file("${jalviewDir}/${install4jBuildDir}/installers-${JALVIEW_VERSION_UNDERSCORES}.json")
2022 delete installersOutputTxt
2023 delete installersSha256
2024 delete hugoDataJsonFile
2028 task installerFiles(type: com.install4j.gradle.Install4jTask) {
2029 group = "distribution"
2030 description = "Create the install4j installers"
2032 dependsOn copyInstall4jTemplate
2033 dependsOn cleanInstallersDataFiles
2035 projectFile = install4jConfFile
2037 // create an md5 for the input files to use as version for install4j conf file
2038 def digest = MessageDigest.getInstance("MD5")
2040 (file("${install4jDir}/${install4j_template}").text +
2041 file("${install4jDir}/${install4j_info_plist_file_associations}").text +
2042 file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
2043 def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
2044 if (filesMd5.length() >= 8) {
2045 filesMd5 = filesMd5.substring(0,8)
2047 def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
2050 'JALVIEW_NAME': jalview_name,
2051 'JALVIEW_APPLICATION_NAME': applicationName,
2052 'JALVIEW_DIR': "../..",
2053 'OSX_KEYSTORE': OSX_KEYSTORE,
2054 'OSX_APPLEID': OSX_APPLEID,
2055 'OSX_ALTOOLPASS': OSX_ALTOOLPASS,
2056 'JSIGN_SH': JSIGN_SH,
2057 'JRE_DIR': getdown_app_dir_java,
2058 'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
2059 'JALVIEW_VERSION': JALVIEW_VERSION,
2060 'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
2061 'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
2062 'JAVA_VERSION': JAVA_VERSION,
2063 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
2064 'VERSION': JALVIEW_VERSION,
2065 'MACOS_JAVA_VM_DIR': macosJavaVMDir,
2066 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
2067 'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
2068 'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
2069 'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
2070 'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
2071 'COPYRIGHT_MESSAGE': install4j_copyright_message,
2072 'BUNDLE_ID': install4jBundleId,
2073 'INTERNAL_ID': install4jInternalId,
2074 'WINDOWS_APPLICATION_ID': install4jWinApplicationId,
2075 'MACOS_DMG_DS_STORE': install4jDMGDSStore,
2076 'MACOS_DMG_BG_IMAGE': install4jDMGBackgroundImage,
2077 'WRAPPER_LINK': getdownWrapperLink,
2078 'BASH_WRAPPER_SCRIPT': getdown_bash_wrapper_script,
2079 'POWERSHELL_WRAPPER_SCRIPT': getdown_powershell_wrapper_script,
2080 'WRAPPER_SCRIPT_BIN_DIR': getdown_wrapper_script_dir,
2081 'INSTALLER_NAME': install4jInstallerName,
2082 'INSTALL4J_UTILS_DIR': install4j_utils_dir,
2083 'GETDOWN_CHANNEL_DIR': getdownChannelDir,
2084 'GETDOWN_FILES_DIR': getdown_files_dir,
2085 'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
2086 'GETDOWN_DIST_DIR': getdownAppDistDir,
2087 'GETDOWN_ALT_DIR': getdown_app_dir_alt,
2088 'GETDOWN_INSTALL_DIR': getdown_install_dir,
2089 'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
2090 'BUILD_DIR': install4jBuildDir,
2091 'APPLICATION_CATEGORIES': install4j_application_categories,
2092 'APPLICATION_FOLDER': install4jApplicationFolder,
2093 'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder,
2094 'EXECUTABLE_NAME': install4jExecutableName,
2095 'EXTRA_SCHEME': install4jExtraScheme,
2096 'MAC_ICONS_FILE': install4jMacIconsFile,
2097 'WINDOWS_ICONS_FILE': install4jWindowsIconsFile,
2098 'PNG_ICON_FILE': install4jPngIconFile,
2099 'BACKGROUND': install4jBackground,
2103 //println("INSTALL4J VARIABLES:")
2104 //variables.each{k,v->println("${k}=${v}")}
2106 destination = "${jalviewDir}/${install4jBuildDir}"
2107 buildSelected = true
2109 if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
2111 disableSigning = true
2112 disableNotarization = true
2116 macKeystorePassword = OSX_KEYPASS
2119 if (OSX_ALTOOLPASS) {
2120 appleIdPassword = OSX_ALTOOLPASS
2121 disableNotarization = false
2123 disableNotarization = true
2127 println("Using projectFile "+projectFile)
2128 if (!disableNotarization) { println("Will notarize OSX App DMG") }
2132 inputs.dir(getdownAppBaseDir)
2133 inputs.file(install4jConfFile)
2134 inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
2135 inputs.dir(macosJavaVMDir)
2136 inputs.dir(windowsJavaVMDir)
2137 outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
2140 def getDataHash(File myFile) {
2141 HashCode hash = Files.asByteSource(myFile).hash(Hashing.sha256())
2142 return myFile.exists()
2144 "file" : myFile.getName(),
2145 "filesize" : myFile.length(),
2146 "sha256" : hash.toString()
2151 def writeDataJsonFile(File installersOutputTxt, File installersSha256, File dataJsonFile) {
2153 "channel" : getdownChannelName,
2154 "date" : getDate("yyyy-MM-dd HH:mm:ss"),
2155 "git-commit" : "${gitHash} [${gitBranch}]",
2156 "version" : JALVIEW_VERSION
2158 // install4j installer files
2159 if (installersOutputTxt.exists()) {
2161 installersOutputTxt.readLines().each { def line ->
2162 if (line.startsWith("#")) {
2165 line.replaceAll("\n","")
2166 def vals = line.split("\t")
2167 def filename = vals[3]
2168 def filesize = file(filename).length()
2169 filename = filename.replaceAll(/^.*\//, "")
2170 hash[vals[0]] = [ "id" : vals[0], "os" : vals[1], "name" : vals[2], "file" : filename, "filesize" : filesize ]
2171 idHash."${filename}" = vals[0]
2173 if (install4jCheckSums && installersSha256.exists()) {
2174 installersSha256.readLines().each { def line ->
2175 if (line.startsWith("#")) {
2178 line.replaceAll("\n","")
2179 def vals = line.split(/\s+\*?/)
2180 def filename = vals[1]
2181 def innerHash = (hash.(idHash."${filename}"))."sha256" = vals[0]
2187 "JAR": shadowJar.archiveFile, // executable JAR
2188 "JVL": getdownVersionLaunchJvl, // version JVL
2189 "SOURCE": sourceDist.archiveFile // source TGZ
2190 ].each { key, value ->
2191 def file = file(value)
2192 if (file.exists()) {
2193 def fileHash = getDataHash(file)
2194 if (fileHash != null) {
2195 hash."${key}" = fileHash;
2199 return dataJsonFile.write(new JsonBuilder(hash).toPrettyString())
2202 task staticMakeInstallersJsonFile {
2204 def output = findProperty("i4j_output")
2205 def sha256 = findProperty("i4j_sha256")
2206 def json = findProperty("i4j_json")
2207 if (output == null || sha256 == null || json == null) {
2208 throw new GradleException("Must provide paths to all of output.txt, sha256sums, and output.json with '-Pi4j_output=... -Pi4j_sha256=... -Pi4j_json=...")
2210 writeDataJsonFile(file(output), file(sha256), file(json))
2215 dependsOn installerFiles
2221 eclipse().configFile(eclipse_codestyle_file)
2225 task createSourceReleaseProperties(type: WriteProperties) {
2226 group = "distribution"
2227 description = "Create the source RELEASE properties file"
2229 def sourceTarBuildDir = "${buildDir}/sourceTar"
2230 def sourceReleasePropertiesFile = "${sourceTarBuildDir}/RELEASE"
2231 outputFile (sourceReleasePropertiesFile)
2234 releaseProps.each{ key, val -> property key, val }
2235 property "git.branch", gitBranch
2236 property "git.hash", gitHash
2239 outputs.file(outputFile)
2242 task sourceDist(type: Tar) {
2243 group "distribution"
2244 description "Create a source .tar.gz file for distribution"
2246 dependsOn createBuildProperties
2247 dependsOn convertMdFiles
2248 dependsOn eclipseAllPreferences
2249 dependsOn createSourceReleaseProperties
2252 def outputFileName = "${project.name}_${JALVIEW_VERSION_UNDERSCORES}.tar.gz"
2253 archiveFileName = outputFileName
2255 compression Compression.GZIP
2270 "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
2272 "utils/InstallAnywhere",
2287 "gradle.properties",
2299 ".settings/org.eclipse.buildship.core.prefs",
2300 ".settings/org.eclipse.jdt.core.prefs"
2304 exclude (EXCLUDE_FILES)
2305 include (PROCESS_FILES)
2306 filter(ReplaceTokens,
2310 'Version-Rel': JALVIEW_VERSION,
2311 'Year-Rel': getDate("yyyy")
2316 exclude (EXCLUDE_FILES)
2317 exclude (PROCESS_FILES)
2318 exclude ("appletlib")
2319 exclude ("**/*locales")
2320 exclude ("*locales/**")
2321 exclude ("utils/InstallAnywhere")
2323 exclude (getdown_files_dir)
2324 // getdown_website_dir and getdown_archive_dir moved to build/website/docroot/getdown
2325 //exclude (getdown_website_dir)
2326 //exclude (getdown_archive_dir)
2328 // exluding these as not using jars as modules yet
2329 exclude ("${j11modDir}/**/*.jar")
2332 include(INCLUDE_FILES)
2334 // from (jalviewDir) {
2335 // // explicit includes for stuff that seemed to not get included
2336 // include(fileTree("test/**/*."))
2337 // exclude(EXCLUDE_FILES)
2338 // exclude(PROCESS_FILES)
2341 from(file(buildProperties).getParent()) {
2342 include(file(buildProperties).getName())
2343 rename(file(buildProperties).getName(), "build_properties")
2345 line.replaceAll("^INSTALLATION=.*\$","INSTALLATION=Source Release"+" git-commit\\\\:"+gitHash+" ["+gitBranch+"]")
2349 def sourceTarBuildDir = "${buildDir}/sourceTar"
2350 from(sourceTarBuildDir) {
2351 // this includes the appended RELEASE properties file
2355 task dataInstallersJson {
2357 description "Create the installers-VERSION.json data file for installer files created"
2359 mustRunAfter installers
2360 mustRunAfter shadowJar
2361 mustRunAfter sourceDist
2362 mustRunAfter getdownArchive
2364 def installersOutputTxt = file("${jalviewDir}/${install4jBuildDir}/output.txt")
2365 def installersSha256 = file("${jalviewDir}/${install4jBuildDir}/sha256sums")
2367 if (installersOutputTxt.exists()) {
2368 inputs.file(installersOutputTxt)
2370 if (install4jCheckSums && installersSha256.exists()) {
2371 inputs.file(installersSha256)
2374 shadowJar.archiveFile, // executable JAR
2375 getdownVersionLaunchJvl, // version JVL
2376 sourceDist.archiveFile // source TGZ
2377 ].each { fileName ->
2378 if (file(fileName).exists()) {
2379 inputs.file(fileName)
2383 outputs.file(hugoDataJsonFile)
2386 writeDataJsonFile(installersOutputTxt, installersSha256, hugoDataJsonFile)
2390 def hugoTemplateSubstitutions(String input) {
2392 output = output.replaceAll("__DATE__", getDate("yyyy-MM-dd"))
2393 output = output.replaceAll("__CHANNEL__", propertiesChannelName)
2394 output = output.replaceAll("__APPLICATION_NAME__", applicationName)
2395 output = output.replaceAll("__GIT_HASH__", gitHash)
2396 output = output.replaceAll("__GIT_BRANCH__", gitBranch)
2397 output = output.replaceAll("__VERSION__", JALVIEW_VERSION)
2398 output = output.replaceAll("__JAVA_VERSION__", JAVA_VERSION)
2399 output = output.replaceAll("__VERSION_UNDERSCORES__", JALVIEW_VERSION_UNDERSCORES)
2403 task hugoTemplates {
2405 description "Create partially populated md pages for hugo website build"
2407 def hugoTemplatesDir = file("${jalviewDir}/${hugo_templates_dir}")
2408 def hugoBuildDir = "${jalviewDir}/${hugo_build_dir}"
2409 def templateFiles = fileTree(dir: hugoTemplatesDir)
2412 // specific release template for version archive
2413 def summary = "${applicationName} ${JALVIEW_VERSION}"
2416 if (CHANNEL == "RELEASE") {
2417 def releasesHtmlFile = file("${helpSourceDir}/${releases_html}")
2419 def html = releasesHtmlFile.text
2420 def doc = Jsoup.parse(html)
2421 def table = doc.select("table").first()
2422 def headings = table.select("tr").first().select("th").collect { it.text() }
2423 def releaseRow = null
2424 def trs = table.select("tr")
2426 def tds = tr.select("td")
2427 if (tds.size() == 0)
2429 def releaseTd = tds.first()
2430 if (releaseTd.text().startsWith("${JALVIEW_VERSION} ")) {
2436 if (releaseRow != null && headings != null && headings.size() == 3) {
2437 def releaseTd = releaseRow.select("td").first()
2438 def spaceIndex = releaseTd.text().indexOf(" ")
2439 if (spaceIndex >= 0) {
2440 oldDate = new Date().parse("dd/MM/yyyy", releaseTd.text().substring(spaceIndex+1))
2442 def releaseCells = releaseRow.select("td")
2443 if (releaseCells.size() == 3) {
2444 def title1 = headings[1]
2445 def title2 = headings[2]
2447 def lastDotIndex = JALVIEW_VERSION.lastIndexOf(".")
2448 if (lastDotIndex > 0) {
2449 def patchRelease = JALVIEW_VERSION.substring(lastDotIndex+1) as Integer
2450 def patchReleaseString = null
2451 if (patchRelease == 0) {
2452 patchReleaseString = "first minor"
2453 } else if (patchRelease == 1) {
2454 patchReleaseString = "first patch"
2455 } else if (patchRelease == 2) {
2456 patchReleaseString = "second patch"
2457 } else if (patchRelease == 3) {
2458 patchReleaseString = "third patch"
2459 } else if (patchRelease == 4) {
2460 patchReleaseString = "fourth patch"
2461 } else if (patchRelease == 5) {
2462 patchReleaseString = "fifth patch"
2463 } else if (patchRelease == 6) {
2464 patchReleaseString = "sixth patch"
2465 } else if (patchRelease == 7) {
2466 patchReleaseString = "seventh patch"
2467 } else if (patchRelease > 13 && (patchRelease % 10 == 1)) {
2468 patchReleaseString += "st"
2469 } else if (patchRelease > 13 && (patchRelease % 10 == 2)) {
2470 patchReleaseString += "nd"
2471 } else if (patchRelease > 13 && (patchRelease % 10 == 3)) {
2472 patchReleaseString += "rd"
2473 } else if (patchRelease != null) {
2474 patchReleaseString += "th"
2476 summary += (patchReleaseString != null) ? " is the ${patchReleaseString} release in the ${JALVIEW_VERSION.substring(0,lastDotIndex)} series." : ""
2479 if (headings[1] != null && headings[1].size() > 0) {
2480 def noheadings = true
2481 releaseCells[1].children().each { e ->
2482 if (e.tagName().toLowerCase() == "ul") {
2483 e.select("li").each { li ->
2485 li.childNodes().any {n ->
2486 if (n.nodeName().equals("#comment")) {
2493 changes += "\n### ${headings[1]}\n\n"
2496 changes += "${mdItem}\n"
2498 } else if (e.tag() == "em") {
2499 changes += "\n#### ${e.text()}\n\n"
2505 if (headings[2] != null && headings[2].size() > 0) {
2506 changes += "\n### ${headings[2]}\n\n"
2507 releaseCells[2].children().each { e ->
2508 if (e.tagName().toLowerCase() == "ul") {
2509 e.select("li").each { li ->
2511 li.childNodes().any {n ->
2512 if (n.nodeName().equals("#comment")) {
2518 changes += "${mdItem}\n"
2520 } else if (e.tagName().toLowerCase() == "em") {
2521 changes += "\n#### ${e.text()}\n\n"
2529 templateFiles.each{ templateFile ->
2530 def newFileName = string(hugoTemplateSubstitutions(templateFile.getName()))
2531 def relPath = hugoTemplatesDir.toPath().relativize(templateFile.toPath()).getParent()
2532 def newRelPathName = hugoTemplateSubstitutions( relPath.toString() )
2534 def outPathName = string("${hugoBuildDir}/$newRelPathName")
2538 rename(templateFile.getName(), newFileName)
2542 def newFile = file("${outPathName}/${newFileName}".toString())
2543 def content = newFile.text
2544 content = content.replaceAll("__SUMMARY__", summary)
2545 content = content.replaceAll("__CHANGES__", changes)
2546 if (oldDate != null) {
2547 content = content.replaceAll("__DATE__", oldDate.format("yyyy-MM-dd"))
2549 newFile.text = hugoTemplateSubstitutions(content)
2553 inputs.dir(hugoTemplatesDir)
2554 inputs.property("JALVIEW_VERSION", { JALVIEW_VERSION })
2555 inputs.property("CHANNEL", { CHANNEL })
2561 dependsOn pubhtmlhelp
2563 inputs.dir("${helpBuildDir}/${help_dir}")
2564 outputs.dir("${buildDir}/distributions/${help_dir}")
2568 task j2sSetHeadlessBuild {
2575 task jalviewjsEnableAltFileProperty(type: WriteProperties) {
2577 description "Enable the alternative J2S Config file for headless build"
2579 outputFile = jalviewjsJ2sSettingsFileName
2580 def j2sPropsFile = file(jalviewjsJ2sSettingsFileName)
2581 def j2sProps = new Properties()
2582 if (j2sPropsFile.exists()) {
2584 def j2sPropsFileFIS = new FileInputStream(j2sPropsFile)
2585 j2sProps.load(j2sPropsFileFIS)
2586 j2sPropsFileFIS.close()
2588 j2sProps.each { prop, val ->
2591 } catch (Exception e) {
2592 println("Exception reading ${jalviewjsJ2sSettingsFileName}")
2596 if (! j2sProps.stringPropertyNames().contains(jalviewjs_j2s_alt_file_property_config)) {
2597 property(jalviewjs_j2s_alt_file_property_config, jalviewjs_j2s_alt_file_property)
2602 task jalviewjsSetEclipseWorkspace {
2603 def propKey = "jalviewjs_eclipse_workspace"
2605 if (project.hasProperty(propKey)) {
2606 propVal = project.getProperty(propKey)
2607 if (propVal.startsWith("~/")) {
2608 propVal = System.getProperty("user.home") + propVal.substring(1)
2611 def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
2612 def propsFile = file(propsFileName)
2613 def eclipseWsDir = propVal
2614 def props = new Properties()
2616 def writeProps = true
2617 if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
2618 def ins = new FileInputStream(propsFileName)
2621 if (props.getProperty(propKey, null) != null) {
2622 eclipseWsDir = props.getProperty(propKey)
2627 if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
2628 def tempDir = File.createTempDir()
2629 eclipseWsDir = tempDir.getAbsolutePath()
2632 eclipseWorkspace = file(eclipseWsDir)
2635 // do not run a headless transpile when we claim to be in Eclipse
2637 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2638 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2640 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2644 props.setProperty(propKey, eclipseWsDir)
2645 propsFile.parentFile.mkdirs()
2646 def bytes = new ByteArrayOutputStream()
2647 props.store(bytes, null)
2648 def propertiesString = bytes.toString()
2649 propsFile.text = propertiesString
2655 println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
2658 //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
2659 outputs.file(propsFileName)
2660 outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
2664 task jalviewjsEclipsePaths {
2667 def eclipseRoot = jalviewjs_eclipse_root
2668 if (eclipseRoot.startsWith("~/")) {
2669 eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
2671 if (OperatingSystem.current().isMacOsX()) {
2672 eclipseRoot += "/Eclipse.app"
2673 eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
2674 eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
2675 } else if (OperatingSystem.current().isWindows()) { // check these paths!!
2676 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2677 eclipseRoot += "/eclipse"
2679 eclipseBinary = "${eclipseRoot}/eclipse.exe"
2680 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2681 } else { // linux or unix
2682 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2683 eclipseRoot += "/eclipse"
2684 println("eclipseDir exists")
2686 eclipseBinary = "${eclipseRoot}/eclipse"
2687 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2690 eclipseVersion = "4.13" // default
2691 def assumedVersion = true
2692 if (file(eclipseProduct).exists()) {
2693 def fis = new FileInputStream(eclipseProduct)
2694 def props = new Properties()
2696 eclipseVersion = props.getProperty("version")
2698 assumedVersion = false
2701 def propKey = "eclipse_debug"
2702 eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
2705 // do not run a headless transpile when we claim to be in Eclipse
2707 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2708 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2710 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2713 if (!assumedVersion) {
2714 println("ECLIPSE VERSION=${eclipseVersion}")
2720 task printProperties {
2722 description "Output to console all System.properties"
2724 System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
2730 dependsOn eclipseProject
2731 dependsOn eclipseClasspath
2732 dependsOn eclipseJdt
2736 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
2737 task jalviewjsEclipseCopyDropins(type: Copy) {
2738 dependsOn jalviewjsEclipsePaths
2740 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
2741 inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
2742 def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
2749 // this eclipse -clean doesn't actually work
2750 task jalviewjsCleanEclipse(type: Exec) {
2751 dependsOn eclipseSetup
2752 dependsOn jalviewjsEclipsePaths
2753 dependsOn jalviewjsEclipseCopyDropins
2755 executable(eclipseBinary)
2756 args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
2762 def inputString = """exit
2765 def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
2766 standardInput = inputByteStream
2769 /* not really working yet
2770 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
2774 task jalviewjsTransferUnzipSwingJs {
2775 def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
2779 from zipTree(file_zip)
2780 into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2784 inputs.file file_zip
2785 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2789 task jalviewjsTransferUnzipLib {
2790 def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
2793 zipFiles.each { file_zip ->
2795 from zipTree(file_zip)
2796 into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2801 inputs.files zipFiles
2802 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2806 task jalviewjsTransferUnzipAllLibs {
2807 dependsOn jalviewjsTransferUnzipSwingJs
2808 dependsOn jalviewjsTransferUnzipLib
2812 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
2814 description "Create the alternative j2s file from the j2s.* properties"
2816 jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
2817 def siteDirProperty = "j2s.site.directory"
2818 def setSiteDir = false
2819 jalviewjsJ2sProps.each { prop, val ->
2821 if (prop == siteDirProperty) {
2822 if (!(val.startsWith('/') || val.startsWith("file://") )) {
2823 val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
2829 if (!setSiteDir) { // default site location, don't override specifically set property
2830 property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
2833 outputFile = jalviewjsJ2sAltSettingsFileName
2836 inputs.properties(jalviewjsJ2sProps)
2837 outputs.file(jalviewjsJ2sAltSettingsFileName)
2842 task jalviewjsEclipseSetup {
2843 dependsOn jalviewjsEclipseCopyDropins
2844 dependsOn jalviewjsSetEclipseWorkspace
2845 dependsOn jalviewjsCreateJ2sSettings
2849 task jalviewjsSyncAllLibs (type: Sync) {
2850 dependsOn jalviewjsTransferUnzipAllLibs
2851 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
2852 inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
2853 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2857 def outputFiles = []
2858 rename { filename ->
2859 outputFiles += "${outputDir}/${filename}"
2866 // should this be exclude really ?
2867 duplicatesStrategy "INCLUDE"
2869 outputs.files outputFiles
2870 inputs.files inputFiles
2874 task jalviewjsSyncResources (type: Sync) {
2875 dependsOn buildResources
2877 def inputFiles = fileTree(dir: resourcesBuildDir)
2878 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2882 def outputFiles = []
2883 rename { filename ->
2884 outputFiles += "${outputDir}/${filename}"
2890 outputs.files outputFiles
2891 inputs.files inputFiles
2895 task jalviewjsSyncSiteResources (type: Sync) {
2896 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
2897 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2901 def outputFiles = []
2902 rename { filename ->
2903 outputFiles += "${outputDir}/${filename}"
2909 outputs.files outputFiles
2910 inputs.files inputFiles
2914 task jalviewjsSyncBuildProperties (type: Sync) {
2915 dependsOn createBuildProperties
2916 def inputFiles = [file(buildProperties)]
2917 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2921 def outputFiles = []
2922 rename { filename ->
2923 outputFiles += "${outputDir}/${filename}"
2929 outputs.files outputFiles
2930 inputs.files inputFiles
2934 task jalviewjsProjectImport(type: Exec) {
2935 dependsOn eclipseSetup
2936 dependsOn jalviewjsEclipsePaths
2937 dependsOn jalviewjsEclipseSetup
2940 // do not run a headless import when we claim to be in Eclipse
2942 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2943 throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2945 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2949 //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
2950 def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
2951 executable(eclipseBinary)
2952 args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
2956 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2958 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2959 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
2962 inputs.file("${jalviewDir}/.project")
2963 outputs.upToDateWhen {
2964 file(projdir).exists()
2969 task jalviewjsTranspile(type: Exec) {
2970 dependsOn jalviewjsEclipseSetup
2971 dependsOn jalviewjsProjectImport
2972 dependsOn jalviewjsEclipsePaths
2974 dependsOn jalviewjsEnableAltFileProperty
2978 // do not run a headless transpile when we claim to be in Eclipse
2980 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2981 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2983 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2987 executable(eclipseBinary)
2988 args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
2992 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2994 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2995 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
3001 stdout = new ByteArrayOutputStream()
3002 stderr = new ByteArrayOutputStream()
3004 def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
3005 def logOutFile = file(logOutFileName)
3006 logOutFile.createNewFile()
3007 logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
3008 BINARY: ${eclipseBinary}
3009 VERSION: ${eclipseVersion}
3010 WORKSPACE: ${eclipseWorkspace}
3011 DEBUG: ${eclipseDebug}
3014 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
3015 // combine stdout and stderr
3016 def logErrFOS = logOutFOS
3018 if (jalviewjs_j2s_to_console.equals("true")) {
3019 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
3020 new org.apache.tools.ant.util.TeeOutputStream(
3024 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
3025 new org.apache.tools.ant.util.TeeOutputStream(
3030 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
3033 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
3040 if (stdout.toString().contains("Error processing ")) {
3041 // j2s did not complete transpile
3042 //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
3043 if (jalviewjs_ignore_transpile_errors.equals("true")) {
3044 println("IGNORING TRANSPILE ERRORS")
3045 println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
3047 throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
3052 inputs.dir("${jalviewDir}/${sourceDir}")
3053 outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
3054 outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
3058 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
3060 def stdout = new ByteArrayOutputStream()
3061 def stderr = new ByteArrayOutputStream()
3063 def coreFile = file(jsfile)
3065 msg = "Creating core for ${name}...\nGenerating ${jsfile}"
3067 logOutFile.createNewFile()
3068 logOutFile.append(msg+"\n")
3070 def coreTop = file(prefixFile)
3071 def coreBottom = file(suffixFile)
3072 coreFile.getParentFile().mkdirs()
3073 coreFile.createNewFile()
3074 coreFile.write( coreTop.getText("UTF-8") )
3078 def t = f.getText("UTF-8")
3079 t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
3080 coreFile.append( t )
3082 msg = "...file '"+f.getPath()+"' does not exist, skipping"
3084 logOutFile.append(msg+"\n")
3087 coreFile.append( coreBottom.getText("UTF-8") )
3089 msg = "Generating ${zjsfile}"
3091 logOutFile.append(msg+"\n")
3092 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
3093 def logErrFOS = logOutFOS
3096 classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
3097 main = "com.google.javascript.jscomp.CommandLineRunner"
3098 jvmArgs = [ "-Dfile.encoding=UTF-8" ]
3099 args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
3102 msg = "\nRunning '"+commandLine.join(' ')+"'\n"
3104 logOutFile.append(msg+"\n")
3106 if (logOutConsole) {
3107 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
3108 new org.apache.tools.ant.util.TeeOutputStream(
3112 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
3113 new org.apache.tools.ant.util.TeeOutputStream(
3118 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
3121 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
3128 logOutFile.append(msg+"\n")
3132 task jalviewjsBuildAllCores {
3134 description "Build the core js lib closures listed in the classlists dir"
3135 dependsOn jalviewjsTranspile
3136 dependsOn jalviewjsTransferUnzipSwingJs
3138 def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
3139 def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
3140 def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
3141 def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
3142 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
3143 def prefixFile = "${jsDir}/core/coretop2.js"
3144 def suffixFile = "${jsDir}/core/corebottom2.js"
3146 inputs.file prefixFile
3147 inputs.file suffixFile
3149 def classlistFiles = []
3150 // add the classlists found int the jalviewjs_classlists_dir
3151 fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
3153 def name = file.getName() - ".txt"
3160 // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
3161 //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
3162 classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
3164 jalviewjsCoreClasslists = []
3166 classlistFiles.each {
3169 def file = hash['file']
3170 if (! file.exists()) {
3171 //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
3172 return false // this is a "continue" in groovy .each closure
3174 def name = hash['name']
3176 name = file.getName() - ".txt"
3184 def list = fileTree(dir: j2sDir, includes: filelist)
3186 def jsfile = "${outputDir}/core${name}.js"
3187 def zjsfile = "${outputDir}/core${name}.z.js"
3189 jalviewjsCoreClasslists += [
3198 outputs.file(jsfile)
3199 outputs.file(zjsfile)
3202 // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
3203 def stevesoftClasslistName = "_stevesoft"
3204 def stevesoftClasslist = [
3205 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
3206 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
3207 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
3208 'name': stevesoftClasslistName
3210 jalviewjsCoreClasslists += stevesoftClasslist
3211 inputs.files(stevesoftClasslist['list'])
3212 outputs.file(stevesoftClasslist['jsfile'])
3213 outputs.file(stevesoftClasslist['zjsfile'])
3216 def allClasslistName = "_all"
3217 def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
3218 allJsFiles += fileTree(
3222 // these exlusions are files that the closure-compiler produces errors for. Should fix them
3223 "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
3224 "**/org/jmol/export/JSExporter.js"
3227 allJsFiles += fileTree(
3231 // these exlusions are files that the closure-compiler produces errors for. Should fix them
3232 "**/sun/misc/Unsafe.js",
3233 "**/swingjs/jquery/jquery-editable-select.js",
3234 "**/swingjs/jquery/j2sComboBox.js",
3235 "**/sun/misc/FloatingDecimal.js"
3238 def allClasslist = [
3239 'jsfile': "${outputDir}/core${allClasslistName}.js",
3240 'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
3242 'name': allClasslistName
3244 // not including this version of "all" core at the moment
3245 //jalviewjsCoreClasslists += allClasslist
3246 inputs.files(allClasslist['list'])
3247 outputs.file(allClasslist['jsfile'])
3248 outputs.file(allClasslist['zjsfile'])
3251 def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
3252 logOutFile.getParentFile().mkdirs()
3253 logOutFile.createNewFile()
3254 logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
3256 jalviewjsCoreClasslists.each {
3257 jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
3264 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
3267 into file(outputFile).getParentFile()
3268 rename { filename ->
3269 if (filename.equals(inputFile.getName())) {
3270 return file(outputFile).getName()
3274 filter(ReplaceTokens,
3278 'MAIN': '"'+main_class+'"',
3280 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
3281 'COREKEY': jalviewjs_core_key,
3282 'CORENAME': coreName
3289 task jalviewjsPublishCoreTemplates {
3290 dependsOn jalviewjsBuildAllCores
3291 def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
3292 def inputFile = file(inputFileName)
3293 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
3295 def outputFiles = []
3296 jalviewjsCoreClasslists.each { cl ->
3297 def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
3298 cl['outputfile'] = outputFile
3299 outputFiles += outputFile
3303 jalviewjsCoreClasslists.each { cl ->
3304 jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
3307 inputs.file(inputFile)
3308 outputs.files(outputFiles)
3312 task jalviewjsSyncCore (type: Sync) {
3313 dependsOn jalviewjsBuildAllCores
3314 dependsOn jalviewjsPublishCoreTemplates
3315 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
3316 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
3320 def outputFiles = []
3321 rename { filename ->
3322 outputFiles += "${outputDir}/${filename}"
3328 outputs.files outputFiles
3329 inputs.files inputFiles
3333 // this Copy version of TransferSiteJs will delete anything else in the target dir
3334 task jalviewjsCopyTransferSiteJs(type: Copy) {
3335 dependsOn jalviewjsTranspile
3336 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
3337 into "${jalviewDir}/${jalviewjsSiteDir}"
3341 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
3342 task jalviewjsSyncTransferSiteJs(type: Sync) {
3343 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
3345 into "${jalviewDir}/${jalviewjsSiteDir}"
3352 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
3353 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
3354 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
3355 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
3357 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
3358 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
3359 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
3360 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
3363 task jalviewjsPrepareSite {
3365 description "Prepares the website folder including unzipping files and copying resources"
3366 dependsOn jalviewjsSyncAllLibs
3367 dependsOn jalviewjsSyncResources
3368 dependsOn jalviewjsSyncSiteResources
3369 dependsOn jalviewjsSyncBuildProperties
3370 dependsOn jalviewjsSyncCore
3374 task jalviewjsBuildSite {
3376 description "Builds the whole website including transpiled code"
3377 dependsOn jalviewjsCopyTransferSiteJs
3378 dependsOn jalviewjsPrepareSite
3382 task cleanJalviewjsTransferSite {
3384 delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
3385 delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
3386 delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
3387 delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
3392 task cleanJalviewjsSite {
3393 dependsOn cleanJalviewjsTransferSite
3395 delete "${jalviewDir}/${jalviewjsSiteDir}"
3400 task jalviewjsSiteTar(type: Tar) {
3402 description "Creates a tar.gz file for the website"
3403 dependsOn jalviewjsBuildSite
3404 def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
3405 archiveFileName = outputFilename
3407 compression Compression.GZIP
3409 from "${jalviewDir}/${jalviewjsSiteDir}"
3410 into jalviewjs_site_dir // this is inside the tar file
3412 inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
3416 task jalviewjsServer {
3418 def filename = "jalviewjsTest.html"
3419 description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
3420 def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
3425 def f = Class.forName("org.gradle.plugins.javascript.envjs.http.simple.SimpleHttpFileServerFactory")
3426 factory = f.newInstance()
3427 } catch (ClassNotFoundException e) {
3428 throw new GradleException("Unable to create SimpleHttpFileServerFactory")
3430 def port = Integer.valueOf(jalviewjs_server_port)
3435 while(port < start+1000 && !running) {
3437 def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
3438 jalviewjsServer = factory.start(doc_root, port)
3440 url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
3441 println("SERVER STARTED with document root ${doc_root}.")
3442 println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).")
3443 println("For debug: "+url+"?j2sdebug")
3444 println("For verbose: "+url+"?j2sverbose")
3445 } catch (Exception e) {
3450 <p><a href="${url}">JalviewJS Test. <${url}></a></p>
3451 <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
3452 <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
3454 jalviewjsCoreClasslists.each { cl ->
3455 def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
3457 <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></a></p>
3459 println("For core ${cl.name}: "+urlcore)
3462 file(htmlFile).text = htmlText
3465 outputs.file(htmlFile)
3466 outputs.upToDateWhen({false})
3470 task cleanJalviewjsAll {
3472 description "Delete all configuration and build artifacts to do with JalviewJS build"
3473 dependsOn cleanJalviewjsSite
3474 dependsOn jalviewjsEclipsePaths
3477 delete "${jalviewDir}/${jalviewjsBuildDir}"
3478 delete "${jalviewDir}/${eclipse_bin_dir}"
3479 if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
3480 delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
3482 delete jalviewjsJ2sAltSettingsFileName
3485 outputs.upToDateWhen( { false } )
3489 task jalviewjsIDE_checkJ2sPlugin {
3490 group "00 JalviewJS in Eclipse"
3491 description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
3494 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3495 def j2sPluginFile = file(j2sPlugin)
3496 def eclipseHome = System.properties["eclipse.home.location"]
3497 if (eclipseHome == null || ! IN_ECLIPSE) {
3498 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
3500 def eclipseJ2sPluginDirs = [ "${eclipseHome}/dropins" ]
3501 def altPluginsDir = System.properties["org.eclipse.equinox.p2.reconciler.dropins.directory"]
3502 if (altPluginsDir != null && file(altPluginsDir).exists()) {
3503 eclipseJ2sPluginDirs += altPluginsDir
3505 def foundPlugin = false
3506 def j2sPluginFileName = j2sPluginFile.getName()
3507 def eclipseJ2sPlugin
3508 def eclipseJ2sPluginFile
3509 eclipseJ2sPluginDirs.any { dir ->
3510 eclipseJ2sPlugin = "${dir}/${j2sPluginFileName}"
3511 eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3512 if (eclipseJ2sPluginFile.exists()) {
3518 def msg = "Eclipse J2S Plugin is not installed (could not find '${j2sPluginFileName}' in\n"+eclipseJ2sPluginDirs.join("\n")+"\n)\nTry running task jalviewjsIDE_copyJ2sPlugin"
3519 System.err.println(msg)
3520 throw new StopExecutionException(msg)
3523 def digest = MessageDigest.getInstance("MD5")
3525 digest.update(j2sPluginFile.text.bytes)
3526 def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3528 digest.update(eclipseJ2sPluginFile.text.bytes)
3529 def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3531 if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
3532 def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
3533 System.err.println(msg)
3534 throw new StopExecutionException(msg)
3536 def msg = "Eclipse J2S Plugin '${eclipseJ2sPlugin}' is the same as '${j2sPlugin}' (this is good)"
3542 task jalviewjsIDE_copyJ2sPlugin {
3543 group "00 JalviewJS in Eclipse"
3544 description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
3547 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3548 def j2sPluginFile = file(j2sPlugin)
3549 def eclipseHome = System.properties["eclipse.home.location"]
3550 if (eclipseHome == null || ! IN_ECLIPSE) {
3551 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
3553 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
3554 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3555 def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
3556 System.err.println(msg)
3559 eclipseJ2sPluginFile.getParentFile().mkdirs()
3560 into eclipseJ2sPluginFile.getParent()
3566 task jalviewjsIDE_j2sFile {
3567 group "00 JalviewJS in Eclipse"
3568 description "Creates the .j2s file"
3569 dependsOn jalviewjsCreateJ2sSettings
3573 task jalviewjsIDE_SyncCore {
3574 group "00 JalviewJS in Eclipse"
3575 description "Build the core js lib closures listed in the classlists dir and publish core html from template"
3576 dependsOn jalviewjsSyncCore
3580 task jalviewjsIDE_SyncSiteAll {
3581 dependsOn jalviewjsSyncAllLibs
3582 dependsOn jalviewjsSyncResources
3583 dependsOn jalviewjsSyncSiteResources
3584 dependsOn jalviewjsSyncBuildProperties
3588 cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
3591 task jalviewjsIDE_PrepareSite {
3592 group "00 JalviewJS in Eclipse"
3593 description "Sync libs and resources to site dir, but not closure cores"
3595 dependsOn jalviewjsIDE_SyncSiteAll
3596 //dependsOn cleanJalviewjsTransferSite // not sure why this clean is here -- will slow down a re-run of this task
3600 task jalviewjsIDE_AssembleSite {
3601 group "00 JalviewJS in Eclipse"
3602 description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
3603 dependsOn jalviewjsPrepareSite
3607 task jalviewjsIDE_SiteClean {
3608 group "00 JalviewJS in Eclipse"
3609 description "Deletes the Eclipse transpiled site"
3610 dependsOn cleanJalviewjsSite
3614 task jalviewjsIDE_Server {
3615 group "00 JalviewJS in Eclipse"
3616 description "Starts a webserver on localhost to test the website"
3617 dependsOn jalviewjsServer
3621 // buildship runs this at import or gradle refresh
3622 task eclipseSynchronizationTask {
3623 //dependsOn eclipseSetup
3624 dependsOn createBuildProperties
3626 dependsOn jalviewjsIDE_j2sFile
3627 dependsOn jalviewjsIDE_checkJ2sPlugin
3628 dependsOn jalviewjsIDE_PrepareSite
3633 // buildship runs this at build time or project refresh
3634 task eclipseAutoBuildTask {
3635 //dependsOn jalviewjsIDE_checkJ2sPlugin
3636 //dependsOn jalviewjsIDE_PrepareSite
3642 description "Build the site"
3643 dependsOn jalviewjsBuildSite