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}")
194 buildProperties = null
196 // the following values might be overridden by the CHANNEL switch
197 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
198 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
199 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
200 getdownAppDistDir = getdown_app_dir_alt
201 getdownImagesDir = string("${jalviewDir}/${getdown_images_dir}")
202 getdownSetAppBaseProperty = false // whether to pass the appbase and appdistdir to the application
203 reportRsyncCommand = false
204 jvlChannelName = CHANNEL.toLowerCase()
205 install4jSuffix = CHANNEL.substring(0, 1).toUpperCase() + CHANNEL.substring(1).toLowerCase(); // BUILD -> Build
206 install4jDMGDSStore = "${install4j_images_dir}/${install4j_dmg_ds_store}"
207 install4jDMGBackgroundImage = "${install4j_images_dir}/${install4j_dmg_background}"
208 install4jInstallerName = "${jalview_name} Non-Release Installer"
209 install4jExecutableName = install4j_executable_name
210 install4jExtraScheme = "jalviewx"
211 install4jMacIconsFile = string("${install4j_images_dir}/${install4j_mac_icons_file}")
212 install4jWindowsIconsFile = string("${install4j_images_dir}/${install4j_windows_icons_file}")
213 install4jPngIconFile = string("${install4j_images_dir}/${install4j_png_icon_file}")
214 install4jBackground = string("${install4j_images_dir}/${install4j_background}")
218 // TODO: get bamboo build artifact URL for getdown artifacts
219 getdown_channel_base = bamboo_channelbase
220 getdownChannelName = string("${bamboo_planKey}/${JAVA_VERSION}")
221 getdownAppBase = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
222 jvlChannelName += "_${getdownChannelName}"
223 // automatically add the test group Not-bamboo for exclusion
224 if ("".equals(testng_excluded_groups)) {
225 testng_excluded_groups = "Not-bamboo"
227 install4jExtraScheme = "jalviewb"
230 case [ "RELEASE", "JALVIEWJS-RELEASE" ]:
231 getdownAppDistDir = getdown_app_dir_release
232 reportRsyncCommand = true
234 install4jInstallerName = "${jalview_name} Installer"
238 getdownChannelName = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
239 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
240 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
241 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
242 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
244 package_dir = string("${ARCHIVEDIR}/${package_dir}")
245 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
248 reportRsyncCommand = true
249 install4jExtraScheme = "jalviewa"
253 getdownChannelName = string("archive/${JALVIEW_VERSION}")
254 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
255 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
256 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
257 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
259 package_dir = string("${ARCHIVEDIR}/${package_dir}")
260 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
263 reportRsyncCommand = true
264 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
265 install4jSuffix = "Archive"
266 install4jExtraScheme = "jalviewa"
270 reportRsyncCommand = true
271 getdownSetAppBaseProperty = true
272 // DEVELOP-RELEASE is usually associated with a Jalview release series so set the version
273 JALVIEW_VERSION=JALVIEW_VERSION+"-d${buildDate}"
275 install4jSuffix = "Develop"
276 install4jExtraScheme = "jalviewd"
277 install4jInstallerName = "${jalview_name} Develop Installer"
281 reportRsyncCommand = true
282 // Don't ignore transpile errors for release build
283 if (jalviewjs_ignore_transpile_errors.equals("true")) {
284 jalviewjs_ignore_transpile_errors = "false"
285 println("Setting jalviewjs_ignore_transpile_errors to 'false'")
287 JALVIEW_VERSION = JALVIEW_VERSION+"-test"
288 install4jSuffix = "Test"
289 install4jExtraScheme = "jalviewt"
290 install4jInstallerName = "${jalview_name} Test Installer"
293 case ~/^SCRATCH(|-[-\w]*)$/:
294 getdownChannelName = CHANNEL
295 JALVIEW_VERSION = JALVIEW_VERSION+"-"+CHANNEL
297 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
298 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
299 reportRsyncCommand = true
300 install4jSuffix = "Scratch"
304 if (!file("${LOCALDIR}").exists()) {
305 throw new GradleException("Must provide a LOCALDIR value to produce a local distribution")
307 getdownAppBase = file(file("${LOCALDIR}").getAbsolutePath()).toURI().toString()
308 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
310 JALVIEW_VERSION = "TEST"
311 install4jSuffix = "Test-Local"
312 install4jExtraScheme = "jalviewt"
313 install4jInstallerName = "${jalview_name} Test Installer"
316 case [ "LOCAL", "JALVIEWJS" ]:
317 JALVIEW_VERSION = "TEST"
318 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
319 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
320 install4jExtraScheme = "jalviewl"
323 default: // something wrong specified
324 throw new GradleException("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
328 // override getdownAppBase if requested
329 if (findProperty("getdown_appbase_override") != null) {
330 // revert to LOCAL if empty string
331 if (string(getdown_appbase_override) == "") {
332 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
333 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
334 } else if (string(getdown_appbase_override).startsWith("file://")) {
335 getdownAppBase = string(getdown_appbase_override)
336 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
338 getdownAppBase = string(getdown_appbase_override)
340 println("Overriding getdown appbase with '${getdownAppBase}'")
342 // sanitise file name for jalview launcher file for this channel
343 jvlChannelName = jvlChannelName.replaceAll("[^\\w\\-]+", "_")
344 // install4j application and folder names
345 if (install4jSuffix == "") {
346 install4jApplicationName = "${jalview_name}"
347 install4jBundleId = "${install4j_bundle_id}"
348 install4jWinApplicationId = install4j_release_win_application_id
350 install4jApplicationName = "${jalview_name} ${install4jSuffix}"
351 install4jBundleId = "${install4j_bundle_id}-" + install4jSuffix.toLowerCase()
352 // add int hash of install4jSuffix to the last part of the application_id
353 def id = install4j_release_win_application_id
354 def idsplitreverse = id.split("-").reverse()
355 idsplitreverse[0] = idsplitreverse[0].toInteger() + install4jSuffix.hashCode()
356 install4jWinApplicationId = idsplitreverse.reverse().join("-")
358 // sanitise folder and id names
359 // install4jApplicationFolder = e.g. "Jalview Build"
360 install4jApplicationFolder = install4jApplicationName
361 .replaceAll("[\"'~:/\\\\\\s]", "_") // replace all awkward filename chars " ' ~ : / \
362 .replaceAll("_+", "_") // collapse __
363 install4jInternalId = install4jApplicationName
365 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
366 .replaceAll("_+", "") // collapse __
367 //.replaceAll("_*-_*", "-") // collapse _-_
368 install4jUnixApplicationFolder = install4jApplicationName
370 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
371 .replaceAll("_+", "_") // collapse __
372 .replaceAll("_*-_*", "-") // collapse _-_
375 getdownWrapperLink = install4jUnixApplicationFolder // e.g. "jalview_local"
376 getdownAppDir = string("${getdownWebsiteDir}/${getdownAppDistDir}")
377 //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}"
378 getdownResourceDir = string("${getdownWebsiteDir}/${getdown_resource_dir}")
379 getdownInstallDir = string("${getdownWebsiteDir}/${getdown_install_dir}")
380 getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
381 getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
382 /* compile without modules -- using classpath libraries
383 modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
384 modules_runtimeClasspath = modules_compileClasspath
390 apply plugin: "com.palantir.git-version"
391 def details = versionDetails()
392 gitHash = details.gitHash
393 gitBranch = details.branchName
394 } catch(org.gradle.api.internal.plugins.PluginApplicationException e) {
395 println("Not in a git repository. Using git values from RELEASE properties file.")
396 gitHash = releaseProps.getProperty("git.hash")
397 gitBranch = releaseProps.getProperty("git.branch")
398 } catch(java.lang.RuntimeException e1) {
399 throw new GradleException("Error with git-version plugin. Directory '.git' exists but versionDetails() cannot be found.")
402 println("Using a ${CHANNEL} profile.")
404 additional_compiler_args = []
405 // configure classpath/args for j8/j11 compilation
406 if (JAVA_VERSION.equals("1.8")) {
407 JAVA_INTEGER_VERSION = string("8")
410 libDistDir = j8libDir
411 compile_source_compatibility = 1.8
412 compile_target_compatibility = 1.8
413 // these are getdown.txt properties defined dependent on the JAVA_VERSION
414 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java8_min_version"))
415 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java8_max_version"))
416 // this property is assigned below and expanded to multiple lines in the getdown task
417 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java8_txt_multi_java_location"))
418 // this property is for the Java library used in eclipse
419 eclipseJavaRuntimeName = string("JavaSE-1.8")
420 } else if (JAVA_VERSION.equals("11")) {
421 JAVA_INTEGER_VERSION = string("11")
423 libDistDir = j11libDir
424 compile_source_compatibility = 11
425 compile_target_compatibility = 11
426 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
427 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
428 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
429 eclipseJavaRuntimeName = string("JavaSE-11")
430 /* compile without modules -- using classpath libraries
431 additional_compiler_args += [
432 '--module-path', modules_compileClasspath.asPath,
433 '--add-modules', j11modules
436 } else if (JAVA_VERSION.equals("17")) {
437 JAVA_INTEGER_VERSION = string("17")
439 libDistDir = j17libDir
440 compile_source_compatibility = 17
441 compile_target_compatibility = 17
442 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
443 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
444 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
445 eclipseJavaRuntimeName = string("JavaSE-17")
446 /* compile without modules -- using classpath libraries
447 additional_compiler_args += [
448 '--module-path', modules_compileClasspath.asPath,
449 '--add-modules', j11modules
453 throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
458 JAVA_MIN_VERSION = JAVA_VERSION
459 JAVA_MAX_VERSION = JAVA_VERSION
460 def jreInstallsDir = string(jre_installs_dir)
461 if (jreInstallsDir.startsWith("~/")) {
462 jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1)
464 macosJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-mac-x64/jre")
465 windowsJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-windows-x64/jre")
466 linuxJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-linux-x64/jre")
467 macosJavaVMTgz = string("${jreInstallsDir}/tgz/jre_${JAVA_INTEGER_VERSION}_mac_x64.tar.gz")
468 windowsJavaVMTgz = string("${jreInstallsDir}/tgz/jre_${JAVA_INTEGER_VERSION}_windows_x64.tar.gz")
469 linuxJavaVMTgz = string("${jreInstallsDir}/tgz/jre_${JAVA_INTEGER_VERSION}_linux_x64.tar.gz")
470 install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
471 install4jConfFileName = string("jalview-install4j-conf.install4j")
472 install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
473 install4jHomeDir = install4j_home_dir
474 if (install4jHomeDir.startsWith("~/")) {
475 install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1)
478 resourceBuildDir = string("${buildDir}/resources")
479 resourcesBuildDir = string("${resourceBuildDir}/resources_build")
480 helpBuildDir = string("${resourceBuildDir}/help_build")
481 docBuildDir = string("${resourceBuildDir}/doc_build")
483 if (buildProperties == null) {
484 buildProperties = string("${resourcesBuildDir}/${build_properties_file}")
486 buildingHTML = string("${jalviewDir}/${doc_dir}/building.html")
487 helpParentDir = string("${jalviewDir}/${help_parent_dir}")
488 helpSourceDir = string("${helpParentDir}/${help_dir}")
489 helpFile = string("${helpBuildDir}/${help_dir}/help.jhm")
492 relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
493 jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
494 jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}")
496 jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
498 jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
500 jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
501 jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
502 jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
503 jalviewjsJalviewCoreHtmlFile = string("")
504 jalviewjsJalviewCoreName = string(jalviewjs_core_name)
505 jalviewjsCoreClasslists = []
506 jalviewjsJalviewTemplateName = string(jalviewjs_name)
507 jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
508 jalviewjsJ2sAltSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_alt_settings}")
509 jalviewjsJ2sProps = null
510 jalviewjsJ2sPlugin = jalviewjs_j2s_plugin
512 eclipseWorkspace = null
513 eclipseBinary = string("")
514 eclipseVersion = string("")
524 outputDir = file(classesDir)
528 srcDirs = [ resourcesBuildDir, docBuildDir, helpBuildDir ]
531 compileClasspath = files(sourceSets.main.java.outputDir)
532 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
534 runtimeClasspath = compileClasspath
535 runtimeClasspath += files(sourceSets.main.resources.srcDirs)
540 srcDirs cloverInstrDir
541 outputDir = cloverClassesDir
545 srcDirs = sourceSets.main.resources.srcDirs
548 compileClasspath = files( sourceSets.clover.java.outputDir )
549 //compileClasspath += files( testClassesDir )
550 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
551 compileClasspath += fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
552 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
554 runtimeClasspath = compileClasspath
559 srcDirs testSourceDir
560 outputDir = file(testClassesDir)
564 srcDirs = useClover ? sourceSets.clover.resources.srcDirs : sourceSets.main.resources.srcDirs
567 compileClasspath = files( sourceSets.test.java.outputDir )
568 compileClasspath += useClover ? sourceSets.clover.compileClasspath : sourceSets.main.compileClasspath
569 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
571 runtimeClasspath = compileClasspath
572 runtimeClasspath += files(sourceSets.test.resources.srcDirs)
578 // eclipse project and settings files creation, also used by buildship
581 name = eclipse_project_name
583 natures 'org.eclipse.jdt.core.javanature',
584 'org.eclipse.jdt.groovy.core.groovyNature',
585 'org.eclipse.buildship.core.gradleprojectnature'
587 buildCommand 'org.eclipse.jdt.core.javabuilder'
588 buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
592 //defaultOutputDir = sourceSets.main.java.outputDir
593 configurations.each{ c->
594 if (c.isCanBeResolved()) {
595 minusConfigurations += [c]
599 plusConfigurations = [ ]
603 def removeTheseToo = []
604 HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
605 cp.entries.each { entry ->
606 // This conditional removes all src classpathentries that a) have already been added or b) aren't "src" or "test".
607 // e.g. this removes the resources dir being copied into bin/main, bin/test AND bin/clover
608 // we add the resources and help/help dirs in as libs afterwards (see below)
609 if (entry.kind == 'src') {
610 if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) {
611 removeTheseToo += entry
613 alreadyAddedSrcPath.putAt(entry.path, true)
618 cp.entries.removeAll(removeTheseToo)
620 //cp.entries += new Output("${eclipse_bin_dir}/main")
621 if (file(helpParentDir).isDirectory()) {
622 cp.entries += new Library(fileReference(helpParentDir))
624 if (file(resourceDir).isDirectory()) {
625 cp.entries += new Library(fileReference(resourceDir))
628 HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
630 sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
631 //don't want to add outputDir as eclipse is using its own output dir in bin/main
632 if (it.isDirectory() || ! it.exists()) {
633 // don't add dirs to classpath, especially if they don't exist
634 return false // groovy "continue" in .any closure
636 def itPath = it.toString()
637 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
638 // make relative path
639 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
641 if (alreadyAddedLibPath.get(itPath)) {
642 //println("Not adding duplicate entry "+itPath)
644 //println("Adding entry "+itPath)
645 cp.entries += new Library(fileReference(itPath))
646 alreadyAddedLibPath.put(itPath, true)
650 sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
651 //no longer want to add outputDir as eclipse is using its own output dir in bin/main
652 if (it.isDirectory() || ! it.exists()) {
653 // don't add dirs to classpath
654 return false // groovy "continue" in .any closure
657 def itPath = it.toString()
658 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
659 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
661 if (alreadyAddedLibPath.get(itPath)) {
664 def lib = new Library(fileReference(itPath))
665 lib.entryAttributes["test"] = "true"
667 alreadyAddedLibPath.put(itPath, true)
675 containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
680 // for the IDE, use java 11 compatibility
681 sourceCompatibility = compile_source_compatibility
682 targetCompatibility = compile_target_compatibility
683 javaRuntimeName = eclipseJavaRuntimeName
685 // add in jalview project specific properties/preferences into eclipse core preferences
687 withProperties { props ->
688 def jalview_prefs = new Properties()
689 def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
690 jalview_prefs.load(ins)
692 jalview_prefs.forEach { t, v ->
693 if (props.getAt(t) == null) {
697 // codestyle file -- overrides previous formatter prefs
698 def csFile = file("${jalviewDirAbsolutePath}/${eclipse_codestyle_file}")
699 if (csFile.exists()) {
700 XmlParser parser = new XmlParser()
701 def profiles = parser.parse(csFile)
702 def profile = profiles.'profile'.find { p -> (p.'@kind' == "CodeFormatterProfile" && p.'@name' == "Jalview") }
703 if (profile != null) {
704 profile.'setting'.each { s ->
706 def value = s.'@value'
707 if (id != null && value != null) {
708 props.putAt(id, value)
719 // Don't want these to be activated if in headless build
720 synchronizationTasks "eclipseSynchronizationTask"
721 //autoBuildTasks "eclipseAutoBuildTask"
727 /* hack to change eclipse prefs in .settings files other than org.eclipse.jdt.core.prefs */
728 // Class to allow updating arbitrary properties files
729 class PropertiesFile extends PropertiesPersistableConfigurationObject {
730 public PropertiesFile(PropertiesTransformer t) { super(t); }
731 @Override protected void load(Properties properties) { }
732 @Override protected void store(Properties properties) { }
733 @Override protected String getDefaultResourceName() { return ""; }
734 // This is necessary, because PropertiesPersistableConfigurationObject fails
735 // if no default properties file exists.
736 @Override public void loadDefaults() { load(new StringBufferInputStream("")); }
739 // Task to update arbitrary properties files (set outputFile)
740 class PropertiesFileTask extends PropertiesGeneratorTask<PropertiesFile> {
741 private final PropertiesFileContentMerger file;
742 public PropertiesFileTask() { file = new PropertiesFileContentMerger(getTransformer()); }
743 protected PropertiesFile create() { return new PropertiesFile(getTransformer()); }
744 protected void configure(PropertiesFile props) {
745 file.getBeforeMerged().execute(props); file.getWhenMerged().execute(props);
747 public void file(Closure closure) { ConfigureUtil.configure(closure, file); }
750 task eclipseUIPreferences(type: PropertiesFileTask) {
751 description = "Generate Eclipse additional settings"
752 def filename = "org.eclipse.jdt.ui.prefs"
753 outputFile = "$projectDir/.settings/${filename}" as File
756 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
761 task eclipseGroovyCorePreferences(type: PropertiesFileTask) {
762 description = "Generate Eclipse additional settings"
763 def filename = "org.eclipse.jdt.groovy.core.prefs"
764 outputFile = "$projectDir/.settings/${filename}" as File
767 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
772 task eclipseAllPreferences {
774 dependsOn eclipseUIPreferences
775 dependsOn eclipseGroovyCorePreferences
778 eclipseUIPreferences.mustRunAfter eclipseJdt
779 eclipseGroovyCorePreferences.mustRunAfter eclipseJdt
781 /* end of eclipse preferences hack */
789 delete cloverBuildDir
790 delete cloverReportDir
795 task cloverInstrJava(type: JavaExec) {
796 group = "Verification"
797 description = "Create clover instrumented source java files"
799 dependsOn cleanClover
801 inputs.files(sourceSets.main.allJava)
802 outputs.dir(cloverInstrDir)
804 //classpath = fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
805 classpath = sourceSets.clover.compileClasspath
806 main = "com.atlassian.clover.CloverInstr"
814 cloverInstrDir.getPath(),
816 def srcFiles = sourceSets.main.allJava.files
819 { file -> file.absolutePath }
822 args argsList.toArray()
825 delete cloverInstrDir
826 println("Clover: About to instrument "+srcFiles.size() +" files")
831 task cloverInstrTests(type: JavaExec) {
832 group = "Verification"
833 description = "Create clover instrumented source test files"
835 dependsOn cleanClover
837 inputs.files(testDir)
838 outputs.dir(cloverTestInstrDir)
840 classpath = sourceSets.clover.compileClasspath
841 main = "com.atlassian.clover.CloverInstr"
851 cloverTestInstrDir.getPath(),
853 args argsList.toArray()
856 delete cloverTestInstrDir
857 println("Clover: About to instrument test files")
863 group = "Verification"
864 description = "Create clover instrumented all source files"
866 dependsOn cloverInstrJava
867 dependsOn cloverInstrTests
871 cloverClasses.dependsOn cloverInstr
874 task cloverConsoleReport(type: JavaExec) {
875 group = "Verification"
876 description = "Creates clover console report"
879 file(cloverDb).exists()
882 inputs.dir cloverClassesDir
884 classpath = sourceSets.clover.runtimeClasspath
885 main = "com.atlassian.clover.reporters.console.ConsoleReporter"
887 if (cloverreport_mem.length() > 0) {
888 maxHeapSize = cloverreport_mem
890 if (cloverreport_jvmargs.length() > 0) {
891 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
901 args argsList.toArray()
905 task cloverHtmlReport(type: JavaExec) {
906 group = "Verification"
907 description = "Creates clover HTML report"
910 file(cloverDb).exists()
913 def cloverHtmlDir = cloverReportDir
914 inputs.dir cloverClassesDir
915 outputs.dir cloverHtmlDir
917 classpath = sourceSets.clover.runtimeClasspath
918 main = "com.atlassian.clover.reporters.html.HtmlReporter"
920 if (cloverreport_mem.length() > 0) {
921 maxHeapSize = cloverreport_mem
923 if (cloverreport_jvmargs.length() > 0) {
924 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
935 if (cloverreport_html_options.length() > 0) {
936 argsList += cloverreport_html_options.split(" ")
939 args argsList.toArray()
943 task cloverXmlReport(type: JavaExec) {
944 group = "Verification"
945 description = "Creates clover XML report"
948 file(cloverDb).exists()
951 def cloverXmlFile = "${cloverReportDir}/clover.xml"
952 inputs.dir cloverClassesDir
953 outputs.file cloverXmlFile
955 classpath = sourceSets.clover.runtimeClasspath
956 main = "com.atlassian.clover.reporters.xml.XMLReporter"
958 if (cloverreport_mem.length() > 0) {
959 maxHeapSize = cloverreport_mem
961 if (cloverreport_jvmargs.length() > 0) {
962 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
973 if (cloverreport_xml_options.length() > 0) {
974 argsList += cloverreport_xml_options.split(" ")
977 args argsList.toArray()
982 group = "Verification"
983 description = "Creates clover reports"
985 dependsOn cloverXmlReport
986 dependsOn cloverHtmlReport
993 sourceCompatibility = compile_source_compatibility
994 targetCompatibility = compile_target_compatibility
995 options.compilerArgs += additional_compiler_args
996 print ("Setting target compatibility to "+targetCompatibility+"\n")
998 //classpath += configurations.cloverRuntime
1004 // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ?
1005 sourceCompatibility = compile_source_compatibility
1006 targetCompatibility = compile_target_compatibility
1007 options.compilerArgs = additional_compiler_args
1008 options.encoding = "UTF-8"
1010 print ("Setting target compatibility to "+compile_target_compatibility+"\n")
1017 sourceCompatibility = compile_source_compatibility
1018 targetCompatibility = compile_target_compatibility
1019 options.compilerArgs = additional_compiler_args
1021 print ("Setting target compatibility to "+targetCompatibility+"\n")
1028 delete sourceSets.main.java.outputDir
1034 dependsOn cleanClover
1036 delete sourceSets.test.java.outputDir
1041 // format is a string like date.format("dd MMMM yyyy")
1042 def getDate(format) {
1043 def date = new Date()
1044 return date.format(format)
1048 def convertMdToHtml (FileTree mdFiles, File cssFile) {
1049 MutableDataSet options = new MutableDataSet()
1051 def extensions = new ArrayList<>()
1052 extensions.add(AnchorLinkExtension.create())
1053 extensions.add(AutolinkExtension.create())
1054 extensions.add(StrikethroughExtension.create())
1055 extensions.add(TaskListExtension.create())
1056 extensions.add(TablesExtension.create())
1057 extensions.add(TocExtension.create())
1059 options.set(Parser.EXTENSIONS, extensions)
1061 // set GFM table parsing options
1062 options.set(TablesExtension.WITH_CAPTION, false)
1063 options.set(TablesExtension.COLUMN_SPANS, false)
1064 options.set(TablesExtension.MIN_HEADER_ROWS, 1)
1065 options.set(TablesExtension.MAX_HEADER_ROWS, 1)
1066 options.set(TablesExtension.APPEND_MISSING_COLUMNS, true)
1067 options.set(TablesExtension.DISCARD_EXTRA_COLUMNS, true)
1068 options.set(TablesExtension.HEADER_SEPARATOR_COLUMN_MATCH, true)
1070 options.set(AnchorLinkExtension.ANCHORLINKS_SET_ID, false)
1071 options.set(AnchorLinkExtension.ANCHORLINKS_ANCHOR_CLASS, "anchor")
1072 options.set(AnchorLinkExtension.ANCHORLINKS_SET_NAME, true)
1073 options.set(AnchorLinkExtension.ANCHORLINKS_TEXT_PREFIX, "<span class=\"octicon octicon-link\"></span>")
1075 Parser parser = Parser.builder(options).build()
1076 HtmlRenderer renderer = HtmlRenderer.builder(options).build()
1078 mdFiles.each { mdFile ->
1079 // add table of contents
1080 def mdText = "[TOC]\n"+mdFile.text
1082 // grab the first top-level title
1084 def titleRegex = /(?m)^#(\s+|([^#]))(.*)/
1085 def matcher = mdText =~ titleRegex
1086 if (matcher.size() > 0) {
1087 // matcher[0][2] is the first character of the title if there wasn't any whitespace after the #
1088 title = (matcher[0][2] != null ? matcher[0][2] : "")+matcher[0][3]
1090 // or use the filename if none found
1091 if (title == null) {
1092 title = mdFile.getName()
1095 Node document = parser.parse(mdText)
1096 String htmlBody = renderer.render(document)
1097 def htmlText = '''<html>
1098 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1099 <html xmlns="http://www.w3.org/1999/xhtml">
1101 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1102 <meta http-equiv="Content-Style-Type" content="text/css" />
1103 <meta name="generator" content="flexmark" />
1105 htmlText += ((title != null) ? " <title>${title}</title>" : '' )
1107 <style type="text/css">code{white-space: pre;}</style>
1109 htmlText += ((cssFile != null) ? cssFile.text : '')
1110 htmlText += '''</head>
1113 htmlText += htmlBody
1119 def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
1120 def htmlFile = file(htmlFilePath)
1121 println("Creating ${htmlFilePath}")
1122 htmlFile.text = htmlText
1127 task copyDocs(type: Copy) {
1128 def inputDir = "${jalviewDir}/${doc_dir}"
1129 def outputDir = "${docBuildDir}/${doc_dir}"
1133 include('**/*.html')
1135 filter(ReplaceTokens,
1139 'Version-Rel': JALVIEW_VERSION,
1140 'Year-Rel': getDate("yyyy")
1147 exclude('**/*.html')
1152 inputs.dir(inputDir)
1153 outputs.dir(outputDir)
1157 task convertMdFiles {
1159 def mdFiles = fileTree(dir: docBuildDir, include: "**/*.md")
1160 def cssFile = file("${jalviewDir}/${flexmark_css}")
1163 convertMdToHtml(mdFiles, cssFile)
1166 inputs.files(mdFiles)
1167 inputs.file(cssFile)
1170 mdFiles.each { mdFile ->
1171 def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
1172 htmlFiles.add(file(htmlFilePath))
1174 outputs.files(htmlFiles)
1178 task copyHelp(type: Copy) {
1179 def inputDir = helpSourceDir
1180 def outputDir = "${helpBuildDir}/${help_dir}"
1184 include('**/*.html')
1188 filter(ReplaceTokens,
1192 'Version-Rel': JALVIEW_VERSION,
1193 'Year-Rel': getDate("yyyy")
1200 exclude('**/*.html')
1207 inputs.dir(inputDir)
1208 outputs.files(helpFile)
1209 outputs.dir(outputDir)
1213 task copyResources(type: Copy) {
1215 description = "Copy (and make text substitutions in) the resources dir to the build area"
1217 def inputDir = resourceDir
1218 def outputDir = resourcesBuildDir
1222 include('**/*.html')
1224 filter(ReplaceTokens,
1228 'Version-Rel': JALVIEW_VERSION,
1229 'Year-Rel': getDate("yyyy")
1236 exclude('**/*.html')
1241 inputs.dir(inputDir)
1242 outputs.dir(outputDir)
1245 task copyChannelResources(type: Copy) {
1246 dependsOn copyResources
1248 description = "Copy the channel resources dir to the build resources area"
1250 def inputDir = "${channelDir}/${resource_dir}"
1251 def outputDir = resourcesBuildDir
1255 inputs.dir(inputDir)
1256 outputs.dir(outputDir)
1259 task createBuildProperties(type: WriteProperties) {
1260 dependsOn copyResources
1262 description = "Create the ${buildProperties} file"
1264 inputs.dir(sourceDir)
1265 inputs.dir(resourcesBuildDir)
1266 outputFile (buildProperties)
1267 // taking time specific comment out to allow better incremental builds
1268 comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
1269 //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
1270 property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
1271 property "VERSION", JALVIEW_VERSION
1272 property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
1273 if (getdownSetAppBaseProperty) {
1274 property "GETDOWNAPPBASE", getdownAppBase
1275 property "GETDOWNAPPDISTDIR", getdownAppDistDir
1277 outputs.file(outputFile)
1281 task buildIndices(type: JavaExec) {
1283 classpath = sourceSets.main.compileClasspath
1284 main = "com.sun.java.help.search.Indexer"
1285 workingDir = "${helpBuildDir}/${help_dir}"
1288 inputs.dir("${workingDir}/${argDir}")
1290 outputs.dir("${classesDir}/doc")
1291 outputs.dir("${classesDir}/help")
1292 outputs.file("${workingDir}/JavaHelpSearch/DOCS")
1293 outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
1294 outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
1295 outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
1296 outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
1297 outputs.file("${workingDir}/JavaHelpSearch/TMAP")
1300 task buildResources {
1301 dependsOn copyResources
1302 dependsOn copyChannelResources
1303 dependsOn createBuildProperties
1307 dependsOn buildResources
1310 dependsOn convertMdFiles
1311 dependsOn buildIndices
1315 compileJava.dependsOn prepare
1316 run.dependsOn compileJava
1317 //run.dependsOn prepare
1320 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
1325 dependsOn cloverClasses
1327 dependsOn compileJava //?
1331 includeGroups testng_groups
1332 excludeGroups testng_excluded_groups
1334 useDefaultListeners=true
1337 maxHeapSize = "1024m"
1339 workingDir = jalviewDir
1340 def testLaf = project.findProperty("test_laf")
1341 if (testLaf != null) {
1342 println("Setting Test LaF to '${testLaf}'")
1343 systemProperty "laf", testLaf
1345 def testHiDPIScale = project.findProperty("test_HiDPIScale")
1346 if (testHiDPIScale != null) {
1347 println("Setting Test HiDPI Scale to '${testHiDPIScale}'")
1348 systemProperty "sun.java2d.uiScale", testHiDPIScale
1350 sourceCompatibility = compile_source_compatibility
1351 targetCompatibility = compile_target_compatibility
1352 jvmArgs += additional_compiler_args
1356 println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
1362 task compileLinkCheck(type: JavaCompile) {
1364 classpath = files("${jalviewDir}/${utils_dir}")
1365 destinationDir = file("${jalviewDir}/${utils_dir}")
1366 source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
1368 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1369 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1370 outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
1371 outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
1375 task linkCheck(type: JavaExec) {
1377 dependsOn compileLinkCheck
1379 def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
1380 classpath = files("${jalviewDir}/${utils_dir}")
1381 main = "HelpLinksChecker"
1382 workingDir = jalviewDir
1383 args = [ "${helpBuildDir}/${help_dir}", "-nointernet" ]
1385 def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
1386 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1389 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1393 inputs.dir(helpBuildDir)
1394 outputs.file(helpLinksCheckerOutFile)
1398 // import the pubhtmlhelp target
1399 ant.properties.basedir = "${jalviewDir}"
1400 ant.properties.helpBuildDir = "${helpBuildDir}/${help_dir}"
1401 ant.importBuild "${utils_dir}/publishHelp.xml"
1404 task cleanPackageDir(type: Delete) {
1406 delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
1416 attributes "Main-Class": main_class,
1417 "Permissions": "all-permissions",
1418 "Application-Name": install4jApplicationName,
1419 "Codebase": application_codebase,
1420 "Implementation-Version": JALVIEW_VERSION
1423 def outputDir = "${jalviewDir}/${package_dir}"
1424 destinationDirectory = file(outputDir)
1425 archiveFileName = rootProject.name+".jar"
1426 duplicatesStrategy "EXCLUDE"
1433 exclude "**/*.jar.*"
1435 inputs.dir(sourceSets.main.java.outputDir)
1436 sourceSets.main.resources.srcDirs.each{ dir ->
1439 outputs.file("${outputDir}/${archiveFileName}")
1443 task copyJars(type: Copy) {
1444 from fileTree(dir: classesDir, include: "**/*.jar").files
1445 into "${jalviewDir}/${package_dir}"
1449 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
1450 task syncJars(type: Sync) {
1452 from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
1453 into "${jalviewDir}/${package_dir}"
1455 include jar.archiveFileName.getOrNull()
1462 description = "Put all required libraries in dist"
1463 // order of "cleanPackageDir", "copyJars", "jar" important!
1464 jar.mustRunAfter cleanPackageDir
1465 syncJars.mustRunAfter cleanPackageDir
1466 dependsOn cleanPackageDir
1469 outputs.dir("${jalviewDir}/${package_dir}")
1474 dependsOn cleanPackageDir
1481 group = "distribution"
1482 description = "Create a single jar file with all dependency libraries merged. Can be run with java -jar"
1486 from ("${jalviewDir}/${libDistDir}") {
1490 attributes "Implementation-Version": JALVIEW_VERSION,
1491 "Application-Name": install4jApplicationName
1494 duplicatesStrategy "INCLUDE"
1496 mainClassName = shadow_jar_main_class
1498 classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
1503 task getdownWebsite() {
1504 group = "distribution"
1505 description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
1510 def getdownWebsiteResourceFilenames = []
1511 def getdownTextString = ""
1512 def getdownResourceDir = getdownResourceDir
1513 def getdownResourceFilenames = []
1516 // clean the getdown website and files dir before creating getdown folders
1517 delete getdownWebsiteDir
1518 delete getdownFilesDir
1521 from buildProperties
1522 rename(file(buildProperties).getName(), getdown_build_properties)
1525 getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
1528 from channelPropsFile
1529 into getdownWebsiteDir
1531 getdownWebsiteResourceFilenames += file(channelPropsFile).getName()
1533 // set some getdown_txt_ properties then go through all properties looking for getdown_txt_...
1534 def props = project.properties.sort { it.key }
1535 if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
1536 props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
1538 if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) {
1539 props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion)
1541 if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
1542 props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
1544 if (getdownImagesDir != null && file(getdownImagesDir).exists()) {
1545 props.put("getdown_txt_ui.background_image", "${getdownImagesDir}/${getdown_background_image}")
1546 props.put("getdown_txt_ui.instant_background_image", "${getdownImagesDir}/${getdown_instant_background_image}")
1547 props.put("getdown_txt_ui.error_background", "${getdownImagesDir}/${getdown_error_background}")
1548 props.put("getdown_txt_ui.progress_image", "${getdownImagesDir}/${getdown_progress_image}")
1549 props.put("getdown_txt_ui.icon", "${getdownImagesDir}/${getdown_icon}")
1550 props.put("getdown_txt_ui.mac_dock_icon", "${getdownImagesDir}/${getdown_mac_dock_icon}")
1553 props.put("getdown_txt_title", jalview_name)
1554 props.put("getdown_txt_ui.name", install4jApplicationName)
1556 // start with appbase
1557 getdownTextString += "appbase = ${getdownAppBase}\n"
1558 props.each{ prop, val ->
1559 if (prop.startsWith("getdown_txt_") && val != null) {
1560 if (prop.startsWith("getdown_txt_multi_")) {
1561 def key = prop.substring(18)
1562 val.split(",").each{ v ->
1563 def line = "${key} = ${v}\n"
1564 getdownTextString += line
1567 // file values rationalised
1568 if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1570 if (val.indexOf('/') == 0) {
1573 } else if (val.indexOf('/') > 0) {
1574 // relative path (relative to jalviewDir)
1575 r = file( "${jalviewDir}/${val}" )
1578 val = "${getdown_resource_dir}/" + r.getName()
1579 getdownWebsiteResourceFilenames += val
1580 getdownResourceFilenames += r.getPath()
1583 if (! prop.startsWith("getdown_txt_resource")) {
1584 def line = prop.substring(12) + " = ${val}\n"
1585 getdownTextString += line
1591 getdownWebsiteResourceFilenames.each{ filename ->
1592 getdownTextString += "resource = ${filename}\n"
1594 getdownResourceFilenames.each{ filename ->
1597 into getdownResourceDir
1601 def getdownWrapperScripts = [ getdown_bash_wrapper_script, getdown_powershell_wrapper_script, getdown_batch_wrapper_script ]
1602 getdownWrapperScripts.each{ script ->
1603 def s = file( "${jalviewDir}/utils/getdown/${getdown_wrapper_script_dir}/${script}" )
1607 into "${getdownWebsiteDir}/${getdown_wrapper_script_dir}"
1609 getdownTextString += "resource = ${getdown_wrapper_script_dir}/${script}\n"
1614 fileTree(file(package_dir)).each{ f ->
1615 if (f.isDirectory()) {
1616 def files = fileTree(dir: f, include: ["*"]).getFiles()
1618 } else if (f.exists()) {
1622 def jalviewJar = jar.archiveFileName.getOrNull()
1623 // put jalview.jar first for CLASSPATH and .properties files reasons
1624 codeFiles.sort{a, b -> ( a.getName() == jalviewJar ? -1 : ( b.getName() == jalviewJar ? 1 : a <=> b ) ) }.each{f ->
1625 def name = f.getName()
1626 def line = "code = ${getdownAppDistDir}/${name}\n"
1627 getdownTextString += line
1634 // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
1636 if (JAVA_VERSION.equals("11")) {
1637 def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
1638 j11libFiles.sort().each{f ->
1639 def name = f.getName()
1640 def line = "code = ${getdown_j11lib_dir}/${name}\n"
1641 getdownTextString += line
1644 into getdownJ11libDir
1650 // 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.
1651 //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
1652 getdownTextString += "resource = ${getdown_launcher_new}\n"
1653 getdownTextString += "class = ${main_class}\n"
1654 // Not setting these properties in general so that getdownappbase and getdowndistdir will default to release version in jalview.bin.Cache
1655 if (getdownSetAppBaseProperty) {
1656 getdownTextString += "jvmarg = -Dgetdowndistdir=${getdownAppDistDir}\n"
1657 getdownTextString += "jvmarg = -Dgetdownappbase=${getdownAppBase}\n"
1660 def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
1661 getdown_txt.write(getdownTextString)
1663 def getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
1664 def launchJvl = file("${getdownWebsiteDir}/${getdownLaunchJvl}")
1665 launchJvl.write("appbase=${getdownAppBase}")
1667 // files going into the getdown website dir: getdown-launcher.jar
1669 from getdownLauncher
1670 rename(file(getdownLauncher).getName(), getdown_launcher_new)
1671 into getdownWebsiteDir
1674 // files going into the getdown website dir: getdown-launcher(-local).jar
1676 from getdownLauncher
1677 if (file(getdownLauncher).getName() != getdown_launcher) {
1678 rename(file(getdownLauncher).getName(), getdown_launcher)
1680 into getdownWebsiteDir
1683 // files going into the getdown website dir: ./install dir and files
1684 if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
1687 from getdownLauncher
1688 from "${getdownAppDir}/${getdown_build_properties}"
1689 if (file(getdownLauncher).getName() != getdown_launcher) {
1690 rename(file(getdownLauncher).getName(), getdown_launcher)
1692 into getdownInstallDir
1695 // and make a copy in the getdown files dir (these are not downloaded by getdown)
1697 from getdownInstallDir
1698 into getdownFilesInstallDir
1702 // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties
1706 from getdownLauncher
1707 from "${getdownWebsiteDir}/${getdown_build_properties}"
1708 from "${getdownWebsiteDir}/${channel_props}"
1709 if (file(getdownLauncher).getName() != getdown_launcher) {
1710 rename(file(getdownLauncher).getName(), getdown_launcher)
1712 into getdownFilesDir
1715 // and ./resources (not all downloaded by getdown)
1717 from getdownResourceDir
1718 into "${getdownFilesDir}/${getdown_resource_dir}"
1723 inputs.dir("${jalviewDir}/${package_dir}")
1725 outputs.dir(getdownWebsiteDir)
1726 outputs.dir(getdownFilesDir)
1730 // a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
1731 task getdownDigestDir(type: JavaExec) {
1733 description "A task to run a getdown Digest on a dir with getdown.txt. Provide a DIGESTDIR property via -PDIGESTDIR=..."
1735 def digestDirPropertyName = "DIGESTDIR"
1737 classpath = files(getdownLauncher)
1738 def digestDir = findProperty(digestDirPropertyName)
1739 if (digestDir == null) {
1740 throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest")
1744 main = "com.threerings.getdown.tools.Digester"
1748 task getdownDigest(type: JavaExec) {
1749 group = "distribution"
1750 description = "Digest the getdown website folder"
1751 dependsOn getdownWebsite
1753 classpath = files(getdownLauncher)
1755 main = "com.threerings.getdown.tools.Digester"
1756 args getdownWebsiteDir
1757 inputs.dir(getdownWebsiteDir)
1758 outputs.file("${getdownWebsiteDir}/digest2.txt")
1763 group = "distribution"
1764 description = "Create the minimal and full getdown app folder for installers and website and create digest file"
1765 dependsOn getdownDigest
1767 if (reportRsyncCommand) {
1768 def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
1769 def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
1770 println "LIKELY RSYNC COMMAND:"
1771 println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
1772 if (RUNRSYNC == "true") {
1774 commandLine "mkdir", "-p", toDir
1777 commandLine "rsync", "-avh", "--delete", fromDir, toDir
1785 tasks.withType(JavaCompile) {
1786 options.encoding = 'UTF-8'
1792 delete getdownWebsiteDir
1793 delete getdownFilesDir
1799 if (file(install4jHomeDir).exists()) {
1801 } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
1802 install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1803 } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
1804 install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
1806 installDir(file(install4jHomeDir))
1808 mediaTypes = Arrays.asList(install4j_media_types.split(","))
1812 task copyInstall4jTemplate {
1813 def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
1814 def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
1815 inputs.file(install4jTemplateFile)
1816 inputs.file(install4jFileAssociationsFile)
1817 inputs.property("CHANNEL", { CHANNEL })
1818 outputs.file(install4jConfFile)
1821 def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
1823 // turn off code signing if no OSX_KEYPASS
1824 if (OSX_KEYPASS == "") {
1825 install4jConfigXml.'**'.codeSigning.each { codeSigning ->
1826 codeSigning.'@macEnabled' = "false"
1828 install4jConfigXml.'**'.windows.each { windows ->
1829 windows.'@runPostProcessor' = "false"
1833 // disable install screen for OSX dmg (for 2.11.2.0)
1834 install4jConfigXml.'**'.macosArchive.each { macosArchive ->
1835 macosArchive.attributes().remove('executeSetupApp')
1836 macosArchive.attributes().remove('setupAppId')
1839 // turn off checksum creation for LOCAL channel
1840 def e = install4jConfigXml.application[0]
1841 if (CHANNEL == "LOCAL") {
1842 e.'@createChecksums' = "false"
1844 e.'@createChecksums' = "true"
1847 // put file association actions where placeholder action is
1848 def install4jFileAssociationsText = install4jFileAssociationsFile.text
1849 def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
1850 install4jConfigXml.'**'.action.any { a -> // .any{} stops after the first one that returns true
1851 if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
1852 def parent = a.parent()
1854 fileAssociationActions.each { faa ->
1857 // don't need to continue in .any loop once replacements have been made
1862 // use Windows Program Group with Examples folder for RELEASE, and Program Group without Examples for everything else
1863 // NB we're deleting the /other/ one!
1864 // Also remove the examples subdir from non-release versions
1865 def customizedIdToDelete = "PROGRAM_GROUP_RELEASE"
1866 // 2.11.1.0 NOT releasing with the Examples folder in the Program Group
1867 if (false && CHANNEL=="RELEASE") { // remove 'false && ' to include Examples folder in RELEASE channel
1868 customizedIdToDelete = "PROGRAM_GROUP_NON_RELEASE"
1870 // remove the examples subdir from Full File Set
1871 def files = install4jConfigXml.files[0]
1872 def fileset = files.filesets.fileset.find { fs -> fs.'@customizedId' == "FULL_FILE_SET" }
1873 def root = files.roots.root.find { r -> r.'@fileset' == fileset.'@id' }
1874 def mountPoint = files.mountPoints.mountPoint.find { mp -> mp.'@root' == root.'@id' }
1875 def dirEntry = files.entries.dirEntry.find { de -> de.'@mountPoint' == mountPoint.'@id' && de.'@subDirectory' == "examples" }
1876 dirEntry.parent().remove(dirEntry)
1878 install4jConfigXml.'**'.action.any { a ->
1879 if (a.'@customizedId' == customizedIdToDelete) {
1880 def parent = a.parent()
1886 // write install4j file
1887 install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
1894 delete install4jConfFile
1899 task installers(type: com.install4j.gradle.Install4jTask) {
1900 group = "distribution"
1901 description = "Create the install4j installers"
1903 dependsOn copyInstall4jTemplate
1905 projectFile = install4jConfFile
1907 // create an md5 for the input files to use as version for install4j conf file
1908 def digest = MessageDigest.getInstance("MD5")
1910 (file("${install4jDir}/${install4j_template}").text +
1911 file("${install4jDir}/${install4j_info_plist_file_associations}").text +
1912 file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
1913 def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
1914 if (filesMd5.length() >= 8) {
1915 filesMd5 = filesMd5.substring(0,8)
1917 def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
1918 // make install4jBuildDir relative to jalviewDir
1919 def install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
1922 'JALVIEW_NAME': jalview_name,
1923 'JALVIEW_APPLICATION_NAME': install4jApplicationName,
1924 'JALVIEW_DIR': "../..",
1925 'OSX_KEYSTORE': OSX_KEYSTORE,
1926 'OSX_APPLEID': OSX_APPLEID,
1927 'OSX_ALTOOLPASS': OSX_ALTOOLPASS,
1928 'JSIGN_SH': JSIGN_SH,
1929 'JRE_DIR': getdown_app_dir_java,
1930 'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
1931 'JALVIEW_VERSION': JALVIEW_VERSION,
1932 'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
1933 'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
1934 'JAVA_VERSION': JAVA_VERSION,
1935 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
1936 'VERSION': JALVIEW_VERSION,
1937 'MACOS_JAVA_VM_DIR': macosJavaVMDir,
1938 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
1939 'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
1940 'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
1941 'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
1942 'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
1943 'COPYRIGHT_MESSAGE': install4j_copyright_message,
1944 'BUNDLE_ID': install4jBundleId,
1945 'INTERNAL_ID': install4jInternalId,
1946 'WINDOWS_APPLICATION_ID': install4jWinApplicationId,
1947 'MACOS_DMG_DS_STORE': install4jDMGDSStore,
1948 'MACOS_DMG_BG_IMAGE': install4jDMGBackgroundImage,
1949 'WRAPPER_LINK': getdownWrapperLink,
1950 'BASH_WRAPPER_SCRIPT': getdown_bash_wrapper_script,
1951 'POWERSHELL_WRAPPER_SCRIPT': getdown_powershell_wrapper_script,
1952 'WRAPPER_SCRIPT_BIN_DIR': getdown_wrapper_script_dir,
1953 'INSTALLER_NAME': install4jInstallerName,
1954 'INSTALL4J_UTILS_DIR': install4j_utils_dir,
1955 'GETDOWN_WEBSITE_DIR': getdown_website_dir,
1956 'GETDOWN_FILES_DIR': getdown_files_dir,
1957 'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
1958 'GETDOWN_DIST_DIR': getdownAppDistDir,
1959 'GETDOWN_ALT_DIR': getdown_app_dir_alt,
1960 'GETDOWN_INSTALL_DIR': getdown_install_dir,
1961 'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
1962 'BUILD_DIR': install4jBuildDir,
1963 'APPLICATION_CATEGORIES': install4j_application_categories,
1964 'APPLICATION_FOLDER': install4jApplicationFolder,
1965 'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder,
1966 'EXECUTABLE_NAME': install4jExecutableName,
1967 'EXTRA_SCHEME': install4jExtraScheme,
1968 'MAC_ICONS_FILE': install4jMacIconsFile,
1969 'WINDOWS_ICONS_FILE': install4jWindowsIconsFile,
1970 'PNG_ICON_FILE': install4jPngIconFile,
1971 'BACKGROUND': install4jBackground,
1975 //println("INSTALL4J VARIABLES:")
1976 //variables.each{k,v->println("${k}=${v}")}
1978 destination = "${jalviewDir}/${install4jBuildDir}"
1979 buildSelected = true
1981 if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
1983 disableSigning = true
1984 disableNotarization = true
1988 macKeystorePassword = OSX_KEYPASS
1991 if (OSX_ALTOOLPASS) {
1992 appleIdPassword = OSX_ALTOOLPASS
1993 disableNotarization = false
1995 disableNotarization = true
1999 println("Using projectFile "+projectFile)
2000 if (!disableNotarization) { println("Will notarize OSX App DMG") }
2004 inputs.dir(getdownWebsiteDir)
2005 inputs.file(install4jConfFile)
2006 inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
2007 inputs.dir(macosJavaVMDir)
2008 inputs.dir(windowsJavaVMDir)
2009 outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
2015 eclipse().configFile(eclipse_codestyle_file)
2019 task createSourceReleaseProperties(type: WriteProperties) {
2020 group = "distribution"
2021 description = "Create the source RELEASE properties file"
2023 def sourceTarBuildDir = "${buildDir}/sourceTar"
2024 def sourceReleasePropertiesFile = "${sourceTarBuildDir}/RELEASE"
2025 outputFile (sourceReleasePropertiesFile)
2028 releaseProps.each{ key, val -> property key, val }
2029 property "git.branch", gitBranch
2030 property "git.hash", gitHash
2033 outputs.file(outputFile)
2036 task sourceDist(type: Tar) {
2037 group "distribution"
2038 description "Create a source .tar.gz file for distribution"
2040 dependsOn createBuildProperties
2041 dependsOn convertMdFiles
2042 dependsOn eclipseAllPreferences
2043 dependsOn createSourceReleaseProperties
2046 def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
2047 def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
2048 archiveFileName = outputFileName
2050 compression Compression.GZIP
2065 "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
2067 "utils/InstallAnywhere",
2082 "gradle.properties",
2094 ".settings/org.eclipse.buildship.core.prefs",
2095 ".settings/org.eclipse.jdt.core.prefs"
2099 exclude (EXCLUDE_FILES)
2100 include (PROCESS_FILES)
2101 filter(ReplaceTokens,
2105 'Version-Rel': JALVIEW_VERSION,
2106 'Year-Rel': getDate("yyyy")
2111 exclude (EXCLUDE_FILES)
2112 exclude (PROCESS_FILES)
2113 exclude ("appletlib")
2114 exclude ("**/*locales")
2115 exclude ("*locales/**")
2116 exclude ("utils/InstallAnywhere")
2118 exclude (getdown_files_dir)
2119 exclude (getdown_website_dir)
2121 // exluding these as not using jars as modules yet
2122 exclude ("${j11modDir}/**/*.jar")
2125 include(INCLUDE_FILES)
2127 // from (jalviewDir) {
2128 // // explicit includes for stuff that seemed to not get included
2129 // include(fileTree("test/**/*."))
2130 // exclude(EXCLUDE_FILES)
2131 // exclude(PROCESS_FILES)
2134 from(file(buildProperties).getParent()) {
2135 include(file(buildProperties).getName())
2136 rename(file(buildProperties).getName(), "build_properties")
2138 line.replaceAll("^INSTALLATION=.*\$","INSTALLATION=Source Release"+" git-commit\\\\:"+gitHash+" ["+gitBranch+"]")
2142 def sourceTarBuildDir = "${buildDir}/sourceTar"
2143 from(sourceTarBuildDir) {
2144 // this includes the appended RELEASE properties file
2151 dependsOn pubhtmlhelp
2153 inputs.dir("${helpBuildDir}/${help_dir}")
2154 outputs.dir("${buildDir}/distributions/${help_dir}")
2158 task j2sSetHeadlessBuild {
2165 task jalviewjsEnableAltFileProperty(type: WriteProperties) {
2167 description "Enable the alternative J2S Config file for headless build"
2169 outputFile = jalviewjsJ2sSettingsFileName
2170 def j2sPropsFile = file(jalviewjsJ2sSettingsFileName)
2171 def j2sProps = new Properties()
2172 if (j2sPropsFile.exists()) {
2174 def j2sPropsFileFIS = new FileInputStream(j2sPropsFile)
2175 j2sProps.load(j2sPropsFileFIS)
2176 j2sPropsFileFIS.close()
2178 j2sProps.each { prop, val ->
2181 } catch (Exception e) {
2182 println("Exception reading ${jalviewjsJ2sSettingsFileName}")
2186 if (! j2sProps.stringPropertyNames().contains(jalviewjs_j2s_alt_file_property_config)) {
2187 property(jalviewjs_j2s_alt_file_property_config, jalviewjs_j2s_alt_file_property)
2192 task jalviewjsSetEclipseWorkspace {
2193 def propKey = "jalviewjs_eclipse_workspace"
2195 if (project.hasProperty(propKey)) {
2196 propVal = project.getProperty(propKey)
2197 if (propVal.startsWith("~/")) {
2198 propVal = System.getProperty("user.home") + propVal.substring(1)
2201 def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
2202 def propsFile = file(propsFileName)
2203 def eclipseWsDir = propVal
2204 def props = new Properties()
2206 def writeProps = true
2207 if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
2208 def ins = new FileInputStream(propsFileName)
2211 if (props.getProperty(propKey, null) != null) {
2212 eclipseWsDir = props.getProperty(propKey)
2217 if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
2218 def tempDir = File.createTempDir()
2219 eclipseWsDir = tempDir.getAbsolutePath()
2222 eclipseWorkspace = file(eclipseWsDir)
2225 // do not run a headless transpile when we claim to be in Eclipse
2227 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2228 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2230 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2234 props.setProperty(propKey, eclipseWsDir)
2235 propsFile.parentFile.mkdirs()
2236 def bytes = new ByteArrayOutputStream()
2237 props.store(bytes, null)
2238 def propertiesString = bytes.toString()
2239 propsFile.text = propertiesString
2245 println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
2248 //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
2249 outputs.file(propsFileName)
2250 outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
2254 task jalviewjsEclipsePaths {
2257 def eclipseRoot = jalviewjs_eclipse_root
2258 if (eclipseRoot.startsWith("~/")) {
2259 eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
2261 if (OperatingSystem.current().isMacOsX()) {
2262 eclipseRoot += "/Eclipse.app"
2263 eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
2264 eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
2265 } else if (OperatingSystem.current().isWindows()) { // check these paths!!
2266 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2267 eclipseRoot += "/eclipse"
2269 eclipseBinary = "${eclipseRoot}/eclipse.exe"
2270 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2271 } else { // linux or unix
2272 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2273 eclipseRoot += "/eclipse"
2274 println("eclipseDir exists")
2276 eclipseBinary = "${eclipseRoot}/eclipse"
2277 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2280 eclipseVersion = "4.13" // default
2281 def assumedVersion = true
2282 if (file(eclipseProduct).exists()) {
2283 def fis = new FileInputStream(eclipseProduct)
2284 def props = new Properties()
2286 eclipseVersion = props.getProperty("version")
2288 assumedVersion = false
2291 def propKey = "eclipse_debug"
2292 eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
2295 // do not run a headless transpile when we claim to be in Eclipse
2297 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2298 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2300 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2303 if (!assumedVersion) {
2304 println("ECLIPSE VERSION=${eclipseVersion}")
2310 task printProperties {
2312 description "Output to console all System.properties"
2314 System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
2320 dependsOn eclipseProject
2321 dependsOn eclipseClasspath
2322 dependsOn eclipseJdt
2326 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
2327 task jalviewjsEclipseCopyDropins(type: Copy) {
2328 dependsOn jalviewjsEclipsePaths
2330 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
2331 inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
2332 def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
2339 // this eclipse -clean doesn't actually work
2340 task jalviewjsCleanEclipse(type: Exec) {
2341 dependsOn eclipseSetup
2342 dependsOn jalviewjsEclipsePaths
2343 dependsOn jalviewjsEclipseCopyDropins
2345 executable(eclipseBinary)
2346 args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
2352 def inputString = """exit
2355 def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
2356 standardInput = inputByteStream
2359 /* not really working yet
2360 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
2364 task jalviewjsTransferUnzipSwingJs {
2365 def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
2369 from zipTree(file_zip)
2370 into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2374 inputs.file file_zip
2375 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2379 task jalviewjsTransferUnzipLib {
2380 def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
2383 zipFiles.each { file_zip ->
2385 from zipTree(file_zip)
2386 into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2391 inputs.files zipFiles
2392 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2396 task jalviewjsTransferUnzipAllLibs {
2397 dependsOn jalviewjsTransferUnzipSwingJs
2398 dependsOn jalviewjsTransferUnzipLib
2402 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
2404 description "Create the alternative j2s file from the j2s.* properties"
2406 jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
2407 def siteDirProperty = "j2s.site.directory"
2408 def setSiteDir = false
2409 jalviewjsJ2sProps.each { prop, val ->
2411 if (prop == siteDirProperty) {
2412 if (!(val.startsWith('/') || val.startsWith("file://") )) {
2413 val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
2419 if (!setSiteDir) { // default site location, don't override specifically set property
2420 property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
2423 outputFile = jalviewjsJ2sAltSettingsFileName
2426 inputs.properties(jalviewjsJ2sProps)
2427 outputs.file(jalviewjsJ2sAltSettingsFileName)
2432 task jalviewjsEclipseSetup {
2433 dependsOn jalviewjsEclipseCopyDropins
2434 dependsOn jalviewjsSetEclipseWorkspace
2435 dependsOn jalviewjsCreateJ2sSettings
2439 task jalviewjsSyncAllLibs (type: Sync) {
2440 dependsOn jalviewjsTransferUnzipAllLibs
2441 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
2442 inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
2443 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2447 def outputFiles = []
2448 rename { filename ->
2449 outputFiles += "${outputDir}/${filename}"
2456 // should this be exclude really ?
2457 duplicatesStrategy "INCLUDE"
2459 outputs.files outputFiles
2460 inputs.files inputFiles
2464 task jalviewjsSyncResources (type: Sync) {
2465 dependsOn buildResources
2467 def inputFiles = fileTree(dir: resourcesBuildDir)
2468 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2472 def outputFiles = []
2473 rename { filename ->
2474 outputFiles += "${outputDir}/${filename}"
2480 outputs.files outputFiles
2481 inputs.files inputFiles
2485 task jalviewjsSyncSiteResources (type: Sync) {
2486 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
2487 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2491 def outputFiles = []
2492 rename { filename ->
2493 outputFiles += "${outputDir}/${filename}"
2499 outputs.files outputFiles
2500 inputs.files inputFiles
2504 task jalviewjsSyncBuildProperties (type: Sync) {
2505 dependsOn createBuildProperties
2506 def inputFiles = [file(buildProperties)]
2507 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2511 def outputFiles = []
2512 rename { filename ->
2513 outputFiles += "${outputDir}/${filename}"
2519 outputs.files outputFiles
2520 inputs.files inputFiles
2524 task jalviewjsProjectImport(type: Exec) {
2525 dependsOn eclipseSetup
2526 dependsOn jalviewjsEclipsePaths
2527 dependsOn jalviewjsEclipseSetup
2530 // do not run a headless import when we claim to be in Eclipse
2532 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2533 throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2535 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2539 //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
2540 def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
2541 executable(eclipseBinary)
2542 args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
2546 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2548 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2549 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
2552 inputs.file("${jalviewDir}/.project")
2553 outputs.upToDateWhen {
2554 file(projdir).exists()
2559 task jalviewjsTranspile(type: Exec) {
2560 dependsOn jalviewjsEclipseSetup
2561 dependsOn jalviewjsProjectImport
2562 dependsOn jalviewjsEclipsePaths
2564 dependsOn jalviewjsEnableAltFileProperty
2568 // do not run a headless transpile when we claim to be in Eclipse
2570 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2571 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2573 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2577 executable(eclipseBinary)
2578 args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
2582 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2584 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2585 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
2591 stdout = new ByteArrayOutputStream()
2592 stderr = new ByteArrayOutputStream()
2594 def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
2595 def logOutFile = file(logOutFileName)
2596 logOutFile.createNewFile()
2597 logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
2598 BINARY: ${eclipseBinary}
2599 VERSION: ${eclipseVersion}
2600 WORKSPACE: ${eclipseWorkspace}
2601 DEBUG: ${eclipseDebug}
2604 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2605 // combine stdout and stderr
2606 def logErrFOS = logOutFOS
2608 if (jalviewjs_j2s_to_console.equals("true")) {
2609 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2610 new org.apache.tools.ant.util.TeeOutputStream(
2614 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2615 new org.apache.tools.ant.util.TeeOutputStream(
2620 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2623 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2630 if (stdout.toString().contains("Error processing ")) {
2631 // j2s did not complete transpile
2632 //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2633 if (jalviewjs_ignore_transpile_errors.equals("true")) {
2634 println("IGNORING TRANSPILE ERRORS")
2635 println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2637 throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2642 inputs.dir("${jalviewDir}/${sourceDir}")
2643 outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
2644 outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
2648 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
2650 def stdout = new ByteArrayOutputStream()
2651 def stderr = new ByteArrayOutputStream()
2653 def coreFile = file(jsfile)
2655 msg = "Creating core for ${name}...\nGenerating ${jsfile}"
2657 logOutFile.createNewFile()
2658 logOutFile.append(msg+"\n")
2660 def coreTop = file(prefixFile)
2661 def coreBottom = file(suffixFile)
2662 coreFile.getParentFile().mkdirs()
2663 coreFile.createNewFile()
2664 coreFile.write( coreTop.getText("UTF-8") )
2668 def t = f.getText("UTF-8")
2669 t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
2670 coreFile.append( t )
2672 msg = "...file '"+f.getPath()+"' does not exist, skipping"
2674 logOutFile.append(msg+"\n")
2677 coreFile.append( coreBottom.getText("UTF-8") )
2679 msg = "Generating ${zjsfile}"
2681 logOutFile.append(msg+"\n")
2682 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2683 def logErrFOS = logOutFOS
2686 classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
2687 main = "com.google.javascript.jscomp.CommandLineRunner"
2688 jvmArgs = [ "-Dfile.encoding=UTF-8" ]
2689 args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
2692 msg = "\nRunning '"+commandLine.join(' ')+"'\n"
2694 logOutFile.append(msg+"\n")
2696 if (logOutConsole) {
2697 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2698 new org.apache.tools.ant.util.TeeOutputStream(
2702 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2703 new org.apache.tools.ant.util.TeeOutputStream(
2708 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2711 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2718 logOutFile.append(msg+"\n")
2722 task jalviewjsBuildAllCores {
2724 description "Build the core js lib closures listed in the classlists dir"
2725 dependsOn jalviewjsTranspile
2726 dependsOn jalviewjsTransferUnzipSwingJs
2728 def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
2729 def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
2730 def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
2731 def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
2732 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
2733 def prefixFile = "${jsDir}/core/coretop2.js"
2734 def suffixFile = "${jsDir}/core/corebottom2.js"
2736 inputs.file prefixFile
2737 inputs.file suffixFile
2739 def classlistFiles = []
2740 // add the classlists found int the jalviewjs_classlists_dir
2741 fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
2743 def name = file.getName() - ".txt"
2750 // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
2751 //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
2752 classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
2754 jalviewjsCoreClasslists = []
2756 classlistFiles.each {
2759 def file = hash['file']
2760 if (! file.exists()) {
2761 //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
2762 return false // this is a "continue" in groovy .each closure
2764 def name = hash['name']
2766 name = file.getName() - ".txt"
2774 def list = fileTree(dir: j2sDir, includes: filelist)
2776 def jsfile = "${outputDir}/core${name}.js"
2777 def zjsfile = "${outputDir}/core${name}.z.js"
2779 jalviewjsCoreClasslists += [
2788 outputs.file(jsfile)
2789 outputs.file(zjsfile)
2792 // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
2793 def stevesoftClasslistName = "_stevesoft"
2794 def stevesoftClasslist = [
2795 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
2796 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
2797 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
2798 'name': stevesoftClasslistName
2800 jalviewjsCoreClasslists += stevesoftClasslist
2801 inputs.files(stevesoftClasslist['list'])
2802 outputs.file(stevesoftClasslist['jsfile'])
2803 outputs.file(stevesoftClasslist['zjsfile'])
2806 def allClasslistName = "_all"
2807 def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
2808 allJsFiles += fileTree(
2812 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2813 "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
2814 "**/org/jmol/export/JSExporter.js"
2817 allJsFiles += fileTree(
2821 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2822 "**/sun/misc/Unsafe.js",
2823 "**/swingjs/jquery/jquery-editable-select.js",
2824 "**/swingjs/jquery/j2sComboBox.js",
2825 "**/sun/misc/FloatingDecimal.js"
2828 def allClasslist = [
2829 'jsfile': "${outputDir}/core${allClasslistName}.js",
2830 'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
2832 'name': allClasslistName
2834 // not including this version of "all" core at the moment
2835 //jalviewjsCoreClasslists += allClasslist
2836 inputs.files(allClasslist['list'])
2837 outputs.file(allClasslist['jsfile'])
2838 outputs.file(allClasslist['zjsfile'])
2841 def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
2842 logOutFile.getParentFile().mkdirs()
2843 logOutFile.createNewFile()
2844 logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
2846 jalviewjsCoreClasslists.each {
2847 jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
2854 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
2857 into file(outputFile).getParentFile()
2858 rename { filename ->
2859 if (filename.equals(inputFile.getName())) {
2860 return file(outputFile).getName()
2864 filter(ReplaceTokens,
2868 'MAIN': '"'+main_class+'"',
2870 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
2871 'COREKEY': jalviewjs_core_key,
2872 'CORENAME': coreName
2879 task jalviewjsPublishCoreTemplates {
2880 dependsOn jalviewjsBuildAllCores
2881 def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
2882 def inputFile = file(inputFileName)
2883 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2885 def outputFiles = []
2886 jalviewjsCoreClasslists.each { cl ->
2887 def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
2888 cl['outputfile'] = outputFile
2889 outputFiles += outputFile
2893 jalviewjsCoreClasslists.each { cl ->
2894 jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
2897 inputs.file(inputFile)
2898 outputs.files(outputFiles)
2902 task jalviewjsSyncCore (type: Sync) {
2903 dependsOn jalviewjsBuildAllCores
2904 dependsOn jalviewjsPublishCoreTemplates
2905 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
2906 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2910 def outputFiles = []
2911 rename { filename ->
2912 outputFiles += "${outputDir}/${filename}"
2918 outputs.files outputFiles
2919 inputs.files inputFiles
2923 // this Copy version of TransferSiteJs will delete anything else in the target dir
2924 task jalviewjsCopyTransferSiteJs(type: Copy) {
2925 dependsOn jalviewjsTranspile
2926 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2927 into "${jalviewDir}/${jalviewjsSiteDir}"
2931 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
2932 task jalviewjsSyncTransferSiteJs(type: Sync) {
2933 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2935 into "${jalviewDir}/${jalviewjsSiteDir}"
2942 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
2943 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
2944 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
2945 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
2947 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
2948 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
2949 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
2950 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
2953 task jalviewjsPrepareSite {
2955 description "Prepares the website folder including unzipping files and copying resources"
2956 dependsOn jalviewjsSyncAllLibs
2957 dependsOn jalviewjsSyncResources
2958 dependsOn jalviewjsSyncSiteResources
2959 dependsOn jalviewjsSyncBuildProperties
2960 dependsOn jalviewjsSyncCore
2964 task jalviewjsBuildSite {
2966 description "Builds the whole website including transpiled code"
2967 dependsOn jalviewjsCopyTransferSiteJs
2968 dependsOn jalviewjsPrepareSite
2972 task cleanJalviewjsTransferSite {
2974 delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2975 delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2976 delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2977 delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2982 task cleanJalviewjsSite {
2983 dependsOn cleanJalviewjsTransferSite
2985 delete "${jalviewDir}/${jalviewjsSiteDir}"
2990 task jalviewjsSiteTar(type: Tar) {
2992 description "Creates a tar.gz file for the website"
2993 dependsOn jalviewjsBuildSite
2994 def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
2995 archiveFileName = outputFilename
2997 compression Compression.GZIP
2999 from "${jalviewDir}/${jalviewjsSiteDir}"
3000 into jalviewjs_site_dir // this is inside the tar file
3002 inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
3006 task jalviewjsServer {
3008 def filename = "jalviewjsTest.html"
3009 description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
3010 def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
3015 def f = Class.forName("org.gradle.plugins.javascript.envjs.http.simple.SimpleHttpFileServerFactory")
3016 factory = f.newInstance()
3017 } catch (ClassNotFoundException e) {
3018 throw new GradleException("Unable to create SimpleHttpFileServerFactory")
3020 def port = Integer.valueOf(jalviewjs_server_port)
3025 while(port < start+1000 && !running) {
3027 def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
3028 jalviewjsServer = factory.start(doc_root, port)
3030 url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
3031 println("SERVER STARTED with document root ${doc_root}.")
3032 println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).")
3033 println("For debug: "+url+"?j2sdebug")
3034 println("For verbose: "+url+"?j2sverbose")
3035 } catch (Exception e) {
3040 <p><a href="${url}">JalviewJS Test. <${url}></a></p>
3041 <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
3042 <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
3044 jalviewjsCoreClasslists.each { cl ->
3045 def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
3047 <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></a></p>
3049 println("For core ${cl.name}: "+urlcore)
3052 file(htmlFile).text = htmlText
3055 outputs.file(htmlFile)
3056 outputs.upToDateWhen({false})
3060 task cleanJalviewjsAll {
3062 description "Delete all configuration and build artifacts to do with JalviewJS build"
3063 dependsOn cleanJalviewjsSite
3064 dependsOn jalviewjsEclipsePaths
3067 delete "${jalviewDir}/${jalviewjsBuildDir}"
3068 delete "${jalviewDir}/${eclipse_bin_dir}"
3069 if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
3070 delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
3072 delete jalviewjsJ2sAltSettingsFileName
3075 outputs.upToDateWhen( { false } )
3079 task jalviewjsIDE_checkJ2sPlugin {
3080 group "00 JalviewJS in Eclipse"
3081 description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
3084 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3085 def j2sPluginFile = file(j2sPlugin)
3086 def eclipseHome = System.properties["eclipse.home.location"]
3087 if (eclipseHome == null || ! IN_ECLIPSE) {
3088 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
3090 def eclipseJ2sPluginDirs = [ "${eclipseHome}/dropins" ]
3091 def altPluginsDir = System.properties["org.eclipse.equinox.p2.reconciler.dropins.directory"]
3092 if (altPluginsDir != null && file(altPluginsDir).exists()) {
3093 eclipseJ2sPluginDirs += altPluginsDir
3095 def foundPlugin = false
3096 def j2sPluginFileName = j2sPluginFile.getName()
3097 def eclipseJ2sPlugin
3098 def eclipseJ2sPluginFile
3099 eclipseJ2sPluginDirs.any { dir ->
3100 eclipseJ2sPlugin = "${dir}/${j2sPluginFileName}"
3101 eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3102 if (eclipseJ2sPluginFile.exists()) {
3108 def msg = "Eclipse J2S Plugin is not installed (could not find '${j2sPluginFileName}' in\n"+eclipseJ2sPluginDirs.join("\n")+"\n)\nTry running task jalviewjsIDE_copyJ2sPlugin"
3109 System.err.println(msg)
3110 throw new StopExecutionException(msg)
3113 def digest = MessageDigest.getInstance("MD5")
3115 digest.update(j2sPluginFile.text.bytes)
3116 def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3118 digest.update(eclipseJ2sPluginFile.text.bytes)
3119 def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3121 if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
3122 def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
3123 System.err.println(msg)
3124 throw new StopExecutionException(msg)
3126 def msg = "Eclipse J2S Plugin '${eclipseJ2sPlugin}' is the same as '${j2sPlugin}' (this is good)"
3132 task jalviewjsIDE_copyJ2sPlugin {
3133 group "00 JalviewJS in Eclipse"
3134 description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
3137 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3138 def j2sPluginFile = file(j2sPlugin)
3139 def eclipseHome = System.properties["eclipse.home.location"]
3140 if (eclipseHome == null || ! IN_ECLIPSE) {
3141 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
3143 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
3144 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3145 def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
3146 System.err.println(msg)
3149 eclipseJ2sPluginFile.getParentFile().mkdirs()
3150 into eclipseJ2sPluginFile.getParent()
3156 task jalviewjsIDE_j2sFile {
3157 group "00 JalviewJS in Eclipse"
3158 description "Creates the .j2s file"
3159 dependsOn jalviewjsCreateJ2sSettings
3163 task jalviewjsIDE_SyncCore {
3164 group "00 JalviewJS in Eclipse"
3165 description "Build the core js lib closures listed in the classlists dir and publish core html from template"
3166 dependsOn jalviewjsSyncCore
3170 task jalviewjsIDE_SyncSiteAll {
3171 dependsOn jalviewjsSyncAllLibs
3172 dependsOn jalviewjsSyncResources
3173 dependsOn jalviewjsSyncSiteResources
3174 dependsOn jalviewjsSyncBuildProperties
3178 cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
3181 task jalviewjsIDE_PrepareSite {
3182 group "00 JalviewJS in Eclipse"
3183 description "Sync libs and resources to site dir, but not closure cores"
3185 dependsOn jalviewjsIDE_SyncSiteAll
3186 //dependsOn cleanJalviewjsTransferSite // not sure why this clean is here -- will slow down a re-run of this task
3190 task jalviewjsIDE_AssembleSite {
3191 group "00 JalviewJS in Eclipse"
3192 description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
3193 dependsOn jalviewjsPrepareSite
3197 task jalviewjsIDE_SiteClean {
3198 group "00 JalviewJS in Eclipse"
3199 description "Deletes the Eclipse transpiled site"
3200 dependsOn cleanJalviewjsSite
3204 task jalviewjsIDE_Server {
3205 group "00 JalviewJS in Eclipse"
3206 description "Starts a webserver on localhost to test the website"
3207 dependsOn jalviewjsServer
3211 // buildship runs this at import or gradle refresh
3212 task eclipseSynchronizationTask {
3213 //dependsOn eclipseSetup
3214 dependsOn createBuildProperties
3216 dependsOn jalviewjsIDE_j2sFile
3217 dependsOn jalviewjsIDE_checkJ2sPlugin
3218 dependsOn jalviewjsIDE_PrepareSite
3223 // buildship runs this at build time or project refresh
3224 task eclipseAutoBuildTask {
3225 //dependsOn jalviewjsIDE_checkJ2sPlugin
3226 //dependsOn jalviewjsIDE_PrepareSite
3232 description "Build the site"
3233 dependsOn jalviewjsBuildSite