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 com.vladsch.flexmark.util.ast.Node
16 import com.vladsch.flexmark.html.HtmlRenderer
17 import com.vladsch.flexmark.parser.Parser
18 import com.vladsch.flexmark.util.data.MutableDataSet
19 import com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension
20 import com.vladsch.flexmark.ext.tables.TablesExtension
21 import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension
22 import com.vladsch.flexmark.ext.autolink.AutolinkExtension
23 import com.vladsch.flexmark.ext.anchorlink.AnchorLinkExtension
24 import com.vladsch.flexmark.ext.toc.TocExtension
32 classpath "com.vladsch.flexmark:flexmark-all:0.62.0"
41 id "com.diffplug.gradle.spotless" version "3.28.0"
42 id 'com.github.johnrengelman.shadow' version '4.0.3'
43 id 'com.install4j.gradle' version '9.0.6'
44 id 'com.dorongold.task-tree' version '1.5' // only needed to display task dependency tree with gradle task1 [task2 ...] taskTree
45 id 'com.palantir.git-version' version '0.13.0' apply false
56 // in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use
57 def string(Object o) {
58 return o == null ? "" : o.toString()
61 def overrideProperties(String propsFileName, boolean output = false) {
62 if (propsFileName == null) {
65 def propsFile = file(propsFileName)
66 if (propsFile != null && propsFile.exists()) {
67 println("Using properties from file '${propsFileName}'")
69 def p = new Properties()
70 def localPropsFIS = new FileInputStream(propsFile)
76 if (project.hasProperty(key)) {
77 oldval = project.findProperty(key)
78 project.setProperty(key, val)
80 println("Overriding property '${key}' ('${oldval}') with ${file(propsFile).getName()} value '${val}'")
83 ext.setProperty(key, val)
85 println("Setting ext property '${key}' with ${file(propsFile).getName()}s value '${val}'")
89 } catch (Exception e) {
90 println("Exception reading local.properties")
97 jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
98 jalviewDirRelativePath = jalviewDir
100 getdownChannelName = CHANNEL.toLowerCase()
101 // default to "default". Currently only has different cosmetics for "develop", "release", "default"
102 propertiesChannelName = ["develop", "release", "test-release", "jalviewjs", "jalviewjs-release" ].contains(getdownChannelName) ? getdownChannelName : "default"
103 // Import channel_properties
104 channelDir = string("${jalviewDir}/${channel_properties_dir}/${propertiesChannelName}")
105 channelGradleProperties = string("${channelDir}/channel_gradle.properties")
106 channelPropsFile = string("${channelDir}/${resource_dir}/${channel_props}")
107 overrideProperties(channelGradleProperties, false)
108 // local build environment properties
109 // can be "projectDir/local.properties"
110 overrideProperties("${projectDir}/local.properties", true)
111 // or "../projectDir_local.properties"
112 overrideProperties(projectDir.getParent() + "/" + projectDir.getName() + "_local.properties", true)
115 // Import releaseProps from the RELEASE file
116 // or a file specified via JALVIEW_RELEASE_FILE if defined
117 // Expect jalview.version and target release branch in jalview.release
118 releaseProps = new Properties();
119 def releasePropFile = findProperty("JALVIEW_RELEASE_FILE");
120 def defaultReleasePropFile = "${jalviewDirAbsolutePath}/RELEASE";
122 (new File(releasePropFile!=null ? releasePropFile : defaultReleasePropFile)).withInputStream {
123 releaseProps.load(it)
125 } catch (Exception fileLoadError) {
126 throw new Error("Couldn't load release properties file "+(releasePropFile==null ? defaultReleasePropFile : "from custom location: releasePropFile"),fileLoadError);
129 // Set JALVIEW_VERSION if it is not already set
130 if (findProperty("JALVIEW_VERSION")==null || "".equals(JALVIEW_VERSION)) {
131 JALVIEW_VERSION = releaseProps.get("jalview.version")
134 // this property set when running Eclipse headlessly
135 j2sHeadlessBuildProperty = string("net.sf.j2s.core.headlessbuild")
136 // this property set by Eclipse
137 eclipseApplicationProperty = string("eclipse.application")
138 // CHECK IF RUNNING FROM WITHIN ECLIPSE
139 def eclipseApplicationPropertyVal = System.properties[eclipseApplicationProperty]
140 IN_ECLIPSE = eclipseApplicationPropertyVal != null && eclipseApplicationPropertyVal.startsWith("org.eclipse.ui.")
141 // BUT WITHOUT THE HEADLESS BUILD PROPERTY SET
142 if (System.properties[j2sHeadlessBuildProperty].equals("true")) {
143 println("Setting IN_ECLIPSE to ${IN_ECLIPSE} as System.properties['${j2sHeadlessBuildProperty}'] == '${System.properties[j2sHeadlessBuildProperty]}'")
147 println("WITHIN ECLIPSE IDE")
149 println("HEADLESS BUILD")
152 J2S_ENABLED = (project.hasProperty('j2s.compiler.status') && project['j2s.compiler.status'] != null && project['j2s.compiler.status'] == "enable")
154 println("J2S ENABLED")
157 System.properties.sort { it.key }.each {
158 key, val -> println("SYSTEM PROPERTY ${key}='${val}'")
161 if (false && IN_ECLIPSE) {
162 jalviewDir = jalviewDirAbsolutePath
167 buildDate = new Date().format("yyyyMMdd")
170 bareSourceDir = string(source_dir)
171 sourceDir = string("${jalviewDir}/${bareSourceDir}")
172 resourceDir = string("${jalviewDir}/${resource_dir}")
173 bareTestSourceDir = string(test_source_dir)
174 testDir = string("${jalviewDir}/${bareTestSourceDir}")
176 classesDir = string("${jalviewDir}/${classes_dir}")
179 useClover = clover.equals("true")
180 cloverBuildDir = "${buildDir}/clover"
181 cloverInstrDir = file("${cloverBuildDir}/clover-instr")
182 cloverClassesDir = file("${cloverBuildDir}/clover-classes")
183 cloverReportDir = file("${buildDir}/reports/clover")
184 cloverTestInstrDir = file("${cloverBuildDir}/clover-test-instr")
185 cloverTestClassesDir = file("${cloverBuildDir}/clover-test-classes")
186 //cloverTestClassesDir = cloverClassesDir
187 cloverDb = string("${cloverBuildDir}/clover.db")
189 testSourceDir = useClover ? cloverTestInstrDir : testDir
190 testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}"
192 getdownWebsiteDir = string("${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}")
193 getdownArchiveDir = string("${jalviewDir}/${getdown_archive_dir}")
194 getdownFullArchiveDir = null
195 getdownTextLines = []
196 getdownLaunchJvl = null
198 buildProperties = null
200 // the following values might be overridden by the CHANNEL switch
201 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
202 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
203 getdownArchiveAppBase = null
204 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
205 getdownAppDistDir = getdown_app_dir_alt
206 getdownImagesDir = string("${jalviewDir}/${getdown_images_dir}")
207 getdownSetAppBaseProperty = false // whether to pass the appbase and appdistdir to the application
208 reportRsyncCommand = false
209 jvlChannelName = CHANNEL.toLowerCase()
210 install4jSuffix = CHANNEL.substring(0, 1).toUpperCase() + CHANNEL.substring(1).toLowerCase(); // BUILD -> Build
211 install4jDMGDSStore = "${install4j_images_dir}/${install4j_dmg_ds_store}"
212 install4jDMGBackgroundImage = "${install4j_images_dir}/${install4j_dmg_background}"
213 install4jInstallerName = "${jalview_name} Non-Release Installer"
214 install4jExecutableName = install4j_executable_name
215 install4jExtraScheme = "jalviewx"
216 install4jMacIconsFile = string("${install4j_images_dir}/${install4j_mac_icons_file}")
217 install4jWindowsIconsFile = string("${install4j_images_dir}/${install4j_windows_icons_file}")
218 install4jPngIconFile = string("${install4j_images_dir}/${install4j_png_icon_file}")
219 install4jBackground = string("${install4j_images_dir}/${install4j_background}")
223 // TODO: get bamboo build artifact URL for getdown artifacts
224 getdown_channel_base = bamboo_channelbase
225 getdownChannelName = string("${bamboo_planKey}/${JAVA_VERSION}")
226 getdownAppBase = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
227 jvlChannelName += "_${getdownChannelName}"
228 // automatically add the test group Not-bamboo for exclusion
229 if ("".equals(testng_excluded_groups)) {
230 testng_excluded_groups = "Not-bamboo"
232 install4jExtraScheme = "jalviewb"
235 case [ "RELEASE", "JALVIEWJS-RELEASE" ]:
236 getdownAppDistDir = getdown_app_dir_release
237 getdownSetAppBaseProperty = true
238 reportRsyncCommand = true
240 install4jInstallerName = "${jalview_name} Installer"
241 getdownArchiveAppBase = getdown_archive_base
245 getdownChannelName = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
246 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
247 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
248 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
249 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
251 package_dir = string("${ARCHIVEDIR}/${package_dir}")
252 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
255 reportRsyncCommand = true
256 install4jExtraScheme = "jalviewa"
260 getdownChannelName = string("archive/${JALVIEW_VERSION}")
261 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
262 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
263 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
264 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
266 package_dir = string("${ARCHIVEDIR}/${package_dir}")
267 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
270 reportRsyncCommand = true
271 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
272 install4jSuffix = "Archive"
273 install4jExtraScheme = "jalviewa"
277 reportRsyncCommand = true
278 getdownSetAppBaseProperty = true
279 // DEVELOP-RELEASE is usually associated with a Jalview release series so set the version
280 JALVIEW_VERSION=JALVIEW_VERSION+"-d${buildDate}"
282 install4jSuffix = "Develop"
283 install4jExtraScheme = "jalviewd"
284 install4jInstallerName = "${jalview_name} Develop Installer"
288 reportRsyncCommand = true
289 getdownSetAppBaseProperty = true
290 // Don't ignore transpile errors for release build
291 if (jalviewjs_ignore_transpile_errors.equals("true")) {
292 jalviewjs_ignore_transpile_errors = "false"
293 println("Setting jalviewjs_ignore_transpile_errors to 'false'")
295 JALVIEW_VERSION = JALVIEW_VERSION+"-test"
296 install4jSuffix = "Test"
297 install4jExtraScheme = "jalviewt"
298 install4jInstallerName = "${jalview_name} Test Installer"
301 case ~/^SCRATCH(|-[-\w]*)$/:
302 getdownChannelName = CHANNEL
303 JALVIEW_VERSION = JALVIEW_VERSION+"-"+CHANNEL
305 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
306 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
307 reportRsyncCommand = true
308 install4jSuffix = "Scratch"
312 if (!file("${LOCALDIR}").exists()) {
313 throw new GradleException("Must provide a LOCALDIR value to produce a local distribution")
315 getdownAppBase = file(file("${LOCALDIR}").getAbsolutePath()).toURI().toString()
316 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
318 JALVIEW_VERSION = "TEST"
319 install4jSuffix = "Test-Local"
320 install4jExtraScheme = "jalviewt"
321 install4jInstallerName = "${jalview_name} Test Installer"
324 case [ "LOCAL", "JALVIEWJS" ]:
325 JALVIEW_VERSION = "TEST"
326 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
327 getdownArchiveAppBase = file("${jalviewDir}/${getdown_archive_dir}").toURI().toString()
328 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
329 install4jExtraScheme = "jalviewl"
332 default: // something wrong specified
333 throw new GradleException("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
337 JALVIEW_VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
338 // override getdownAppBase if requested
339 if (findProperty("getdown_appbase_override") != null) {
340 // revert to LOCAL if empty string
341 if (string(getdown_appbase_override) == "") {
342 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
343 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
344 } else if (string(getdown_appbase_override).startsWith("file://")) {
345 getdownAppBase = string(getdown_appbase_override)
346 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
348 getdownAppBase = string(getdown_appbase_override)
350 println("Overriding getdown appbase with '${getdownAppBase}'")
352 // sanitise file name for jalview launcher file for this channel
353 jvlChannelName = jvlChannelName.replaceAll("[^\\w\\-]+", "_")
354 // install4j application and folder names
355 if (install4jSuffix == "") {
356 install4jApplicationName = "${jalview_name}"
357 install4jBundleId = "${install4j_bundle_id}"
358 install4jWinApplicationId = install4j_release_win_application_id
360 install4jApplicationName = "${jalview_name} ${install4jSuffix}"
361 install4jBundleId = "${install4j_bundle_id}-" + install4jSuffix.toLowerCase()
362 // add int hash of install4jSuffix to the last part of the application_id
363 def id = install4j_release_win_application_id
364 def idsplitreverse = id.split("-").reverse()
365 idsplitreverse[0] = idsplitreverse[0].toInteger() + install4jSuffix.hashCode()
366 install4jWinApplicationId = idsplitreverse.reverse().join("-")
368 // sanitise folder and id names
369 // install4jApplicationFolder = e.g. "Jalview Build"
370 install4jApplicationFolder = install4jApplicationName
371 .replaceAll("[\"'~:/\\\\\\s]", "_") // replace all awkward filename chars " ' ~ : / \
372 .replaceAll("_+", "_") // collapse __
373 install4jInternalId = install4jApplicationName
375 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
376 .replaceAll("_+", "") // collapse __
377 //.replaceAll("_*-_*", "-") // collapse _-_
378 install4jUnixApplicationFolder = install4jApplicationName
380 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
381 .replaceAll("_+", "_") // collapse __
382 .replaceAll("_*-_*", "-") // collapse _-_
385 getdownWrapperLink = install4jUnixApplicationFolder // e.g. "jalview_local"
386 getdownAppDir = string("${getdownWebsiteDir}/${getdownAppDistDir}")
387 //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}"
388 getdownResourceDir = string("${getdownWebsiteDir}/${getdown_resource_dir}")
389 getdownInstallDir = string("${getdownWebsiteDir}/${getdown_install_dir}")
390 getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
391 getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
392 /* compile without modules -- using classpath libraries
393 modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
394 modules_runtimeClasspath = modules_compileClasspath
400 apply plugin: "com.palantir.git-version"
401 def details = versionDetails()
402 gitHash = details.gitHash
403 gitBranch = details.branchName
404 } catch(org.gradle.api.internal.plugins.PluginApplicationException e) {
405 println("Not in a git repository. Using git values from RELEASE properties file.")
406 gitHash = releaseProps.getProperty("git.hash")
407 gitBranch = releaseProps.getProperty("git.branch")
408 } catch(java.lang.RuntimeException e1) {
409 throw new GradleException("Error with git-version plugin. Directory '.git' exists but versionDetails() cannot be found.")
412 println("Using a ${CHANNEL} profile.")
414 additional_compiler_args = []
415 // configure classpath/args for j8/j11 compilation
416 if (JAVA_VERSION.equals("1.8")) {
417 JAVA_INTEGER_VERSION = string("8")
420 libDistDir = j8libDir
421 compile_source_compatibility = 1.8
422 compile_target_compatibility = 1.8
423 // these are getdown.txt properties defined dependent on the JAVA_VERSION
424 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java8_min_version"))
425 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java8_max_version"))
426 // this property is assigned below and expanded to multiple lines in the getdown task
427 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java8_txt_multi_java_location"))
428 // this property is for the Java library used in eclipse
429 eclipseJavaRuntimeName = string("JavaSE-1.8")
430 } else if (JAVA_VERSION.equals("11")) {
431 JAVA_INTEGER_VERSION = string("11")
433 libDistDir = j11libDir
434 compile_source_compatibility = 11
435 compile_target_compatibility = 11
436 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
437 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
438 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
439 eclipseJavaRuntimeName = string("JavaSE-11")
440 /* compile without modules -- using classpath libraries
441 additional_compiler_args += [
442 '--module-path', modules_compileClasspath.asPath,
443 '--add-modules', j11modules
446 } else if (JAVA_VERSION.equals("17")) {
447 JAVA_INTEGER_VERSION = string("17")
449 libDistDir = j17libDir
450 compile_source_compatibility = 17
451 compile_target_compatibility = 17
452 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
453 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
454 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
455 eclipseJavaRuntimeName = string("JavaSE-17")
456 /* compile without modules -- using classpath libraries
457 additional_compiler_args += [
458 '--module-path', modules_compileClasspath.asPath,
459 '--add-modules', j11modules
463 throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
468 JAVA_MIN_VERSION = JAVA_VERSION
469 JAVA_MAX_VERSION = JAVA_VERSION
470 def jreInstallsDir = string(jre_installs_dir)
471 if (jreInstallsDir.startsWith("~/")) {
472 jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1)
474 macosJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-mac-x64/jre")
475 windowsJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-windows-x64/jre")
476 linuxJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-linux-x64/jre")
477 macosJavaVMTgz = string("${jreInstallsDir}/tgz/jre_${JAVA_INTEGER_VERSION}_mac_x64.tar.gz")
478 windowsJavaVMTgz = string("${jreInstallsDir}/tgz/jre_${JAVA_INTEGER_VERSION}_windows_x64.tar.gz")
479 linuxJavaVMTgz = string("${jreInstallsDir}/tgz/jre_${JAVA_INTEGER_VERSION}_linux_x64.tar.gz")
480 install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
481 install4jConfFileName = string("jalview-install4j-conf.install4j")
482 install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
483 install4jHomeDir = install4j_home_dir
484 if (install4jHomeDir.startsWith("~/")) {
485 install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1)
488 resourceBuildDir = string("${buildDir}/resources")
489 resourcesBuildDir = string("${resourceBuildDir}/resources_build")
490 helpBuildDir = string("${resourceBuildDir}/help_build")
491 docBuildDir = string("${resourceBuildDir}/doc_build")
493 if (buildProperties == null) {
494 buildProperties = string("${resourcesBuildDir}/${build_properties_file}")
496 buildingHTML = string("${jalviewDir}/${doc_dir}/building.html")
497 helpParentDir = string("${jalviewDir}/${help_parent_dir}")
498 helpSourceDir = string("${helpParentDir}/${help_dir}")
499 helpFile = string("${helpBuildDir}/${help_dir}/help.jhm")
502 relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
503 jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
504 jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}")
506 jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
508 jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
510 jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
511 jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
512 jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
513 jalviewjsJalviewCoreHtmlFile = string("")
514 jalviewjsJalviewCoreName = string(jalviewjs_core_name)
515 jalviewjsCoreClasslists = []
516 jalviewjsJalviewTemplateName = string(jalviewjs_name)
517 jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
518 jalviewjsJ2sAltSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_alt_settings}")
519 jalviewjsJ2sProps = null
520 jalviewjsJ2sPlugin = jalviewjs_j2s_plugin
522 eclipseWorkspace = null
523 eclipseBinary = string("")
524 eclipseVersion = string("")
534 outputDir = file(classesDir)
538 srcDirs = [ resourcesBuildDir, docBuildDir, helpBuildDir ]
541 compileClasspath = files(sourceSets.main.java.outputDir)
542 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
544 runtimeClasspath = compileClasspath
545 runtimeClasspath += files(sourceSets.main.resources.srcDirs)
550 srcDirs cloverInstrDir
551 outputDir = cloverClassesDir
555 srcDirs = sourceSets.main.resources.srcDirs
558 compileClasspath = files( sourceSets.clover.java.outputDir )
559 //compileClasspath += files( testClassesDir )
560 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
561 compileClasspath += fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
562 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
564 runtimeClasspath = compileClasspath
569 srcDirs testSourceDir
570 outputDir = file(testClassesDir)
574 srcDirs = useClover ? sourceSets.clover.resources.srcDirs : sourceSets.main.resources.srcDirs
577 compileClasspath = files( sourceSets.test.java.outputDir )
578 compileClasspath += useClover ? sourceSets.clover.compileClasspath : sourceSets.main.compileClasspath
579 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
581 runtimeClasspath = compileClasspath
582 runtimeClasspath += files(sourceSets.test.resources.srcDirs)
588 // eclipse project and settings files creation, also used by buildship
591 name = eclipse_project_name
593 natures 'org.eclipse.jdt.core.javanature',
594 'org.eclipse.jdt.groovy.core.groovyNature',
595 'org.eclipse.buildship.core.gradleprojectnature'
597 buildCommand 'org.eclipse.jdt.core.javabuilder'
598 buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
602 //defaultOutputDir = sourceSets.main.java.outputDir
603 configurations.each{ c->
604 if (c.isCanBeResolved()) {
605 minusConfigurations += [c]
609 plusConfigurations = [ ]
613 def removeTheseToo = []
614 HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
615 cp.entries.each { entry ->
616 // This conditional removes all src classpathentries that a) have already been added or b) aren't "src" or "test".
617 // e.g. this removes the resources dir being copied into bin/main, bin/test AND bin/clover
618 // we add the resources and help/help dirs in as libs afterwards (see below)
619 if (entry.kind == 'src') {
620 if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) {
621 removeTheseToo += entry
623 alreadyAddedSrcPath.putAt(entry.path, true)
628 cp.entries.removeAll(removeTheseToo)
630 //cp.entries += new Output("${eclipse_bin_dir}/main")
631 if (file(helpParentDir).isDirectory()) {
632 cp.entries += new Library(fileReference(helpParentDir))
634 if (file(resourceDir).isDirectory()) {
635 cp.entries += new Library(fileReference(resourceDir))
638 HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
640 sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
641 //don't want to add outputDir as eclipse is using its own output dir in bin/main
642 if (it.isDirectory() || ! it.exists()) {
643 // don't add dirs to classpath, especially if they don't exist
644 return false // groovy "continue" in .any closure
646 def itPath = it.toString()
647 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
648 // make relative path
649 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
651 if (alreadyAddedLibPath.get(itPath)) {
652 //println("Not adding duplicate entry "+itPath)
654 //println("Adding entry "+itPath)
655 cp.entries += new Library(fileReference(itPath))
656 alreadyAddedLibPath.put(itPath, true)
660 sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
661 //no longer want to add outputDir as eclipse is using its own output dir in bin/main
662 if (it.isDirectory() || ! it.exists()) {
663 // don't add dirs to classpath
664 return false // groovy "continue" in .any closure
667 def itPath = it.toString()
668 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
669 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
671 if (alreadyAddedLibPath.get(itPath)) {
674 def lib = new Library(fileReference(itPath))
675 lib.entryAttributes["test"] = "true"
677 alreadyAddedLibPath.put(itPath, true)
685 containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
690 // for the IDE, use java 11 compatibility
691 sourceCompatibility = compile_source_compatibility
692 targetCompatibility = compile_target_compatibility
693 javaRuntimeName = eclipseJavaRuntimeName
695 // add in jalview project specific properties/preferences into eclipse core preferences
697 withProperties { props ->
698 def jalview_prefs = new Properties()
699 def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
700 jalview_prefs.load(ins)
702 jalview_prefs.forEach { t, v ->
703 if (props.getAt(t) == null) {
707 // codestyle file -- overrides previous formatter prefs
708 def csFile = file("${jalviewDirAbsolutePath}/${eclipse_codestyle_file}")
709 if (csFile.exists()) {
710 XmlParser parser = new XmlParser()
711 def profiles = parser.parse(csFile)
712 def profile = profiles.'profile'.find { p -> (p.'@kind' == "CodeFormatterProfile" && p.'@name' == "Jalview") }
713 if (profile != null) {
714 profile.'setting'.each { s ->
716 def value = s.'@value'
717 if (id != null && value != null) {
718 props.putAt(id, value)
729 // Don't want these to be activated if in headless build
730 synchronizationTasks "eclipseSynchronizationTask"
731 //autoBuildTasks "eclipseAutoBuildTask"
737 /* hack to change eclipse prefs in .settings files other than org.eclipse.jdt.core.prefs */
738 // Class to allow updating arbitrary properties files
739 class PropertiesFile extends PropertiesPersistableConfigurationObject {
740 public PropertiesFile(PropertiesTransformer t) { super(t); }
741 @Override protected void load(Properties properties) { }
742 @Override protected void store(Properties properties) { }
743 @Override protected String getDefaultResourceName() { return ""; }
744 // This is necessary, because PropertiesPersistableConfigurationObject fails
745 // if no default properties file exists.
746 @Override public void loadDefaults() { load(new StringBufferInputStream("")); }
749 // Task to update arbitrary properties files (set outputFile)
750 class PropertiesFileTask extends PropertiesGeneratorTask<PropertiesFile> {
751 private final PropertiesFileContentMerger file;
752 public PropertiesFileTask() { file = new PropertiesFileContentMerger(getTransformer()); }
753 protected PropertiesFile create() { return new PropertiesFile(getTransformer()); }
754 protected void configure(PropertiesFile props) {
755 file.getBeforeMerged().execute(props); file.getWhenMerged().execute(props);
757 public void file(Closure closure) { ConfigureUtil.configure(closure, file); }
760 task eclipseUIPreferences(type: PropertiesFileTask) {
761 description = "Generate Eclipse additional settings"
762 def filename = "org.eclipse.jdt.ui.prefs"
763 outputFile = "$projectDir/.settings/${filename}" as File
766 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
771 task eclipseGroovyCorePreferences(type: PropertiesFileTask) {
772 description = "Generate Eclipse additional settings"
773 def filename = "org.eclipse.jdt.groovy.core.prefs"
774 outputFile = "$projectDir/.settings/${filename}" as File
777 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
782 task eclipseAllPreferences {
784 dependsOn eclipseUIPreferences
785 dependsOn eclipseGroovyCorePreferences
788 eclipseUIPreferences.mustRunAfter eclipseJdt
789 eclipseGroovyCorePreferences.mustRunAfter eclipseJdt
791 /* end of eclipse preferences hack */
799 delete cloverBuildDir
800 delete cloverReportDir
805 task cloverInstrJava(type: JavaExec) {
806 group = "Verification"
807 description = "Create clover instrumented source java files"
809 dependsOn cleanClover
811 inputs.files(sourceSets.main.allJava)
812 outputs.dir(cloverInstrDir)
814 //classpath = fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
815 classpath = sourceSets.clover.compileClasspath
816 main = "com.atlassian.clover.CloverInstr"
824 cloverInstrDir.getPath(),
826 def srcFiles = sourceSets.main.allJava.files
829 { file -> file.absolutePath }
832 args argsList.toArray()
835 delete cloverInstrDir
836 println("Clover: About to instrument "+srcFiles.size() +" files")
841 task cloverInstrTests(type: JavaExec) {
842 group = "Verification"
843 description = "Create clover instrumented source test files"
845 dependsOn cleanClover
847 inputs.files(testDir)
848 outputs.dir(cloverTestInstrDir)
850 classpath = sourceSets.clover.compileClasspath
851 main = "com.atlassian.clover.CloverInstr"
861 cloverTestInstrDir.getPath(),
863 args argsList.toArray()
866 delete cloverTestInstrDir
867 println("Clover: About to instrument test files")
873 group = "Verification"
874 description = "Create clover instrumented all source files"
876 dependsOn cloverInstrJava
877 dependsOn cloverInstrTests
881 cloverClasses.dependsOn cloverInstr
884 task cloverConsoleReport(type: JavaExec) {
885 group = "Verification"
886 description = "Creates clover console report"
889 file(cloverDb).exists()
892 inputs.dir cloverClassesDir
894 classpath = sourceSets.clover.runtimeClasspath
895 main = "com.atlassian.clover.reporters.console.ConsoleReporter"
897 if (cloverreport_mem.length() > 0) {
898 maxHeapSize = cloverreport_mem
900 if (cloverreport_jvmargs.length() > 0) {
901 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
911 args argsList.toArray()
915 task cloverHtmlReport(type: JavaExec) {
916 group = "Verification"
917 description = "Creates clover HTML report"
920 file(cloverDb).exists()
923 def cloverHtmlDir = cloverReportDir
924 inputs.dir cloverClassesDir
925 outputs.dir cloverHtmlDir
927 classpath = sourceSets.clover.runtimeClasspath
928 main = "com.atlassian.clover.reporters.html.HtmlReporter"
930 if (cloverreport_mem.length() > 0) {
931 maxHeapSize = cloverreport_mem
933 if (cloverreport_jvmargs.length() > 0) {
934 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
945 if (cloverreport_html_options.length() > 0) {
946 argsList += cloverreport_html_options.split(" ")
949 args argsList.toArray()
953 task cloverXmlReport(type: JavaExec) {
954 group = "Verification"
955 description = "Creates clover XML report"
958 file(cloverDb).exists()
961 def cloverXmlFile = "${cloverReportDir}/clover.xml"
962 inputs.dir cloverClassesDir
963 outputs.file cloverXmlFile
965 classpath = sourceSets.clover.runtimeClasspath
966 main = "com.atlassian.clover.reporters.xml.XMLReporter"
968 if (cloverreport_mem.length() > 0) {
969 maxHeapSize = cloverreport_mem
971 if (cloverreport_jvmargs.length() > 0) {
972 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
983 if (cloverreport_xml_options.length() > 0) {
984 argsList += cloverreport_xml_options.split(" ")
987 args argsList.toArray()
992 group = "Verification"
993 description = "Creates clover reports"
995 dependsOn cloverXmlReport
996 dependsOn cloverHtmlReport
1003 sourceCompatibility = compile_source_compatibility
1004 targetCompatibility = compile_target_compatibility
1005 options.compilerArgs += additional_compiler_args
1006 print ("Setting target compatibility to "+targetCompatibility+"\n")
1008 //classpath += configurations.cloverRuntime
1014 // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ?
1015 sourceCompatibility = compile_source_compatibility
1016 targetCompatibility = compile_target_compatibility
1017 options.compilerArgs = additional_compiler_args
1018 options.encoding = "UTF-8"
1020 print ("Setting target compatibility to "+compile_target_compatibility+"\n")
1027 sourceCompatibility = compile_source_compatibility
1028 targetCompatibility = compile_target_compatibility
1029 options.compilerArgs = additional_compiler_args
1031 print ("Setting target compatibility to "+targetCompatibility+"\n")
1038 delete sourceSets.main.java.outputDir
1044 dependsOn cleanClover
1046 delete sourceSets.test.java.outputDir
1051 // format is a string like date.format("dd MMMM yyyy")
1052 def getDate(format) {
1053 def date = new Date()
1054 return date.format(format)
1058 def convertMdToHtml (FileTree mdFiles, File cssFile) {
1059 MutableDataSet options = new MutableDataSet()
1061 def extensions = new ArrayList<>()
1062 extensions.add(AnchorLinkExtension.create())
1063 extensions.add(AutolinkExtension.create())
1064 extensions.add(StrikethroughExtension.create())
1065 extensions.add(TaskListExtension.create())
1066 extensions.add(TablesExtension.create())
1067 extensions.add(TocExtension.create())
1069 options.set(Parser.EXTENSIONS, extensions)
1071 // set GFM table parsing options
1072 options.set(TablesExtension.WITH_CAPTION, false)
1073 options.set(TablesExtension.COLUMN_SPANS, false)
1074 options.set(TablesExtension.MIN_HEADER_ROWS, 1)
1075 options.set(TablesExtension.MAX_HEADER_ROWS, 1)
1076 options.set(TablesExtension.APPEND_MISSING_COLUMNS, true)
1077 options.set(TablesExtension.DISCARD_EXTRA_COLUMNS, true)
1078 options.set(TablesExtension.HEADER_SEPARATOR_COLUMN_MATCH, true)
1080 options.set(AnchorLinkExtension.ANCHORLINKS_SET_ID, false)
1081 options.set(AnchorLinkExtension.ANCHORLINKS_ANCHOR_CLASS, "anchor")
1082 options.set(AnchorLinkExtension.ANCHORLINKS_SET_NAME, true)
1083 options.set(AnchorLinkExtension.ANCHORLINKS_TEXT_PREFIX, "<span class=\"octicon octicon-link\"></span>")
1085 Parser parser = Parser.builder(options).build()
1086 HtmlRenderer renderer = HtmlRenderer.builder(options).build()
1088 mdFiles.each { mdFile ->
1089 // add table of contents
1090 def mdText = "[TOC]\n"+mdFile.text
1092 // grab the first top-level title
1094 def titleRegex = /(?m)^#(\s+|([^#]))(.*)/
1095 def matcher = mdText =~ titleRegex
1096 if (matcher.size() > 0) {
1097 // matcher[0][2] is the first character of the title if there wasn't any whitespace after the #
1098 title = (matcher[0][2] != null ? matcher[0][2] : "")+matcher[0][3]
1100 // or use the filename if none found
1101 if (title == null) {
1102 title = mdFile.getName()
1105 Node document = parser.parse(mdText)
1106 String htmlBody = renderer.render(document)
1107 def htmlText = '''<html>
1108 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1109 <html xmlns="http://www.w3.org/1999/xhtml">
1111 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1112 <meta http-equiv="Content-Style-Type" content="text/css" />
1113 <meta name="generator" content="flexmark" />
1115 htmlText += ((title != null) ? " <title>${title}</title>" : '' )
1117 <style type="text/css">code{white-space: pre;}</style>
1119 htmlText += ((cssFile != null) ? cssFile.text : '')
1120 htmlText += '''</head>
1123 htmlText += htmlBody
1129 def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
1130 def htmlFile = file(htmlFilePath)
1131 println("Creating ${htmlFilePath}")
1132 htmlFile.text = htmlText
1137 task copyDocs(type: Copy) {
1138 def inputDir = "${jalviewDir}/${doc_dir}"
1139 def outputDir = "${docBuildDir}/${doc_dir}"
1143 include('**/*.html')
1145 filter(ReplaceTokens,
1149 'Version-Rel': JALVIEW_VERSION,
1150 'Year-Rel': getDate("yyyy")
1157 exclude('**/*.html')
1162 inputs.dir(inputDir)
1163 outputs.dir(outputDir)
1167 task convertMdFiles {
1169 def mdFiles = fileTree(dir: docBuildDir, include: "**/*.md")
1170 def cssFile = file("${jalviewDir}/${flexmark_css}")
1173 convertMdToHtml(mdFiles, cssFile)
1176 inputs.files(mdFiles)
1177 inputs.file(cssFile)
1180 mdFiles.each { mdFile ->
1181 def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
1182 htmlFiles.add(file(htmlFilePath))
1184 outputs.files(htmlFiles)
1188 task copyHelp(type: Copy) {
1189 def inputDir = helpSourceDir
1190 def outputDir = "${helpBuildDir}/${help_dir}"
1194 include('**/*.html')
1198 filter(ReplaceTokens,
1202 'Version-Rel': JALVIEW_VERSION,
1203 'Year-Rel': getDate("yyyy")
1210 exclude('**/*.html')
1217 inputs.dir(inputDir)
1218 outputs.files(helpFile)
1219 outputs.dir(outputDir)
1223 task copyResources(type: Copy) {
1225 description = "Copy (and make text substitutions in) the resources dir to the build area"
1227 def inputDir = resourceDir
1228 def outputDir = resourcesBuildDir
1232 include('**/*.html')
1234 filter(ReplaceTokens,
1238 'Version-Rel': JALVIEW_VERSION,
1239 'Year-Rel': getDate("yyyy")
1246 exclude('**/*.html')
1251 inputs.dir(inputDir)
1252 outputs.dir(outputDir)
1255 task copyChannelResources(type: Copy) {
1256 dependsOn copyResources
1258 description = "Copy the channel resources dir to the build resources area"
1260 def inputDir = "${channelDir}/${resource_dir}"
1261 def outputDir = resourcesBuildDir
1265 inputs.dir(inputDir)
1266 outputs.dir(outputDir)
1269 task createBuildProperties(type: WriteProperties) {
1270 dependsOn copyResources
1272 description = "Create the ${buildProperties} file"
1274 inputs.dir(sourceDir)
1275 inputs.dir(resourcesBuildDir)
1276 outputFile (buildProperties)
1277 // taking time specific comment out to allow better incremental builds
1278 comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
1279 //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
1280 property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
1281 property "VERSION", JALVIEW_VERSION
1282 property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
1283 if (getdownSetAppBaseProperty) {
1284 property "GETDOWNAPPBASE", getdownAppBase
1285 property "GETDOWNAPPDISTDIR", getdownAppDistDir
1287 outputs.file(outputFile)
1291 task buildIndices(type: JavaExec) {
1293 classpath = sourceSets.main.compileClasspath
1294 main = "com.sun.java.help.search.Indexer"
1295 workingDir = "${helpBuildDir}/${help_dir}"
1298 inputs.dir("${workingDir}/${argDir}")
1300 outputs.dir("${classesDir}/doc")
1301 outputs.dir("${classesDir}/help")
1302 outputs.file("${workingDir}/JavaHelpSearch/DOCS")
1303 outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
1304 outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
1305 outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
1306 outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
1307 outputs.file("${workingDir}/JavaHelpSearch/TMAP")
1310 task buildResources {
1311 dependsOn copyResources
1312 dependsOn copyChannelResources
1313 dependsOn createBuildProperties
1317 dependsOn buildResources
1320 dependsOn convertMdFiles
1321 dependsOn buildIndices
1325 compileJava.dependsOn prepare
1326 run.dependsOn compileJava
1327 //run.dependsOn prepare
1330 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
1335 dependsOn cloverClasses
1337 dependsOn compileJava //?
1341 includeGroups testng_groups
1342 excludeGroups testng_excluded_groups
1344 useDefaultListeners=true
1347 maxHeapSize = "1024m"
1349 workingDir = jalviewDir
1350 def testLaf = project.findProperty("test_laf")
1351 if (testLaf != null) {
1352 println("Setting Test LaF to '${testLaf}'")
1353 systemProperty "laf", testLaf
1355 def testHiDPIScale = project.findProperty("test_HiDPIScale")
1356 if (testHiDPIScale != null) {
1357 println("Setting Test HiDPI Scale to '${testHiDPIScale}'")
1358 systemProperty "sun.java2d.uiScale", testHiDPIScale
1360 sourceCompatibility = compile_source_compatibility
1361 targetCompatibility = compile_target_compatibility
1362 jvmArgs += additional_compiler_args
1366 println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
1372 task compileLinkCheck(type: JavaCompile) {
1374 classpath = files("${jalviewDir}/${utils_dir}")
1375 destinationDir = file("${jalviewDir}/${utils_dir}")
1376 source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
1378 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1379 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1380 outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
1381 outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
1385 task linkCheck(type: JavaExec) {
1387 dependsOn compileLinkCheck
1389 def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
1390 classpath = files("${jalviewDir}/${utils_dir}")
1391 main = "HelpLinksChecker"
1392 workingDir = jalviewDir
1393 args = [ "${helpBuildDir}/${help_dir}", "-nointernet" ]
1395 def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
1396 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1399 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1403 inputs.dir(helpBuildDir)
1404 outputs.file(helpLinksCheckerOutFile)
1408 // import the pubhtmlhelp target
1409 ant.properties.basedir = "${jalviewDir}"
1410 ant.properties.helpBuildDir = "${helpBuildDir}/${help_dir}"
1411 ant.importBuild "${utils_dir}/publishHelp.xml"
1414 task cleanPackageDir(type: Delete) {
1416 delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
1426 attributes "Main-Class": main_class,
1427 "Permissions": "all-permissions",
1428 "Application-Name": install4jApplicationName,
1429 "Codebase": application_codebase,
1430 "Implementation-Version": JALVIEW_VERSION
1433 def outputDir = "${jalviewDir}/${package_dir}"
1434 destinationDirectory = file(outputDir)
1435 archiveFileName = rootProject.name+".jar"
1436 duplicatesStrategy "EXCLUDE"
1443 exclude "**/*.jar.*"
1445 inputs.dir(sourceSets.main.java.outputDir)
1446 sourceSets.main.resources.srcDirs.each{ dir ->
1449 outputs.file("${outputDir}/${archiveFileName}")
1453 task copyJars(type: Copy) {
1454 from fileTree(dir: classesDir, include: "**/*.jar").files
1455 into "${jalviewDir}/${package_dir}"
1459 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
1460 task syncJars(type: Sync) {
1462 from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
1463 into "${jalviewDir}/${package_dir}"
1465 include jar.archiveFileName.getOrNull()
1472 description = "Put all required libraries in dist"
1473 // order of "cleanPackageDir", "copyJars", "jar" important!
1474 jar.mustRunAfter cleanPackageDir
1475 syncJars.mustRunAfter cleanPackageDir
1476 dependsOn cleanPackageDir
1479 outputs.dir("${jalviewDir}/${package_dir}")
1484 dependsOn cleanPackageDir
1491 group = "distribution"
1492 description = "Create a single jar file with all dependency libraries merged. Can be run with java -jar"
1496 from ("${jalviewDir}/${libDistDir}") {
1500 attributes "Implementation-Version": JALVIEW_VERSION,
1501 "Application-Name": install4jApplicationName
1504 duplicatesStrategy "INCLUDE"
1506 mainClassName = shadow_jar_main_class
1508 classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
1513 task getdownWebsite() {
1514 group = "distribution"
1515 description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
1520 def getdownWebsiteResourceFilenames = []
1521 def getdownResourceDir = getdownResourceDir
1522 def getdownResourceFilenames = []
1525 // clean the getdown website and files dir before creating getdown folders
1526 delete getdownWebsiteDir
1527 delete getdownFilesDir
1530 from buildProperties
1531 rename(file(buildProperties).getName(), getdown_build_properties)
1534 getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
1537 from channelPropsFile
1538 into getdownWebsiteDir
1540 getdownWebsiteResourceFilenames += file(channelPropsFile).getName()
1542 // set some getdownTxt_ properties then go through all properties looking for getdownTxt_...
1543 def props = project.properties.sort { it.key }
1544 if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
1545 props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
1547 if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) {
1548 props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion)
1550 if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
1551 props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
1553 if (getdownImagesDir != null && file(getdownImagesDir).exists()) {
1554 props.put("getdown_txt_ui.background_image", "${getdownImagesDir}/${getdown_background_image}")
1555 props.put("getdown_txt_ui.instant_background_image", "${getdownImagesDir}/${getdown_instant_background_image}")
1556 props.put("getdown_txt_ui.error_background", "${getdownImagesDir}/${getdown_error_background}")
1557 props.put("getdown_txt_ui.progress_image", "${getdownImagesDir}/${getdown_progress_image}")
1558 props.put("getdown_txt_ui.icon", "${getdownImagesDir}/${getdown_icon}")
1559 props.put("getdown_txt_ui.mac_dock_icon", "${getdownImagesDir}/${getdown_mac_dock_icon}")
1562 props.put("getdown_txt_title", jalview_name)
1563 props.put("getdown_txt_ui.name", install4jApplicationName)
1565 // start with appbase
1566 getdownTextLines += "appbase = ${getdownAppBase}"
1567 props.each{ prop, val ->
1568 if (prop.startsWith("getdown_txt_") && val != null) {
1569 if (prop.startsWith("getdown_txt_multi_")) {
1570 def key = prop.substring(18)
1571 val.split(",").each{ v ->
1572 def line = "${key} = ${v}"
1573 getdownTextLines += line
1576 // file values rationalised
1577 if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1579 if (val.indexOf('/') == 0) {
1582 } else if (val.indexOf('/') > 0) {
1583 // relative path (relative to jalviewDir)
1584 r = file( "${jalviewDir}/${val}" )
1587 val = "${getdown_resource_dir}/" + r.getName()
1588 getdownWebsiteResourceFilenames += val
1589 getdownResourceFilenames += r.getPath()
1592 if (! prop.startsWith("getdown_txt_resource")) {
1593 def line = prop.substring(12) + " = ${val}"
1594 getdownTextLines += line
1600 getdownWebsiteResourceFilenames.each{ filename ->
1601 getdownTextLines += "resource = ${filename}"
1603 getdownResourceFilenames.each{ filename ->
1606 into getdownResourceDir
1610 def getdownWrapperScripts = [ getdown_bash_wrapper_script, getdown_powershell_wrapper_script, getdown_batch_wrapper_script ]
1611 getdownWrapperScripts.each{ script ->
1612 def s = file( "${jalviewDir}/utils/getdown/${getdown_wrapper_script_dir}/${script}" )
1616 into "${getdownWebsiteDir}/${getdown_wrapper_script_dir}"
1618 getdownTextLines += "resource = ${getdown_wrapper_script_dir}/${script}"
1623 fileTree(file(package_dir)).each{ f ->
1624 if (f.isDirectory()) {
1625 def files = fileTree(dir: f, include: ["*"]).getFiles()
1627 } else if (f.exists()) {
1631 def jalviewJar = jar.archiveFileName.getOrNull()
1632 // put jalview.jar first for CLASSPATH and .properties files reasons
1633 codeFiles.sort{a, b -> ( a.getName() == jalviewJar ? -1 : ( b.getName() == jalviewJar ? 1 : a <=> b ) ) }.each{f ->
1634 def name = f.getName()
1635 def line = "code = ${getdownAppDistDir}/${name}"
1636 getdownTextLines += line
1643 // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
1645 if (JAVA_VERSION.equals("11")) {
1646 def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
1647 j11libFiles.sort().each{f ->
1648 def name = f.getName()
1649 def line = "code = ${getdown_j11lib_dir}/${name}"
1650 getdownTextLines += line
1653 into getdownJ11libDir
1659 // 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.
1660 //getdownTextLines += "class = " + file(getdownLauncher).getName()
1661 getdownTextLines += "resource = ${getdown_launcher_new}"
1662 getdownTextLines += "class = ${main_class}"
1663 // Not setting these properties in general so that getdownappbase and getdowndistdir will default to release version in jalview.bin.Cache
1664 if (getdownSetAppBaseProperty) {
1665 getdownTextLines += "jvmarg = -Dgetdowndistdir=${getdownAppDistDir}"
1666 getdownTextLines += "jvmarg = -Dgetdownappbase=${getdownAppBase}"
1669 def getdownTxt = file("${getdownWebsiteDir}/getdown.txt")
1670 getdownTxt.write(getdownTextLines.join("\n"))
1672 getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
1673 def launchJvl = file("${getdownWebsiteDir}/${getdownLaunchJvl}")
1674 launchJvl.write("appbase=${getdownAppBase}")
1676 // files going into the getdown website dir: getdown-launcher.jar
1678 from getdownLauncher
1679 rename(file(getdownLauncher).getName(), getdown_launcher_new)
1680 into getdownWebsiteDir
1683 // files going into the getdown website dir: getdown-launcher(-local).jar
1685 from getdownLauncher
1686 if (file(getdownLauncher).getName() != getdown_launcher) {
1687 rename(file(getdownLauncher).getName(), getdown_launcher)
1689 into getdownWebsiteDir
1692 // files going into the getdown website dir: ./install dir and files
1693 if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
1696 from getdownLauncher
1697 from "${getdownAppDir}/${getdown_build_properties}"
1698 if (file(getdownLauncher).getName() != getdown_launcher) {
1699 rename(file(getdownLauncher).getName(), getdown_launcher)
1701 into getdownInstallDir
1704 // and make a copy in the getdown files dir (these are not downloaded by getdown)
1706 from getdownInstallDir
1707 into getdownFilesInstallDir
1711 // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties
1715 from getdownLauncher
1716 from "${getdownWebsiteDir}/${getdown_build_properties}"
1717 from "${getdownWebsiteDir}/${channel_props}"
1718 if (file(getdownLauncher).getName() != getdown_launcher) {
1719 rename(file(getdownLauncher).getName(), getdown_launcher)
1721 into getdownFilesDir
1724 // and ./resource (not all downloaded by getdown)
1726 from getdownResourceDir
1727 into "${getdownFilesDir}/${getdown_resource_dir}"
1732 inputs.dir("${jalviewDir}/${package_dir}")
1734 outputs.dir(getdownWebsiteDir)
1735 outputs.dir(getdownFilesDir)
1739 // a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
1740 task getdownDigestDir(type: JavaExec) {
1742 description "A task to run a getdown Digest on a dir with getdown.txt. Provide a DIGESTDIR property via -PDIGESTDIR=..."
1744 def digestDirPropertyName = "DIGESTDIR"
1746 classpath = files(getdownLauncher)
1747 def digestDir = findProperty(digestDirPropertyName)
1748 if (digestDir == null) {
1749 throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest")
1753 main = "com.threerings.getdown.tools.Digester"
1757 task getdownDigest(type: JavaExec) {
1758 group = "distribution"
1759 description = "Digest the getdown website folder"
1760 dependsOn getdownWebsite
1762 classpath = files(getdownLauncher)
1764 main = "com.threerings.getdown.tools.Digester"
1765 args getdownWebsiteDir
1766 inputs.dir(getdownWebsiteDir)
1767 outputs.file("${getdownWebsiteDir}/digest2.txt")
1772 group = "distribution"
1773 description = "Create the minimal and full getdown app folder for installers and website and create digest file"
1774 dependsOn getdownDigest
1776 if (reportRsyncCommand) {
1777 def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
1778 def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
1779 println "LIKELY RSYNC COMMAND:"
1780 println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
1781 if (RUNRSYNC == "true") {
1783 commandLine "mkdir", "-p", toDir
1786 commandLine "rsync", "-avh", "--delete", fromDir, toDir
1794 task getdownArchiveBuild() {
1795 group = "distribution"
1796 description = "Put files in the archive dir to go on the website"
1798 dependsOn getdownWebsite
1800 def v = "v${JALVIEW_VERSION_UNDERSCORES}"
1801 def vDir = "${getdownArchiveDir}/${v}"
1802 getdownFullArchiveDir = "${vDir}/getdown"
1803 def vLaunchVersionJvl = "${vDir}/jalview-${v}.jvl"
1804 def vAltDir = "alt_${v}"
1805 def archiveImagesDir = "${jalviewDir}/${channel_properties_dir}/old/images"
1808 if (getdownArchiveAppBase == null) {
1809 throw new StopExecutionException("Cannot create getdownArchive for CHANNEL=${CHANNEL}")
1812 // cleanup old "old" dir
1813 delete getdownArchiveDir
1815 def getdownArchiveTxt = file("${getdownFullArchiveDir}/getdown.txt")
1816 getdownArchiveTxt.getParentFile().mkdirs()
1817 def getdownArchiveTextLines = []
1818 def getdownFullArchiveAppBase = "${getdownArchiveAppBase}${getdownArchiveAppBase.endsWith("/")?"":"/"}${v}/getdown/"
1822 from "${getdownWebsiteDir}/${getdownAppDistDir}"
1823 into "${getdownFullArchiveDir}/${vAltDir}"
1826 getdownTextLines.each { line ->
1827 line = line.replaceAll("^(?<s>appbase\\s*=\\s*).*", '${s}'+getdownFullArchiveAppBase)
1828 line = line.replaceAll("^(?<s>(resource|code)\\s*=\\s*)${getdownAppDistDir}/", '${s}'+vAltDir+"/")
1829 line = line.replaceAll("^(?<s>ui.background_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background.png")
1830 line = line.replaceAll("^(?<s>ui.instant_background_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background_initialising.png")
1831 line = line.replaceAll("^(?<s>ui.error_background\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background_error.png")
1832 line = line.replaceAll("^(?<s>ui.progress_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_progress_bar.png")
1833 // remove the existing resource = resource/ or bin/ lines
1834 if (! line.matches("resource\\s*=\\s*(resource|bin)/.*")) {
1835 getdownArchiveTextLines += line
1839 // the resource dir -- add these files as resource lines in getdown.txt
1841 from "${archiveImagesDir}"
1842 into "${getdownFullArchiveDir}/${getdown_resource_dir}"
1844 getdownArchiveTextLines += "resource = ${getdown_resource_dir}/${file.getName()}"
1848 getdownArchiveTxt.write(getdownArchiveTextLines.join("\n"))
1850 def vLaunchJvl = file(vLaunchVersionJvl)
1851 vLaunchJvl.getParentFile().mkdirs()
1852 vLaunchJvl.write("appbase=${getdownFullArchiveAppBase}\n")
1853 def vLaunchJvlPath = vLaunchJvl.toPath().toAbsolutePath()
1854 def jvlLinkPath = file("${vDir}/jalview.jvl").toPath().toAbsolutePath()
1855 // for some reason filepath.relativize(fileInSameDirPath) gives a path to "../" which is wrong
1856 //java.nio.file.Files.createSymbolicLink(jvlLinkPath, jvlLinkPath.relativize(vLaunchJvlPath));
1857 java.nio.file.Files.createSymbolicLink(jvlLinkPath, java.nio.file.Paths.get(".",vLaunchJvl.getName()));
1859 // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties
1861 from getdownLauncher
1862 from "${getdownWebsiteDir}/${getdownLaunchJvl}"
1863 from "${getdownWebsiteDir}/${getdown_launcher_new}"
1864 from "${getdownWebsiteDir}/${channel_props}"
1865 if (file(getdownLauncher).getName() != getdown_launcher) {
1866 rename(file(getdownLauncher).getName(), getdown_launcher)
1868 into getdownFullArchiveDir
1874 task getdownArchiveDigest(type: JavaExec) {
1875 group = "distribution"
1876 description = "Digest the getdown archive folder"
1878 dependsOn getdownArchiveBuild
1881 classpath = files(getdownLauncher)
1882 args getdownFullArchiveDir
1884 main = "com.threerings.getdown.tools.Digester"
1885 inputs.dir(getdownFullArchiveDir)
1886 outputs.file("${getdownFullArchiveDir}/digest2.txt")
1889 task getdownArchive() {
1890 group = "distribution"
1891 description = "Build the website archive dir with getdown digest"
1893 dependsOn getdownArchiveBuild
1894 dependsOn getdownArchiveDigest
1897 tasks.withType(JavaCompile) {
1898 options.encoding = 'UTF-8'
1904 delete getdownWebsiteDir
1905 delete getdownFilesDir
1906 delete getdownArchiveDir
1912 if (file(install4jHomeDir).exists()) {
1914 } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
1915 install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1916 } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
1917 install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
1919 installDir(file(install4jHomeDir))
1921 mediaTypes = Arrays.asList(install4j_media_types.split(","))
1925 task copyInstall4jTemplate {
1926 def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
1927 def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
1928 inputs.file(install4jTemplateFile)
1929 inputs.file(install4jFileAssociationsFile)
1930 inputs.property("CHANNEL", { CHANNEL })
1931 outputs.file(install4jConfFile)
1934 def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
1936 // turn off code signing if no OSX_KEYPASS
1937 if (OSX_KEYPASS == "") {
1938 install4jConfigXml.'**'.codeSigning.each { codeSigning ->
1939 codeSigning.'@macEnabled' = "false"
1941 install4jConfigXml.'**'.windows.each { windows ->
1942 windows.'@runPostProcessor' = "false"
1946 // disable install screen for OSX dmg (for 2.11.2.0)
1947 install4jConfigXml.'**'.macosArchive.each { macosArchive ->
1948 macosArchive.attributes().remove('executeSetupApp')
1949 macosArchive.attributes().remove('setupAppId')
1952 // turn off checksum creation for LOCAL channel
1953 def e = install4jConfigXml.application[0]
1954 if (CHANNEL == "LOCAL") {
1955 e.'@createChecksums' = "false"
1957 e.'@createChecksums' = "true"
1960 // put file association actions where placeholder action is
1961 def install4jFileAssociationsText = install4jFileAssociationsFile.text
1962 def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
1963 install4jConfigXml.'**'.action.any { a -> // .any{} stops after the first one that returns true
1964 if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
1965 def parent = a.parent()
1967 fileAssociationActions.each { faa ->
1970 // don't need to continue in .any loop once replacements have been made
1975 // use Windows Program Group with Examples folder for RELEASE, and Program Group without Examples for everything else
1976 // NB we're deleting the /other/ one!
1977 // Also remove the examples subdir from non-release versions
1978 def customizedIdToDelete = "PROGRAM_GROUP_RELEASE"
1979 // 2.11.1.0 NOT releasing with the Examples folder in the Program Group
1980 if (false && CHANNEL=="RELEASE") { // remove 'false && ' to include Examples folder in RELEASE channel
1981 customizedIdToDelete = "PROGRAM_GROUP_NON_RELEASE"
1983 // remove the examples subdir from Full File Set
1984 def files = install4jConfigXml.files[0]
1985 def fileset = files.filesets.fileset.find { fs -> fs.'@customizedId' == "FULL_FILE_SET" }
1986 def root = files.roots.root.find { r -> r.'@fileset' == fileset.'@id' }
1987 def mountPoint = files.mountPoints.mountPoint.find { mp -> mp.'@root' == root.'@id' }
1988 def dirEntry = files.entries.dirEntry.find { de -> de.'@mountPoint' == mountPoint.'@id' && de.'@subDirectory' == "examples" }
1989 dirEntry.parent().remove(dirEntry)
1991 install4jConfigXml.'**'.action.any { a ->
1992 if (a.'@customizedId' == customizedIdToDelete) {
1993 def parent = a.parent()
1999 // write install4j file
2000 install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
2007 delete install4jConfFile
2012 task installers(type: com.install4j.gradle.Install4jTask) {
2013 group = "distribution"
2014 description = "Create the install4j installers"
2016 dependsOn copyInstall4jTemplate
2018 projectFile = install4jConfFile
2020 // create an md5 for the input files to use as version for install4j conf file
2021 def digest = MessageDigest.getInstance("MD5")
2023 (file("${install4jDir}/${install4j_template}").text +
2024 file("${install4jDir}/${install4j_info_plist_file_associations}").text +
2025 file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
2026 def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
2027 if (filesMd5.length() >= 8) {
2028 filesMd5 = filesMd5.substring(0,8)
2030 def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
2031 // make install4jBuildDir relative to jalviewDir
2032 def install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
2035 'JALVIEW_NAME': jalview_name,
2036 'JALVIEW_APPLICATION_NAME': install4jApplicationName,
2037 'JALVIEW_DIR': "../..",
2038 'OSX_KEYSTORE': OSX_KEYSTORE,
2039 'OSX_APPLEID': OSX_APPLEID,
2040 'OSX_ALTOOLPASS': OSX_ALTOOLPASS,
2041 'JSIGN_SH': JSIGN_SH,
2042 'JRE_DIR': getdown_app_dir_java,
2043 'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
2044 'JALVIEW_VERSION': JALVIEW_VERSION,
2045 'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
2046 'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
2047 'JAVA_VERSION': JAVA_VERSION,
2048 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
2049 'VERSION': JALVIEW_VERSION,
2050 'MACOS_JAVA_VM_DIR': macosJavaVMDir,
2051 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
2052 'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
2053 'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
2054 'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
2055 'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
2056 'COPYRIGHT_MESSAGE': install4j_copyright_message,
2057 'BUNDLE_ID': install4jBundleId,
2058 'INTERNAL_ID': install4jInternalId,
2059 'WINDOWS_APPLICATION_ID': install4jWinApplicationId,
2060 'MACOS_DMG_DS_STORE': install4jDMGDSStore,
2061 'MACOS_DMG_BG_IMAGE': install4jDMGBackgroundImage,
2062 'WRAPPER_LINK': getdownWrapperLink,
2063 'BASH_WRAPPER_SCRIPT': getdown_bash_wrapper_script,
2064 'POWERSHELL_WRAPPER_SCRIPT': getdown_powershell_wrapper_script,
2065 'WRAPPER_SCRIPT_BIN_DIR': getdown_wrapper_script_dir,
2066 'INSTALLER_NAME': install4jInstallerName,
2067 'INSTALL4J_UTILS_DIR': install4j_utils_dir,
2068 'GETDOWN_WEBSITE_DIR': getdown_website_dir,
2069 'GETDOWN_FILES_DIR': getdown_files_dir,
2070 'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
2071 'GETDOWN_DIST_DIR': getdownAppDistDir,
2072 'GETDOWN_ALT_DIR': getdown_app_dir_alt,
2073 'GETDOWN_INSTALL_DIR': getdown_install_dir,
2074 'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
2075 'BUILD_DIR': install4jBuildDir,
2076 'APPLICATION_CATEGORIES': install4j_application_categories,
2077 'APPLICATION_FOLDER': install4jApplicationFolder,
2078 'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder,
2079 'EXECUTABLE_NAME': install4jExecutableName,
2080 'EXTRA_SCHEME': install4jExtraScheme,
2081 'MAC_ICONS_FILE': install4jMacIconsFile,
2082 'WINDOWS_ICONS_FILE': install4jWindowsIconsFile,
2083 'PNG_ICON_FILE': install4jPngIconFile,
2084 'BACKGROUND': install4jBackground,
2088 //println("INSTALL4J VARIABLES:")
2089 //variables.each{k,v->println("${k}=${v}")}
2091 destination = "${jalviewDir}/${install4jBuildDir}"
2092 buildSelected = true
2094 if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
2096 disableSigning = true
2097 disableNotarization = true
2101 macKeystorePassword = OSX_KEYPASS
2104 if (OSX_ALTOOLPASS) {
2105 appleIdPassword = OSX_ALTOOLPASS
2106 disableNotarization = false
2108 disableNotarization = true
2112 println("Using projectFile "+projectFile)
2113 if (!disableNotarization) { println("Will notarize OSX App DMG") }
2117 inputs.dir(getdownWebsiteDir)
2118 inputs.file(install4jConfFile)
2119 inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
2120 inputs.dir(macosJavaVMDir)
2121 inputs.dir(windowsJavaVMDir)
2122 outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
2128 eclipse().configFile(eclipse_codestyle_file)
2132 task createSourceReleaseProperties(type: WriteProperties) {
2133 group = "distribution"
2134 description = "Create the source RELEASE properties file"
2136 def sourceTarBuildDir = "${buildDir}/sourceTar"
2137 def sourceReleasePropertiesFile = "${sourceTarBuildDir}/RELEASE"
2138 outputFile (sourceReleasePropertiesFile)
2141 releaseProps.each{ key, val -> property key, val }
2142 property "git.branch", gitBranch
2143 property "git.hash", gitHash
2146 outputs.file(outputFile)
2149 task sourceDist(type: Tar) {
2150 group "distribution"
2151 description "Create a source .tar.gz file for distribution"
2153 dependsOn createBuildProperties
2154 dependsOn convertMdFiles
2155 dependsOn eclipseAllPreferences
2156 dependsOn createSourceReleaseProperties
2159 def outputFileName = "${project.name}_${JALVIEW_VERSION_UNDERSCORES}.tar.gz"
2160 archiveFileName = outputFileName
2162 compression Compression.GZIP
2177 "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
2179 "utils/InstallAnywhere",
2194 "gradle.properties",
2206 ".settings/org.eclipse.buildship.core.prefs",
2207 ".settings/org.eclipse.jdt.core.prefs"
2211 exclude (EXCLUDE_FILES)
2212 include (PROCESS_FILES)
2213 filter(ReplaceTokens,
2217 'Version-Rel': JALVIEW_VERSION,
2218 'Year-Rel': getDate("yyyy")
2223 exclude (EXCLUDE_FILES)
2224 exclude (PROCESS_FILES)
2225 exclude ("appletlib")
2226 exclude ("**/*locales")
2227 exclude ("*locales/**")
2228 exclude ("utils/InstallAnywhere")
2230 exclude (getdown_files_dir)
2231 exclude (getdown_website_dir)
2233 // exluding these as not using jars as modules yet
2234 exclude ("${j11modDir}/**/*.jar")
2237 include(INCLUDE_FILES)
2239 // from (jalviewDir) {
2240 // // explicit includes for stuff that seemed to not get included
2241 // include(fileTree("test/**/*."))
2242 // exclude(EXCLUDE_FILES)
2243 // exclude(PROCESS_FILES)
2246 from(file(buildProperties).getParent()) {
2247 include(file(buildProperties).getName())
2248 rename(file(buildProperties).getName(), "build_properties")
2250 line.replaceAll("^INSTALLATION=.*\$","INSTALLATION=Source Release"+" git-commit\\\\:"+gitHash+" ["+gitBranch+"]")
2254 def sourceTarBuildDir = "${buildDir}/sourceTar"
2255 from(sourceTarBuildDir) {
2256 // this includes the appended RELEASE properties file
2263 dependsOn pubhtmlhelp
2265 inputs.dir("${helpBuildDir}/${help_dir}")
2266 outputs.dir("${buildDir}/distributions/${help_dir}")
2270 task j2sSetHeadlessBuild {
2277 task jalviewjsEnableAltFileProperty(type: WriteProperties) {
2279 description "Enable the alternative J2S Config file for headless build"
2281 outputFile = jalviewjsJ2sSettingsFileName
2282 def j2sPropsFile = file(jalviewjsJ2sSettingsFileName)
2283 def j2sProps = new Properties()
2284 if (j2sPropsFile.exists()) {
2286 def j2sPropsFileFIS = new FileInputStream(j2sPropsFile)
2287 j2sProps.load(j2sPropsFileFIS)
2288 j2sPropsFileFIS.close()
2290 j2sProps.each { prop, val ->
2293 } catch (Exception e) {
2294 println("Exception reading ${jalviewjsJ2sSettingsFileName}")
2298 if (! j2sProps.stringPropertyNames().contains(jalviewjs_j2s_alt_file_property_config)) {
2299 property(jalviewjs_j2s_alt_file_property_config, jalviewjs_j2s_alt_file_property)
2304 task jalviewjsSetEclipseWorkspace {
2305 def propKey = "jalviewjs_eclipse_workspace"
2307 if (project.hasProperty(propKey)) {
2308 propVal = project.getProperty(propKey)
2309 if (propVal.startsWith("~/")) {
2310 propVal = System.getProperty("user.home") + propVal.substring(1)
2313 def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
2314 def propsFile = file(propsFileName)
2315 def eclipseWsDir = propVal
2316 def props = new Properties()
2318 def writeProps = true
2319 if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
2320 def ins = new FileInputStream(propsFileName)
2323 if (props.getProperty(propKey, null) != null) {
2324 eclipseWsDir = props.getProperty(propKey)
2329 if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
2330 def tempDir = File.createTempDir()
2331 eclipseWsDir = tempDir.getAbsolutePath()
2334 eclipseWorkspace = file(eclipseWsDir)
2337 // do not run a headless transpile when we claim to be in Eclipse
2339 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2340 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2342 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2346 props.setProperty(propKey, eclipseWsDir)
2347 propsFile.parentFile.mkdirs()
2348 def bytes = new ByteArrayOutputStream()
2349 props.store(bytes, null)
2350 def propertiesString = bytes.toString()
2351 propsFile.text = propertiesString
2357 println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
2360 //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
2361 outputs.file(propsFileName)
2362 outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
2366 task jalviewjsEclipsePaths {
2369 def eclipseRoot = jalviewjs_eclipse_root
2370 if (eclipseRoot.startsWith("~/")) {
2371 eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
2373 if (OperatingSystem.current().isMacOsX()) {
2374 eclipseRoot += "/Eclipse.app"
2375 eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
2376 eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
2377 } else if (OperatingSystem.current().isWindows()) { // check these paths!!
2378 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2379 eclipseRoot += "/eclipse"
2381 eclipseBinary = "${eclipseRoot}/eclipse.exe"
2382 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2383 } else { // linux or unix
2384 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2385 eclipseRoot += "/eclipse"
2386 println("eclipseDir exists")
2388 eclipseBinary = "${eclipseRoot}/eclipse"
2389 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2392 eclipseVersion = "4.13" // default
2393 def assumedVersion = true
2394 if (file(eclipseProduct).exists()) {
2395 def fis = new FileInputStream(eclipseProduct)
2396 def props = new Properties()
2398 eclipseVersion = props.getProperty("version")
2400 assumedVersion = false
2403 def propKey = "eclipse_debug"
2404 eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
2407 // do not run a headless transpile when we claim to be in Eclipse
2409 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2410 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2412 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2415 if (!assumedVersion) {
2416 println("ECLIPSE VERSION=${eclipseVersion}")
2422 task printProperties {
2424 description "Output to console all System.properties"
2426 System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
2432 dependsOn eclipseProject
2433 dependsOn eclipseClasspath
2434 dependsOn eclipseJdt
2438 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
2439 task jalviewjsEclipseCopyDropins(type: Copy) {
2440 dependsOn jalviewjsEclipsePaths
2442 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
2443 inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
2444 def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
2451 // this eclipse -clean doesn't actually work
2452 task jalviewjsCleanEclipse(type: Exec) {
2453 dependsOn eclipseSetup
2454 dependsOn jalviewjsEclipsePaths
2455 dependsOn jalviewjsEclipseCopyDropins
2457 executable(eclipseBinary)
2458 args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
2464 def inputString = """exit
2467 def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
2468 standardInput = inputByteStream
2471 /* not really working yet
2472 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
2476 task jalviewjsTransferUnzipSwingJs {
2477 def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
2481 from zipTree(file_zip)
2482 into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2486 inputs.file file_zip
2487 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2491 task jalviewjsTransferUnzipLib {
2492 def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
2495 zipFiles.each { file_zip ->
2497 from zipTree(file_zip)
2498 into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2503 inputs.files zipFiles
2504 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2508 task jalviewjsTransferUnzipAllLibs {
2509 dependsOn jalviewjsTransferUnzipSwingJs
2510 dependsOn jalviewjsTransferUnzipLib
2514 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
2516 description "Create the alternative j2s file from the j2s.* properties"
2518 jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
2519 def siteDirProperty = "j2s.site.directory"
2520 def setSiteDir = false
2521 jalviewjsJ2sProps.each { prop, val ->
2523 if (prop == siteDirProperty) {
2524 if (!(val.startsWith('/') || val.startsWith("file://") )) {
2525 val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
2531 if (!setSiteDir) { // default site location, don't override specifically set property
2532 property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
2535 outputFile = jalviewjsJ2sAltSettingsFileName
2538 inputs.properties(jalviewjsJ2sProps)
2539 outputs.file(jalviewjsJ2sAltSettingsFileName)
2544 task jalviewjsEclipseSetup {
2545 dependsOn jalviewjsEclipseCopyDropins
2546 dependsOn jalviewjsSetEclipseWorkspace
2547 dependsOn jalviewjsCreateJ2sSettings
2551 task jalviewjsSyncAllLibs (type: Sync) {
2552 dependsOn jalviewjsTransferUnzipAllLibs
2553 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
2554 inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
2555 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2559 def outputFiles = []
2560 rename { filename ->
2561 outputFiles += "${outputDir}/${filename}"
2568 // should this be exclude really ?
2569 duplicatesStrategy "INCLUDE"
2571 outputs.files outputFiles
2572 inputs.files inputFiles
2576 task jalviewjsSyncResources (type: Sync) {
2577 dependsOn buildResources
2579 def inputFiles = fileTree(dir: resourcesBuildDir)
2580 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2584 def outputFiles = []
2585 rename { filename ->
2586 outputFiles += "${outputDir}/${filename}"
2592 outputs.files outputFiles
2593 inputs.files inputFiles
2597 task jalviewjsSyncSiteResources (type: Sync) {
2598 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
2599 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2603 def outputFiles = []
2604 rename { filename ->
2605 outputFiles += "${outputDir}/${filename}"
2611 outputs.files outputFiles
2612 inputs.files inputFiles
2616 task jalviewjsSyncBuildProperties (type: Sync) {
2617 dependsOn createBuildProperties
2618 def inputFiles = [file(buildProperties)]
2619 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2623 def outputFiles = []
2624 rename { filename ->
2625 outputFiles += "${outputDir}/${filename}"
2631 outputs.files outputFiles
2632 inputs.files inputFiles
2636 task jalviewjsProjectImport(type: Exec) {
2637 dependsOn eclipseSetup
2638 dependsOn jalviewjsEclipsePaths
2639 dependsOn jalviewjsEclipseSetup
2642 // do not run a headless import when we claim to be in Eclipse
2644 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2645 throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2647 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2651 //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
2652 def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
2653 executable(eclipseBinary)
2654 args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
2658 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2660 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2661 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
2664 inputs.file("${jalviewDir}/.project")
2665 outputs.upToDateWhen {
2666 file(projdir).exists()
2671 task jalviewjsTranspile(type: Exec) {
2672 dependsOn jalviewjsEclipseSetup
2673 dependsOn jalviewjsProjectImport
2674 dependsOn jalviewjsEclipsePaths
2676 dependsOn jalviewjsEnableAltFileProperty
2680 // do not run a headless transpile when we claim to be in Eclipse
2682 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2683 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2685 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2689 executable(eclipseBinary)
2690 args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
2694 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2696 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2697 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
2703 stdout = new ByteArrayOutputStream()
2704 stderr = new ByteArrayOutputStream()
2706 def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
2707 def logOutFile = file(logOutFileName)
2708 logOutFile.createNewFile()
2709 logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
2710 BINARY: ${eclipseBinary}
2711 VERSION: ${eclipseVersion}
2712 WORKSPACE: ${eclipseWorkspace}
2713 DEBUG: ${eclipseDebug}
2716 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2717 // combine stdout and stderr
2718 def logErrFOS = logOutFOS
2720 if (jalviewjs_j2s_to_console.equals("true")) {
2721 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2722 new org.apache.tools.ant.util.TeeOutputStream(
2726 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2727 new org.apache.tools.ant.util.TeeOutputStream(
2732 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2735 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2742 if (stdout.toString().contains("Error processing ")) {
2743 // j2s did not complete transpile
2744 //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2745 if (jalviewjs_ignore_transpile_errors.equals("true")) {
2746 println("IGNORING TRANSPILE ERRORS")
2747 println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2749 throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2754 inputs.dir("${jalviewDir}/${sourceDir}")
2755 outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
2756 outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
2760 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
2762 def stdout = new ByteArrayOutputStream()
2763 def stderr = new ByteArrayOutputStream()
2765 def coreFile = file(jsfile)
2767 msg = "Creating core for ${name}...\nGenerating ${jsfile}"
2769 logOutFile.createNewFile()
2770 logOutFile.append(msg+"\n")
2772 def coreTop = file(prefixFile)
2773 def coreBottom = file(suffixFile)
2774 coreFile.getParentFile().mkdirs()
2775 coreFile.createNewFile()
2776 coreFile.write( coreTop.getText("UTF-8") )
2780 def t = f.getText("UTF-8")
2781 t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
2782 coreFile.append( t )
2784 msg = "...file '"+f.getPath()+"' does not exist, skipping"
2786 logOutFile.append(msg+"\n")
2789 coreFile.append( coreBottom.getText("UTF-8") )
2791 msg = "Generating ${zjsfile}"
2793 logOutFile.append(msg+"\n")
2794 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2795 def logErrFOS = logOutFOS
2798 classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
2799 main = "com.google.javascript.jscomp.CommandLineRunner"
2800 jvmArgs = [ "-Dfile.encoding=UTF-8" ]
2801 args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
2804 msg = "\nRunning '"+commandLine.join(' ')+"'\n"
2806 logOutFile.append(msg+"\n")
2808 if (logOutConsole) {
2809 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2810 new org.apache.tools.ant.util.TeeOutputStream(
2814 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2815 new org.apache.tools.ant.util.TeeOutputStream(
2820 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2823 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2830 logOutFile.append(msg+"\n")
2834 task jalviewjsBuildAllCores {
2836 description "Build the core js lib closures listed in the classlists dir"
2837 dependsOn jalviewjsTranspile
2838 dependsOn jalviewjsTransferUnzipSwingJs
2840 def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
2841 def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
2842 def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
2843 def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
2844 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
2845 def prefixFile = "${jsDir}/core/coretop2.js"
2846 def suffixFile = "${jsDir}/core/corebottom2.js"
2848 inputs.file prefixFile
2849 inputs.file suffixFile
2851 def classlistFiles = []
2852 // add the classlists found int the jalviewjs_classlists_dir
2853 fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
2855 def name = file.getName() - ".txt"
2862 // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
2863 //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
2864 classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
2866 jalviewjsCoreClasslists = []
2868 classlistFiles.each {
2871 def file = hash['file']
2872 if (! file.exists()) {
2873 //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
2874 return false // this is a "continue" in groovy .each closure
2876 def name = hash['name']
2878 name = file.getName() - ".txt"
2886 def list = fileTree(dir: j2sDir, includes: filelist)
2888 def jsfile = "${outputDir}/core${name}.js"
2889 def zjsfile = "${outputDir}/core${name}.z.js"
2891 jalviewjsCoreClasslists += [
2900 outputs.file(jsfile)
2901 outputs.file(zjsfile)
2904 // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
2905 def stevesoftClasslistName = "_stevesoft"
2906 def stevesoftClasslist = [
2907 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
2908 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
2909 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
2910 'name': stevesoftClasslistName
2912 jalviewjsCoreClasslists += stevesoftClasslist
2913 inputs.files(stevesoftClasslist['list'])
2914 outputs.file(stevesoftClasslist['jsfile'])
2915 outputs.file(stevesoftClasslist['zjsfile'])
2918 def allClasslistName = "_all"
2919 def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
2920 allJsFiles += fileTree(
2924 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2925 "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
2926 "**/org/jmol/export/JSExporter.js"
2929 allJsFiles += fileTree(
2933 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2934 "**/sun/misc/Unsafe.js",
2935 "**/swingjs/jquery/jquery-editable-select.js",
2936 "**/swingjs/jquery/j2sComboBox.js",
2937 "**/sun/misc/FloatingDecimal.js"
2940 def allClasslist = [
2941 'jsfile': "${outputDir}/core${allClasslistName}.js",
2942 'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
2944 'name': allClasslistName
2946 // not including this version of "all" core at the moment
2947 //jalviewjsCoreClasslists += allClasslist
2948 inputs.files(allClasslist['list'])
2949 outputs.file(allClasslist['jsfile'])
2950 outputs.file(allClasslist['zjsfile'])
2953 def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
2954 logOutFile.getParentFile().mkdirs()
2955 logOutFile.createNewFile()
2956 logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
2958 jalviewjsCoreClasslists.each {
2959 jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
2966 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
2969 into file(outputFile).getParentFile()
2970 rename { filename ->
2971 if (filename.equals(inputFile.getName())) {
2972 return file(outputFile).getName()
2976 filter(ReplaceTokens,
2980 'MAIN': '"'+main_class+'"',
2982 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
2983 'COREKEY': jalviewjs_core_key,
2984 'CORENAME': coreName
2991 task jalviewjsPublishCoreTemplates {
2992 dependsOn jalviewjsBuildAllCores
2993 def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
2994 def inputFile = file(inputFileName)
2995 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2997 def outputFiles = []
2998 jalviewjsCoreClasslists.each { cl ->
2999 def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
3000 cl['outputfile'] = outputFile
3001 outputFiles += outputFile
3005 jalviewjsCoreClasslists.each { cl ->
3006 jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
3009 inputs.file(inputFile)
3010 outputs.files(outputFiles)
3014 task jalviewjsSyncCore (type: Sync) {
3015 dependsOn jalviewjsBuildAllCores
3016 dependsOn jalviewjsPublishCoreTemplates
3017 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
3018 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
3022 def outputFiles = []
3023 rename { filename ->
3024 outputFiles += "${outputDir}/${filename}"
3030 outputs.files outputFiles
3031 inputs.files inputFiles
3035 // this Copy version of TransferSiteJs will delete anything else in the target dir
3036 task jalviewjsCopyTransferSiteJs(type: Copy) {
3037 dependsOn jalviewjsTranspile
3038 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
3039 into "${jalviewDir}/${jalviewjsSiteDir}"
3043 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
3044 task jalviewjsSyncTransferSiteJs(type: Sync) {
3045 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
3047 into "${jalviewDir}/${jalviewjsSiteDir}"
3054 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
3055 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
3056 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
3057 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
3059 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
3060 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
3061 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
3062 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
3065 task jalviewjsPrepareSite {
3067 description "Prepares the website folder including unzipping files and copying resources"
3068 dependsOn jalviewjsSyncAllLibs
3069 dependsOn jalviewjsSyncResources
3070 dependsOn jalviewjsSyncSiteResources
3071 dependsOn jalviewjsSyncBuildProperties
3072 dependsOn jalviewjsSyncCore
3076 task jalviewjsBuildSite {
3078 description "Builds the whole website including transpiled code"
3079 dependsOn jalviewjsCopyTransferSiteJs
3080 dependsOn jalviewjsPrepareSite
3084 task cleanJalviewjsTransferSite {
3086 delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
3087 delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
3088 delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
3089 delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
3094 task cleanJalviewjsSite {
3095 dependsOn cleanJalviewjsTransferSite
3097 delete "${jalviewDir}/${jalviewjsSiteDir}"
3102 task jalviewjsSiteTar(type: Tar) {
3104 description "Creates a tar.gz file for the website"
3105 dependsOn jalviewjsBuildSite
3106 def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
3107 archiveFileName = outputFilename
3109 compression Compression.GZIP
3111 from "${jalviewDir}/${jalviewjsSiteDir}"
3112 into jalviewjs_site_dir // this is inside the tar file
3114 inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
3118 task jalviewjsServer {
3120 def filename = "jalviewjsTest.html"
3121 description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
3122 def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
3127 def f = Class.forName("org.gradle.plugins.javascript.envjs.http.simple.SimpleHttpFileServerFactory")
3128 factory = f.newInstance()
3129 } catch (ClassNotFoundException e) {
3130 throw new GradleException("Unable to create SimpleHttpFileServerFactory")
3132 def port = Integer.valueOf(jalviewjs_server_port)
3137 while(port < start+1000 && !running) {
3139 def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
3140 jalviewjsServer = factory.start(doc_root, port)
3142 url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
3143 println("SERVER STARTED with document root ${doc_root}.")
3144 println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).")
3145 println("For debug: "+url+"?j2sdebug")
3146 println("For verbose: "+url+"?j2sverbose")
3147 } catch (Exception e) {
3152 <p><a href="${url}">JalviewJS Test. <${url}></a></p>
3153 <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
3154 <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
3156 jalviewjsCoreClasslists.each { cl ->
3157 def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
3159 <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></a></p>
3161 println("For core ${cl.name}: "+urlcore)
3164 file(htmlFile).text = htmlText
3167 outputs.file(htmlFile)
3168 outputs.upToDateWhen({false})
3172 task cleanJalviewjsAll {
3174 description "Delete all configuration and build artifacts to do with JalviewJS build"
3175 dependsOn cleanJalviewjsSite
3176 dependsOn jalviewjsEclipsePaths
3179 delete "${jalviewDir}/${jalviewjsBuildDir}"
3180 delete "${jalviewDir}/${eclipse_bin_dir}"
3181 if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
3182 delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
3184 delete jalviewjsJ2sAltSettingsFileName
3187 outputs.upToDateWhen( { false } )
3191 task jalviewjsIDE_checkJ2sPlugin {
3192 group "00 JalviewJS in Eclipse"
3193 description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
3196 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3197 def j2sPluginFile = file(j2sPlugin)
3198 def eclipseHome = System.properties["eclipse.home.location"]
3199 if (eclipseHome == null || ! IN_ECLIPSE) {
3200 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
3202 def eclipseJ2sPluginDirs = [ "${eclipseHome}/dropins" ]
3203 def altPluginsDir = System.properties["org.eclipse.equinox.p2.reconciler.dropins.directory"]
3204 if (altPluginsDir != null && file(altPluginsDir).exists()) {
3205 eclipseJ2sPluginDirs += altPluginsDir
3207 def foundPlugin = false
3208 def j2sPluginFileName = j2sPluginFile.getName()
3209 def eclipseJ2sPlugin
3210 def eclipseJ2sPluginFile
3211 eclipseJ2sPluginDirs.any { dir ->
3212 eclipseJ2sPlugin = "${dir}/${j2sPluginFileName}"
3213 eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3214 if (eclipseJ2sPluginFile.exists()) {
3220 def msg = "Eclipse J2S Plugin is not installed (could not find '${j2sPluginFileName}' in\n"+eclipseJ2sPluginDirs.join("\n")+"\n)\nTry running task jalviewjsIDE_copyJ2sPlugin"
3221 System.err.println(msg)
3222 throw new StopExecutionException(msg)
3225 def digest = MessageDigest.getInstance("MD5")
3227 digest.update(j2sPluginFile.text.bytes)
3228 def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3230 digest.update(eclipseJ2sPluginFile.text.bytes)
3231 def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3233 if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
3234 def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
3235 System.err.println(msg)
3236 throw new StopExecutionException(msg)
3238 def msg = "Eclipse J2S Plugin '${eclipseJ2sPlugin}' is the same as '${j2sPlugin}' (this is good)"
3244 task jalviewjsIDE_copyJ2sPlugin {
3245 group "00 JalviewJS in Eclipse"
3246 description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
3249 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3250 def j2sPluginFile = file(j2sPlugin)
3251 def eclipseHome = System.properties["eclipse.home.location"]
3252 if (eclipseHome == null || ! IN_ECLIPSE) {
3253 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
3255 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
3256 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3257 def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
3258 System.err.println(msg)
3261 eclipseJ2sPluginFile.getParentFile().mkdirs()
3262 into eclipseJ2sPluginFile.getParent()
3268 task jalviewjsIDE_j2sFile {
3269 group "00 JalviewJS in Eclipse"
3270 description "Creates the .j2s file"
3271 dependsOn jalviewjsCreateJ2sSettings
3275 task jalviewjsIDE_SyncCore {
3276 group "00 JalviewJS in Eclipse"
3277 description "Build the core js lib closures listed in the classlists dir and publish core html from template"
3278 dependsOn jalviewjsSyncCore
3282 task jalviewjsIDE_SyncSiteAll {
3283 dependsOn jalviewjsSyncAllLibs
3284 dependsOn jalviewjsSyncResources
3285 dependsOn jalviewjsSyncSiteResources
3286 dependsOn jalviewjsSyncBuildProperties
3290 cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
3293 task jalviewjsIDE_PrepareSite {
3294 group "00 JalviewJS in Eclipse"
3295 description "Sync libs and resources to site dir, but not closure cores"
3297 dependsOn jalviewjsIDE_SyncSiteAll
3298 //dependsOn cleanJalviewjsTransferSite // not sure why this clean is here -- will slow down a re-run of this task
3302 task jalviewjsIDE_AssembleSite {
3303 group "00 JalviewJS in Eclipse"
3304 description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
3305 dependsOn jalviewjsPrepareSite
3309 task jalviewjsIDE_SiteClean {
3310 group "00 JalviewJS in Eclipse"
3311 description "Deletes the Eclipse transpiled site"
3312 dependsOn cleanJalviewjsSite
3316 task jalviewjsIDE_Server {
3317 group "00 JalviewJS in Eclipse"
3318 description "Starts a webserver on localhost to test the website"
3319 dependsOn jalviewjsServer
3323 // buildship runs this at import or gradle refresh
3324 task eclipseSynchronizationTask {
3325 //dependsOn eclipseSetup
3326 dependsOn createBuildProperties
3328 dependsOn jalviewjsIDE_j2sFile
3329 dependsOn jalviewjsIDE_checkJ2sPlugin
3330 dependsOn jalviewjsIDE_PrepareSite
3335 // buildship runs this at build time or project refresh
3336 task eclipseAutoBuildTask {
3337 //dependsOn jalviewjsIDE_checkJ2sPlugin
3338 //dependsOn jalviewjsIDE_PrepareSite
3344 description "Build the site"
3345 dependsOn jalviewjsBuildSite