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 copyChannelResources
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
1314 processResources.dependsOn prepare
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) {
1363 dependsOn convertMdFiles
1364 dependsOn copyChannelResources
1366 classpath = files("${jalviewDir}/${utils_dir}")
1367 destinationDir = file("${jalviewDir}/${utils_dir}")
1368 source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
1370 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1371 inputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.java")
1372 outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
1373 outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
1377 task linkCheck(type: JavaExec) {
1379 dependsOn compileLinkCheck
1381 def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
1382 classpath = files("${jalviewDir}/${utils_dir}")
1383 main = "HelpLinksChecker"
1384 workingDir = jalviewDir
1385 args = [ "${helpBuildDir}/${help_dir}", "-nointernet" ]
1387 def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
1388 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1391 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1395 inputs.dir(helpBuildDir)
1396 outputs.file(helpLinksCheckerOutFile)
1400 // import the pubhtmlhelp target
1401 ant.properties.basedir = "${jalviewDir}"
1402 ant.properties.helpBuildDir = "${helpBuildDir}/${help_dir}"
1403 ant.importBuild "${utils_dir}/publishHelp.xml"
1406 task cleanPackageDir(type: Delete) {
1408 delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
1418 attributes "Main-Class": main_class,
1419 "Permissions": "all-permissions",
1420 "Application-Name": install4jApplicationName,
1421 "Codebase": application_codebase,
1422 "Implementation-Version": JALVIEW_VERSION
1425 def outputDir = "${jalviewDir}/${package_dir}"
1426 destinationDirectory = file(outputDir)
1427 archiveFileName = rootProject.name+".jar"
1428 duplicatesStrategy "EXCLUDE"
1435 exclude "**/*.jar.*"
1437 inputs.dir(sourceSets.main.java.outputDir)
1438 sourceSets.main.resources.srcDirs.each{ dir ->
1441 outputs.file("${outputDir}/${archiveFileName}")
1445 task copyJars(type: Copy) {
1446 from fileTree(dir: classesDir, include: "**/*.jar").files
1447 into "${jalviewDir}/${package_dir}"
1451 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
1452 task syncJars(type: Sync) {
1454 from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
1455 into "${jalviewDir}/${package_dir}"
1457 include jar.archiveFileName.getOrNull()
1464 description = "Put all required libraries in dist"
1465 // order of "cleanPackageDir", "copyJars", "jar" important!
1466 jar.mustRunAfter cleanPackageDir
1467 syncJars.mustRunAfter cleanPackageDir
1468 dependsOn cleanPackageDir
1471 outputs.dir("${jalviewDir}/${package_dir}")
1476 dependsOn cleanPackageDir
1483 group = "distribution"
1484 description = "Create a single jar file with all dependency libraries merged. Can be run with java -jar"
1488 from ("${jalviewDir}/${libDistDir}") {
1492 attributes "Implementation-Version": JALVIEW_VERSION,
1493 "Application-Name": install4jApplicationName
1496 duplicatesStrategy "INCLUDE"
1498 mainClassName = shadow_jar_main_class
1500 classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
1505 task getdownWebsite() {
1506 group = "distribution"
1507 description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
1512 def getdownWebsiteResourceFilenames = []
1513 def getdownTextString = ""
1514 def getdownResourceDir = getdownResourceDir
1515 def getdownResourceFilenames = []
1518 // clean the getdown website and files dir before creating getdown folders
1519 delete getdownWebsiteDir
1520 delete getdownFilesDir
1523 from buildProperties
1524 rename(file(buildProperties).getName(), getdown_build_properties)
1527 getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
1530 from channelPropsFile
1531 into getdownWebsiteDir
1533 getdownWebsiteResourceFilenames += file(channelPropsFile).getName()
1535 // set some getdown_txt_ properties then go through all properties looking for getdown_txt_...
1536 def props = project.properties.sort { it.key }
1537 if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
1538 props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
1540 if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) {
1541 props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion)
1543 if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
1544 props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
1546 if (getdownImagesDir != null && file(getdownImagesDir).exists()) {
1547 props.put("getdown_txt_ui.background_image", "${getdownImagesDir}/${getdown_background_image}")
1548 props.put("getdown_txt_ui.instant_background_image", "${getdownImagesDir}/${getdown_instant_background_image}")
1549 props.put("getdown_txt_ui.error_background", "${getdownImagesDir}/${getdown_error_background}")
1550 props.put("getdown_txt_ui.progress_image", "${getdownImagesDir}/${getdown_progress_image}")
1551 props.put("getdown_txt_ui.icon", "${getdownImagesDir}/${getdown_icon}")
1552 props.put("getdown_txt_ui.mac_dock_icon", "${getdownImagesDir}/${getdown_mac_dock_icon}")
1555 props.put("getdown_txt_title", jalview_name)
1556 props.put("getdown_txt_ui.name", install4jApplicationName)
1558 // start with appbase
1559 getdownTextString += "appbase = ${getdownAppBase}\n"
1560 props.each{ prop, val ->
1561 if (prop.startsWith("getdown_txt_") && val != null) {
1562 if (prop.startsWith("getdown_txt_multi_")) {
1563 def key = prop.substring(18)
1564 val.split(",").each{ v ->
1565 def line = "${key} = ${v}\n"
1566 getdownTextString += line
1569 // file values rationalised
1570 if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1572 if (val.indexOf('/') == 0) {
1575 } else if (val.indexOf('/') > 0) {
1576 // relative path (relative to jalviewDir)
1577 r = file( "${jalviewDir}/${val}" )
1580 val = "${getdown_resource_dir}/" + r.getName()
1581 getdownWebsiteResourceFilenames += val
1582 getdownResourceFilenames += r.getPath()
1585 if (! prop.startsWith("getdown_txt_resource")) {
1586 def line = prop.substring(12) + " = ${val}\n"
1587 getdownTextString += line
1593 getdownWebsiteResourceFilenames.each{ filename ->
1594 getdownTextString += "resource = ${filename}\n"
1596 getdownResourceFilenames.each{ filename ->
1599 into getdownResourceDir
1603 def getdownWrapperScripts = [ getdown_bash_wrapper_script, getdown_powershell_wrapper_script, getdown_batch_wrapper_script ]
1604 getdownWrapperScripts.each{ script ->
1605 def s = file( "${jalviewDir}/utils/getdown/${getdown_wrapper_script_dir}/${script}" )
1609 into "${getdownWebsiteDir}/${getdown_wrapper_script_dir}"
1611 getdownTextString += "resource = ${getdown_wrapper_script_dir}/${script}\n"
1616 fileTree(file(package_dir)).each{ f ->
1617 if (f.isDirectory()) {
1618 def files = fileTree(dir: f, include: ["*"]).getFiles()
1620 } else if (f.exists()) {
1624 def jalviewJar = jar.archiveFileName.getOrNull()
1625 // put jalview.jar first for CLASSPATH and .properties files reasons
1626 codeFiles.sort{a, b -> ( a.getName() == jalviewJar ? -1 : ( b.getName() == jalviewJar ? 1 : a <=> b ) ) }.each{f ->
1627 def name = f.getName()
1628 def line = "code = ${getdownAppDistDir}/${name}\n"
1629 getdownTextString += line
1636 // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
1638 if (JAVA_VERSION.equals("11")) {
1639 def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
1640 j11libFiles.sort().each{f ->
1641 def name = f.getName()
1642 def line = "code = ${getdown_j11lib_dir}/${name}\n"
1643 getdownTextString += line
1646 into getdownJ11libDir
1652 // 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.
1653 //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
1654 getdownTextString += "resource = ${getdown_launcher_new}\n"
1655 getdownTextString += "class = ${main_class}\n"
1656 // Not setting these properties in general so that getdownappbase and getdowndistdir will default to release version in jalview.bin.Cache
1657 if (getdownSetAppBaseProperty) {
1658 getdownTextString += "jvmarg = -Dgetdowndistdir=${getdownAppDistDir}\n"
1659 getdownTextString += "jvmarg = -Dgetdownappbase=${getdownAppBase}\n"
1662 def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
1663 getdown_txt.write(getdownTextString)
1665 def getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
1666 def launchJvl = file("${getdownWebsiteDir}/${getdownLaunchJvl}")
1667 launchJvl.write("appbase=${getdownAppBase}")
1669 // files going into the getdown website dir: getdown-launcher.jar
1671 from getdownLauncher
1672 rename(file(getdownLauncher).getName(), getdown_launcher_new)
1673 into getdownWebsiteDir
1676 // files going into the getdown website dir: getdown-launcher(-local).jar
1678 from getdownLauncher
1679 if (file(getdownLauncher).getName() != getdown_launcher) {
1680 rename(file(getdownLauncher).getName(), getdown_launcher)
1682 into getdownWebsiteDir
1685 // files going into the getdown website dir: ./install dir and files
1686 if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
1689 from getdownLauncher
1690 from "${getdownAppDir}/${getdown_build_properties}"
1691 if (file(getdownLauncher).getName() != getdown_launcher) {
1692 rename(file(getdownLauncher).getName(), getdown_launcher)
1694 into getdownInstallDir
1697 // and make a copy in the getdown files dir (these are not downloaded by getdown)
1699 from getdownInstallDir
1700 into getdownFilesInstallDir
1704 // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties
1708 from getdownLauncher
1709 from "${getdownWebsiteDir}/${getdown_build_properties}"
1710 from "${getdownWebsiteDir}/${channel_props}"
1711 if (file(getdownLauncher).getName() != getdown_launcher) {
1712 rename(file(getdownLauncher).getName(), getdown_launcher)
1714 into getdownFilesDir
1717 // and ./resources (not all downloaded by getdown)
1719 from getdownResourceDir
1720 into "${getdownFilesDir}/${getdown_resource_dir}"
1725 inputs.dir("${jalviewDir}/${package_dir}")
1727 outputs.dir(getdownWebsiteDir)
1728 outputs.dir(getdownFilesDir)
1732 // a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
1733 task getdownDigestDir(type: JavaExec) {
1735 description "A task to run a getdown Digest on a dir with getdown.txt. Provide a DIGESTDIR property via -PDIGESTDIR=..."
1737 def digestDirPropertyName = "DIGESTDIR"
1739 classpath = files(getdownLauncher)
1740 def digestDir = findProperty(digestDirPropertyName)
1741 if (digestDir == null) {
1742 throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest")
1746 main = "com.threerings.getdown.tools.Digester"
1750 task getdownDigest(type: JavaExec) {
1751 group = "distribution"
1752 description = "Digest the getdown website folder"
1753 dependsOn getdownWebsite
1755 classpath = files(getdownLauncher)
1757 main = "com.threerings.getdown.tools.Digester"
1758 args getdownWebsiteDir
1759 inputs.dir(getdownWebsiteDir)
1760 outputs.file("${getdownWebsiteDir}/digest2.txt")
1765 group = "distribution"
1766 description = "Create the minimal and full getdown app folder for installers and website and create digest file"
1767 dependsOn getdownDigest
1769 if (reportRsyncCommand) {
1770 def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
1771 def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
1772 println "LIKELY RSYNC COMMAND:"
1773 println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
1774 if (RUNRSYNC == "true") {
1776 commandLine "mkdir", "-p", toDir
1779 commandLine "rsync", "-avh", "--delete", fromDir, toDir
1787 tasks.withType(JavaCompile) {
1788 options.encoding = 'UTF-8'
1794 delete getdownWebsiteDir
1795 delete getdownFilesDir
1801 if (file(install4jHomeDir).exists()) {
1803 } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
1804 install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1805 } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
1806 install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
1808 installDir(file(install4jHomeDir))
1810 mediaTypes = Arrays.asList(install4j_media_types.split(","))
1814 task copyInstall4jTemplate {
1815 def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
1816 def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
1817 inputs.file(install4jTemplateFile)
1818 inputs.file(install4jFileAssociationsFile)
1819 inputs.property("CHANNEL", { CHANNEL })
1820 outputs.file(install4jConfFile)
1823 def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
1825 // turn off code signing if no OSX_KEYPASS
1826 if (OSX_KEYPASS == "") {
1827 install4jConfigXml.'**'.codeSigning.each { codeSigning ->
1828 codeSigning.'@macEnabled' = "false"
1830 install4jConfigXml.'**'.windows.each { windows ->
1831 windows.'@runPostProcessor' = "false"
1835 // disable install screen for OSX dmg (for 2.11.2.0)
1836 install4jConfigXml.'**'.macosArchive.each { macosArchive ->
1837 macosArchive.attributes().remove('executeSetupApp')
1838 macosArchive.attributes().remove('setupAppId')
1841 // turn off checksum creation for LOCAL channel
1842 def e = install4jConfigXml.application[0]
1843 if (CHANNEL == "LOCAL") {
1844 e.'@createChecksums' = "false"
1846 e.'@createChecksums' = "true"
1849 // put file association actions where placeholder action is
1850 def install4jFileAssociationsText = install4jFileAssociationsFile.text
1851 def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
1852 install4jConfigXml.'**'.action.any { a -> // .any{} stops after the first one that returns true
1853 if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
1854 def parent = a.parent()
1856 fileAssociationActions.each { faa ->
1859 // don't need to continue in .any loop once replacements have been made
1864 // use Windows Program Group with Examples folder for RELEASE, and Program Group without Examples for everything else
1865 // NB we're deleting the /other/ one!
1866 // Also remove the examples subdir from non-release versions
1867 def customizedIdToDelete = "PROGRAM_GROUP_RELEASE"
1868 // 2.11.1.0 NOT releasing with the Examples folder in the Program Group
1869 if (false && CHANNEL=="RELEASE") { // remove 'false && ' to include Examples folder in RELEASE channel
1870 customizedIdToDelete = "PROGRAM_GROUP_NON_RELEASE"
1872 // remove the examples subdir from Full File Set
1873 def files = install4jConfigXml.files[0]
1874 def fileset = files.filesets.fileset.find { fs -> fs.'@customizedId' == "FULL_FILE_SET" }
1875 def root = files.roots.root.find { r -> r.'@fileset' == fileset.'@id' }
1876 def mountPoint = files.mountPoints.mountPoint.find { mp -> mp.'@root' == root.'@id' }
1877 def dirEntry = files.entries.dirEntry.find { de -> de.'@mountPoint' == mountPoint.'@id' && de.'@subDirectory' == "examples" }
1878 dirEntry.parent().remove(dirEntry)
1880 install4jConfigXml.'**'.action.any { a ->
1881 if (a.'@customizedId' == customizedIdToDelete) {
1882 def parent = a.parent()
1888 // write install4j file
1889 install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
1896 delete install4jConfFile
1901 task installers(type: com.install4j.gradle.Install4jTask) {
1902 group = "distribution"
1903 description = "Create the install4j installers"
1905 dependsOn copyInstall4jTemplate
1907 projectFile = install4jConfFile
1909 // create an md5 for the input files to use as version for install4j conf file
1910 def digest = MessageDigest.getInstance("MD5")
1912 (file("${install4jDir}/${install4j_template}").text +
1913 file("${install4jDir}/${install4j_info_plist_file_associations}").text +
1914 file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
1915 def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
1916 if (filesMd5.length() >= 8) {
1917 filesMd5 = filesMd5.substring(0,8)
1919 def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
1920 // make install4jBuildDir relative to jalviewDir
1921 def install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
1924 'JALVIEW_NAME': jalview_name,
1925 'JALVIEW_APPLICATION_NAME': install4jApplicationName,
1926 'JALVIEW_DIR': "../..",
1927 'OSX_KEYSTORE': OSX_KEYSTORE,
1928 'OSX_APPLEID': OSX_APPLEID,
1929 'OSX_ALTOOLPASS': OSX_ALTOOLPASS,
1930 'JSIGN_SH': JSIGN_SH,
1931 'JRE_DIR': getdown_app_dir_java,
1932 'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
1933 'JALVIEW_VERSION': JALVIEW_VERSION,
1934 'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
1935 'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
1936 'JAVA_VERSION': JAVA_VERSION,
1937 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
1938 'VERSION': JALVIEW_VERSION,
1939 'MACOS_JAVA_VM_DIR': macosJavaVMDir,
1940 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
1941 'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
1942 'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
1943 'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
1944 'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
1945 'COPYRIGHT_MESSAGE': install4j_copyright_message,
1946 'BUNDLE_ID': install4jBundleId,
1947 'INTERNAL_ID': install4jInternalId,
1948 'WINDOWS_APPLICATION_ID': install4jWinApplicationId,
1949 'MACOS_DMG_DS_STORE': install4jDMGDSStore,
1950 'MACOS_DMG_BG_IMAGE': install4jDMGBackgroundImage,
1951 'WRAPPER_LINK': getdownWrapperLink,
1952 'BASH_WRAPPER_SCRIPT': getdown_bash_wrapper_script,
1953 'POWERSHELL_WRAPPER_SCRIPT': getdown_powershell_wrapper_script,
1954 'WRAPPER_SCRIPT_BIN_DIR': getdown_wrapper_script_dir,
1955 'INSTALLER_NAME': install4jInstallerName,
1956 'INSTALL4J_UTILS_DIR': install4j_utils_dir,
1957 'GETDOWN_WEBSITE_DIR': getdown_website_dir,
1958 'GETDOWN_FILES_DIR': getdown_files_dir,
1959 'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
1960 'GETDOWN_DIST_DIR': getdownAppDistDir,
1961 'GETDOWN_ALT_DIR': getdown_app_dir_alt,
1962 'GETDOWN_INSTALL_DIR': getdown_install_dir,
1963 'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
1964 'BUILD_DIR': install4jBuildDir,
1965 'APPLICATION_CATEGORIES': install4j_application_categories,
1966 'APPLICATION_FOLDER': install4jApplicationFolder,
1967 'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder,
1968 'EXECUTABLE_NAME': install4jExecutableName,
1969 'EXTRA_SCHEME': install4jExtraScheme,
1970 'MAC_ICONS_FILE': install4jMacIconsFile,
1971 'WINDOWS_ICONS_FILE': install4jWindowsIconsFile,
1972 'PNG_ICON_FILE': install4jPngIconFile,
1973 'BACKGROUND': install4jBackground,
1977 //println("INSTALL4J VARIABLES:")
1978 //variables.each{k,v->println("${k}=${v}")}
1980 destination = "${jalviewDir}/${install4jBuildDir}"
1981 buildSelected = true
1983 if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
1985 disableSigning = true
1986 disableNotarization = true
1990 macKeystorePassword = OSX_KEYPASS
1993 if (OSX_ALTOOLPASS) {
1994 appleIdPassword = OSX_ALTOOLPASS
1995 disableNotarization = false
1997 disableNotarization = true
2001 println("Using projectFile "+projectFile)
2002 if (!disableNotarization) { println("Will notarize OSX App DMG") }
2006 inputs.dir(getdownWebsiteDir)
2007 inputs.file(install4jConfFile)
2008 inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
2009 inputs.dir(macosJavaVMDir)
2010 inputs.dir(windowsJavaVMDir)
2011 outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
2017 eclipse().configFile(eclipse_codestyle_file)
2021 task createSourceReleaseProperties(type: WriteProperties) {
2022 group = "distribution"
2023 description = "Create the source RELEASE properties file"
2025 def sourceTarBuildDir = "${buildDir}/sourceTar"
2026 def sourceReleasePropertiesFile = "${sourceTarBuildDir}/RELEASE"
2027 outputFile (sourceReleasePropertiesFile)
2030 releaseProps.each{ key, val -> property key, val }
2031 property "git.branch", gitBranch
2032 property "git.hash", gitHash
2035 outputs.file(outputFile)
2038 task sourceDist(type: Tar) {
2039 group "distribution"
2040 description "Create a source .tar.gz file for distribution"
2042 dependsOn createBuildProperties
2043 dependsOn convertMdFiles
2044 dependsOn eclipseAllPreferences
2045 dependsOn createSourceReleaseProperties
2048 def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
2049 def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
2050 archiveFileName = outputFileName
2052 compression Compression.GZIP
2067 "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
2069 "utils/InstallAnywhere",
2084 "gradle.properties",
2096 ".settings/org.eclipse.buildship.core.prefs",
2097 ".settings/org.eclipse.jdt.core.prefs"
2101 exclude (EXCLUDE_FILES)
2102 include (PROCESS_FILES)
2103 filter(ReplaceTokens,
2107 'Version-Rel': JALVIEW_VERSION,
2108 'Year-Rel': getDate("yyyy")
2113 exclude (EXCLUDE_FILES)
2114 exclude (PROCESS_FILES)
2115 exclude ("appletlib")
2116 exclude ("**/*locales")
2117 exclude ("*locales/**")
2118 exclude ("utils/InstallAnywhere")
2120 exclude (getdown_files_dir)
2121 exclude (getdown_website_dir)
2123 // exluding these as not using jars as modules yet
2124 exclude ("${j11modDir}/**/*.jar")
2127 include(INCLUDE_FILES)
2129 // from (jalviewDir) {
2130 // // explicit includes for stuff that seemed to not get included
2131 // include(fileTree("test/**/*."))
2132 // exclude(EXCLUDE_FILES)
2133 // exclude(PROCESS_FILES)
2136 from(file(buildProperties).getParent()) {
2137 include(file(buildProperties).getName())
2138 rename(file(buildProperties).getName(), "build_properties")
2140 line.replaceAll("^INSTALLATION=.*\$","INSTALLATION=Source Release"+" git-commit\\\\:"+gitHash+" ["+gitBranch+"]")
2144 def sourceTarBuildDir = "${buildDir}/sourceTar"
2145 from(sourceTarBuildDir) {
2146 // this includes the appended RELEASE properties file
2153 dependsOn pubhtmlhelp
2155 inputs.dir("${helpBuildDir}/${help_dir}")
2156 outputs.dir("${buildDir}/distributions/${help_dir}")
2160 task j2sSetHeadlessBuild {
2167 task jalviewjsEnableAltFileProperty(type: WriteProperties) {
2169 description "Enable the alternative J2S Config file for headless build"
2171 outputFile = jalviewjsJ2sSettingsFileName
2172 def j2sPropsFile = file(jalviewjsJ2sSettingsFileName)
2173 def j2sProps = new Properties()
2174 if (j2sPropsFile.exists()) {
2176 def j2sPropsFileFIS = new FileInputStream(j2sPropsFile)
2177 j2sProps.load(j2sPropsFileFIS)
2178 j2sPropsFileFIS.close()
2180 j2sProps.each { prop, val ->
2183 } catch (Exception e) {
2184 println("Exception reading ${jalviewjsJ2sSettingsFileName}")
2188 if (! j2sProps.stringPropertyNames().contains(jalviewjs_j2s_alt_file_property_config)) {
2189 property(jalviewjs_j2s_alt_file_property_config, jalviewjs_j2s_alt_file_property)
2194 task jalviewjsSetEclipseWorkspace {
2195 def propKey = "jalviewjs_eclipse_workspace"
2197 if (project.hasProperty(propKey)) {
2198 propVal = project.getProperty(propKey)
2199 if (propVal.startsWith("~/")) {
2200 propVal = System.getProperty("user.home") + propVal.substring(1)
2203 def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
2204 def propsFile = file(propsFileName)
2205 def eclipseWsDir = propVal
2206 def props = new Properties()
2208 def writeProps = true
2209 if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
2210 def ins = new FileInputStream(propsFileName)
2213 if (props.getProperty(propKey, null) != null) {
2214 eclipseWsDir = props.getProperty(propKey)
2219 if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
2220 def tempDir = File.createTempDir()
2221 eclipseWsDir = tempDir.getAbsolutePath()
2224 eclipseWorkspace = file(eclipseWsDir)
2227 // do not run a headless transpile when we claim to be in Eclipse
2229 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2230 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2232 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2236 props.setProperty(propKey, eclipseWsDir)
2237 propsFile.parentFile.mkdirs()
2238 def bytes = new ByteArrayOutputStream()
2239 props.store(bytes, null)
2240 def propertiesString = bytes.toString()
2241 propsFile.text = propertiesString
2247 println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
2250 //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
2251 outputs.file(propsFileName)
2252 outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
2256 task jalviewjsEclipsePaths {
2259 def eclipseRoot = jalviewjs_eclipse_root
2260 if (eclipseRoot.startsWith("~/")) {
2261 eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
2263 if (OperatingSystem.current().isMacOsX()) {
2264 eclipseRoot += "/Eclipse.app"
2265 eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
2266 eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
2267 } else if (OperatingSystem.current().isWindows()) { // check these paths!!
2268 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2269 eclipseRoot += "/eclipse"
2271 eclipseBinary = "${eclipseRoot}/eclipse.exe"
2272 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2273 } else { // linux or unix
2274 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2275 eclipseRoot += "/eclipse"
2276 println("eclipseDir exists")
2278 eclipseBinary = "${eclipseRoot}/eclipse"
2279 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2282 eclipseVersion = "4.13" // default
2283 def assumedVersion = true
2284 if (file(eclipseProduct).exists()) {
2285 def fis = new FileInputStream(eclipseProduct)
2286 def props = new Properties()
2288 eclipseVersion = props.getProperty("version")
2290 assumedVersion = false
2293 def propKey = "eclipse_debug"
2294 eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
2297 // do not run a headless transpile when we claim to be in Eclipse
2299 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2300 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2302 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2305 if (!assumedVersion) {
2306 println("ECLIPSE VERSION=${eclipseVersion}")
2312 task printProperties {
2314 description "Output to console all System.properties"
2316 System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
2322 dependsOn eclipseProject
2323 dependsOn eclipseClasspath
2324 dependsOn eclipseJdt
2328 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
2329 task jalviewjsEclipseCopyDropins(type: Copy) {
2330 dependsOn jalviewjsEclipsePaths
2332 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
2333 inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
2334 def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
2341 // this eclipse -clean doesn't actually work
2342 task jalviewjsCleanEclipse(type: Exec) {
2343 dependsOn eclipseSetup
2344 dependsOn jalviewjsEclipsePaths
2345 dependsOn jalviewjsEclipseCopyDropins
2347 executable(eclipseBinary)
2348 args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
2354 def inputString = """exit
2357 def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
2358 standardInput = inputByteStream
2361 /* not really working yet
2362 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
2366 task jalviewjsTransferUnzipSwingJs {
2367 def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
2371 from zipTree(file_zip)
2372 into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2376 inputs.file file_zip
2377 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2381 task jalviewjsTransferUnzipLib {
2382 def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
2385 zipFiles.each { file_zip ->
2387 from zipTree(file_zip)
2388 into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2393 inputs.files zipFiles
2394 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2398 task jalviewjsTransferUnzipAllLibs {
2399 dependsOn jalviewjsTransferUnzipSwingJs
2400 dependsOn jalviewjsTransferUnzipLib
2404 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
2406 description "Create the alternative j2s file from the j2s.* properties"
2408 jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
2409 def siteDirProperty = "j2s.site.directory"
2410 def setSiteDir = false
2411 jalviewjsJ2sProps.each { prop, val ->
2413 if (prop == siteDirProperty) {
2414 if (!(val.startsWith('/') || val.startsWith("file://") )) {
2415 val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
2421 if (!setSiteDir) { // default site location, don't override specifically set property
2422 property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
2425 outputFile = jalviewjsJ2sAltSettingsFileName
2428 inputs.properties(jalviewjsJ2sProps)
2429 outputs.file(jalviewjsJ2sAltSettingsFileName)
2434 task jalviewjsEclipseSetup {
2435 dependsOn jalviewjsEclipseCopyDropins
2436 dependsOn jalviewjsSetEclipseWorkspace
2437 dependsOn jalviewjsCreateJ2sSettings
2441 task jalviewjsSyncAllLibs (type: Sync) {
2442 dependsOn jalviewjsTransferUnzipAllLibs
2443 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
2444 inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
2445 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2449 def outputFiles = []
2450 rename { filename ->
2451 outputFiles += "${outputDir}/${filename}"
2458 // should this be exclude really ?
2459 duplicatesStrategy "INCLUDE"
2461 outputs.files outputFiles
2462 inputs.files inputFiles
2466 task jalviewjsSyncResources (type: Sync) {
2467 dependsOn buildResources
2469 def inputFiles = fileTree(dir: resourcesBuildDir)
2470 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2474 def outputFiles = []
2475 rename { filename ->
2476 outputFiles += "${outputDir}/${filename}"
2482 outputs.files outputFiles
2483 inputs.files inputFiles
2487 task jalviewjsSyncSiteResources (type: Sync) {
2488 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
2489 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2493 def outputFiles = []
2494 rename { filename ->
2495 outputFiles += "${outputDir}/${filename}"
2501 outputs.files outputFiles
2502 inputs.files inputFiles
2506 task jalviewjsSyncBuildProperties (type: Sync) {
2507 dependsOn createBuildProperties
2508 def inputFiles = [file(buildProperties)]
2509 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2513 def outputFiles = []
2514 rename { filename ->
2515 outputFiles += "${outputDir}/${filename}"
2521 outputs.files outputFiles
2522 inputs.files inputFiles
2526 task jalviewjsProjectImport(type: Exec) {
2527 dependsOn eclipseSetup
2528 dependsOn jalviewjsEclipsePaths
2529 dependsOn jalviewjsEclipseSetup
2532 // do not run a headless import when we claim to be in Eclipse
2534 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2535 throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2537 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2541 //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
2542 def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
2543 executable(eclipseBinary)
2544 args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
2548 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2550 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2551 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
2554 inputs.file("${jalviewDir}/.project")
2555 outputs.upToDateWhen {
2556 file(projdir).exists()
2561 task jalviewjsTranspile(type: Exec) {
2562 dependsOn jalviewjsEclipseSetup
2563 dependsOn jalviewjsProjectImport
2564 dependsOn jalviewjsEclipsePaths
2566 dependsOn jalviewjsEnableAltFileProperty
2570 // do not run a headless transpile when we claim to be in Eclipse
2572 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2573 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2575 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2579 executable(eclipseBinary)
2580 args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
2584 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2586 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2587 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
2593 stdout = new ByteArrayOutputStream()
2594 stderr = new ByteArrayOutputStream()
2596 def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
2597 def logOutFile = file(logOutFileName)
2598 logOutFile.createNewFile()
2599 logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
2600 BINARY: ${eclipseBinary}
2601 VERSION: ${eclipseVersion}
2602 WORKSPACE: ${eclipseWorkspace}
2603 DEBUG: ${eclipseDebug}
2606 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2607 // combine stdout and stderr
2608 def logErrFOS = logOutFOS
2610 if (jalviewjs_j2s_to_console.equals("true")) {
2611 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2612 new org.apache.tools.ant.util.TeeOutputStream(
2616 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2617 new org.apache.tools.ant.util.TeeOutputStream(
2622 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2625 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2632 if (stdout.toString().contains("Error processing ")) {
2633 // j2s did not complete transpile
2634 //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2635 if (jalviewjs_ignore_transpile_errors.equals("true")) {
2636 println("IGNORING TRANSPILE ERRORS")
2637 println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2639 throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2644 inputs.dir("${jalviewDir}/${sourceDir}")
2645 outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
2646 outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
2650 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
2652 def stdout = new ByteArrayOutputStream()
2653 def stderr = new ByteArrayOutputStream()
2655 def coreFile = file(jsfile)
2657 msg = "Creating core for ${name}...\nGenerating ${jsfile}"
2659 logOutFile.createNewFile()
2660 logOutFile.append(msg+"\n")
2662 def coreTop = file(prefixFile)
2663 def coreBottom = file(suffixFile)
2664 coreFile.getParentFile().mkdirs()
2665 coreFile.createNewFile()
2666 coreFile.write( coreTop.getText("UTF-8") )
2670 def t = f.getText("UTF-8")
2671 t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
2672 coreFile.append( t )
2674 msg = "...file '"+f.getPath()+"' does not exist, skipping"
2676 logOutFile.append(msg+"\n")
2679 coreFile.append( coreBottom.getText("UTF-8") )
2681 msg = "Generating ${zjsfile}"
2683 logOutFile.append(msg+"\n")
2684 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2685 def logErrFOS = logOutFOS
2688 classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
2689 main = "com.google.javascript.jscomp.CommandLineRunner"
2690 jvmArgs = [ "-Dfile.encoding=UTF-8" ]
2691 args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
2694 msg = "\nRunning '"+commandLine.join(' ')+"'\n"
2696 logOutFile.append(msg+"\n")
2698 if (logOutConsole) {
2699 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2700 new org.apache.tools.ant.util.TeeOutputStream(
2704 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2705 new org.apache.tools.ant.util.TeeOutputStream(
2710 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2713 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2720 logOutFile.append(msg+"\n")
2724 task jalviewjsBuildAllCores {
2726 description "Build the core js lib closures listed in the classlists dir"
2727 dependsOn jalviewjsTranspile
2728 dependsOn jalviewjsTransferUnzipSwingJs
2730 def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
2731 def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
2732 def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
2733 def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
2734 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
2735 def prefixFile = "${jsDir}/core/coretop2.js"
2736 def suffixFile = "${jsDir}/core/corebottom2.js"
2738 inputs.file prefixFile
2739 inputs.file suffixFile
2741 def classlistFiles = []
2742 // add the classlists found int the jalviewjs_classlists_dir
2743 fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
2745 def name = file.getName() - ".txt"
2752 // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
2753 //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
2754 classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
2756 jalviewjsCoreClasslists = []
2758 classlistFiles.each {
2761 def file = hash['file']
2762 if (! file.exists()) {
2763 //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
2764 return false // this is a "continue" in groovy .each closure
2766 def name = hash['name']
2768 name = file.getName() - ".txt"
2776 def list = fileTree(dir: j2sDir, includes: filelist)
2778 def jsfile = "${outputDir}/core${name}.js"
2779 def zjsfile = "${outputDir}/core${name}.z.js"
2781 jalviewjsCoreClasslists += [
2790 outputs.file(jsfile)
2791 outputs.file(zjsfile)
2794 // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
2795 def stevesoftClasslistName = "_stevesoft"
2796 def stevesoftClasslist = [
2797 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
2798 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
2799 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
2800 'name': stevesoftClasslistName
2802 jalviewjsCoreClasslists += stevesoftClasslist
2803 inputs.files(stevesoftClasslist['list'])
2804 outputs.file(stevesoftClasslist['jsfile'])
2805 outputs.file(stevesoftClasslist['zjsfile'])
2808 def allClasslistName = "_all"
2809 def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
2810 allJsFiles += fileTree(
2814 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2815 "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
2816 "**/org/jmol/export/JSExporter.js"
2819 allJsFiles += fileTree(
2823 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2824 "**/sun/misc/Unsafe.js",
2825 "**/swingjs/jquery/jquery-editable-select.js",
2826 "**/swingjs/jquery/j2sComboBox.js",
2827 "**/sun/misc/FloatingDecimal.js"
2830 def allClasslist = [
2831 'jsfile': "${outputDir}/core${allClasslistName}.js",
2832 'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
2834 'name': allClasslistName
2836 // not including this version of "all" core at the moment
2837 //jalviewjsCoreClasslists += allClasslist
2838 inputs.files(allClasslist['list'])
2839 outputs.file(allClasslist['jsfile'])
2840 outputs.file(allClasslist['zjsfile'])
2843 def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
2844 logOutFile.getParentFile().mkdirs()
2845 logOutFile.createNewFile()
2846 logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
2848 jalviewjsCoreClasslists.each {
2849 jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
2856 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
2859 into file(outputFile).getParentFile()
2860 rename { filename ->
2861 if (filename.equals(inputFile.getName())) {
2862 return file(outputFile).getName()
2866 filter(ReplaceTokens,
2870 'MAIN': '"'+main_class+'"',
2872 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
2873 'COREKEY': jalviewjs_core_key,
2874 'CORENAME': coreName
2881 task jalviewjsPublishCoreTemplates {
2882 dependsOn jalviewjsBuildAllCores
2883 def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
2884 def inputFile = file(inputFileName)
2885 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2887 def outputFiles = []
2888 jalviewjsCoreClasslists.each { cl ->
2889 def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
2890 cl['outputfile'] = outputFile
2891 outputFiles += outputFile
2895 jalviewjsCoreClasslists.each { cl ->
2896 jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
2899 inputs.file(inputFile)
2900 outputs.files(outputFiles)
2904 task jalviewjsSyncCore (type: Sync) {
2905 dependsOn jalviewjsBuildAllCores
2906 dependsOn jalviewjsPublishCoreTemplates
2907 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
2908 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2912 def outputFiles = []
2913 rename { filename ->
2914 outputFiles += "${outputDir}/${filename}"
2920 outputs.files outputFiles
2921 inputs.files inputFiles
2925 // this Copy version of TransferSiteJs will delete anything else in the target dir
2926 task jalviewjsCopyTransferSiteJs(type: Copy) {
2927 dependsOn jalviewjsTranspile
2928 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2929 into "${jalviewDir}/${jalviewjsSiteDir}"
2933 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
2934 task jalviewjsSyncTransferSiteJs(type: Sync) {
2935 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2937 into "${jalviewDir}/${jalviewjsSiteDir}"
2944 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
2945 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
2946 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
2947 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
2949 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
2950 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
2951 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
2952 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
2955 task jalviewjsPrepareSite {
2957 description "Prepares the website folder including unzipping files and copying resources"
2958 dependsOn jalviewjsSyncAllLibs
2959 dependsOn jalviewjsSyncResources
2960 dependsOn jalviewjsSyncSiteResources
2961 dependsOn jalviewjsSyncBuildProperties
2962 dependsOn jalviewjsSyncCore
2966 task jalviewjsBuildSite {
2968 description "Builds the whole website including transpiled code"
2969 dependsOn jalviewjsCopyTransferSiteJs
2970 dependsOn jalviewjsPrepareSite
2974 task cleanJalviewjsTransferSite {
2976 delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2977 delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2978 delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2979 delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2984 task cleanJalviewjsSite {
2985 dependsOn cleanJalviewjsTransferSite
2987 delete "${jalviewDir}/${jalviewjsSiteDir}"
2992 task jalviewjsSiteTar(type: Tar) {
2994 description "Creates a tar.gz file for the website"
2995 dependsOn jalviewjsBuildSite
2996 def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
2997 archiveFileName = outputFilename
2999 compression Compression.GZIP
3001 from "${jalviewDir}/${jalviewjsSiteDir}"
3002 into jalviewjs_site_dir // this is inside the tar file
3004 inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
3008 task jalviewjsServer {
3010 def filename = "jalviewjsTest.html"
3011 description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
3012 def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
3017 def f = Class.forName("org.gradle.plugins.javascript.envjs.http.simple.SimpleHttpFileServerFactory")
3018 factory = f.newInstance()
3019 } catch (ClassNotFoundException e) {
3020 throw new GradleException("Unable to create SimpleHttpFileServerFactory")
3022 def port = Integer.valueOf(jalviewjs_server_port)
3027 while(port < start+1000 && !running) {
3029 def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
3030 jalviewjsServer = factory.start(doc_root, port)
3032 url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
3033 println("SERVER STARTED with document root ${doc_root}.")
3034 println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).")
3035 println("For debug: "+url+"?j2sdebug")
3036 println("For verbose: "+url+"?j2sverbose")
3037 } catch (Exception e) {
3042 <p><a href="${url}">JalviewJS Test. <${url}></a></p>
3043 <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
3044 <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
3046 jalviewjsCoreClasslists.each { cl ->
3047 def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
3049 <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></a></p>
3051 println("For core ${cl.name}: "+urlcore)
3054 file(htmlFile).text = htmlText
3057 outputs.file(htmlFile)
3058 outputs.upToDateWhen({false})
3062 task cleanJalviewjsAll {
3064 description "Delete all configuration and build artifacts to do with JalviewJS build"
3065 dependsOn cleanJalviewjsSite
3066 dependsOn jalviewjsEclipsePaths
3069 delete "${jalviewDir}/${jalviewjsBuildDir}"
3070 delete "${jalviewDir}/${eclipse_bin_dir}"
3071 if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
3072 delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
3074 delete jalviewjsJ2sAltSettingsFileName
3077 outputs.upToDateWhen( { false } )
3081 task jalviewjsIDE_checkJ2sPlugin {
3082 group "00 JalviewJS in Eclipse"
3083 description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
3086 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3087 def j2sPluginFile = file(j2sPlugin)
3088 def eclipseHome = System.properties["eclipse.home.location"]
3089 if (eclipseHome == null || ! IN_ECLIPSE) {
3090 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
3092 def eclipseJ2sPluginDirs = [ "${eclipseHome}/dropins" ]
3093 def altPluginsDir = System.properties["org.eclipse.equinox.p2.reconciler.dropins.directory"]
3094 if (altPluginsDir != null && file(altPluginsDir).exists()) {
3095 eclipseJ2sPluginDirs += altPluginsDir
3097 def foundPlugin = false
3098 def j2sPluginFileName = j2sPluginFile.getName()
3099 def eclipseJ2sPlugin
3100 def eclipseJ2sPluginFile
3101 eclipseJ2sPluginDirs.any { dir ->
3102 eclipseJ2sPlugin = "${dir}/${j2sPluginFileName}"
3103 eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3104 if (eclipseJ2sPluginFile.exists()) {
3110 def msg = "Eclipse J2S Plugin is not installed (could not find '${j2sPluginFileName}' in\n"+eclipseJ2sPluginDirs.join("\n")+"\n)\nTry running task jalviewjsIDE_copyJ2sPlugin"
3111 System.err.println(msg)
3112 throw new StopExecutionException(msg)
3115 def digest = MessageDigest.getInstance("MD5")
3117 digest.update(j2sPluginFile.text.bytes)
3118 def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3120 digest.update(eclipseJ2sPluginFile.text.bytes)
3121 def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3123 if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
3124 def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
3125 System.err.println(msg)
3126 throw new StopExecutionException(msg)
3128 def msg = "Eclipse J2S Plugin '${eclipseJ2sPlugin}' is the same as '${j2sPlugin}' (this is good)"
3134 task jalviewjsIDE_copyJ2sPlugin {
3135 group "00 JalviewJS in Eclipse"
3136 description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
3139 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3140 def j2sPluginFile = file(j2sPlugin)
3141 def eclipseHome = System.properties["eclipse.home.location"]
3142 if (eclipseHome == null || ! IN_ECLIPSE) {
3143 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
3145 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
3146 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3147 def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
3148 System.err.println(msg)
3151 eclipseJ2sPluginFile.getParentFile().mkdirs()
3152 into eclipseJ2sPluginFile.getParent()
3158 task jalviewjsIDE_j2sFile {
3159 group "00 JalviewJS in Eclipse"
3160 description "Creates the .j2s file"
3161 dependsOn jalviewjsCreateJ2sSettings
3165 task jalviewjsIDE_SyncCore {
3166 group "00 JalviewJS in Eclipse"
3167 description "Build the core js lib closures listed in the classlists dir and publish core html from template"
3168 dependsOn jalviewjsSyncCore
3172 task jalviewjsIDE_SyncSiteAll {
3173 dependsOn jalviewjsSyncAllLibs
3174 dependsOn jalviewjsSyncResources
3175 dependsOn jalviewjsSyncSiteResources
3176 dependsOn jalviewjsSyncBuildProperties
3180 cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
3183 task jalviewjsIDE_PrepareSite {
3184 group "00 JalviewJS in Eclipse"
3185 description "Sync libs and resources to site dir, but not closure cores"
3187 dependsOn jalviewjsIDE_SyncSiteAll
3188 //dependsOn cleanJalviewjsTransferSite // not sure why this clean is here -- will slow down a re-run of this task
3192 task jalviewjsIDE_AssembleSite {
3193 group "00 JalviewJS in Eclipse"
3194 description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
3195 dependsOn jalviewjsPrepareSite
3199 task jalviewjsIDE_SiteClean {
3200 group "00 JalviewJS in Eclipse"
3201 description "Deletes the Eclipse transpiled site"
3202 dependsOn cleanJalviewjsSite
3206 task jalviewjsIDE_Server {
3207 group "00 JalviewJS in Eclipse"
3208 description "Starts a webserver on localhost to test the website"
3209 dependsOn jalviewjsServer
3213 // buildship runs this at import or gradle refresh
3214 task eclipseSynchronizationTask {
3215 //dependsOn eclipseSetup
3216 dependsOn createBuildProperties
3218 dependsOn jalviewjsIDE_j2sFile
3219 dependsOn jalviewjsIDE_checkJ2sPlugin
3220 dependsOn jalviewjsIDE_PrepareSite
3225 // buildship runs this at build time or project refresh
3226 task eclipseAutoBuildTask {
3227 //dependsOn jalviewjsIDE_checkJ2sPlugin
3228 //dependsOn jalviewjsIDE_PrepareSite
3234 description "Build the site"
3235 dependsOn jalviewjsBuildSite