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." : ""
2480 if (headings[col] != null && headings[col].size() > 0) {
2481 def noheadings = true
2482 releaseCells[col].children().each { e ->
2483 if (e.tagName().toLowerCase() == "ul") {
2484 e.select("li").each { li ->
2487 li.childNodes().any {n ->
2488 if (n.nodeName().equals("#comment")) {
2490 issues = n.getData().trim().split(/[,\s]+/)
2495 issues.each { jal ->
2496 mdItem += " {{< jal issue=\"${jal}\" >}}"
2499 changes += "\n### ${headings[1]}\n\n"
2502 changes += "${mdItem}\n"
2504 } else if (e.tag() == "em") {
2505 changes += "\n#### ${e.text()}\n\n"
2516 templateFiles.each{ templateFile ->
2517 def newFileName = string(hugoTemplateSubstitutions(templateFile.getName()))
2518 def relPath = hugoTemplatesDir.toPath().relativize(templateFile.toPath()).getParent()
2519 def newRelPathName = hugoTemplateSubstitutions( relPath.toString() )
2521 def outPathName = string("${hugoBuildDir}/$newRelPathName")
2525 rename(templateFile.getName(), newFileName)
2529 def newFile = file("${outPathName}/${newFileName}".toString())
2530 def content = newFile.text
2531 content = content.replaceAll("__SUMMARY__", summary)
2532 content = content.replaceAll("__CHANGES__", changes)
2533 if (oldDate != null) {
2534 content = content.replaceAll("__DATE__", oldDate.format("yyyy-MM-dd"))
2536 newFile.text = hugoTemplateSubstitutions(content)
2540 inputs.dir(hugoTemplatesDir)
2541 inputs.property("JALVIEW_VERSION", { JALVIEW_VERSION })
2542 inputs.property("CHANNEL", { CHANNEL })
2548 dependsOn pubhtmlhelp
2550 inputs.dir("${helpBuildDir}/${help_dir}")
2551 outputs.dir("${buildDir}/distributions/${help_dir}")
2555 task j2sSetHeadlessBuild {
2562 task jalviewjsEnableAltFileProperty(type: WriteProperties) {
2564 description "Enable the alternative J2S Config file for headless build"
2566 outputFile = jalviewjsJ2sSettingsFileName
2567 def j2sPropsFile = file(jalviewjsJ2sSettingsFileName)
2568 def j2sProps = new Properties()
2569 if (j2sPropsFile.exists()) {
2571 def j2sPropsFileFIS = new FileInputStream(j2sPropsFile)
2572 j2sProps.load(j2sPropsFileFIS)
2573 j2sPropsFileFIS.close()
2575 j2sProps.each { prop, val ->
2578 } catch (Exception e) {
2579 println("Exception reading ${jalviewjsJ2sSettingsFileName}")
2583 if (! j2sProps.stringPropertyNames().contains(jalviewjs_j2s_alt_file_property_config)) {
2584 property(jalviewjs_j2s_alt_file_property_config, jalviewjs_j2s_alt_file_property)
2589 task jalviewjsSetEclipseWorkspace {
2590 def propKey = "jalviewjs_eclipse_workspace"
2592 if (project.hasProperty(propKey)) {
2593 propVal = project.getProperty(propKey)
2594 if (propVal.startsWith("~/")) {
2595 propVal = System.getProperty("user.home") + propVal.substring(1)
2598 def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
2599 def propsFile = file(propsFileName)
2600 def eclipseWsDir = propVal
2601 def props = new Properties()
2603 def writeProps = true
2604 if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
2605 def ins = new FileInputStream(propsFileName)
2608 if (props.getProperty(propKey, null) != null) {
2609 eclipseWsDir = props.getProperty(propKey)
2614 if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
2615 def tempDir = File.createTempDir()
2616 eclipseWsDir = tempDir.getAbsolutePath()
2619 eclipseWorkspace = file(eclipseWsDir)
2622 // do not run a headless transpile when we claim to be in Eclipse
2624 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2625 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2627 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2631 props.setProperty(propKey, eclipseWsDir)
2632 propsFile.parentFile.mkdirs()
2633 def bytes = new ByteArrayOutputStream()
2634 props.store(bytes, null)
2635 def propertiesString = bytes.toString()
2636 propsFile.text = propertiesString
2642 println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
2645 //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
2646 outputs.file(propsFileName)
2647 outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
2651 task jalviewjsEclipsePaths {
2654 def eclipseRoot = jalviewjs_eclipse_root
2655 if (eclipseRoot.startsWith("~/")) {
2656 eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
2658 if (OperatingSystem.current().isMacOsX()) {
2659 eclipseRoot += "/Eclipse.app"
2660 eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
2661 eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
2662 } else if (OperatingSystem.current().isWindows()) { // check these paths!!
2663 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2664 eclipseRoot += "/eclipse"
2666 eclipseBinary = "${eclipseRoot}/eclipse.exe"
2667 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2668 } else { // linux or unix
2669 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2670 eclipseRoot += "/eclipse"
2671 println("eclipseDir exists")
2673 eclipseBinary = "${eclipseRoot}/eclipse"
2674 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2677 eclipseVersion = "4.13" // default
2678 def assumedVersion = true
2679 if (file(eclipseProduct).exists()) {
2680 def fis = new FileInputStream(eclipseProduct)
2681 def props = new Properties()
2683 eclipseVersion = props.getProperty("version")
2685 assumedVersion = false
2688 def propKey = "eclipse_debug"
2689 eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
2692 // do not run a headless transpile when we claim to be in Eclipse
2694 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2695 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2697 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2700 if (!assumedVersion) {
2701 println("ECLIPSE VERSION=${eclipseVersion}")
2707 task printProperties {
2709 description "Output to console all System.properties"
2711 System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
2717 dependsOn eclipseProject
2718 dependsOn eclipseClasspath
2719 dependsOn eclipseJdt
2723 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
2724 task jalviewjsEclipseCopyDropins(type: Copy) {
2725 dependsOn jalviewjsEclipsePaths
2727 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
2728 inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
2729 def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
2736 // this eclipse -clean doesn't actually work
2737 task jalviewjsCleanEclipse(type: Exec) {
2738 dependsOn eclipseSetup
2739 dependsOn jalviewjsEclipsePaths
2740 dependsOn jalviewjsEclipseCopyDropins
2742 executable(eclipseBinary)
2743 args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
2749 def inputString = """exit
2752 def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
2753 standardInput = inputByteStream
2756 /* not really working yet
2757 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
2761 task jalviewjsTransferUnzipSwingJs {
2762 def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
2766 from zipTree(file_zip)
2767 into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2771 inputs.file file_zip
2772 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2776 task jalviewjsTransferUnzipLib {
2777 def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
2780 zipFiles.each { file_zip ->
2782 from zipTree(file_zip)
2783 into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2788 inputs.files zipFiles
2789 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2793 task jalviewjsTransferUnzipAllLibs {
2794 dependsOn jalviewjsTransferUnzipSwingJs
2795 dependsOn jalviewjsTransferUnzipLib
2799 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
2801 description "Create the alternative j2s file from the j2s.* properties"
2803 jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
2804 def siteDirProperty = "j2s.site.directory"
2805 def setSiteDir = false
2806 jalviewjsJ2sProps.each { prop, val ->
2808 if (prop == siteDirProperty) {
2809 if (!(val.startsWith('/') || val.startsWith("file://") )) {
2810 val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
2816 if (!setSiteDir) { // default site location, don't override specifically set property
2817 property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
2820 outputFile = jalviewjsJ2sAltSettingsFileName
2823 inputs.properties(jalviewjsJ2sProps)
2824 outputs.file(jalviewjsJ2sAltSettingsFileName)
2829 task jalviewjsEclipseSetup {
2830 dependsOn jalviewjsEclipseCopyDropins
2831 dependsOn jalviewjsSetEclipseWorkspace
2832 dependsOn jalviewjsCreateJ2sSettings
2836 task jalviewjsSyncAllLibs (type: Sync) {
2837 dependsOn jalviewjsTransferUnzipAllLibs
2838 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
2839 inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
2840 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2844 def outputFiles = []
2845 rename { filename ->
2846 outputFiles += "${outputDir}/${filename}"
2853 // should this be exclude really ?
2854 duplicatesStrategy "INCLUDE"
2856 outputs.files outputFiles
2857 inputs.files inputFiles
2861 task jalviewjsSyncResources (type: Sync) {
2862 dependsOn buildResources
2864 def inputFiles = fileTree(dir: resourcesBuildDir)
2865 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2869 def outputFiles = []
2870 rename { filename ->
2871 outputFiles += "${outputDir}/${filename}"
2877 outputs.files outputFiles
2878 inputs.files inputFiles
2882 task jalviewjsSyncSiteResources (type: Sync) {
2883 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
2884 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2888 def outputFiles = []
2889 rename { filename ->
2890 outputFiles += "${outputDir}/${filename}"
2896 outputs.files outputFiles
2897 inputs.files inputFiles
2901 task jalviewjsSyncBuildProperties (type: Sync) {
2902 dependsOn createBuildProperties
2903 def inputFiles = [file(buildProperties)]
2904 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2908 def outputFiles = []
2909 rename { filename ->
2910 outputFiles += "${outputDir}/${filename}"
2916 outputs.files outputFiles
2917 inputs.files inputFiles
2921 task jalviewjsProjectImport(type: Exec) {
2922 dependsOn eclipseSetup
2923 dependsOn jalviewjsEclipsePaths
2924 dependsOn jalviewjsEclipseSetup
2927 // do not run a headless import when we claim to be in Eclipse
2929 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2930 throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2932 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2936 //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
2937 def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
2938 executable(eclipseBinary)
2939 args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
2943 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2945 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2946 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
2949 inputs.file("${jalviewDir}/.project")
2950 outputs.upToDateWhen {
2951 file(projdir).exists()
2956 task jalviewjsTranspile(type: Exec) {
2957 dependsOn jalviewjsEclipseSetup
2958 dependsOn jalviewjsProjectImport
2959 dependsOn jalviewjsEclipsePaths
2961 dependsOn jalviewjsEnableAltFileProperty
2965 // do not run a headless transpile when we claim to be in Eclipse
2967 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2968 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2970 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2974 executable(eclipseBinary)
2975 args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
2979 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2981 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2982 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
2988 stdout = new ByteArrayOutputStream()
2989 stderr = new ByteArrayOutputStream()
2991 def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
2992 def logOutFile = file(logOutFileName)
2993 logOutFile.createNewFile()
2994 logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
2995 BINARY: ${eclipseBinary}
2996 VERSION: ${eclipseVersion}
2997 WORKSPACE: ${eclipseWorkspace}
2998 DEBUG: ${eclipseDebug}
3001 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
3002 // combine stdout and stderr
3003 def logErrFOS = logOutFOS
3005 if (jalviewjs_j2s_to_console.equals("true")) {
3006 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
3007 new org.apache.tools.ant.util.TeeOutputStream(
3011 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
3012 new org.apache.tools.ant.util.TeeOutputStream(
3017 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
3020 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
3027 if (stdout.toString().contains("Error processing ")) {
3028 // j2s did not complete transpile
3029 //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
3030 if (jalviewjs_ignore_transpile_errors.equals("true")) {
3031 println("IGNORING TRANSPILE ERRORS")
3032 println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
3034 throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
3039 inputs.dir("${jalviewDir}/${sourceDir}")
3040 outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
3041 outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
3045 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
3047 def stdout = new ByteArrayOutputStream()
3048 def stderr = new ByteArrayOutputStream()
3050 def coreFile = file(jsfile)
3052 msg = "Creating core for ${name}...\nGenerating ${jsfile}"
3054 logOutFile.createNewFile()
3055 logOutFile.append(msg+"\n")
3057 def coreTop = file(prefixFile)
3058 def coreBottom = file(suffixFile)
3059 coreFile.getParentFile().mkdirs()
3060 coreFile.createNewFile()
3061 coreFile.write( coreTop.getText("UTF-8") )
3065 def t = f.getText("UTF-8")
3066 t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
3067 coreFile.append( t )
3069 msg = "...file '"+f.getPath()+"' does not exist, skipping"
3071 logOutFile.append(msg+"\n")
3074 coreFile.append( coreBottom.getText("UTF-8") )
3076 msg = "Generating ${zjsfile}"
3078 logOutFile.append(msg+"\n")
3079 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
3080 def logErrFOS = logOutFOS
3083 classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
3084 main = "com.google.javascript.jscomp.CommandLineRunner"
3085 jvmArgs = [ "-Dfile.encoding=UTF-8" ]
3086 args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
3089 msg = "\nRunning '"+commandLine.join(' ')+"'\n"
3091 logOutFile.append(msg+"\n")
3093 if (logOutConsole) {
3094 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
3095 new org.apache.tools.ant.util.TeeOutputStream(
3099 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
3100 new org.apache.tools.ant.util.TeeOutputStream(
3105 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
3108 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
3115 logOutFile.append(msg+"\n")
3119 task jalviewjsBuildAllCores {
3121 description "Build the core js lib closures listed in the classlists dir"
3122 dependsOn jalviewjsTranspile
3123 dependsOn jalviewjsTransferUnzipSwingJs
3125 def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
3126 def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
3127 def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
3128 def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
3129 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
3130 def prefixFile = "${jsDir}/core/coretop2.js"
3131 def suffixFile = "${jsDir}/core/corebottom2.js"
3133 inputs.file prefixFile
3134 inputs.file suffixFile
3136 def classlistFiles = []
3137 // add the classlists found int the jalviewjs_classlists_dir
3138 fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
3140 def name = file.getName() - ".txt"
3147 // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
3148 //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
3149 classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
3151 jalviewjsCoreClasslists = []
3153 classlistFiles.each {
3156 def file = hash['file']
3157 if (! file.exists()) {
3158 //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
3159 return false // this is a "continue" in groovy .each closure
3161 def name = hash['name']
3163 name = file.getName() - ".txt"
3171 def list = fileTree(dir: j2sDir, includes: filelist)
3173 def jsfile = "${outputDir}/core${name}.js"
3174 def zjsfile = "${outputDir}/core${name}.z.js"
3176 jalviewjsCoreClasslists += [
3185 outputs.file(jsfile)
3186 outputs.file(zjsfile)
3189 // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
3190 def stevesoftClasslistName = "_stevesoft"
3191 def stevesoftClasslist = [
3192 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
3193 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
3194 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
3195 'name': stevesoftClasslistName
3197 jalviewjsCoreClasslists += stevesoftClasslist
3198 inputs.files(stevesoftClasslist['list'])
3199 outputs.file(stevesoftClasslist['jsfile'])
3200 outputs.file(stevesoftClasslist['zjsfile'])
3203 def allClasslistName = "_all"
3204 def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
3205 allJsFiles += fileTree(
3209 // these exlusions are files that the closure-compiler produces errors for. Should fix them
3210 "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
3211 "**/org/jmol/export/JSExporter.js"
3214 allJsFiles += fileTree(
3218 // these exlusions are files that the closure-compiler produces errors for. Should fix them
3219 "**/sun/misc/Unsafe.js",
3220 "**/swingjs/jquery/jquery-editable-select.js",
3221 "**/swingjs/jquery/j2sComboBox.js",
3222 "**/sun/misc/FloatingDecimal.js"
3225 def allClasslist = [
3226 'jsfile': "${outputDir}/core${allClasslistName}.js",
3227 'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
3229 'name': allClasslistName
3231 // not including this version of "all" core at the moment
3232 //jalviewjsCoreClasslists += allClasslist
3233 inputs.files(allClasslist['list'])
3234 outputs.file(allClasslist['jsfile'])
3235 outputs.file(allClasslist['zjsfile'])
3238 def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
3239 logOutFile.getParentFile().mkdirs()
3240 logOutFile.createNewFile()
3241 logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
3243 jalviewjsCoreClasslists.each {
3244 jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
3251 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
3254 into file(outputFile).getParentFile()
3255 rename { filename ->
3256 if (filename.equals(inputFile.getName())) {
3257 return file(outputFile).getName()
3261 filter(ReplaceTokens,
3265 'MAIN': '"'+main_class+'"',
3267 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
3268 'COREKEY': jalviewjs_core_key,
3269 'CORENAME': coreName
3276 task jalviewjsPublishCoreTemplates {
3277 dependsOn jalviewjsBuildAllCores
3278 def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
3279 def inputFile = file(inputFileName)
3280 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
3282 def outputFiles = []
3283 jalviewjsCoreClasslists.each { cl ->
3284 def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
3285 cl['outputfile'] = outputFile
3286 outputFiles += outputFile
3290 jalviewjsCoreClasslists.each { cl ->
3291 jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
3294 inputs.file(inputFile)
3295 outputs.files(outputFiles)
3299 task jalviewjsSyncCore (type: Sync) {
3300 dependsOn jalviewjsBuildAllCores
3301 dependsOn jalviewjsPublishCoreTemplates
3302 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
3303 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
3307 def outputFiles = []
3308 rename { filename ->
3309 outputFiles += "${outputDir}/${filename}"
3315 outputs.files outputFiles
3316 inputs.files inputFiles
3320 // this Copy version of TransferSiteJs will delete anything else in the target dir
3321 task jalviewjsCopyTransferSiteJs(type: Copy) {
3322 dependsOn jalviewjsTranspile
3323 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
3324 into "${jalviewDir}/${jalviewjsSiteDir}"
3328 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
3329 task jalviewjsSyncTransferSiteJs(type: Sync) {
3330 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
3332 into "${jalviewDir}/${jalviewjsSiteDir}"
3339 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
3340 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
3341 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
3342 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
3344 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
3345 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
3346 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
3347 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
3350 task jalviewjsPrepareSite {
3352 description "Prepares the website folder including unzipping files and copying resources"
3353 dependsOn jalviewjsSyncAllLibs
3354 dependsOn jalviewjsSyncResources
3355 dependsOn jalviewjsSyncSiteResources
3356 dependsOn jalviewjsSyncBuildProperties
3357 dependsOn jalviewjsSyncCore
3361 task jalviewjsBuildSite {
3363 description "Builds the whole website including transpiled code"
3364 dependsOn jalviewjsCopyTransferSiteJs
3365 dependsOn jalviewjsPrepareSite
3369 task cleanJalviewjsTransferSite {
3371 delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
3372 delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
3373 delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
3374 delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
3379 task cleanJalviewjsSite {
3380 dependsOn cleanJalviewjsTransferSite
3382 delete "${jalviewDir}/${jalviewjsSiteDir}"
3387 task jalviewjsSiteTar(type: Tar) {
3389 description "Creates a tar.gz file for the website"
3390 dependsOn jalviewjsBuildSite
3391 def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
3392 archiveFileName = outputFilename
3394 compression Compression.GZIP
3396 from "${jalviewDir}/${jalviewjsSiteDir}"
3397 into jalviewjs_site_dir // this is inside the tar file
3399 inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
3403 task jalviewjsServer {
3405 def filename = "jalviewjsTest.html"
3406 description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
3407 def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
3412 def f = Class.forName("org.gradle.plugins.javascript.envjs.http.simple.SimpleHttpFileServerFactory")
3413 factory = f.newInstance()
3414 } catch (ClassNotFoundException e) {
3415 throw new GradleException("Unable to create SimpleHttpFileServerFactory")
3417 def port = Integer.valueOf(jalviewjs_server_port)
3422 while(port < start+1000 && !running) {
3424 def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
3425 jalviewjsServer = factory.start(doc_root, port)
3427 url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
3428 println("SERVER STARTED with document root ${doc_root}.")
3429 println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).")
3430 println("For debug: "+url+"?j2sdebug")
3431 println("For verbose: "+url+"?j2sverbose")
3432 } catch (Exception e) {
3437 <p><a href="${url}">JalviewJS Test. <${url}></a></p>
3438 <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
3439 <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
3441 jalviewjsCoreClasslists.each { cl ->
3442 def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
3444 <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></a></p>
3446 println("For core ${cl.name}: "+urlcore)
3449 file(htmlFile).text = htmlText
3452 outputs.file(htmlFile)
3453 outputs.upToDateWhen({false})
3457 task cleanJalviewjsAll {
3459 description "Delete all configuration and build artifacts to do with JalviewJS build"
3460 dependsOn cleanJalviewjsSite
3461 dependsOn jalviewjsEclipsePaths
3464 delete "${jalviewDir}/${jalviewjsBuildDir}"
3465 delete "${jalviewDir}/${eclipse_bin_dir}"
3466 if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
3467 delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
3469 delete jalviewjsJ2sAltSettingsFileName
3472 outputs.upToDateWhen( { false } )
3476 task jalviewjsIDE_checkJ2sPlugin {
3477 group "00 JalviewJS in Eclipse"
3478 description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
3481 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3482 def j2sPluginFile = file(j2sPlugin)
3483 def eclipseHome = System.properties["eclipse.home.location"]
3484 if (eclipseHome == null || ! IN_ECLIPSE) {
3485 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
3487 def eclipseJ2sPluginDirs = [ "${eclipseHome}/dropins" ]
3488 def altPluginsDir = System.properties["org.eclipse.equinox.p2.reconciler.dropins.directory"]
3489 if (altPluginsDir != null && file(altPluginsDir).exists()) {
3490 eclipseJ2sPluginDirs += altPluginsDir
3492 def foundPlugin = false
3493 def j2sPluginFileName = j2sPluginFile.getName()
3494 def eclipseJ2sPlugin
3495 def eclipseJ2sPluginFile
3496 eclipseJ2sPluginDirs.any { dir ->
3497 eclipseJ2sPlugin = "${dir}/${j2sPluginFileName}"
3498 eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3499 if (eclipseJ2sPluginFile.exists()) {
3505 def msg = "Eclipse J2S Plugin is not installed (could not find '${j2sPluginFileName}' in\n"+eclipseJ2sPluginDirs.join("\n")+"\n)\nTry running task jalviewjsIDE_copyJ2sPlugin"
3506 System.err.println(msg)
3507 throw new StopExecutionException(msg)
3510 def digest = MessageDigest.getInstance("MD5")
3512 digest.update(j2sPluginFile.text.bytes)
3513 def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3515 digest.update(eclipseJ2sPluginFile.text.bytes)
3516 def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3518 if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
3519 def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
3520 System.err.println(msg)
3521 throw new StopExecutionException(msg)
3523 def msg = "Eclipse J2S Plugin '${eclipseJ2sPlugin}' is the same as '${j2sPlugin}' (this is good)"
3529 task jalviewjsIDE_copyJ2sPlugin {
3530 group "00 JalviewJS in Eclipse"
3531 description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
3534 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3535 def j2sPluginFile = file(j2sPlugin)
3536 def eclipseHome = System.properties["eclipse.home.location"]
3537 if (eclipseHome == null || ! IN_ECLIPSE) {
3538 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
3540 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
3541 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3542 def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
3543 System.err.println(msg)
3546 eclipseJ2sPluginFile.getParentFile().mkdirs()
3547 into eclipseJ2sPluginFile.getParent()
3553 task jalviewjsIDE_j2sFile {
3554 group "00 JalviewJS in Eclipse"
3555 description "Creates the .j2s file"
3556 dependsOn jalviewjsCreateJ2sSettings
3560 task jalviewjsIDE_SyncCore {
3561 group "00 JalviewJS in Eclipse"
3562 description "Build the core js lib closures listed in the classlists dir and publish core html from template"
3563 dependsOn jalviewjsSyncCore
3567 task jalviewjsIDE_SyncSiteAll {
3568 dependsOn jalviewjsSyncAllLibs
3569 dependsOn jalviewjsSyncResources
3570 dependsOn jalviewjsSyncSiteResources
3571 dependsOn jalviewjsSyncBuildProperties
3575 cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
3578 task jalviewjsIDE_PrepareSite {
3579 group "00 JalviewJS in Eclipse"
3580 description "Sync libs and resources to site dir, but not closure cores"
3582 dependsOn jalviewjsIDE_SyncSiteAll
3583 //dependsOn cleanJalviewjsTransferSite // not sure why this clean is here -- will slow down a re-run of this task
3587 task jalviewjsIDE_AssembleSite {
3588 group "00 JalviewJS in Eclipse"
3589 description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
3590 dependsOn jalviewjsPrepareSite
3594 task jalviewjsIDE_SiteClean {
3595 group "00 JalviewJS in Eclipse"
3596 description "Deletes the Eclipse transpiled site"
3597 dependsOn cleanJalviewjsSite
3601 task jalviewjsIDE_Server {
3602 group "00 JalviewJS in Eclipse"
3603 description "Starts a webserver on localhost to test the website"
3604 dependsOn jalviewjsServer
3608 // buildship runs this at import or gradle refresh
3609 task eclipseSynchronizationTask {
3610 //dependsOn eclipseSetup
3611 dependsOn createBuildProperties
3613 dependsOn jalviewjsIDE_j2sFile
3614 dependsOn jalviewjsIDE_checkJ2sPlugin
3615 dependsOn jalviewjsIDE_PrepareSite
3620 // buildship runs this at build time or project refresh
3621 task eclipseAutoBuildTask {
3622 //dependsOn jalviewjsIDE_checkJ2sPlugin
3623 //dependsOn jalviewjsIDE_PrepareSite
3629 description "Build the site"
3630 dependsOn jalviewjsBuildSite