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 '8.0.10'
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.12.3'
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 overrideProperties(channelGradleProperties, false)
107 // local build environment properties
108 // can be "projectDir/local.properties"
109 overrideProperties("${projectDir}/local.properties", true)
110 // or "../projectDir_local.properties"
111 overrideProperties(projectDir.getParent() + "/" + projectDir.getName() + "_local.properties", true)
114 // Import releaseProps from the RELEASE file
115 // or a file specified via JALVIEW_RELEASE_FILE if defined
116 // Expect jalview.version and target release branch in jalview.release
117 def releaseProps = new Properties();
118 def releasePropFile = findProperty("JALVIEW_RELEASE_FILE");
119 def defaultReleasePropFile = "${jalviewDirAbsolutePath}/RELEASE";
121 (new File(releasePropFile!=null ? releasePropFile : defaultReleasePropFile)).withInputStream {
122 releaseProps.load(it)
124 } catch (Exception fileLoadError) {
125 throw new Error("Couldn't load release properties file "+(releasePropFile==null ? defaultReleasePropFile : "from custom location: releasePropFile"),fileLoadError);
128 // Set JALVIEW_VERSION if it is not already set
129 if (findProperty("JALVIEW_VERSION")==null || "".equals(JALVIEW_VERSION)) {
130 JALVIEW_VERSION = releaseProps.get("jalview.version")
133 // this property set when running Eclipse headlessly
134 j2sHeadlessBuildProperty = string("net.sf.j2s.core.headlessbuild")
135 // this property set by Eclipse
136 eclipseApplicationProperty = string("eclipse.application")
137 // CHECK IF RUNNING FROM WITHIN ECLIPSE
138 def eclipseApplicationPropertyVal = System.properties[eclipseApplicationProperty]
139 IN_ECLIPSE = eclipseApplicationPropertyVal != null && eclipseApplicationPropertyVal.startsWith("org.eclipse.ui.")
140 // BUT WITHOUT THE HEADLESS BUILD PROPERTY SET
141 if (System.properties[j2sHeadlessBuildProperty].equals("true")) {
142 println("Setting IN_ECLIPSE to ${IN_ECLIPSE} as System.properties['${j2sHeadlessBuildProperty}'] == '${System.properties[j2sHeadlessBuildProperty]}'")
146 println("WITHIN ECLIPSE IDE")
148 println("HEADLESS BUILD")
151 J2S_ENABLED = (project.hasProperty('j2s.compiler.status') && project['j2s.compiler.status'] != null && project['j2s.compiler.status'] == "enable")
153 println("J2S ENABLED")
156 System.properties.sort { it.key }.each {
157 key, val -> println("SYSTEM PROPERTY ${key}='${val}'")
160 if (false && IN_ECLIPSE) {
161 jalviewDir = jalviewDirAbsolutePath
166 buildDate = new Date().format("yyyyMMdd")
169 bareSourceDir = string(source_dir)
170 sourceDir = string("${jalviewDir}/${bareSourceDir}")
171 resourceDir = string("${jalviewDir}/${resource_dir}")
172 bareTestSourceDir = string(test_source_dir)
173 testDir = string("${jalviewDir}/${bareTestSourceDir}")
175 classesDir = string("${jalviewDir}/${classes_dir}")
178 useClover = clover.equals("true")
179 cloverBuildDir = "${buildDir}/clover"
180 cloverInstrDir = file("${cloverBuildDir}/clover-instr")
181 cloverClassesDir = file("${cloverBuildDir}/clover-classes")
182 cloverReportDir = file("${buildDir}/reports/clover")
183 cloverTestInstrDir = file("${cloverBuildDir}/clover-test-instr")
184 cloverTestClassesDir = file("${cloverBuildDir}/clover-test-classes")
185 //cloverTestClassesDir = cloverClassesDir
186 cloverDb = string("${cloverBuildDir}/clover.db")
188 testSourceDir = useClover ? cloverTestInstrDir : testDir
189 testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}"
191 getdownWebsiteDir = string("${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}")
193 buildProperties = null
195 // the following values might be overridden by the CHANNEL switch
196 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
197 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
198 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
199 getdownAppDistDir = getdown_app_dir_alt
200 getdownImagesDir = string("${jalviewDir}/${getdown_images_dir}")
201 getdownSetAppBaseProperty = false // whether to pass the appbase and appdistdir to the application
202 reportRsyncCommand = false
203 jvlChannelName = CHANNEL.toLowerCase()
204 install4jSuffix = CHANNEL.substring(0, 1).toUpperCase() + CHANNEL.substring(1).toLowerCase(); // BUILD -> Build
205 install4jDMGDSStore = "${install4j_images_dir}/${install4j_dmg_ds_store}"
206 install4jDMGBackgroundImage = "${install4j_images_dir}/${install4j_dmg_background}"
207 install4jInstallerName = "${jalview_name} Non-Release Installer"
208 install4jExecutableName = install4j_executable_name
209 install4jExtraScheme = "jalviewx"
210 install4jMacIconsFile = string("${install4j_images_dir}/${install4j_mac_icons_file}")
211 install4jWindowsIconsFile = string("${install4j_images_dir}/${install4j_windows_icons_file}")
212 install4jPngIconFile = string("${install4j_images_dir}/${install4j_png_icon_file}")
213 install4jBackground = string("${install4j_images_dir}/${install4j_background}")
217 // TODO: get bamboo build artifact URL for getdown artifacts
218 getdown_channel_base = bamboo_channelbase
219 getdownChannelName = string("${bamboo_planKey}/${JAVA_VERSION}")
220 getdownAppBase = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
221 jvlChannelName += "_${getdownChannelName}"
222 // automatically add the test group Not-bamboo for exclusion
223 if ("".equals(testng_excluded_groups)) {
224 testng_excluded_groups = "Not-bamboo"
226 install4jExtraScheme = "jalviewb"
229 case [ "RELEASE", "JALVIEWJS-RELEASE" ]:
230 getdownAppDistDir = getdown_app_dir_release
231 reportRsyncCommand = true
233 install4jInstallerName = "${jalview_name} Installer"
237 getdownChannelName = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
238 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
239 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
240 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
241 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
243 package_dir = string("${ARCHIVEDIR}/${package_dir}")
244 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
247 reportRsyncCommand = true
248 install4jExtraScheme = "jalviewa"
252 getdownChannelName = string("archive/${JALVIEW_VERSION}")
253 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
254 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
255 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
256 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
258 package_dir = string("${ARCHIVEDIR}/${package_dir}")
259 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
262 reportRsyncCommand = true
263 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
264 install4jSuffix = "Archive"
265 install4jExtraScheme = "jalviewa"
269 reportRsyncCommand = true
270 getdownSetAppBaseProperty = true
271 // DEVELOP-RELEASE is usually associated with a Jalview release series so set the version
272 JALVIEW_VERSION=JALVIEW_VERSION+"-d${buildDate}"
274 install4jSuffix = "Develop"
275 install4jExtraScheme = "jalviewd"
276 install4jInstallerName = "${jalview_name} Develop Installer"
280 reportRsyncCommand = true
281 // Don't ignore transpile errors for release build
282 if (jalviewjs_ignore_transpile_errors.equals("true")) {
283 jalviewjs_ignore_transpile_errors = "false"
284 println("Setting jalviewjs_ignore_transpile_errors to 'false'")
286 JALVIEW_VERSION = JALVIEW_VERSION+"-test"
287 install4jSuffix = "Test"
288 install4jExtraScheme = "jalviewt"
289 install4jInstallerName = "${jalview_name} Test Installer"
292 case ~/^SCRATCH(|-[-\w]*)$/:
293 getdownChannelName = CHANNEL
294 JALVIEW_VERSION = JALVIEW_VERSION+"-"+CHANNEL
296 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
297 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
298 reportRsyncCommand = true
299 install4jSuffix = "Scratch"
303 if (!file("${LOCALDIR}").exists()) {
304 throw new GradleException("Must provide a LOCALDIR value to produce a local distribution")
306 getdownAppBase = file(file("${LOCALDIR}").getAbsolutePath()).toURI().toString()
307 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
309 JALVIEW_VERSION = "TEST"
310 install4jSuffix = "Test-Local"
311 install4jExtraScheme = "jalviewt"
312 install4jInstallerName = "${jalview_name} Test Installer"
315 case [ "LOCAL", "JALVIEWJS" ]:
316 JALVIEW_VERSION = "TEST"
317 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
318 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
319 install4jExtraScheme = "jalviewl"
322 default: // something wrong specified
323 throw new GradleException("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
327 // override getdownAppBase if requested
328 if (findProperty("getdown_appbase_override") != null) {
329 // revert to LOCAL if empty string
330 if (string(getdown_appbase_override) == "") {
331 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
332 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
333 } else if (string(getdown_appbase_override).startsWith("file://")) {
334 getdownAppBase = string(getdown_appbase_override)
335 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
337 getdownAppBase = string(getdown_appbase_override)
339 println("Overriding getdown appbase with '${getdownAppBase}'")
341 // sanitise file name for jalview launcher file for this channel
342 jvlChannelName = jvlChannelName.replaceAll("[^\\w\\-]+", "_")
343 // install4j application and folder names
344 if (install4jSuffix == "") {
345 install4jApplicationName = "${jalview_name}"
346 install4jBundleId = "${install4j_bundle_id}"
347 install4jWinApplicationId = install4j_release_win_application_id
349 install4jApplicationName = "${jalview_name} ${install4jSuffix}"
350 install4jBundleId = "${install4j_bundle_id}-" + install4jSuffix.toLowerCase()
351 // add int hash of install4jSuffix to the last part of the application_id
352 def id = install4j_release_win_application_id
353 def idsplitreverse = id.split("-").reverse()
354 idsplitreverse[0] = idsplitreverse[0].toInteger() + install4jSuffix.hashCode()
355 install4jWinApplicationId = idsplitreverse.reverse().join("-")
357 // sanitise folder and id names
358 // install4jApplicationFolder = e.g. "Jalview Build"
359 install4jApplicationFolder = install4jApplicationName
360 .replaceAll("[\"'~:/\\\\\\s]", "_") // replace all awkward filename chars " ' ~ : / \
361 .replaceAll("_+", "_") // collapse __
362 install4jInternalId = install4jApplicationName
364 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
365 .replaceAll("_+", "") // collapse __
366 //.replaceAll("_*-_*", "-") // collapse _-_
367 install4jUnixApplicationFolder = install4jApplicationName
369 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
370 .replaceAll("_+", "_") // collapse __
371 .replaceAll("_*-_*", "-") // collapse _-_
374 getdownWrapperLink = install4jUnixApplicationFolder // e.g. "jalview_local"
375 getdownAppDir = string("${getdownWebsiteDir}/${getdownAppDistDir}")
376 //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}"
377 getdownResourceDir = string("${getdownWebsiteDir}/${getdown_resource_dir}")
378 getdownInstallDir = string("${getdownWebsiteDir}/${getdown_install_dir}")
379 getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
380 getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
381 /* compile without modules -- using classpath libraries
382 modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
383 modules_runtimeClasspath = modules_compileClasspath
385 def details = versionDetails()
386 gitHash = details.gitHash
387 gitBranch = details.branchName
389 println("Using a ${CHANNEL} profile.")
391 additional_compiler_args = []
392 // configure classpath/args for j8/j11 compilation
393 if (JAVA_VERSION.equals("1.8")) {
394 JAVA_INTEGER_VERSION = string("8")
397 libDistDir = j8libDir
398 compile_source_compatibility = 1.8
399 compile_target_compatibility = 1.8
400 // these are getdown.txt properties defined dependent on the JAVA_VERSION
401 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java8_min_version"))
402 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java8_max_version"))
403 // this property is assigned below and expanded to multiple lines in the getdown task
404 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java8_txt_multi_java_location"))
405 // this property is for the Java library used in eclipse
406 eclipseJavaRuntimeName = string("JavaSE-1.8")
407 } else if (JAVA_VERSION.equals("11")) {
408 JAVA_INTEGER_VERSION = string("11")
410 libDistDir = j11libDir
411 compile_source_compatibility = 11
412 compile_target_compatibility = 11
413 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
414 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
415 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
416 eclipseJavaRuntimeName = string("JavaSE-11")
417 /* compile without modules -- using classpath libraries
418 additional_compiler_args += [
419 '--module-path', modules_compileClasspath.asPath,
420 '--add-modules', j11modules
423 } else if (JAVA_VERSION.equals("17")) {
424 JAVA_INTEGER_VERSION = string("17")
426 libDistDir = j17libDir
427 compile_source_compatibility = 17
428 compile_target_compatibility = 17
429 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
430 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
431 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
432 eclipseJavaRuntimeName = string("JavaSE-17")
433 /* compile without modules -- using classpath libraries
434 additional_compiler_args += [
435 '--module-path', modules_compileClasspath.asPath,
436 '--add-modules', j11modules
440 throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
445 JAVA_MIN_VERSION = JAVA_VERSION
446 JAVA_MAX_VERSION = JAVA_VERSION
447 def jreInstallsDir = string(jre_installs_dir)
448 if (jreInstallsDir.startsWith("~/")) {
449 jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1)
451 macosJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-mac-x64/jre")
452 macosJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-mac-x64.tar.gz")
453 windowsJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-windows-x64/jre")
454 windowsJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-windows-x64.tar.gz")
455 linuxJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-linux-x64/jre")
456 linuxJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-linux-x64.tar.gz")
457 install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
458 install4jConfFileName = string("jalview-install4j-conf.install4j")
459 install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
460 install4jHomeDir = install4j_home_dir
461 if (install4jHomeDir.startsWith("~/")) {
462 install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1)
465 resourceBuildDir = string("${buildDir}/resources")
466 resourcesBuildDir = string("${resourceBuildDir}/resources_build")
467 helpBuildDir = string("${resourceBuildDir}/help_build")
468 docBuildDir = string("${resourceBuildDir}/doc_build")
470 if (buildProperties == null) {
471 buildProperties = string("${resourcesBuildDir}/${build_properties_file}")
473 buildingHTML = string("${jalviewDir}/${doc_dir}/building.html")
474 helpParentDir = string("${jalviewDir}/${help_parent_dir}")
475 helpSourceDir = string("${helpParentDir}/${help_dir}")
476 helpFile = string("${helpBuildDir}/${help_dir}/help.jhm")
479 relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
480 jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
481 jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}")
483 jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
485 jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
487 jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
488 jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
489 jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
490 jalviewjsJalviewCoreHtmlFile = string("")
491 jalviewjsJalviewCoreName = string(jalviewjs_core_name)
492 jalviewjsCoreClasslists = []
493 jalviewjsJalviewTemplateName = string(jalviewjs_name)
494 jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
495 jalviewjsJ2sAltSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_alt_settings}")
496 jalviewjsJ2sProps = null
497 jalviewjsJ2sPlugin = jalviewjs_j2s_plugin
499 eclipseWorkspace = null
500 eclipseBinary = string("")
501 eclipseVersion = string("")
511 outputDir = file(classesDir)
515 srcDirs = [ resourcesBuildDir, docBuildDir, helpBuildDir ]
518 compileClasspath = files(sourceSets.main.java.outputDir)
519 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
521 runtimeClasspath = compileClasspath
522 runtimeClasspath += files(sourceSets.main.resources.srcDirs)
527 srcDirs cloverInstrDir
528 outputDir = cloverClassesDir
532 srcDirs = sourceSets.main.resources.srcDirs
535 compileClasspath = files( sourceSets.clover.java.outputDir )
536 //compileClasspath += files( testClassesDir )
537 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
538 compileClasspath += fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
539 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
541 runtimeClasspath = compileClasspath
546 srcDirs testSourceDir
547 outputDir = file(testClassesDir)
551 srcDirs = useClover ? sourceSets.clover.resources.srcDirs : sourceSets.main.resources.srcDirs
554 compileClasspath = files( sourceSets.test.java.outputDir )
555 compileClasspath += useClover ? sourceSets.clover.compileClasspath : sourceSets.main.compileClasspath
556 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
558 runtimeClasspath = compileClasspath
559 runtimeClasspath += files(sourceSets.test.resources.srcDirs)
565 // eclipse project and settings files creation, also used by buildship
568 name = eclipse_project_name
570 natures 'org.eclipse.jdt.core.javanature',
571 'org.eclipse.jdt.groovy.core.groovyNature',
572 'org.eclipse.buildship.core.gradleprojectnature'
574 buildCommand 'org.eclipse.jdt.core.javabuilder'
575 buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
579 //defaultOutputDir = sourceSets.main.java.outputDir
580 configurations.each{ c->
581 if (c.isCanBeResolved()) {
582 minusConfigurations += [c]
586 plusConfigurations = [ ]
590 def removeTheseToo = []
591 HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
592 cp.entries.each { entry ->
593 // This conditional removes all src classpathentries that a) have already been added or b) aren't "src" or "test".
594 // e.g. this removes the resources dir being copied into bin/main, bin/test AND bin/clover
595 // we add the resources and help/help dirs in as libs afterwards (see below)
596 if (entry.kind == 'src') {
597 if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) {
598 removeTheseToo += entry
600 alreadyAddedSrcPath.putAt(entry.path, true)
605 cp.entries.removeAll(removeTheseToo)
607 //cp.entries += new Output("${eclipse_bin_dir}/main")
608 if (file(helpParentDir).isDirectory()) {
609 cp.entries += new Library(fileReference(helpParentDir))
611 if (file(resourceDir).isDirectory()) {
612 cp.entries += new Library(fileReference(resourceDir))
615 HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
617 sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
618 //don't want to add outputDir as eclipse is using its own output dir in bin/main
619 if (it.isDirectory() || ! it.exists()) {
620 // don't add dirs to classpath, especially if they don't exist
621 return false // groovy "continue" in .any closure
623 def itPath = it.toString()
624 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
625 // make relative path
626 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
628 if (alreadyAddedLibPath.get(itPath)) {
629 //println("Not adding duplicate entry "+itPath)
631 //println("Adding entry "+itPath)
632 cp.entries += new Library(fileReference(itPath))
633 alreadyAddedLibPath.put(itPath, true)
637 sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
638 //no longer want to add outputDir as eclipse is using its own output dir in bin/main
639 if (it.isDirectory() || ! it.exists()) {
640 // don't add dirs to classpath
641 return false // groovy "continue" in .any closure
644 def itPath = it.toString()
645 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
646 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
648 if (alreadyAddedLibPath.get(itPath)) {
651 def lib = new Library(fileReference(itPath))
652 lib.entryAttributes["test"] = "true"
654 alreadyAddedLibPath.put(itPath, true)
662 containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
667 // for the IDE, use java 11 compatibility
668 sourceCompatibility = compile_source_compatibility
669 targetCompatibility = compile_target_compatibility
670 javaRuntimeName = eclipseJavaRuntimeName
672 // add in jalview project specific properties/preferences into eclipse core preferences
674 withProperties { props ->
675 def jalview_prefs = new Properties()
676 def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
677 jalview_prefs.load(ins)
679 jalview_prefs.forEach { t, v ->
680 if (props.getAt(t) == null) {
684 // codestyle file -- overrides previous formatter prefs
685 def csFile = file("${jalviewDirAbsolutePath}/${eclipse_codestyle_file}")
686 if (csFile.exists()) {
687 XmlParser parser = new XmlParser()
688 def profiles = parser.parse(csFile)
689 def profile = profiles.'profile'.find { p -> (p.'@kind' == "CodeFormatterProfile" && p.'@name' == "Jalview") }
690 if (profile != null) {
691 profile.'setting'.each { s ->
693 def value = s.'@value'
694 if (id != null && value != null) {
695 props.putAt(id, value)
706 // Don't want these to be activated if in headless build
707 synchronizationTasks "eclipseSynchronizationTask"
708 //autoBuildTasks "eclipseAutoBuildTask"
714 /* hack to change eclipse prefs in .settings files other than org.eclipse.jdt.core.prefs */
715 // Class to allow updating arbitrary properties files
716 class PropertiesFile extends PropertiesPersistableConfigurationObject {
717 public PropertiesFile(PropertiesTransformer t) { super(t); }
718 @Override protected void load(Properties properties) { }
719 @Override protected void store(Properties properties) { }
720 @Override protected String getDefaultResourceName() { return ""; }
721 // This is necessary, because PropertiesPersistableConfigurationObject fails
722 // if no default properties file exists.
723 @Override public void loadDefaults() { load(new StringBufferInputStream("")); }
726 // Task to update arbitrary properties files (set outputFile)
727 class PropertiesFileTask extends PropertiesGeneratorTask<PropertiesFile> {
728 private final PropertiesFileContentMerger file;
729 public PropertiesFileTask() { file = new PropertiesFileContentMerger(getTransformer()); }
730 protected PropertiesFile create() { return new PropertiesFile(getTransformer()); }
731 protected void configure(PropertiesFile props) {
732 file.getBeforeMerged().execute(props); file.getWhenMerged().execute(props);
734 public void file(Closure closure) { ConfigureUtil.configure(closure, file); }
737 task eclipseUIPreferences(type: PropertiesFileTask) {
738 description = "Generate Eclipse additional settings"
739 def filename = "org.eclipse.jdt.ui.prefs"
740 outputFile = "$projectDir/.settings/${filename}" as File
743 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
748 task eclipseGroovyCorePreferences(type: PropertiesFileTask) {
749 description = "Generate Eclipse additional settings"
750 def filename = "org.eclipse.jdt.groovy.core.prefs"
751 outputFile = "$projectDir/.settings/${filename}" as File
754 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
759 task eclipseAllPreferences {
761 dependsOn eclipseUIPreferences
762 dependsOn eclipseGroovyCorePreferences
765 eclipseUIPreferences.mustRunAfter eclipseJdt
766 eclipseGroovyCorePreferences.mustRunAfter eclipseJdt
768 /* end of eclipse preferences hack */
776 delete cloverBuildDir
777 delete cloverReportDir
782 task cloverInstrJava(type: JavaExec) {
783 group = "Verification"
784 description = "Create clover instrumented source java files"
786 dependsOn cleanClover
788 inputs.files(sourceSets.main.allJava)
789 outputs.dir(cloverInstrDir)
791 //classpath = fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
792 classpath = sourceSets.clover.compileClasspath
793 main = "com.atlassian.clover.CloverInstr"
801 cloverInstrDir.getPath(),
803 def srcFiles = sourceSets.main.allJava.files
806 { file -> file.absolutePath }
809 args argsList.toArray()
812 delete cloverInstrDir
813 println("Clover: About to instrument "+srcFiles.size() +" files")
818 task cloverInstrTests(type: JavaExec) {
819 group = "Verification"
820 description = "Create clover instrumented source test files"
822 dependsOn cleanClover
824 inputs.files(testDir)
825 outputs.dir(cloverTestInstrDir)
827 classpath = sourceSets.clover.compileClasspath
828 main = "com.atlassian.clover.CloverInstr"
838 cloverTestInstrDir.getPath(),
840 args argsList.toArray()
843 delete cloverTestInstrDir
844 println("Clover: About to instrument test files")
850 group = "Verification"
851 description = "Create clover instrumented all source files"
853 dependsOn cloverInstrJava
854 dependsOn cloverInstrTests
858 cloverClasses.dependsOn cloverInstr
861 task cloverConsoleReport(type: JavaExec) {
862 group = "Verification"
863 description = "Creates clover console report"
866 file(cloverDb).exists()
869 inputs.dir cloverClassesDir
871 classpath = sourceSets.clover.runtimeClasspath
872 main = "com.atlassian.clover.reporters.console.ConsoleReporter"
874 if (cloverreport_mem.length() > 0) {
875 maxHeapSize = cloverreport_mem
877 if (cloverreport_jvmargs.length() > 0) {
878 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
888 args argsList.toArray()
892 task cloverHtmlReport(type: JavaExec) {
893 group = "Verification"
894 description = "Creates clover HTML report"
897 file(cloverDb).exists()
900 def cloverHtmlDir = cloverReportDir
901 inputs.dir cloverClassesDir
902 outputs.dir cloverHtmlDir
904 classpath = sourceSets.clover.runtimeClasspath
905 main = "com.atlassian.clover.reporters.html.HtmlReporter"
907 if (cloverreport_mem.length() > 0) {
908 maxHeapSize = cloverreport_mem
910 if (cloverreport_jvmargs.length() > 0) {
911 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
922 if (cloverreport_html_options.length() > 0) {
923 argsList += cloverreport_html_options.split(" ")
926 args argsList.toArray()
930 task cloverXmlReport(type: JavaExec) {
931 group = "Verification"
932 description = "Creates clover XML report"
935 file(cloverDb).exists()
938 def cloverXmlFile = "${cloverReportDir}/clover.xml"
939 inputs.dir cloverClassesDir
940 outputs.file cloverXmlFile
942 classpath = sourceSets.clover.runtimeClasspath
943 main = "com.atlassian.clover.reporters.xml.XMLReporter"
945 if (cloverreport_mem.length() > 0) {
946 maxHeapSize = cloverreport_mem
948 if (cloverreport_jvmargs.length() > 0) {
949 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
960 if (cloverreport_xml_options.length() > 0) {
961 argsList += cloverreport_xml_options.split(" ")
964 args argsList.toArray()
969 group = "Verification"
970 description = "Creates clover reports"
972 dependsOn cloverXmlReport
973 dependsOn cloverHtmlReport
980 sourceCompatibility = compile_source_compatibility
981 targetCompatibility = compile_target_compatibility
982 options.compilerArgs += additional_compiler_args
983 print ("Setting target compatibility to "+targetCompatibility+"\n")
985 //classpath += configurations.cloverRuntime
991 // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ?
992 sourceCompatibility = compile_source_compatibility
993 targetCompatibility = compile_target_compatibility
994 options.compilerArgs = additional_compiler_args
995 options.encoding = "UTF-8"
997 print ("Setting target compatibility to "+compile_target_compatibility+"\n")
1004 sourceCompatibility = compile_source_compatibility
1005 targetCompatibility = compile_target_compatibility
1006 options.compilerArgs = additional_compiler_args
1008 print ("Setting target compatibility to "+targetCompatibility+"\n")
1015 delete sourceSets.main.java.outputDir
1021 dependsOn cleanClover
1023 delete sourceSets.test.java.outputDir
1028 // format is a string like date.format("dd MMMM yyyy")
1029 def getDate(format) {
1030 def date = new Date()
1031 return date.format(format)
1035 def convertMdToHtml (FileTree mdFiles, File cssFile) {
1036 MutableDataSet options = new MutableDataSet()
1038 def extensions = new ArrayList<>()
1039 extensions.add(AnchorLinkExtension.create())
1040 extensions.add(AutolinkExtension.create())
1041 extensions.add(StrikethroughExtension.create())
1042 extensions.add(TaskListExtension.create())
1043 extensions.add(TablesExtension.create())
1044 extensions.add(TocExtension.create())
1046 options.set(Parser.EXTENSIONS, extensions)
1048 // set GFM table parsing options
1049 options.set(TablesExtension.WITH_CAPTION, false)
1050 options.set(TablesExtension.COLUMN_SPANS, false)
1051 options.set(TablesExtension.MIN_HEADER_ROWS, 1)
1052 options.set(TablesExtension.MAX_HEADER_ROWS, 1)
1053 options.set(TablesExtension.APPEND_MISSING_COLUMNS, true)
1054 options.set(TablesExtension.DISCARD_EXTRA_COLUMNS, true)
1055 options.set(TablesExtension.HEADER_SEPARATOR_COLUMN_MATCH, true)
1057 options.set(AnchorLinkExtension.ANCHORLINKS_SET_ID, false)
1058 options.set(AnchorLinkExtension.ANCHORLINKS_ANCHOR_CLASS, "anchor")
1059 options.set(AnchorLinkExtension.ANCHORLINKS_SET_NAME, true)
1060 options.set(AnchorLinkExtension.ANCHORLINKS_TEXT_PREFIX, "<span class=\"octicon octicon-link\"></span>")
1062 Parser parser = Parser.builder(options).build()
1063 HtmlRenderer renderer = HtmlRenderer.builder(options).build()
1065 mdFiles.each { mdFile ->
1066 // add table of contents
1067 def mdText = "[TOC]\n"+mdFile.text
1069 // grab the first top-level title
1071 def titleRegex = /(?m)^#(\s+|([^#]))(.*)/
1072 def matcher = mdText =~ titleRegex
1073 if (matcher.size() > 0) {
1074 // matcher[0][2] is the first character of the title if there wasn't any whitespace after the #
1075 title = (matcher[0][2] != null ? matcher[0][2] : "")+matcher[0][3]
1077 // or use the filename if none found
1078 if (title == null) {
1079 title = mdFile.getName()
1082 Node document = parser.parse(mdText)
1083 String htmlBody = renderer.render(document)
1084 def htmlText = '''<html>
1085 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1086 <html xmlns="http://www.w3.org/1999/xhtml">
1088 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1089 <meta http-equiv="Content-Style-Type" content="text/css" />
1090 <meta name="generator" content="flexmark" />
1092 htmlText += ((title != null) ? " <title>${title}</title>" : '' )
1094 <style type="text/css">code{white-space: pre;}</style>
1096 htmlText += ((cssFile != null) ? cssFile.text : '')
1097 htmlText += '''</head>
1100 htmlText += htmlBody
1106 def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
1107 def htmlFile = file(htmlFilePath)
1108 println("Creating ${htmlFilePath}")
1109 htmlFile.text = htmlText
1114 task copyDocs(type: Copy) {
1115 def inputDir = "${jalviewDir}/${doc_dir}"
1116 def outputDir = "${docBuildDir}/${doc_dir}"
1120 include('**/*.html')
1122 filter(ReplaceTokens,
1126 'Version-Rel': JALVIEW_VERSION,
1127 'Year-Rel': getDate("yyyy")
1134 exclude('**/*.html')
1139 inputs.dir(inputDir)
1140 outputs.dir(outputDir)
1144 task convertMdFiles {
1146 def mdFiles = fileTree(dir: docBuildDir, include: "**/*.md")
1147 def cssFile = file("${jalviewDir}/${flexmark_css}")
1150 convertMdToHtml(mdFiles, cssFile)
1153 inputs.files(mdFiles)
1154 inputs.file(cssFile)
1157 mdFiles.each { mdFile ->
1158 def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
1159 htmlFiles.add(file(htmlFilePath))
1161 outputs.files(htmlFiles)
1165 task copyHelp(type: Copy) {
1166 def inputDir = helpSourceDir
1167 def outputDir = "${helpBuildDir}/${help_dir}"
1171 include('**/*.html')
1175 filter(ReplaceTokens,
1179 'Version-Rel': JALVIEW_VERSION,
1180 'Year-Rel': getDate("yyyy")
1187 exclude('**/*.html')
1194 inputs.dir(inputDir)
1195 outputs.files(helpFile)
1196 outputs.dir(outputDir)
1200 task copyResources(type: Copy) {
1202 description = "Copy (and make text substitutions in) the resources dir to the build area"
1204 def inputDir = resourceDir
1205 def outputDir = resourcesBuildDir
1209 include('**/*.html')
1211 filter(ReplaceTokens,
1215 'Version-Rel': JALVIEW_VERSION,
1216 'Year-Rel': getDate("yyyy")
1223 exclude('**/*.html')
1228 inputs.dir(inputDir)
1229 outputs.dir(outputDir)
1232 task copyChannelResources(type: Copy) {
1233 dependsOn copyResources
1235 description = "Copy the channel resources dir to the build resources area"
1237 def inputDir = "${channelDir}/${resource_dir}"
1238 def outputDir = resourcesBuildDir
1242 inputs.dir(inputDir)
1243 outputs.dir(outputDir)
1246 task createBuildProperties(type: WriteProperties) {
1247 dependsOn copyResources
1249 description = "Create the ${buildProperties} file"
1251 inputs.dir(sourceDir)
1252 inputs.dir(resourcesBuildDir)
1253 outputFile (buildProperties)
1254 // taking time specific comment out to allow better incremental builds
1255 comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
1256 //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
1257 property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
1258 property "VERSION", JALVIEW_VERSION
1259 property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
1260 if (getdownSetAppBaseProperty) {
1261 property "GETDOWNAPPBASE", getdownAppBase
1262 property "GETDOWNAPPDISTDIR", getdownAppDistDir
1264 outputs.file(outputFile)
1268 task buildIndices(type: JavaExec) {
1270 classpath = sourceSets.main.compileClasspath
1271 main = "com.sun.java.help.search.Indexer"
1272 workingDir = "${helpBuildDir}/${help_dir}"
1275 inputs.dir("${workingDir}/${argDir}")
1277 outputs.dir("${classesDir}/doc")
1278 outputs.dir("${classesDir}/help")
1279 outputs.file("${workingDir}/JavaHelpSearch/DOCS")
1280 outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
1281 outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
1282 outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
1283 outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
1284 outputs.file("${workingDir}/JavaHelpSearch/TMAP")
1287 task buildResources {
1288 dependsOn copyResources
1289 dependsOn copyChannelResources
1290 dependsOn createBuildProperties
1294 dependsOn buildResources
1297 dependsOn convertMdFiles
1298 dependsOn buildIndices
1302 compileJava.dependsOn prepare
1303 run.dependsOn compileJava
1304 //run.dependsOn prepare
1307 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
1312 dependsOn cloverClasses
1314 dependsOn compileJava //?
1318 includeGroups testng_groups
1319 excludeGroups testng_excluded_groups
1321 useDefaultListeners=true
1324 maxHeapSize = "1024m"
1326 workingDir = jalviewDir
1327 def testLaf = project.findProperty("test_laf")
1328 if (testLaf != null) {
1329 println("Setting Test LaF to '${testLaf}'")
1330 systemProperty "laf", testLaf
1332 def testHiDPIScale = project.findProperty("test_HiDPIScale")
1333 if (testHiDPIScale != null) {
1334 println("Setting Test HiDPI Scale to '${testHiDPIScale}'")
1335 systemProperty "sun.java2d.uiScale", testHiDPIScale
1337 sourceCompatibility = compile_source_compatibility
1338 targetCompatibility = compile_target_compatibility
1339 jvmArgs += additional_compiler_args
1343 println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
1349 task compileLinkCheck(type: JavaCompile) {
1351 classpath = files("${jalviewDir}/${utils_dir}")
1352 destinationDir = file("${jalviewDir}/${utils_dir}")
1353 source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
1355 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1356 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1357 outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
1358 outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
1362 task linkCheck(type: JavaExec) {
1364 dependsOn compileLinkCheck
1366 def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
1367 classpath = files("${jalviewDir}/${utils_dir}")
1368 main = "HelpLinksChecker"
1369 workingDir = jalviewDir
1370 args = [ "${helpBuildDir}/${help_dir}", "-nointernet" ]
1372 def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
1373 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1376 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1380 inputs.dir(helpBuildDir)
1381 outputs.file(helpLinksCheckerOutFile)
1385 // import the pubhtmlhelp target
1386 ant.properties.basedir = "${jalviewDir}"
1387 ant.properties.helpBuildDir = "${helpBuildDir}/${help_dir}"
1388 ant.importBuild "${utils_dir}/publishHelp.xml"
1391 task cleanPackageDir(type: Delete) {
1393 delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
1403 attributes "Main-Class": main_class,
1404 "Permissions": "all-permissions",
1405 "Application-Name": install4jApplicationName,
1406 "Codebase": application_codebase,
1407 "Implementation-Version": JALVIEW_VERSION
1410 def outputDir = "${jalviewDir}/${package_dir}"
1411 destinationDirectory = file(outputDir)
1412 archiveFileName = rootProject.name+".jar"
1413 duplicatesStrategy "EXCLUDE"
1420 exclude "**/*.jar.*"
1422 inputs.dir(sourceSets.main.java.outputDir)
1423 sourceSets.main.resources.srcDirs.each{ dir ->
1426 outputs.file("${outputDir}/${archiveFileName}")
1430 task copyJars(type: Copy) {
1431 from fileTree(dir: classesDir, include: "**/*.jar").files
1432 into "${jalviewDir}/${package_dir}"
1436 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
1437 task syncJars(type: Sync) {
1439 from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
1440 into "${jalviewDir}/${package_dir}"
1442 include jar.archiveFileName.getOrNull()
1449 description = "Put all required libraries in dist"
1450 // order of "cleanPackageDir", "copyJars", "jar" important!
1451 jar.mustRunAfter cleanPackageDir
1452 syncJars.mustRunAfter cleanPackageDir
1453 dependsOn cleanPackageDir
1456 outputs.dir("${jalviewDir}/${package_dir}")
1461 dependsOn cleanPackageDir
1468 group = "distribution"
1469 description = "Create a single jar file with all dependency libraries merged. Can be run with java -jar"
1473 from ("${jalviewDir}/${libDistDir}") {
1477 attributes "Implementation-Version": JALVIEW_VERSION,
1478 "Application-Name": install4jApplicationName
1481 duplicatesStrategy "INCLUDE"
1483 mainClassName = shadow_jar_main_class
1485 classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
1490 task getdownWebsite() {
1491 group = "distribution"
1492 description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
1497 def getdownWebsiteResourceFilenames = []
1498 def getdownTextString = ""
1499 def getdownResourceDir = getdownResourceDir
1500 def getdownResourceFilenames = []
1503 // clean the getdown website and files dir before creating getdown folders
1504 delete getdownWebsiteDir
1505 delete getdownFilesDir
1508 from buildProperties
1509 rename(file(buildProperties).getName(), getdown_build_properties)
1512 getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
1514 // set some getdown_txt_ properties then go through all properties looking for getdown_txt_...
1515 def props = project.properties.sort { it.key }
1516 if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
1517 props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
1519 if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) {
1520 props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion)
1522 if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
1523 props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
1525 if (getdownImagesDir != null && file(getdownImagesDir).exists()) {
1526 props.put("getdown_txt_ui.background_image", "${getdownImagesDir}/${getdown_background_image}")
1527 props.put("getdown_txt_ui.instant_background_image", "${getdownImagesDir}/${getdown_instant_background_image}")
1528 props.put("getdown_txt_ui.error_background", "${getdownImagesDir}/${getdown_error_background}")
1529 props.put("getdown_txt_ui.progress_image", "${getdownImagesDir}/${getdown_progress_image}")
1530 props.put("getdown_txt_ui.icon", "${getdownImagesDir}/${getdown_icon}")
1531 props.put("getdown_txt_ui.mac_dock_icon", "${getdownImagesDir}/${getdown_mac_dock_icon}")
1534 props.put("getdown_txt_title", jalview_name)
1535 props.put("getdown_txt_ui.name", install4jApplicationName)
1537 // start with appbase
1538 getdownTextString += "appbase = ${getdownAppBase}\n"
1539 props.each{ prop, val ->
1540 if (prop.startsWith("getdown_txt_") && val != null) {
1541 if (prop.startsWith("getdown_txt_multi_")) {
1542 def key = prop.substring(18)
1543 val.split(",").each{ v ->
1544 def line = "${key} = ${v}\n"
1545 getdownTextString += line
1548 // file values rationalised
1549 if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1551 if (val.indexOf('/') == 0) {
1554 } else if (val.indexOf('/') > 0) {
1555 // relative path (relative to jalviewDir)
1556 r = file( "${jalviewDir}/${val}" )
1559 val = "${getdown_resource_dir}/" + r.getName()
1560 getdownWebsiteResourceFilenames += val
1561 getdownResourceFilenames += r.getPath()
1564 if (! prop.startsWith("getdown_txt_resource")) {
1565 def line = prop.substring(12) + " = ${val}\n"
1566 getdownTextString += line
1572 getdownWebsiteResourceFilenames.each{ filename ->
1573 getdownTextString += "resource = ${filename}\n"
1575 getdownResourceFilenames.each{ filename ->
1578 into getdownResourceDir
1582 def getdownWrapperScripts = [ getdown_bash_wrapper_script, getdown_powershell_wrapper_script, getdown_batch_wrapper_script ]
1583 getdownWrapperScripts.each{ script ->
1584 def s = file( "${jalviewDir}/utils/getdown/${getdown_wrapper_script_dir}/${script}" )
1588 into "${getdownWebsiteDir}/${getdown_wrapper_script_dir}"
1590 getdownTextString += "resource = ${getdown_wrapper_script_dir}/${script}\n"
1595 fileTree(file(package_dir)).each{ f ->
1596 if (f.isDirectory()) {
1597 def files = fileTree(dir: f, include: ["*"]).getFiles()
1599 } else if (f.exists()) {
1603 codeFiles.sort().each{f ->
1604 def name = f.getName()
1605 def line = "code = ${getdownAppDistDir}/${name}\n"
1606 getdownTextString += line
1613 // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
1615 if (JAVA_VERSION.equals("11")) {
1616 def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
1617 j11libFiles.sort().each{f ->
1618 def name = f.getName()
1619 def line = "code = ${getdown_j11lib_dir}/${name}\n"
1620 getdownTextString += line
1623 into getdownJ11libDir
1629 // 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.
1630 //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
1631 getdownTextString += "resource = ${getdown_launcher_new}\n"
1632 getdownTextString += "class = ${main_class}\n"
1633 // Not setting these properties in general so that getdownappbase and getdowndistdir will default to release version in jalview.bin.Cache
1634 if (getdownSetAppBaseProperty) {
1635 getdownTextString += "jvmarg = -Dgetdowndistdir=${getdownAppDistDir}\n"
1636 getdownTextString += "jvmarg = -Dgetdownappbase=${getdownAppBase}\n"
1639 def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
1640 getdown_txt.write(getdownTextString)
1642 def getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
1643 def launchJvl = file("${getdownWebsiteDir}/${getdownLaunchJvl}")
1644 launchJvl.write("appbase=${getdownAppBase}")
1646 // files going into the getdown website dir: getdown-launcher.jar
1648 from getdownLauncher
1649 rename(file(getdownLauncher).getName(), getdown_launcher_new)
1650 into getdownWebsiteDir
1653 // files going into the getdown website dir: getdown-launcher(-local).jar
1655 from getdownLauncher
1656 if (file(getdownLauncher).getName() != getdown_launcher) {
1657 rename(file(getdownLauncher).getName(), getdown_launcher)
1659 into getdownWebsiteDir
1662 // files going into the getdown website dir: ./install dir and files
1663 if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
1666 from getdownLauncher
1667 from "${getdownAppDir}/${getdown_build_properties}"
1668 if (file(getdownLauncher).getName() != getdown_launcher) {
1669 rename(file(getdownLauncher).getName(), getdown_launcher)
1671 into getdownInstallDir
1674 // and make a copy in the getdown files dir (these are not downloaded by getdown)
1676 from getdownInstallDir
1677 into getdownFilesInstallDir
1681 // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties
1685 from getdownLauncher
1686 from "${getdownWebsiteDir}/${getdown_build_properties}"
1687 if (file(getdownLauncher).getName() != getdown_launcher) {
1688 rename(file(getdownLauncher).getName(), getdown_launcher)
1690 into getdownFilesDir
1693 // and ./resources (not all downloaded by getdown)
1695 from getdownResourceDir
1696 into "${getdownFilesDir}/${getdown_resource_dir}"
1701 inputs.dir("${jalviewDir}/${package_dir}")
1703 outputs.dir(getdownWebsiteDir)
1704 outputs.dir(getdownFilesDir)
1708 // a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
1709 task getdownDigestDir(type: JavaExec) {
1711 description "A task to run a getdown Digest on a dir with getdown.txt. Provide a DIGESTDIR property via -PDIGESTDIR=..."
1713 def digestDirPropertyName = "DIGESTDIR"
1715 classpath = files(getdownLauncher)
1716 def digestDir = findProperty(digestDirPropertyName)
1717 if (digestDir == null) {
1718 throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest")
1722 main = "com.threerings.getdown.tools.Digester"
1726 task getdownDigest(type: JavaExec) {
1727 group = "distribution"
1728 description = "Digest the getdown website folder"
1729 dependsOn getdownWebsite
1731 classpath = files(getdownLauncher)
1733 main = "com.threerings.getdown.tools.Digester"
1734 args getdownWebsiteDir
1735 inputs.dir(getdownWebsiteDir)
1736 outputs.file("${getdownWebsiteDir}/digest2.txt")
1741 group = "distribution"
1742 description = "Create the minimal and full getdown app folder for installers and website and create digest file"
1743 dependsOn getdownDigest
1745 if (reportRsyncCommand) {
1746 def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
1747 def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
1748 println "LIKELY RSYNC COMMAND:"
1749 println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
1750 if (RUNRSYNC == "true") {
1752 commandLine "mkdir", "-p", toDir
1755 commandLine "rsync", "-avh", "--delete", fromDir, toDir
1763 tasks.withType(JavaCompile) {
1764 options.encoding = 'UTF-8'
1770 delete getdownWebsiteDir
1771 delete getdownFilesDir
1777 if (file(install4jHomeDir).exists()) {
1779 } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
1780 install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1781 } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
1782 install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
1784 installDir(file(install4jHomeDir))
1786 mediaTypes = Arrays.asList(install4j_media_types.split(","))
1790 task copyInstall4jTemplate {
1791 def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
1792 def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
1793 inputs.file(install4jTemplateFile)
1794 inputs.file(install4jFileAssociationsFile)
1795 inputs.property("CHANNEL", { CHANNEL })
1796 outputs.file(install4jConfFile)
1799 def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
1801 // turn off code signing if no OSX_KEYPASS
1802 if (OSX_KEYPASS == "") {
1803 install4jConfigXml.'**'.codeSigning.each { codeSigning ->
1804 codeSigning.'@macEnabled' = "false"
1806 install4jConfigXml.'**'.windows.each { windows ->
1807 windows.'@runPostProcessor' = "false"
1811 // turn off checksum creation for LOCAL channel
1812 def e = install4jConfigXml.application[0]
1813 if (CHANNEL == "LOCAL") {
1814 e.'@createChecksums' = "false"
1816 e.'@createChecksums' = "true"
1819 // put file association actions where placeholder action is
1820 def install4jFileAssociationsText = install4jFileAssociationsFile.text
1821 def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
1822 install4jConfigXml.'**'.action.any { a -> // .any{} stops after the first one that returns true
1823 if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
1824 def parent = a.parent()
1826 fileAssociationActions.each { faa ->
1829 // don't need to continue in .any loop once replacements have been made
1834 // use Windows Program Group with Examples folder for RELEASE, and Program Group without Examples for everything else
1835 // NB we're deleting the /other/ one!
1836 // Also remove the examples subdir from non-release versions
1837 def customizedIdToDelete = "PROGRAM_GROUP_RELEASE"
1838 // 2.11.1.0 NOT releasing with the Examples folder in the Program Group
1839 if (false && CHANNEL=="RELEASE") { // remove 'false && ' to include Examples folder in RELEASE channel
1840 customizedIdToDelete = "PROGRAM_GROUP_NON_RELEASE"
1842 // remove the examples subdir from Full File Set
1843 def files = install4jConfigXml.files[0]
1844 def fileset = files.filesets.fileset.find { fs -> fs.'@customizedId' == "FULL_FILE_SET" }
1845 def root = files.roots.root.find { r -> r.'@fileset' == fileset.'@id' }
1846 def mountPoint = files.mountPoints.mountPoint.find { mp -> mp.'@root' == root.'@id' }
1847 def dirEntry = files.entries.dirEntry.find { de -> de.'@mountPoint' == mountPoint.'@id' && de.'@subDirectory' == "examples" }
1848 dirEntry.parent().remove(dirEntry)
1850 install4jConfigXml.'**'.action.any { a ->
1851 if (a.'@customizedId' == customizedIdToDelete) {
1852 def parent = a.parent()
1858 // write install4j file
1859 install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
1866 delete install4jConfFile
1870 task installerFiles(type: com.install4j.gradle.Install4jTask) {
1871 group = "distribution"
1872 description = "Create the install4j installers"
1874 dependsOn copyInstall4jTemplate
1876 projectFile = install4jConfFile
1878 // create an md5 for the input files to use as version for install4j conf file
1879 def digest = MessageDigest.getInstance("MD5")
1881 (file("${install4jDir}/${install4j_template}").text +
1882 file("${install4jDir}/${install4j_info_plist_file_associations}").text +
1883 file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
1884 def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
1885 if (filesMd5.length() >= 8) {
1886 filesMd5 = filesMd5.substring(0,8)
1888 def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
1889 // make install4jBuildDir relative to jalviewDir
1890 def install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
1893 'JALVIEW_NAME': jalview_name,
1894 'JALVIEW_APPLICATION_NAME': install4jApplicationName,
1895 'JALVIEW_DIR': "../..",
1896 'OSX_KEYSTORE': OSX_KEYSTORE,
1897 'OSX_APPLEID': OSX_APPLEID,
1898 'OSX_ALTOOLPASS': OSX_ALTOOLPASS,
1899 'JSIGN_SH': JSIGN_SH,
1900 'JRE_DIR': getdown_app_dir_java,
1901 'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
1902 'JALVIEW_VERSION': JALVIEW_VERSION,
1903 'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
1904 'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
1905 'JAVA_VERSION': JAVA_VERSION,
1906 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
1907 'VERSION': JALVIEW_VERSION,
1908 'MACOS_JAVA_VM_DIR': macosJavaVMDir,
1909 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
1910 'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
1911 'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
1912 'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
1913 'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
1914 'COPYRIGHT_MESSAGE': install4j_copyright_message,
1915 'BUNDLE_ID': install4jBundleId,
1916 'INTERNAL_ID': install4jInternalId,
1917 'WINDOWS_APPLICATION_ID': install4jWinApplicationId,
1918 'MACOS_DMG_DS_STORE': install4jDMGDSStore,
1919 'MACOS_DMG_BG_IMAGE': install4jDMGBackgroundImage,
1920 'WRAPPER_LINK': getdownWrapperLink,
1921 'BASH_WRAPPER_SCRIPT': getdown_bash_wrapper_script,
1922 'POWERSHELL_WRAPPER_SCRIPT': getdown_powershell_wrapper_script,
1923 'WRAPPER_SCRIPT_BIN_DIR': getdown_wrapper_script_dir,
1924 'INSTALLER_NAME': install4jInstallerName,
1925 'INSTALL4J_UTILS_DIR': install4j_utils_dir,
1926 'GETDOWN_WEBSITE_DIR': getdown_website_dir,
1927 'GETDOWN_FILES_DIR': getdown_files_dir,
1928 'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
1929 'GETDOWN_DIST_DIR': getdownAppDistDir,
1930 'GETDOWN_ALT_DIR': getdown_app_dir_alt,
1931 'GETDOWN_INSTALL_DIR': getdown_install_dir,
1932 'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
1933 'BUILD_DIR': install4jBuildDir,
1934 'APPLICATION_CATEGORIES': install4j_application_categories,
1935 'APPLICATION_FOLDER': install4jApplicationFolder,
1936 'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder,
1937 'EXECUTABLE_NAME': install4jExecutableName,
1938 'EXTRA_SCHEME': install4jExtraScheme,
1939 'MAC_ICONS_FILE': install4jMacIconsFile,
1940 'WINDOWS_ICONS_FILE': install4jWindowsIconsFile,
1941 'PNG_ICON_FILE': install4jPngIconFile,
1942 'BACKGROUND': install4jBackground,
1946 //println("INSTALL4J VARIABLES:")
1947 //variables.each{k,v->println("${k}=${v}")}
1949 destination = "${jalviewDir}/${install4jBuildDir}"
1950 buildSelected = true
1952 if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
1954 disableSigning = true
1955 disableNotarization = true
1959 macKeystorePassword = OSX_KEYPASS
1962 if (OSX_ALTOOLPASS) {
1963 appleIdPassword = OSX_ALTOOLPASS
1964 disableNotarization = false
1966 disableNotarization = true
1970 println("Using projectFile "+projectFile)
1971 if (!disableNotarization) { println("Will notarize OSX App DMG") }
1975 inputs.dir(getdownWebsiteDir)
1976 inputs.file(install4jConfFile)
1977 inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
1978 inputs.dir(macosJavaVMDir)
1979 inputs.dir(windowsJavaVMDir)
1980 outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
1983 task copyInstallersOutputTxt {
1984 dependsOn installerFiles
1986 def install4jBuildDir = "${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}"
1987 def installersOutputTxt = "${install4jBuildDir}/output.txt"
1988 def installersOutputVersionTxt = "${install4jBuildDir}/output-${JALVIEW_VERSION}.txt"
1990 inputs.file(installersOutputTxt)
1991 outputs.file("${install4jBuildDir}/${installersOutputVersionTxt}")
1994 file(installersOutputVersionTxt).write(file(installersOutputTxt).text)
1999 dependsOn installerFiles
2000 dependsOn copyInstallersOutputTxt
2006 eclipse().configFile(eclipse_codestyle_file)
2011 task sourceDist(type: Tar) {
2012 group "distribution"
2013 description "Create a source .tar.gz file for distribution"
2015 dependsOn createBuildProperties
2016 dependsOn convertMdFiles
2018 def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
2019 def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
2020 archiveFileName = outputFileName
2022 compression Compression.GZIP
2037 "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
2039 "utils/InstallAnywhere",
2054 "gradle.properties",
2065 ".settings/org.eclipse.jdt.core.jalview.prefs",
2069 exclude (EXCLUDE_FILES)
2070 include (PROCESS_FILES)
2071 filter(ReplaceTokens,
2075 'Version-Rel': JALVIEW_VERSION,
2076 'Year-Rel': getDate("yyyy")
2081 exclude (EXCLUDE_FILES)
2082 exclude (PROCESS_FILES)
2083 exclude ("appletlib")
2084 exclude ("**/*locales")
2085 exclude ("*locales/**")
2086 exclude ("utils/InstallAnywhere")
2088 exclude (getdown_files_dir)
2089 exclude (getdown_website_dir)
2091 // exluding these as not using jars as modules yet
2092 exclude ("${j11modDir}/**/*.jar")
2095 include(INCLUDE_FILES)
2097 // from (jalviewDir) {
2098 // // explicit includes for stuff that seemed to not get included
2099 // include(fileTree("test/**/*."))
2100 // exclude(EXCLUDE_FILES)
2101 // exclude(PROCESS_FILES)
2104 from(file(buildProperties).getParent()) {
2105 include(file(buildProperties).getName())
2106 rename(file(buildProperties).getName(), "build_properties")
2108 line.replaceAll("^INSTALLATION=.*\$","INSTALLATION=Source Release"+" git-commit\\\\:"+gitHash+" ["+gitBranch+"]")
2117 dependsOn pubhtmlhelp
2119 inputs.dir("${helpBuildDir}/${help_dir}")
2120 outputs.dir("${buildDir}/distributions/${help_dir}")
2124 task j2sSetHeadlessBuild {
2131 task jalviewjsEnableAltFileProperty(type: WriteProperties) {
2133 description "Enable the alternative J2S Config file for headless build"
2135 outputFile = jalviewjsJ2sSettingsFileName
2136 def j2sPropsFile = file(jalviewjsJ2sSettingsFileName)
2137 def j2sProps = new Properties()
2138 if (j2sPropsFile.exists()) {
2140 def j2sPropsFileFIS = new FileInputStream(j2sPropsFile)
2141 j2sProps.load(j2sPropsFileFIS)
2142 j2sPropsFileFIS.close()
2144 j2sProps.each { prop, val ->
2147 } catch (Exception e) {
2148 println("Exception reading ${jalviewjsJ2sSettingsFileName}")
2152 if (! j2sProps.stringPropertyNames().contains(jalviewjs_j2s_alt_file_property_config)) {
2153 property(jalviewjs_j2s_alt_file_property_config, jalviewjs_j2s_alt_file_property)
2158 task jalviewjsSetEclipseWorkspace {
2159 def propKey = "jalviewjs_eclipse_workspace"
2161 if (project.hasProperty(propKey)) {
2162 propVal = project.getProperty(propKey)
2163 if (propVal.startsWith("~/")) {
2164 propVal = System.getProperty("user.home") + propVal.substring(1)
2167 def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
2168 def propsFile = file(propsFileName)
2169 def eclipseWsDir = propVal
2170 def props = new Properties()
2172 def writeProps = true
2173 if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
2174 def ins = new FileInputStream(propsFileName)
2177 if (props.getProperty(propKey, null) != null) {
2178 eclipseWsDir = props.getProperty(propKey)
2183 if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
2184 def tempDir = File.createTempDir()
2185 eclipseWsDir = tempDir.getAbsolutePath()
2188 eclipseWorkspace = file(eclipseWsDir)
2191 // do not run a headless transpile when we claim to be in Eclipse
2193 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2194 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2196 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2200 props.setProperty(propKey, eclipseWsDir)
2201 propsFile.parentFile.mkdirs()
2202 def bytes = new ByteArrayOutputStream()
2203 props.store(bytes, null)
2204 def propertiesString = bytes.toString()
2205 propsFile.text = propertiesString
2211 println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
2214 //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
2215 outputs.file(propsFileName)
2216 outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
2220 task jalviewjsEclipsePaths {
2223 def eclipseRoot = jalviewjs_eclipse_root
2224 if (eclipseRoot.startsWith("~/")) {
2225 eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
2227 if (OperatingSystem.current().isMacOsX()) {
2228 eclipseRoot += "/Eclipse.app"
2229 eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
2230 eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
2231 } else if (OperatingSystem.current().isWindows()) { // check these paths!!
2232 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2233 eclipseRoot += "/eclipse"
2235 eclipseBinary = "${eclipseRoot}/eclipse.exe"
2236 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2237 } else { // linux or unix
2238 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2239 eclipseRoot += "/eclipse"
2240 println("eclipseDir exists")
2242 eclipseBinary = "${eclipseRoot}/eclipse"
2243 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2246 eclipseVersion = "4.13" // default
2247 def assumedVersion = true
2248 if (file(eclipseProduct).exists()) {
2249 def fis = new FileInputStream(eclipseProduct)
2250 def props = new Properties()
2252 eclipseVersion = props.getProperty("version")
2254 assumedVersion = false
2257 def propKey = "eclipse_debug"
2258 eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
2261 // do not run a headless transpile when we claim to be in Eclipse
2263 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2264 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2266 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2269 if (!assumedVersion) {
2270 println("ECLIPSE VERSION=${eclipseVersion}")
2276 task printProperties {
2278 description "Output to console all System.properties"
2280 System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
2286 dependsOn eclipseProject
2287 dependsOn eclipseClasspath
2288 dependsOn eclipseJdt
2292 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
2293 task jalviewjsEclipseCopyDropins(type: Copy) {
2294 dependsOn jalviewjsEclipsePaths
2296 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
2297 inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
2298 def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
2305 // this eclipse -clean doesn't actually work
2306 task jalviewjsCleanEclipse(type: Exec) {
2307 dependsOn eclipseSetup
2308 dependsOn jalviewjsEclipsePaths
2309 dependsOn jalviewjsEclipseCopyDropins
2311 executable(eclipseBinary)
2312 args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
2318 def inputString = """exit
2321 def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
2322 standardInput = inputByteStream
2325 /* not really working yet
2326 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
2330 task jalviewjsTransferUnzipSwingJs {
2331 def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
2335 from zipTree(file_zip)
2336 into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2340 inputs.file file_zip
2341 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2345 task jalviewjsTransferUnzipLib {
2346 def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
2349 zipFiles.each { file_zip ->
2351 from zipTree(file_zip)
2352 into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2357 inputs.files zipFiles
2358 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2362 task jalviewjsTransferUnzipAllLibs {
2363 dependsOn jalviewjsTransferUnzipSwingJs
2364 dependsOn jalviewjsTransferUnzipLib
2368 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
2370 description "Create the alternative j2s file from the j2s.* properties"
2372 jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
2373 def siteDirProperty = "j2s.site.directory"
2374 def setSiteDir = false
2375 jalviewjsJ2sProps.each { prop, val ->
2377 if (prop == siteDirProperty) {
2378 if (!(val.startsWith('/') || val.startsWith("file://") )) {
2379 val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
2385 if (!setSiteDir) { // default site location, don't override specifically set property
2386 property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
2389 outputFile = jalviewjsJ2sAltSettingsFileName
2392 inputs.properties(jalviewjsJ2sProps)
2393 outputs.file(jalviewjsJ2sAltSettingsFileName)
2398 task jalviewjsEclipseSetup {
2399 dependsOn jalviewjsEclipseCopyDropins
2400 dependsOn jalviewjsSetEclipseWorkspace
2401 dependsOn jalviewjsCreateJ2sSettings
2405 task jalviewjsSyncAllLibs (type: Sync) {
2406 dependsOn jalviewjsTransferUnzipAllLibs
2407 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
2408 inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
2409 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2413 def outputFiles = []
2414 rename { filename ->
2415 outputFiles += "${outputDir}/${filename}"
2422 // should this be exclude really ?
2423 duplicatesStrategy "INCLUDE"
2425 outputs.files outputFiles
2426 inputs.files inputFiles
2430 task jalviewjsSyncResources (type: Sync) {
2431 dependsOn buildResources
2433 def inputFiles = fileTree(dir: resourcesBuildDir)
2434 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2438 def outputFiles = []
2439 rename { filename ->
2440 outputFiles += "${outputDir}/${filename}"
2446 outputs.files outputFiles
2447 inputs.files inputFiles
2451 task jalviewjsSyncSiteResources (type: Sync) {
2452 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
2453 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2457 def outputFiles = []
2458 rename { filename ->
2459 outputFiles += "${outputDir}/${filename}"
2465 outputs.files outputFiles
2466 inputs.files inputFiles
2470 task jalviewjsSyncBuildProperties (type: Sync) {
2471 dependsOn createBuildProperties
2472 def inputFiles = [file(buildProperties)]
2473 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2477 def outputFiles = []
2478 rename { filename ->
2479 outputFiles += "${outputDir}/${filename}"
2485 outputs.files outputFiles
2486 inputs.files inputFiles
2490 task jalviewjsProjectImport(type: Exec) {
2491 dependsOn eclipseSetup
2492 dependsOn jalviewjsEclipsePaths
2493 dependsOn jalviewjsEclipseSetup
2496 // do not run a headless import when we claim to be in Eclipse
2498 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2499 throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2501 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2505 //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
2506 def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
2507 executable(eclipseBinary)
2508 args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
2512 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2514 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2515 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
2518 inputs.file("${jalviewDir}/.project")
2519 outputs.upToDateWhen {
2520 file(projdir).exists()
2525 task jalviewjsTranspile(type: Exec) {
2526 dependsOn jalviewjsEclipseSetup
2527 dependsOn jalviewjsProjectImport
2528 dependsOn jalviewjsEclipsePaths
2530 dependsOn jalviewjsEnableAltFileProperty
2534 // do not run a headless transpile when we claim to be in Eclipse
2536 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2537 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2539 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2543 executable(eclipseBinary)
2544 args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
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}" ]
2557 stdout = new ByteArrayOutputStream()
2558 stderr = new ByteArrayOutputStream()
2560 def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
2561 def logOutFile = file(logOutFileName)
2562 logOutFile.createNewFile()
2563 logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
2564 BINARY: ${eclipseBinary}
2565 VERSION: ${eclipseVersion}
2566 WORKSPACE: ${eclipseWorkspace}
2567 DEBUG: ${eclipseDebug}
2570 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2571 // combine stdout and stderr
2572 def logErrFOS = logOutFOS
2574 if (jalviewjs_j2s_to_console.equals("true")) {
2575 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2576 new org.apache.tools.ant.util.TeeOutputStream(
2580 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2581 new org.apache.tools.ant.util.TeeOutputStream(
2586 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2589 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2596 if (stdout.toString().contains("Error processing ")) {
2597 // j2s did not complete transpile
2598 //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2599 if (jalviewjs_ignore_transpile_errors.equals("true")) {
2600 println("IGNORING TRANSPILE ERRORS")
2601 println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2603 throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2608 inputs.dir("${jalviewDir}/${sourceDir}")
2609 outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
2610 outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
2614 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
2616 def stdout = new ByteArrayOutputStream()
2617 def stderr = new ByteArrayOutputStream()
2619 def coreFile = file(jsfile)
2621 msg = "Creating core for ${name}...\nGenerating ${jsfile}"
2623 logOutFile.createNewFile()
2624 logOutFile.append(msg+"\n")
2626 def coreTop = file(prefixFile)
2627 def coreBottom = file(suffixFile)
2628 coreFile.getParentFile().mkdirs()
2629 coreFile.createNewFile()
2630 coreFile.write( coreTop.getText("UTF-8") )
2634 def t = f.getText("UTF-8")
2635 t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
2636 coreFile.append( t )
2638 msg = "...file '"+f.getPath()+"' does not exist, skipping"
2640 logOutFile.append(msg+"\n")
2643 coreFile.append( coreBottom.getText("UTF-8") )
2645 msg = "Generating ${zjsfile}"
2647 logOutFile.append(msg+"\n")
2648 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2649 def logErrFOS = logOutFOS
2652 classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
2653 main = "com.google.javascript.jscomp.CommandLineRunner"
2654 jvmArgs = [ "-Dfile.encoding=UTF-8" ]
2655 args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
2658 msg = "\nRunning '"+commandLine.join(' ')+"'\n"
2660 logOutFile.append(msg+"\n")
2662 if (logOutConsole) {
2663 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2664 new org.apache.tools.ant.util.TeeOutputStream(
2668 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2669 new org.apache.tools.ant.util.TeeOutputStream(
2674 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2677 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2684 logOutFile.append(msg+"\n")
2688 task jalviewjsBuildAllCores {
2690 description "Build the core js lib closures listed in the classlists dir"
2691 dependsOn jalviewjsTranspile
2692 dependsOn jalviewjsTransferUnzipSwingJs
2694 def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
2695 def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
2696 def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
2697 def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
2698 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
2699 def prefixFile = "${jsDir}/core/coretop2.js"
2700 def suffixFile = "${jsDir}/core/corebottom2.js"
2702 inputs.file prefixFile
2703 inputs.file suffixFile
2705 def classlistFiles = []
2706 // add the classlists found int the jalviewjs_classlists_dir
2707 fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
2709 def name = file.getName() - ".txt"
2716 // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
2717 //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
2718 classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
2720 jalviewjsCoreClasslists = []
2722 classlistFiles.each {
2725 def file = hash['file']
2726 if (! file.exists()) {
2727 //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
2728 return false // this is a "continue" in groovy .each closure
2730 def name = hash['name']
2732 name = file.getName() - ".txt"
2740 def list = fileTree(dir: j2sDir, includes: filelist)
2742 def jsfile = "${outputDir}/core${name}.js"
2743 def zjsfile = "${outputDir}/core${name}.z.js"
2745 jalviewjsCoreClasslists += [
2754 outputs.file(jsfile)
2755 outputs.file(zjsfile)
2758 // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
2759 def stevesoftClasslistName = "_stevesoft"
2760 def stevesoftClasslist = [
2761 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
2762 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
2763 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
2764 'name': stevesoftClasslistName
2766 jalviewjsCoreClasslists += stevesoftClasslist
2767 inputs.files(stevesoftClasslist['list'])
2768 outputs.file(stevesoftClasslist['jsfile'])
2769 outputs.file(stevesoftClasslist['zjsfile'])
2772 def allClasslistName = "_all"
2773 def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
2774 allJsFiles += fileTree(
2778 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2779 "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
2780 "**/org/jmol/export/JSExporter.js"
2783 allJsFiles += fileTree(
2787 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2788 "**/sun/misc/Unsafe.js",
2789 "**/swingjs/jquery/jquery-editable-select.js",
2790 "**/swingjs/jquery/j2sComboBox.js",
2791 "**/sun/misc/FloatingDecimal.js"
2794 def allClasslist = [
2795 'jsfile': "${outputDir}/core${allClasslistName}.js",
2796 'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
2798 'name': allClasslistName
2800 // not including this version of "all" core at the moment
2801 //jalviewjsCoreClasslists += allClasslist
2802 inputs.files(allClasslist['list'])
2803 outputs.file(allClasslist['jsfile'])
2804 outputs.file(allClasslist['zjsfile'])
2807 def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
2808 logOutFile.getParentFile().mkdirs()
2809 logOutFile.createNewFile()
2810 logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
2812 jalviewjsCoreClasslists.each {
2813 jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
2820 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
2823 into file(outputFile).getParentFile()
2824 rename { filename ->
2825 if (filename.equals(inputFile.getName())) {
2826 return file(outputFile).getName()
2830 filter(ReplaceTokens,
2834 'MAIN': '"'+main_class+'"',
2836 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
2837 'COREKEY': jalviewjs_core_key,
2838 'CORENAME': coreName
2845 task jalviewjsPublishCoreTemplates {
2846 dependsOn jalviewjsBuildAllCores
2847 def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
2848 def inputFile = file(inputFileName)
2849 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2851 def outputFiles = []
2852 jalviewjsCoreClasslists.each { cl ->
2853 def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
2854 cl['outputfile'] = outputFile
2855 outputFiles += outputFile
2859 jalviewjsCoreClasslists.each { cl ->
2860 jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
2863 inputs.file(inputFile)
2864 outputs.files(outputFiles)
2868 task jalviewjsSyncCore (type: Sync) {
2869 dependsOn jalviewjsBuildAllCores
2870 dependsOn jalviewjsPublishCoreTemplates
2871 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
2872 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2876 def outputFiles = []
2877 rename { filename ->
2878 outputFiles += "${outputDir}/${filename}"
2884 outputs.files outputFiles
2885 inputs.files inputFiles
2889 // this Copy version of TransferSiteJs will delete anything else in the target dir
2890 task jalviewjsCopyTransferSiteJs(type: Copy) {
2891 dependsOn jalviewjsTranspile
2892 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2893 into "${jalviewDir}/${jalviewjsSiteDir}"
2897 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
2898 task jalviewjsSyncTransferSiteJs(type: Sync) {
2899 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2901 into "${jalviewDir}/${jalviewjsSiteDir}"
2908 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
2909 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
2910 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
2911 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
2913 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
2914 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
2915 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
2916 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
2919 task jalviewjsPrepareSite {
2921 description "Prepares the website folder including unzipping files and copying resources"
2922 dependsOn jalviewjsSyncAllLibs
2923 dependsOn jalviewjsSyncResources
2924 dependsOn jalviewjsSyncSiteResources
2925 dependsOn jalviewjsSyncBuildProperties
2926 dependsOn jalviewjsSyncCore
2930 task jalviewjsBuildSite {
2932 description "Builds the whole website including transpiled code"
2933 dependsOn jalviewjsCopyTransferSiteJs
2934 dependsOn jalviewjsPrepareSite
2938 task cleanJalviewjsTransferSite {
2940 delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2941 delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2942 delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2943 delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2948 task cleanJalviewjsSite {
2949 dependsOn cleanJalviewjsTransferSite
2951 delete "${jalviewDir}/${jalviewjsSiteDir}"
2956 task jalviewjsSiteTar(type: Tar) {
2958 description "Creates a tar.gz file for the website"
2959 dependsOn jalviewjsBuildSite
2960 def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
2961 archiveFileName = outputFilename
2963 compression Compression.GZIP
2965 from "${jalviewDir}/${jalviewjsSiteDir}"
2966 into jalviewjs_site_dir // this is inside the tar file
2968 inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
2972 task jalviewjsServer {
2974 def filename = "jalviewjsTest.html"
2975 description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
2976 def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
2981 def f = Class.forName("org.gradle.plugins.javascript.envjs.http.simple.SimpleHttpFileServerFactory")
2982 factory = f.newInstance()
2983 } catch (ClassNotFoundException e) {
2984 throw new GradleException("Unable to create SimpleHttpFileServerFactory")
2986 def port = Integer.valueOf(jalviewjs_server_port)
2991 while(port < start+1000 && !running) {
2993 def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
2994 jalviewjsServer = factory.start(doc_root, port)
2996 url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
2997 println("SERVER STARTED with document root ${doc_root}.")
2998 println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).")
2999 println("For debug: "+url+"?j2sdebug")
3000 println("For verbose: "+url+"?j2sverbose")
3001 } catch (Exception e) {
3006 <p><a href="${url}">JalviewJS Test. <${url}></a></p>
3007 <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
3008 <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
3010 jalviewjsCoreClasslists.each { cl ->
3011 def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
3013 <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></a></p>
3015 println("For core ${cl.name}: "+urlcore)
3018 file(htmlFile).text = htmlText
3021 outputs.file(htmlFile)
3022 outputs.upToDateWhen({false})
3026 task cleanJalviewjsAll {
3028 description "Delete all configuration and build artifacts to do with JalviewJS build"
3029 dependsOn cleanJalviewjsSite
3030 dependsOn jalviewjsEclipsePaths
3033 delete "${jalviewDir}/${jalviewjsBuildDir}"
3034 delete "${jalviewDir}/${eclipse_bin_dir}"
3035 if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
3036 delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
3038 delete jalviewjsJ2sAltSettingsFileName
3041 outputs.upToDateWhen( { false } )
3045 task jalviewjsIDE_checkJ2sPlugin {
3046 group "00 JalviewJS in Eclipse"
3047 description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
3050 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3051 def j2sPluginFile = file(j2sPlugin)
3052 def eclipseHome = System.properties["eclipse.home.location"]
3053 if (eclipseHome == null || ! IN_ECLIPSE) {
3054 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
3056 def eclipseJ2sPluginDirs = [ "${eclipseHome}/dropins" ]
3057 def altPluginsDir = System.properties["org.eclipse.equinox.p2.reconciler.dropins.directory"]
3058 if (altPluginsDir != null && file(altPluginsDir).exists()) {
3059 eclipseJ2sPluginDirs += altPluginsDir
3061 def foundPlugin = false
3062 def j2sPluginFileName = j2sPluginFile.getName()
3063 def eclipseJ2sPlugin
3064 def eclipseJ2sPluginFile
3065 eclipseJ2sPluginDirs.any { dir ->
3066 eclipseJ2sPlugin = "${dir}/${j2sPluginFileName}"
3067 eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3068 if (eclipseJ2sPluginFile.exists()) {
3074 def msg = "Eclipse J2S Plugin is not installed (could not find '${j2sPluginFileName}' in\n"+eclipseJ2sPluginDirs.join("\n")+"\n)\nTry running task jalviewjsIDE_copyJ2sPlugin"
3075 System.err.println(msg)
3076 throw new StopExecutionException(msg)
3079 def digest = MessageDigest.getInstance("MD5")
3081 digest.update(j2sPluginFile.text.bytes)
3082 def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3084 digest.update(eclipseJ2sPluginFile.text.bytes)
3085 def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3087 if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
3088 def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
3089 System.err.println(msg)
3090 throw new StopExecutionException(msg)
3092 def msg = "Eclipse J2S Plugin '${eclipseJ2sPlugin}' is the same as '${j2sPlugin}' (this is good)"
3098 task jalviewjsIDE_copyJ2sPlugin {
3099 group "00 JalviewJS in Eclipse"
3100 description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
3103 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3104 def j2sPluginFile = file(j2sPlugin)
3105 def eclipseHome = System.properties["eclipse.home.location"]
3106 if (eclipseHome == null || ! IN_ECLIPSE) {
3107 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
3109 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
3110 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3111 def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
3112 System.err.println(msg)
3115 eclipseJ2sPluginFile.getParentFile().mkdirs()
3116 into eclipseJ2sPluginFile.getParent()
3122 task jalviewjsIDE_j2sFile {
3123 group "00 JalviewJS in Eclipse"
3124 description "Creates the .j2s file"
3125 dependsOn jalviewjsCreateJ2sSettings
3129 task jalviewjsIDE_SyncCore {
3130 group "00 JalviewJS in Eclipse"
3131 description "Build the core js lib closures listed in the classlists dir and publish core html from template"
3132 dependsOn jalviewjsSyncCore
3136 task jalviewjsIDE_SyncSiteAll {
3137 dependsOn jalviewjsSyncAllLibs
3138 dependsOn jalviewjsSyncResources
3139 dependsOn jalviewjsSyncSiteResources
3140 dependsOn jalviewjsSyncBuildProperties
3144 cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
3147 task jalviewjsIDE_PrepareSite {
3148 group "00 JalviewJS in Eclipse"
3149 description "Sync libs and resources to site dir, but not closure cores"
3151 dependsOn jalviewjsIDE_SyncSiteAll
3152 //dependsOn cleanJalviewjsTransferSite // not sure why this clean is here -- will slow down a re-run of this task
3156 task jalviewjsIDE_AssembleSite {
3157 group "00 JalviewJS in Eclipse"
3158 description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
3159 dependsOn jalviewjsPrepareSite
3163 task jalviewjsIDE_SiteClean {
3164 group "00 JalviewJS in Eclipse"
3165 description "Deletes the Eclipse transpiled site"
3166 dependsOn cleanJalviewjsSite
3170 task jalviewjsIDE_Server {
3171 group "00 JalviewJS in Eclipse"
3172 description "Starts a webserver on localhost to test the website"
3173 dependsOn jalviewjsServer
3177 // buildship runs this at import or gradle refresh
3178 task eclipseSynchronizationTask {
3179 //dependsOn eclipseSetup
3180 dependsOn createBuildProperties
3182 dependsOn jalviewjsIDE_j2sFile
3183 dependsOn jalviewjsIDE_checkJ2sPlugin
3184 dependsOn jalviewjsIDE_PrepareSite
3189 // buildship runs this at build time or project refresh
3190 task eclipseAutoBuildTask {
3191 //dependsOn jalviewjsIDE_checkJ2sPlugin
3192 //dependsOn jalviewjsIDE_PrepareSite
3198 description "Build the site"
3199 dependsOn jalviewjsBuildSite