1 /* Convention for properties. Read from gradle.properties, use lower_case_underlines for property names.
2 * For properties set within build.gradle, use camelCaseNoSpace.
4 import org.apache.tools.ant.filters.ReplaceTokens
5 import org.gradle.internal.os.OperatingSystem
6 import org.gradle.plugins.ide.internal.generator.PropertiesPersistableConfigurationObject
7 import org.gradle.api.internal.PropertiesTransformer
8 import org.gradle.util.ConfigureUtil
9 import org.gradle.plugins.ide.eclipse.model.Output
10 import org.gradle.plugins.ide.eclipse.model.Library
11 import java.security.MessageDigest
12 import groovy.transform.ExternalizeMethods
13 import groovy.util.XmlParser
14 import groovy.xml.XmlUtil
15 import groovy.json.JsonBuilder
16 import com.vladsch.flexmark.util.ast.Node
17 import com.vladsch.flexmark.html.HtmlRenderer
18 import com.vladsch.flexmark.parser.Parser
19 import com.vladsch.flexmark.util.data.MutableDataSet
20 import com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension
21 import com.vladsch.flexmark.ext.tables.TablesExtension
22 import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension
23 import com.vladsch.flexmark.ext.autolink.AutolinkExtension
24 import com.vladsch.flexmark.ext.anchorlink.AnchorLinkExtension
25 import com.vladsch.flexmark.ext.toc.TocExtension
33 classpath "com.vladsch.flexmark:flexmark-all:0.62.0"
42 id "com.diffplug.gradle.spotless" version "3.28.0"
43 id 'com.github.johnrengelman.shadow' version '4.0.3'
44 id 'com.install4j.gradle' version '8.0.10'
45 id 'com.dorongold.task-tree' version '1.5' // only needed to display task dependency tree with gradle task1 [task2 ...] taskTree
46 id 'com.palantir.git-version' version '0.12.3'
57 // in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use
58 def string(Object o) {
59 return o == null ? "" : o.toString()
62 def overrideProperties(String propsFileName, boolean output = false) {
63 if (propsFileName == null) {
66 def propsFile = file(propsFileName)
67 if (propsFile != null && propsFile.exists()) {
68 println("Using properties from file '${propsFileName}'")
70 def p = new Properties()
71 def localPropsFIS = new FileInputStream(propsFile)
77 if (project.hasProperty(key)) {
78 oldval = project.findProperty(key)
79 project.setProperty(key, val)
81 println("Overriding property '${key}' ('${oldval}') with ${file(propsFile).getName()} value '${val}'")
84 ext.setProperty(key, val)
86 println("Setting ext property '${key}' with ${file(propsFile).getName()}s value '${val}'")
90 } catch (Exception e) {
91 println("Exception reading local.properties")
98 jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
99 jalviewDirRelativePath = jalviewDir
101 getdownChannelName = CHANNEL.toLowerCase()
102 // default to "default". Currently only has different cosmetics for "develop", "release", "default"
103 propertiesChannelName = ["develop", "release", "test-release", "jalviewjs", "jalviewjs-release" ].contains(getdownChannelName) ? getdownChannelName : "default"
104 // Import channel_properties
105 channelDir = string("${jalviewDir}/${channel_properties_dir}/${propertiesChannelName}")
106 channelGradleProperties = string("${channelDir}/channel_gradle.properties")
107 overrideProperties(channelGradleProperties, false)
108 // local build environment properties
109 // can be "projectDir/local.properties"
110 overrideProperties("${projectDir}/local.properties", true)
111 // or "../projectDir_local.properties"
112 overrideProperties(projectDir.getParent() + "/" + projectDir.getName() + "_local.properties", true)
115 // Import releaseProps from the RELEASE file
116 // or a file specified via JALVIEW_RELEASE_FILE if defined
117 // Expect jalview.version and target release branch in jalview.release
118 def releaseProps = new Properties();
119 def releasePropFile = findProperty("JALVIEW_RELEASE_FILE");
120 def defaultReleasePropFile = "${jalviewDirAbsolutePath}/RELEASE";
122 (new File(releasePropFile!=null ? releasePropFile : defaultReleasePropFile)).withInputStream {
123 releaseProps.load(it)
125 } catch (Exception fileLoadError) {
126 throw new Error("Couldn't load release properties file "+(releasePropFile==null ? defaultReleasePropFile : "from custom location: releasePropFile"),fileLoadError);
129 // Set JALVIEW_VERSION if it is not already set
130 if (findProperty("JALVIEW_VERSION")==null || "".equals(JALVIEW_VERSION)) {
131 JALVIEW_VERSION = releaseProps.get("jalview.version")
134 // this property set when running Eclipse headlessly
135 j2sHeadlessBuildProperty = string("net.sf.j2s.core.headlessbuild")
136 // this property set by Eclipse
137 eclipseApplicationProperty = string("eclipse.application")
138 // CHECK IF RUNNING FROM WITHIN ECLIPSE
139 def eclipseApplicationPropertyVal = System.properties[eclipseApplicationProperty]
140 IN_ECLIPSE = eclipseApplicationPropertyVal != null && eclipseApplicationPropertyVal.startsWith("org.eclipse.ui.")
141 // BUT WITHOUT THE HEADLESS BUILD PROPERTY SET
142 if (System.properties[j2sHeadlessBuildProperty].equals("true")) {
143 println("Setting IN_ECLIPSE to ${IN_ECLIPSE} as System.properties['${j2sHeadlessBuildProperty}'] == '${System.properties[j2sHeadlessBuildProperty]}'")
147 println("WITHIN ECLIPSE IDE")
149 println("HEADLESS BUILD")
152 J2S_ENABLED = (project.hasProperty('j2s.compiler.status') && project['j2s.compiler.status'] != null && project['j2s.compiler.status'] == "enable")
154 println("J2S ENABLED")
157 System.properties.sort { it.key }.each {
158 key, val -> println("SYSTEM PROPERTY ${key}='${val}'")
161 if (false && IN_ECLIPSE) {
162 jalviewDir = jalviewDirAbsolutePath
167 buildDate = new Date().format("yyyyMMdd")
170 bareSourceDir = string(source_dir)
171 sourceDir = string("${jalviewDir}/${bareSourceDir}")
172 resourceDir = string("${jalviewDir}/${resource_dir}")
173 bareTestSourceDir = string(test_source_dir)
174 testDir = string("${jalviewDir}/${bareTestSourceDir}")
176 classesDir = string("${jalviewDir}/${classes_dir}")
179 useClover = clover.equals("true")
180 cloverBuildDir = "${buildDir}/clover"
181 cloverInstrDir = file("${cloverBuildDir}/clover-instr")
182 cloverClassesDir = file("${cloverBuildDir}/clover-classes")
183 cloverReportDir = file("${buildDir}/reports/clover")
184 cloverTestInstrDir = file("${cloverBuildDir}/clover-test-instr")
185 cloverTestClassesDir = file("${cloverBuildDir}/clover-test-classes")
186 //cloverTestClassesDir = cloverClassesDir
187 cloverDb = string("${cloverBuildDir}/clover.db")
189 testSourceDir = useClover ? cloverTestInstrDir : testDir
190 testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}"
192 getdownWebsiteDir = string("${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}")
194 buildProperties = null
196 // the following values might be overridden by the CHANNEL switch
197 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
198 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
199 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
200 getdownAppDistDir = getdown_app_dir_alt
201 getdownImagesDir = string("${jalviewDir}/${getdown_images_dir}")
202 getdownSetAppBaseProperty = false // whether to pass the appbase and appdistdir to the application
203 reportRsyncCommand = false
204 jvlChannelName = CHANNEL.toLowerCase()
205 install4jSuffix = CHANNEL.substring(0, 1).toUpperCase() + CHANNEL.substring(1).toLowerCase(); // BUILD -> Build
206 install4jDMGDSStore = "${install4j_images_dir}/${install4j_dmg_ds_store}"
207 install4jDMGBackgroundImage = "${install4j_images_dir}/${install4j_dmg_background}"
208 install4jInstallerName = "${jalview_name} Non-Release Installer"
209 install4jExecutableName = install4j_executable_name
210 install4jExtraScheme = "jalviewx"
211 install4jMacIconsFile = string("${install4j_images_dir}/${install4j_mac_icons_file}")
212 install4jWindowsIconsFile = string("${install4j_images_dir}/${install4j_windows_icons_file}")
213 install4jPngIconFile = string("${install4j_images_dir}/${install4j_png_icon_file}")
214 install4jBackground = string("${install4j_images_dir}/${install4j_background}")
215 install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
216 install4jCheckSums = true
220 // TODO: get bamboo build artifact URL for getdown artifacts
221 getdown_channel_base = bamboo_channelbase
222 getdownChannelName = string("${bamboo_planKey}/${JAVA_VERSION}")
223 getdownAppBase = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
224 jvlChannelName += "_${getdownChannelName}"
225 // automatically add the test group Not-bamboo for exclusion
226 if ("".equals(testng_excluded_groups)) {
227 testng_excluded_groups = "Not-bamboo"
229 install4jExtraScheme = "jalviewb"
232 case [ "RELEASE", "JALVIEWJS-RELEASE" ]:
233 getdownAppDistDir = getdown_app_dir_release
234 reportRsyncCommand = true
236 install4jInstallerName = "${jalview_name} Installer"
240 getdownChannelName = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
241 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
242 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
243 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
244 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
246 package_dir = string("${ARCHIVEDIR}/${package_dir}")
247 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
250 reportRsyncCommand = true
251 install4jExtraScheme = "jalviewa"
255 getdownChannelName = string("archive/${JALVIEW_VERSION}")
256 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
257 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
258 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
259 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
261 package_dir = string("${ARCHIVEDIR}/${package_dir}")
262 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
265 reportRsyncCommand = true
266 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
267 install4jSuffix = "Archive"
268 install4jExtraScheme = "jalviewa"
272 reportRsyncCommand = true
273 getdownSetAppBaseProperty = true
274 // DEVELOP-RELEASE is usually associated with a Jalview release series so set the version
275 JALVIEW_VERSION=JALVIEW_VERSION+"-d${buildDate}"
277 install4jSuffix = "Develop"
278 install4jExtraScheme = "jalviewd"
279 install4jInstallerName = "${jalview_name} Develop Installer"
283 reportRsyncCommand = true
284 // Don't ignore transpile errors for release build
285 if (jalviewjs_ignore_transpile_errors.equals("true")) {
286 jalviewjs_ignore_transpile_errors = "false"
287 println("Setting jalviewjs_ignore_transpile_errors to 'false'")
289 JALVIEW_VERSION = JALVIEW_VERSION+"-test"
290 install4jSuffix = "Test"
291 install4jExtraScheme = "jalviewt"
292 install4jInstallerName = "${jalview_name} Test Installer"
295 case ~/^SCRATCH(|-[-\w]*)$/:
296 getdownChannelName = CHANNEL
297 JALVIEW_VERSION = JALVIEW_VERSION+"-"+CHANNEL
299 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
300 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
301 reportRsyncCommand = true
302 install4jSuffix = "Scratch"
306 if (!file("${LOCALDIR}").exists()) {
307 throw new GradleException("Must provide a LOCALDIR value to produce a local distribution")
309 getdownAppBase = file(file("${LOCALDIR}").getAbsolutePath()).toURI().toString()
310 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
312 JALVIEW_VERSION = "TEST"
313 install4jSuffix = "Test-Local"
314 install4jExtraScheme = "jalviewt"
315 install4jInstallerName = "${jalview_name} Test Installer"
318 case [ "LOCAL", "JALVIEWJS" ]:
319 JALVIEW_VERSION = "TEST"
320 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
321 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
322 install4jExtraScheme = "jalviewl"
323 install4jCheckSums = false
326 default: // something wrong specified
327 throw new GradleException("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
331 // override getdownAppBase if requested
332 if (findProperty("getdown_appbase_override") != null) {
333 // revert to LOCAL if empty string
334 if (string(getdown_appbase_override) == "") {
335 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
336 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
337 } else if (string(getdown_appbase_override).startsWith("file://")) {
338 getdownAppBase = string(getdown_appbase_override)
339 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
341 getdownAppBase = string(getdown_appbase_override)
343 println("Overriding getdown appbase with '${getdownAppBase}'")
345 // sanitise file name for jalview launcher file for this channel
346 jvlChannelName = jvlChannelName.replaceAll("[^\\w\\-]+", "_")
347 // install4j application and folder names
348 if (install4jSuffix == "") {
349 install4jApplicationName = "${jalview_name}"
350 install4jBundleId = "${install4j_bundle_id}"
351 install4jWinApplicationId = install4j_release_win_application_id
353 install4jApplicationName = "${jalview_name} ${install4jSuffix}"
354 install4jBundleId = "${install4j_bundle_id}-" + install4jSuffix.toLowerCase()
355 // add int hash of install4jSuffix to the last part of the application_id
356 def id = install4j_release_win_application_id
357 def idsplitreverse = id.split("-").reverse()
358 idsplitreverse[0] = idsplitreverse[0].toInteger() + install4jSuffix.hashCode()
359 install4jWinApplicationId = idsplitreverse.reverse().join("-")
361 // sanitise folder and id names
362 // install4jApplicationFolder = e.g. "Jalview Build"
363 install4jApplicationFolder = install4jApplicationName
364 .replaceAll("[\"'~:/\\\\\\s]", "_") // replace all awkward filename chars " ' ~ : / \
365 .replaceAll("_+", "_") // collapse __
366 install4jInternalId = install4jApplicationName
368 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
369 .replaceAll("_+", "") // collapse __
370 //.replaceAll("_*-_*", "-") // collapse _-_
371 install4jUnixApplicationFolder = install4jApplicationName
373 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
374 .replaceAll("_+", "_") // collapse __
375 .replaceAll("_*-_*", "-") // collapse _-_
378 getdownWrapperLink = install4jUnixApplicationFolder // e.g. "jalview_local"
379 getdownAppDir = string("${getdownWebsiteDir}/${getdownAppDistDir}")
380 //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}"
381 getdownResourceDir = string("${getdownWebsiteDir}/${getdown_resource_dir}")
382 getdownInstallDir = string("${getdownWebsiteDir}/${getdown_install_dir}")
383 getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
384 getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
385 /* compile without modules -- using classpath libraries
386 modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
387 modules_runtimeClasspath = modules_compileClasspath
389 def details = versionDetails()
390 gitHash = details.gitHash
391 gitBranch = details.branchName
393 println("Using a ${CHANNEL} profile.")
395 additional_compiler_args = []
396 // configure classpath/args for j8/j11 compilation
397 if (JAVA_VERSION.equals("1.8")) {
398 JAVA_INTEGER_VERSION = string("8")
401 libDistDir = j8libDir
402 compile_source_compatibility = 1.8
403 compile_target_compatibility = 1.8
404 // these are getdown.txt properties defined dependent on the JAVA_VERSION
405 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java8_min_version"))
406 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java8_max_version"))
407 // this property is assigned below and expanded to multiple lines in the getdown task
408 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java8_txt_multi_java_location"))
409 // this property is for the Java library used in eclipse
410 eclipseJavaRuntimeName = string("JavaSE-1.8")
411 } else if (JAVA_VERSION.equals("11")) {
412 JAVA_INTEGER_VERSION = string("11")
414 libDistDir = j11libDir
415 compile_source_compatibility = 11
416 compile_target_compatibility = 11
417 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
418 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
419 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
420 eclipseJavaRuntimeName = string("JavaSE-11")
421 /* compile without modules -- using classpath libraries
422 additional_compiler_args += [
423 '--module-path', modules_compileClasspath.asPath,
424 '--add-modules', j11modules
427 } else if (JAVA_VERSION.equals("17")) {
428 JAVA_INTEGER_VERSION = string("17")
430 libDistDir = j17libDir
431 compile_source_compatibility = 17
432 compile_target_compatibility = 17
433 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
434 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
435 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
436 eclipseJavaRuntimeName = string("JavaSE-17")
437 /* compile without modules -- using classpath libraries
438 additional_compiler_args += [
439 '--module-path', modules_compileClasspath.asPath,
440 '--add-modules', j11modules
444 throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
449 JAVA_MIN_VERSION = JAVA_VERSION
450 JAVA_MAX_VERSION = JAVA_VERSION
451 def jreInstallsDir = string(jre_installs_dir)
452 if (jreInstallsDir.startsWith("~/")) {
453 jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1)
455 macosJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-mac-x64/jre")
456 macosJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-mac-x64.tar.gz")
457 windowsJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-windows-x64/jre")
458 windowsJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-windows-x64.tar.gz")
459 linuxJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-linux-x64/jre")
460 linuxJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-linux-x64.tar.gz")
461 install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
462 install4jConfFileName = string("jalview-install4j-conf.install4j")
463 install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
464 install4jHomeDir = install4j_home_dir
465 if (install4jHomeDir.startsWith("~/")) {
466 install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1)
469 resourceBuildDir = string("${buildDir}/resources")
470 resourcesBuildDir = string("${resourceBuildDir}/resources_build")
471 helpBuildDir = string("${resourceBuildDir}/help_build")
472 docBuildDir = string("${resourceBuildDir}/doc_build")
474 if (buildProperties == null) {
475 buildProperties = string("${resourcesBuildDir}/${build_properties_file}")
477 buildingHTML = string("${jalviewDir}/${doc_dir}/building.html")
478 helpParentDir = string("${jalviewDir}/${help_parent_dir}")
479 helpSourceDir = string("${helpParentDir}/${help_dir}")
480 helpFile = string("${helpBuildDir}/${help_dir}/help.jhm")
483 relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
484 jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
485 jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}")
487 jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
489 jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
491 jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
492 jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
493 jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
494 jalviewjsJalviewCoreHtmlFile = string("")
495 jalviewjsJalviewCoreName = string(jalviewjs_core_name)
496 jalviewjsCoreClasslists = []
497 jalviewjsJalviewTemplateName = string(jalviewjs_name)
498 jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
499 jalviewjsJ2sAltSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_alt_settings}")
500 jalviewjsJ2sProps = null
501 jalviewjsJ2sPlugin = jalviewjs_j2s_plugin
503 eclipseWorkspace = null
504 eclipseBinary = string("")
505 eclipseVersion = string("")
515 outputDir = file(classesDir)
519 srcDirs = [ resourcesBuildDir, docBuildDir, helpBuildDir ]
522 compileClasspath = files(sourceSets.main.java.outputDir)
523 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
525 runtimeClasspath = compileClasspath
526 runtimeClasspath += files(sourceSets.main.resources.srcDirs)
531 srcDirs cloverInstrDir
532 outputDir = cloverClassesDir
536 srcDirs = sourceSets.main.resources.srcDirs
539 compileClasspath = files( sourceSets.clover.java.outputDir )
540 //compileClasspath += files( testClassesDir )
541 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
542 compileClasspath += fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
543 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
545 runtimeClasspath = compileClasspath
550 srcDirs testSourceDir
551 outputDir = file(testClassesDir)
555 srcDirs = useClover ? sourceSets.clover.resources.srcDirs : sourceSets.main.resources.srcDirs
558 compileClasspath = files( sourceSets.test.java.outputDir )
559 compileClasspath += useClover ? sourceSets.clover.compileClasspath : sourceSets.main.compileClasspath
560 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
562 runtimeClasspath = compileClasspath
563 runtimeClasspath += files(sourceSets.test.resources.srcDirs)
569 // eclipse project and settings files creation, also used by buildship
572 name = eclipse_project_name
574 natures 'org.eclipse.jdt.core.javanature',
575 'org.eclipse.jdt.groovy.core.groovyNature',
576 'org.eclipse.buildship.core.gradleprojectnature'
578 buildCommand 'org.eclipse.jdt.core.javabuilder'
579 buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
583 //defaultOutputDir = sourceSets.main.java.outputDir
584 configurations.each{ c->
585 if (c.isCanBeResolved()) {
586 minusConfigurations += [c]
590 plusConfigurations = [ ]
594 def removeTheseToo = []
595 HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
596 cp.entries.each { entry ->
597 // This conditional removes all src classpathentries that a) have already been added or b) aren't "src" or "test".
598 // e.g. this removes the resources dir being copied into bin/main, bin/test AND bin/clover
599 // we add the resources and help/help dirs in as libs afterwards (see below)
600 if (entry.kind == 'src') {
601 if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) {
602 removeTheseToo += entry
604 alreadyAddedSrcPath.putAt(entry.path, true)
609 cp.entries.removeAll(removeTheseToo)
611 //cp.entries += new Output("${eclipse_bin_dir}/main")
612 if (file(helpParentDir).isDirectory()) {
613 cp.entries += new Library(fileReference(helpParentDir))
615 if (file(resourceDir).isDirectory()) {
616 cp.entries += new Library(fileReference(resourceDir))
619 HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
621 sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
622 //don't want to add outputDir as eclipse is using its own output dir in bin/main
623 if (it.isDirectory() || ! it.exists()) {
624 // don't add dirs to classpath, especially if they don't exist
625 return false // groovy "continue" in .any closure
627 def itPath = it.toString()
628 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
629 // make relative path
630 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
632 if (alreadyAddedLibPath.get(itPath)) {
633 //println("Not adding duplicate entry "+itPath)
635 //println("Adding entry "+itPath)
636 cp.entries += new Library(fileReference(itPath))
637 alreadyAddedLibPath.put(itPath, true)
641 sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
642 //no longer want to add outputDir as eclipse is using its own output dir in bin/main
643 if (it.isDirectory() || ! it.exists()) {
644 // don't add dirs to classpath
645 return false // groovy "continue" in .any closure
648 def itPath = it.toString()
649 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
650 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
652 if (alreadyAddedLibPath.get(itPath)) {
655 def lib = new Library(fileReference(itPath))
656 lib.entryAttributes["test"] = "true"
658 alreadyAddedLibPath.put(itPath, true)
666 containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
671 // for the IDE, use java 11 compatibility
672 sourceCompatibility = compile_source_compatibility
673 targetCompatibility = compile_target_compatibility
674 javaRuntimeName = eclipseJavaRuntimeName
676 // add in jalview project specific properties/preferences into eclipse core preferences
678 withProperties { props ->
679 def jalview_prefs = new Properties()
680 def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
681 jalview_prefs.load(ins)
683 jalview_prefs.forEach { t, v ->
684 if (props.getAt(t) == null) {
688 // codestyle file -- overrides previous formatter prefs
689 def csFile = file("${jalviewDirAbsolutePath}/${eclipse_codestyle_file}")
690 if (csFile.exists()) {
691 XmlParser parser = new XmlParser()
692 def profiles = parser.parse(csFile)
693 def profile = profiles.'profile'.find { p -> (p.'@kind' == "CodeFormatterProfile" && p.'@name' == "Jalview") }
694 if (profile != null) {
695 profile.'setting'.each { s ->
697 def value = s.'@value'
698 if (id != null && value != null) {
699 props.putAt(id, value)
710 // Don't want these to be activated if in headless build
711 synchronizationTasks "eclipseSynchronizationTask"
712 //autoBuildTasks "eclipseAutoBuildTask"
718 /* hack to change eclipse prefs in .settings files other than org.eclipse.jdt.core.prefs */
719 // Class to allow updating arbitrary properties files
720 class PropertiesFile extends PropertiesPersistableConfigurationObject {
721 public PropertiesFile(PropertiesTransformer t) { super(t); }
722 @Override protected void load(Properties properties) { }
723 @Override protected void store(Properties properties) { }
724 @Override protected String getDefaultResourceName() { return ""; }
725 // This is necessary, because PropertiesPersistableConfigurationObject fails
726 // if no default properties file exists.
727 @Override public void loadDefaults() { load(new StringBufferInputStream("")); }
730 // Task to update arbitrary properties files (set outputFile)
731 class PropertiesFileTask extends PropertiesGeneratorTask<PropertiesFile> {
732 private final PropertiesFileContentMerger file;
733 public PropertiesFileTask() { file = new PropertiesFileContentMerger(getTransformer()); }
734 protected PropertiesFile create() { return new PropertiesFile(getTransformer()); }
735 protected void configure(PropertiesFile props) {
736 file.getBeforeMerged().execute(props); file.getWhenMerged().execute(props);
738 public void file(Closure closure) { ConfigureUtil.configure(closure, file); }
741 task eclipseUIPreferences(type: PropertiesFileTask) {
742 description = "Generate Eclipse additional settings"
743 def filename = "org.eclipse.jdt.ui.prefs"
744 outputFile = "$projectDir/.settings/${filename}" as File
747 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
752 task eclipseGroovyCorePreferences(type: PropertiesFileTask) {
753 description = "Generate Eclipse additional settings"
754 def filename = "org.eclipse.jdt.groovy.core.prefs"
755 outputFile = "$projectDir/.settings/${filename}" as File
758 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
763 task eclipseAllPreferences {
765 dependsOn eclipseUIPreferences
766 dependsOn eclipseGroovyCorePreferences
769 eclipseUIPreferences.mustRunAfter eclipseJdt
770 eclipseGroovyCorePreferences.mustRunAfter eclipseJdt
772 /* end of eclipse preferences hack */
780 delete cloverBuildDir
781 delete cloverReportDir
786 task cloverInstrJava(type: JavaExec) {
787 group = "Verification"
788 description = "Create clover instrumented source java files"
790 dependsOn cleanClover
792 inputs.files(sourceSets.main.allJava)
793 outputs.dir(cloverInstrDir)
795 //classpath = fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
796 classpath = sourceSets.clover.compileClasspath
797 main = "com.atlassian.clover.CloverInstr"
805 cloverInstrDir.getPath(),
807 def srcFiles = sourceSets.main.allJava.files
810 { file -> file.absolutePath }
813 args argsList.toArray()
816 delete cloverInstrDir
817 println("Clover: About to instrument "+srcFiles.size() +" files")
822 task cloverInstrTests(type: JavaExec) {
823 group = "Verification"
824 description = "Create clover instrumented source test files"
826 dependsOn cleanClover
828 inputs.files(testDir)
829 outputs.dir(cloverTestInstrDir)
831 classpath = sourceSets.clover.compileClasspath
832 main = "com.atlassian.clover.CloverInstr"
842 cloverTestInstrDir.getPath(),
844 args argsList.toArray()
847 delete cloverTestInstrDir
848 println("Clover: About to instrument test files")
854 group = "Verification"
855 description = "Create clover instrumented all source files"
857 dependsOn cloverInstrJava
858 dependsOn cloverInstrTests
862 cloverClasses.dependsOn cloverInstr
865 task cloverConsoleReport(type: JavaExec) {
866 group = "Verification"
867 description = "Creates clover console report"
870 file(cloverDb).exists()
873 inputs.dir cloverClassesDir
875 classpath = sourceSets.clover.runtimeClasspath
876 main = "com.atlassian.clover.reporters.console.ConsoleReporter"
878 if (cloverreport_mem.length() > 0) {
879 maxHeapSize = cloverreport_mem
881 if (cloverreport_jvmargs.length() > 0) {
882 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
892 args argsList.toArray()
896 task cloverHtmlReport(type: JavaExec) {
897 group = "Verification"
898 description = "Creates clover HTML report"
901 file(cloverDb).exists()
904 def cloverHtmlDir = cloverReportDir
905 inputs.dir cloverClassesDir
906 outputs.dir cloverHtmlDir
908 classpath = sourceSets.clover.runtimeClasspath
909 main = "com.atlassian.clover.reporters.html.HtmlReporter"
911 if (cloverreport_mem.length() > 0) {
912 maxHeapSize = cloverreport_mem
914 if (cloverreport_jvmargs.length() > 0) {
915 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
926 if (cloverreport_html_options.length() > 0) {
927 argsList += cloverreport_html_options.split(" ")
930 args argsList.toArray()
934 task cloverXmlReport(type: JavaExec) {
935 group = "Verification"
936 description = "Creates clover XML report"
939 file(cloverDb).exists()
942 def cloverXmlFile = "${cloverReportDir}/clover.xml"
943 inputs.dir cloverClassesDir
944 outputs.file cloverXmlFile
946 classpath = sourceSets.clover.runtimeClasspath
947 main = "com.atlassian.clover.reporters.xml.XMLReporter"
949 if (cloverreport_mem.length() > 0) {
950 maxHeapSize = cloverreport_mem
952 if (cloverreport_jvmargs.length() > 0) {
953 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
964 if (cloverreport_xml_options.length() > 0) {
965 argsList += cloverreport_xml_options.split(" ")
968 args argsList.toArray()
973 group = "Verification"
974 description = "Creates clover reports"
976 dependsOn cloverXmlReport
977 dependsOn cloverHtmlReport
984 sourceCompatibility = compile_source_compatibility
985 targetCompatibility = compile_target_compatibility
986 options.compilerArgs += additional_compiler_args
987 print ("Setting target compatibility to "+targetCompatibility+"\n")
989 //classpath += configurations.cloverRuntime
995 // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ?
996 sourceCompatibility = compile_source_compatibility
997 targetCompatibility = compile_target_compatibility
998 options.compilerArgs = additional_compiler_args
999 options.encoding = "UTF-8"
1001 print ("Setting target compatibility to "+compile_target_compatibility+"\n")
1008 sourceCompatibility = compile_source_compatibility
1009 targetCompatibility = compile_target_compatibility
1010 options.compilerArgs = additional_compiler_args
1012 print ("Setting target compatibility to "+targetCompatibility+"\n")
1019 delete sourceSets.main.java.outputDir
1025 dependsOn cleanClover
1027 delete sourceSets.test.java.outputDir
1032 // format is a string like date.format("dd MMMM yyyy")
1033 def getDate(format) {
1034 def date = new Date()
1035 return date.format(format)
1039 def convertMdToHtml (FileTree mdFiles, File cssFile) {
1040 MutableDataSet options = new MutableDataSet()
1042 def extensions = new ArrayList<>()
1043 extensions.add(AnchorLinkExtension.create())
1044 extensions.add(AutolinkExtension.create())
1045 extensions.add(StrikethroughExtension.create())
1046 extensions.add(TaskListExtension.create())
1047 extensions.add(TablesExtension.create())
1048 extensions.add(TocExtension.create())
1050 options.set(Parser.EXTENSIONS, extensions)
1052 // set GFM table parsing options
1053 options.set(TablesExtension.WITH_CAPTION, false)
1054 options.set(TablesExtension.COLUMN_SPANS, false)
1055 options.set(TablesExtension.MIN_HEADER_ROWS, 1)
1056 options.set(TablesExtension.MAX_HEADER_ROWS, 1)
1057 options.set(TablesExtension.APPEND_MISSING_COLUMNS, true)
1058 options.set(TablesExtension.DISCARD_EXTRA_COLUMNS, true)
1059 options.set(TablesExtension.HEADER_SEPARATOR_COLUMN_MATCH, true)
1061 options.set(AnchorLinkExtension.ANCHORLINKS_SET_ID, false)
1062 options.set(AnchorLinkExtension.ANCHORLINKS_ANCHOR_CLASS, "anchor")
1063 options.set(AnchorLinkExtension.ANCHORLINKS_SET_NAME, true)
1064 options.set(AnchorLinkExtension.ANCHORLINKS_TEXT_PREFIX, "<span class=\"octicon octicon-link\"></span>")
1066 Parser parser = Parser.builder(options).build()
1067 HtmlRenderer renderer = HtmlRenderer.builder(options).build()
1069 mdFiles.each { mdFile ->
1070 // add table of contents
1071 def mdText = "[TOC]\n"+mdFile.text
1073 // grab the first top-level title
1075 def titleRegex = /(?m)^#(\s+|([^#]))(.*)/
1076 def matcher = mdText =~ titleRegex
1077 if (matcher.size() > 0) {
1078 // matcher[0][2] is the first character of the title if there wasn't any whitespace after the #
1079 title = (matcher[0][2] != null ? matcher[0][2] : "")+matcher[0][3]
1081 // or use the filename if none found
1082 if (title == null) {
1083 title = mdFile.getName()
1086 Node document = parser.parse(mdText)
1087 String htmlBody = renderer.render(document)
1088 def htmlText = '''<html>
1089 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1090 <html xmlns="http://www.w3.org/1999/xhtml">
1092 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1093 <meta http-equiv="Content-Style-Type" content="text/css" />
1094 <meta name="generator" content="flexmark" />
1096 htmlText += ((title != null) ? " <title>${title}</title>" : '' )
1098 <style type="text/css">code{white-space: pre;}</style>
1100 htmlText += ((cssFile != null) ? cssFile.text : '')
1101 htmlText += '''</head>
1104 htmlText += htmlBody
1110 def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
1111 def htmlFile = file(htmlFilePath)
1112 println("Creating ${htmlFilePath}")
1113 htmlFile.text = htmlText
1118 task copyDocs(type: Copy) {
1119 def inputDir = "${jalviewDir}/${doc_dir}"
1120 def outputDir = "${docBuildDir}/${doc_dir}"
1124 include('**/*.html')
1126 filter(ReplaceTokens,
1130 'Version-Rel': JALVIEW_VERSION,
1131 'Year-Rel': getDate("yyyy")
1138 exclude('**/*.html')
1143 inputs.dir(inputDir)
1144 outputs.dir(outputDir)
1148 task convertMdFiles {
1150 def mdFiles = fileTree(dir: docBuildDir, include: "**/*.md")
1151 def cssFile = file("${jalviewDir}/${flexmark_css}")
1154 convertMdToHtml(mdFiles, cssFile)
1157 inputs.files(mdFiles)
1158 inputs.file(cssFile)
1161 mdFiles.each { mdFile ->
1162 def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
1163 htmlFiles.add(file(htmlFilePath))
1165 outputs.files(htmlFiles)
1169 task copyHelp(type: Copy) {
1170 def inputDir = helpSourceDir
1171 def outputDir = "${helpBuildDir}/${help_dir}"
1175 include('**/*.html')
1179 filter(ReplaceTokens,
1183 'Version-Rel': JALVIEW_VERSION,
1184 'Year-Rel': getDate("yyyy")
1191 exclude('**/*.html')
1198 inputs.dir(inputDir)
1199 outputs.files(helpFile)
1200 outputs.dir(outputDir)
1204 task copyResources(type: Copy) {
1206 description = "Copy (and make text substitutions in) the resources dir to the build area"
1208 def inputDir = resourceDir
1209 def outputDir = resourcesBuildDir
1213 include('**/*.html')
1215 filter(ReplaceTokens,
1219 'Version-Rel': JALVIEW_VERSION,
1220 'Year-Rel': getDate("yyyy")
1227 exclude('**/*.html')
1232 inputs.dir(inputDir)
1233 outputs.dir(outputDir)
1236 task copyChannelResources(type: Copy) {
1237 dependsOn copyResources
1239 description = "Copy the channel resources dir to the build resources area"
1241 def inputDir = "${channelDir}/${resource_dir}"
1242 def outputDir = resourcesBuildDir
1246 inputs.dir(inputDir)
1247 outputs.dir(outputDir)
1250 task createBuildProperties(type: WriteProperties) {
1251 dependsOn copyResources
1253 description = "Create the ${buildProperties} file"
1255 inputs.dir(sourceDir)
1256 inputs.dir(resourcesBuildDir)
1257 outputFile (buildProperties)
1258 // taking time specific comment out to allow better incremental builds
1259 comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
1260 //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
1261 property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
1262 property "VERSION", JALVIEW_VERSION
1263 property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
1264 if (getdownSetAppBaseProperty) {
1265 property "GETDOWNAPPBASE", getdownAppBase
1266 property "GETDOWNAPPDISTDIR", getdownAppDistDir
1268 outputs.file(outputFile)
1272 task buildIndices(type: JavaExec) {
1274 classpath = sourceSets.main.compileClasspath
1275 main = "com.sun.java.help.search.Indexer"
1276 workingDir = "${helpBuildDir}/${help_dir}"
1279 inputs.dir("${workingDir}/${argDir}")
1281 outputs.dir("${classesDir}/doc")
1282 outputs.dir("${classesDir}/help")
1283 outputs.file("${workingDir}/JavaHelpSearch/DOCS")
1284 outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
1285 outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
1286 outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
1287 outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
1288 outputs.file("${workingDir}/JavaHelpSearch/TMAP")
1291 task buildResources {
1292 dependsOn copyResources
1293 dependsOn copyChannelResources
1294 dependsOn createBuildProperties
1298 dependsOn buildResources
1301 dependsOn convertMdFiles
1302 dependsOn buildIndices
1306 compileJava.dependsOn prepare
1307 run.dependsOn compileJava
1308 //run.dependsOn prepare
1311 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
1316 dependsOn cloverClasses
1318 dependsOn compileJava //?
1322 includeGroups testng_groups
1323 excludeGroups testng_excluded_groups
1325 useDefaultListeners=true
1328 maxHeapSize = "1024m"
1330 workingDir = jalviewDir
1331 def testLaf = project.findProperty("test_laf")
1332 if (testLaf != null) {
1333 println("Setting Test LaF to '${testLaf}'")
1334 systemProperty "laf", testLaf
1336 def testHiDPIScale = project.findProperty("test_HiDPIScale")
1337 if (testHiDPIScale != null) {
1338 println("Setting Test HiDPI Scale to '${testHiDPIScale}'")
1339 systemProperty "sun.java2d.uiScale", testHiDPIScale
1341 sourceCompatibility = compile_source_compatibility
1342 targetCompatibility = compile_target_compatibility
1343 jvmArgs += additional_compiler_args
1347 println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
1353 task compileLinkCheck(type: JavaCompile) {
1355 classpath = files("${jalviewDir}/${utils_dir}")
1356 destinationDir = file("${jalviewDir}/${utils_dir}")
1357 source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
1359 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1360 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1361 outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
1362 outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
1366 task linkCheck(type: JavaExec) {
1368 dependsOn compileLinkCheck
1370 def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
1371 classpath = files("${jalviewDir}/${utils_dir}")
1372 main = "HelpLinksChecker"
1373 workingDir = jalviewDir
1374 args = [ "${helpBuildDir}/${help_dir}", "-nointernet" ]
1376 def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
1377 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1380 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1384 inputs.dir(helpBuildDir)
1385 outputs.file(helpLinksCheckerOutFile)
1389 // import the pubhtmlhelp target
1390 ant.properties.basedir = "${jalviewDir}"
1391 ant.properties.helpBuildDir = "${helpBuildDir}/${help_dir}"
1392 ant.importBuild "${utils_dir}/publishHelp.xml"
1395 task cleanPackageDir(type: Delete) {
1397 delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
1407 attributes "Main-Class": main_class,
1408 "Permissions": "all-permissions",
1409 "Application-Name": install4jApplicationName,
1410 "Codebase": application_codebase,
1411 "Implementation-Version": JALVIEW_VERSION
1414 def outputDir = "${jalviewDir}/${package_dir}"
1415 destinationDirectory = file(outputDir)
1416 archiveFileName = rootProject.name+".jar"
1417 duplicatesStrategy "EXCLUDE"
1424 exclude "**/*.jar.*"
1426 inputs.dir(sourceSets.main.java.outputDir)
1427 sourceSets.main.resources.srcDirs.each{ dir ->
1430 outputs.file("${outputDir}/${archiveFileName}")
1434 task copyJars(type: Copy) {
1435 from fileTree(dir: classesDir, include: "**/*.jar").files
1436 into "${jalviewDir}/${package_dir}"
1440 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
1441 task syncJars(type: Sync) {
1443 from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
1444 into "${jalviewDir}/${package_dir}"
1446 include jar.archiveFileName.getOrNull()
1453 description = "Put all required libraries in dist"
1454 // order of "cleanPackageDir", "copyJars", "jar" important!
1455 jar.mustRunAfter cleanPackageDir
1456 syncJars.mustRunAfter cleanPackageDir
1457 dependsOn cleanPackageDir
1460 outputs.dir("${jalviewDir}/${package_dir}")
1465 dependsOn cleanPackageDir
1472 group = "distribution"
1473 description = "Create a single jar file with all dependency libraries merged. Can be run with java -jar"
1477 from ("${jalviewDir}/${libDistDir}") {
1481 attributes "Implementation-Version": JALVIEW_VERSION,
1482 "Application-Name": install4jApplicationName
1485 duplicatesStrategy "INCLUDE"
1487 mainClassName = shadow_jar_main_class
1489 classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
1494 task getdownWebsite() {
1495 group = "distribution"
1496 description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
1501 def getdownWebsiteResourceFilenames = []
1502 def getdownTextString = ""
1503 def getdownResourceDir = getdownResourceDir
1504 def getdownResourceFilenames = []
1507 // clean the getdown website and files dir before creating getdown folders
1508 delete getdownWebsiteDir
1509 delete getdownFilesDir
1512 from buildProperties
1513 rename(file(buildProperties).getName(), getdown_build_properties)
1516 getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
1518 // set some getdown_txt_ properties then go through all properties looking for getdown_txt_...
1519 def props = project.properties.sort { it.key }
1520 if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
1521 props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
1523 if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) {
1524 props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion)
1526 if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
1527 props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
1529 if (getdownImagesDir != null && file(getdownImagesDir).exists()) {
1530 props.put("getdown_txt_ui.background_image", "${getdownImagesDir}/${getdown_background_image}")
1531 props.put("getdown_txt_ui.instant_background_image", "${getdownImagesDir}/${getdown_instant_background_image}")
1532 props.put("getdown_txt_ui.error_background", "${getdownImagesDir}/${getdown_error_background}")
1533 props.put("getdown_txt_ui.progress_image", "${getdownImagesDir}/${getdown_progress_image}")
1534 props.put("getdown_txt_ui.icon", "${getdownImagesDir}/${getdown_icon}")
1535 props.put("getdown_txt_ui.mac_dock_icon", "${getdownImagesDir}/${getdown_mac_dock_icon}")
1538 props.put("getdown_txt_title", jalview_name)
1539 props.put("getdown_txt_ui.name", install4jApplicationName)
1541 // start with appbase
1542 getdownTextString += "appbase = ${getdownAppBase}\n"
1543 props.each{ prop, val ->
1544 if (prop.startsWith("getdown_txt_") && val != null) {
1545 if (prop.startsWith("getdown_txt_multi_")) {
1546 def key = prop.substring(18)
1547 val.split(",").each{ v ->
1548 def line = "${key} = ${v}\n"
1549 getdownTextString += line
1552 // file values rationalised
1553 if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1555 if (val.indexOf('/') == 0) {
1558 } else if (val.indexOf('/') > 0) {
1559 // relative path (relative to jalviewDir)
1560 r = file( "${jalviewDir}/${val}" )
1563 val = "${getdown_resource_dir}/" + r.getName()
1564 getdownWebsiteResourceFilenames += val
1565 getdownResourceFilenames += r.getPath()
1568 if (! prop.startsWith("getdown_txt_resource")) {
1569 def line = prop.substring(12) + " = ${val}\n"
1570 getdownTextString += line
1576 getdownWebsiteResourceFilenames.each{ filename ->
1577 getdownTextString += "resource = ${filename}\n"
1579 getdownResourceFilenames.each{ filename ->
1582 into getdownResourceDir
1586 def getdownWrapperScripts = [ getdown_bash_wrapper_script, getdown_powershell_wrapper_script, getdown_batch_wrapper_script ]
1587 getdownWrapperScripts.each{ script ->
1588 def s = file( "${jalviewDir}/utils/getdown/${getdown_wrapper_script_dir}/${script}" )
1592 into "${getdownWebsiteDir}/${getdown_wrapper_script_dir}"
1594 getdownTextString += "resource = ${getdown_wrapper_script_dir}/${script}\n"
1599 fileTree(file(package_dir)).each{ f ->
1600 if (f.isDirectory()) {
1601 def files = fileTree(dir: f, include: ["*"]).getFiles()
1603 } else if (f.exists()) {
1607 codeFiles.sort().each{f ->
1608 def name = f.getName()
1609 def line = "code = ${getdownAppDistDir}/${name}\n"
1610 getdownTextString += line
1617 // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
1619 if (JAVA_VERSION.equals("11")) {
1620 def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
1621 j11libFiles.sort().each{f ->
1622 def name = f.getName()
1623 def line = "code = ${getdown_j11lib_dir}/${name}\n"
1624 getdownTextString += line
1627 into getdownJ11libDir
1633 // 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.
1634 //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
1635 getdownTextString += "resource = ${getdown_launcher_new}\n"
1636 getdownTextString += "class = ${main_class}\n"
1637 // Not setting these properties in general so that getdownappbase and getdowndistdir will default to release version in jalview.bin.Cache
1638 if (getdownSetAppBaseProperty) {
1639 getdownTextString += "jvmarg = -Dgetdowndistdir=${getdownAppDistDir}\n"
1640 getdownTextString += "jvmarg = -Dgetdownappbase=${getdownAppBase}\n"
1643 def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
1644 getdown_txt.write(getdownTextString)
1646 def getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
1647 def launchJvl = file("${getdownWebsiteDir}/${getdownLaunchJvl}")
1648 launchJvl.write("appbase=${getdownAppBase}")
1650 // files going into the getdown website dir: getdown-launcher.jar
1652 from getdownLauncher
1653 rename(file(getdownLauncher).getName(), getdown_launcher_new)
1654 into getdownWebsiteDir
1657 // files going into the getdown website dir: getdown-launcher(-local).jar
1659 from getdownLauncher
1660 if (file(getdownLauncher).getName() != getdown_launcher) {
1661 rename(file(getdownLauncher).getName(), getdown_launcher)
1663 into getdownWebsiteDir
1666 // files going into the getdown website dir: ./install dir and files
1667 if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
1670 from getdownLauncher
1671 from "${getdownAppDir}/${getdown_build_properties}"
1672 if (file(getdownLauncher).getName() != getdown_launcher) {
1673 rename(file(getdownLauncher).getName(), getdown_launcher)
1675 into getdownInstallDir
1678 // and make a copy in the getdown files dir (these are not downloaded by getdown)
1680 from getdownInstallDir
1681 into getdownFilesInstallDir
1685 // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties
1689 from getdownLauncher
1690 from "${getdownWebsiteDir}/${getdown_build_properties}"
1691 if (file(getdownLauncher).getName() != getdown_launcher) {
1692 rename(file(getdownLauncher).getName(), getdown_launcher)
1694 into getdownFilesDir
1697 // and ./resources (not all downloaded by getdown)
1699 from getdownResourceDir
1700 into "${getdownFilesDir}/${getdown_resource_dir}"
1705 inputs.dir("${jalviewDir}/${package_dir}")
1707 outputs.dir(getdownWebsiteDir)
1708 outputs.dir(getdownFilesDir)
1712 // a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
1713 task getdownDigestDir(type: JavaExec) {
1715 description "A task to run a getdown Digest on a dir with getdown.txt. Provide a DIGESTDIR property via -PDIGESTDIR=..."
1717 def digestDirPropertyName = "DIGESTDIR"
1719 classpath = files(getdownLauncher)
1720 def digestDir = findProperty(digestDirPropertyName)
1721 if (digestDir == null) {
1722 throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest")
1726 main = "com.threerings.getdown.tools.Digester"
1730 task getdownDigest(type: JavaExec) {
1731 group = "distribution"
1732 description = "Digest the getdown website folder"
1733 dependsOn getdownWebsite
1735 classpath = files(getdownLauncher)
1737 main = "com.threerings.getdown.tools.Digester"
1738 args getdownWebsiteDir
1739 inputs.dir(getdownWebsiteDir)
1740 outputs.file("${getdownWebsiteDir}/digest2.txt")
1745 group = "distribution"
1746 description = "Create the minimal and full getdown app folder for installers and website and create digest file"
1747 dependsOn getdownDigest
1749 if (reportRsyncCommand) {
1750 def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
1751 def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
1752 println "LIKELY RSYNC COMMAND:"
1753 println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
1754 if (RUNRSYNC == "true") {
1756 commandLine "mkdir", "-p", toDir
1759 commandLine "rsync", "-avh", "--delete", fromDir, toDir
1767 tasks.withType(JavaCompile) {
1768 options.encoding = 'UTF-8'
1774 delete getdownWebsiteDir
1775 delete getdownFilesDir
1781 if (file(install4jHomeDir).exists()) {
1783 } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
1784 install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1785 } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
1786 install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
1788 installDir(file(install4jHomeDir))
1790 mediaTypes = Arrays.asList(install4j_media_types.split(","))
1794 task copyInstall4jTemplate {
1795 def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
1796 def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
1797 inputs.file(install4jTemplateFile)
1798 inputs.file(install4jFileAssociationsFile)
1799 inputs.property("CHANNEL", { CHANNEL })
1800 outputs.file(install4jConfFile)
1803 def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
1805 // turn off code signing if no OSX_KEYPASS
1806 if (OSX_KEYPASS == "") {
1807 install4jConfigXml.'**'.codeSigning.each { codeSigning ->
1808 codeSigning.'@macEnabled' = "false"
1810 install4jConfigXml.'**'.windows.each { windows ->
1811 windows.'@runPostProcessor' = "false"
1815 // turn off checksum creation for LOCAL channel
1816 def e = install4jConfigXml.application[0]
1817 e.'@createChecksums' = string(install4jCheckSums)
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 cleanInstallersDataFiles {
1871 def installersOutputTxt = file("${jalviewDir}/${install4jBuildDir}/output.txt")
1872 def installersSha256 = file("${jalviewDir}/${install4jBuildDir}/sha256sums")
1873 def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
1874 def installersJsonFile = file("${jalviewDir}/${install4jBuildDir}/installers-${VERSION_UNDERSCORES}.json")
1876 delete installersOutputTxt
1877 delete installersSha256
1878 delete installersJsonFile
1882 task installerFiles(type: com.install4j.gradle.Install4jTask) {
1883 group = "distribution"
1884 description = "Create the install4j installers"
1886 dependsOn copyInstall4jTemplate
1887 dependsOn cleanInstallersDataFiles
1889 projectFile = install4jConfFile
1891 // create an md5 for the input files to use as version for install4j conf file
1892 def digest = MessageDigest.getInstance("MD5")
1894 (file("${install4jDir}/${install4j_template}").text +
1895 file("${install4jDir}/${install4j_info_plist_file_associations}").text +
1896 file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
1897 def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
1898 if (filesMd5.length() >= 8) {
1899 filesMd5 = filesMd5.substring(0,8)
1901 def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
1904 'JALVIEW_NAME': jalview_name,
1905 'JALVIEW_APPLICATION_NAME': install4jApplicationName,
1906 'JALVIEW_DIR': "../..",
1907 'OSX_KEYSTORE': OSX_KEYSTORE,
1908 'OSX_APPLEID': OSX_APPLEID,
1909 'OSX_ALTOOLPASS': OSX_ALTOOLPASS,
1910 'JSIGN_SH': JSIGN_SH,
1911 'JRE_DIR': getdown_app_dir_java,
1912 'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
1913 'JALVIEW_VERSION': JALVIEW_VERSION,
1914 'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
1915 'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
1916 'JAVA_VERSION': JAVA_VERSION,
1917 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
1918 'VERSION': JALVIEW_VERSION,
1919 'MACOS_JAVA_VM_DIR': macosJavaVMDir,
1920 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
1921 'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
1922 'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
1923 'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
1924 'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
1925 'COPYRIGHT_MESSAGE': install4j_copyright_message,
1926 'BUNDLE_ID': install4jBundleId,
1927 'INTERNAL_ID': install4jInternalId,
1928 'WINDOWS_APPLICATION_ID': install4jWinApplicationId,
1929 'MACOS_DMG_DS_STORE': install4jDMGDSStore,
1930 'MACOS_DMG_BG_IMAGE': install4jDMGBackgroundImage,
1931 'WRAPPER_LINK': getdownWrapperLink,
1932 'BASH_WRAPPER_SCRIPT': getdown_bash_wrapper_script,
1933 'POWERSHELL_WRAPPER_SCRIPT': getdown_powershell_wrapper_script,
1934 'WRAPPER_SCRIPT_BIN_DIR': getdown_wrapper_script_dir,
1935 'INSTALLER_NAME': install4jInstallerName,
1936 'INSTALL4J_UTILS_DIR': install4j_utils_dir,
1937 'GETDOWN_WEBSITE_DIR': getdown_website_dir,
1938 'GETDOWN_FILES_DIR': getdown_files_dir,
1939 'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
1940 'GETDOWN_DIST_DIR': getdownAppDistDir,
1941 'GETDOWN_ALT_DIR': getdown_app_dir_alt,
1942 'GETDOWN_INSTALL_DIR': getdown_install_dir,
1943 'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
1944 'BUILD_DIR': install4jBuildDir,
1945 'APPLICATION_CATEGORIES': install4j_application_categories,
1946 'APPLICATION_FOLDER': install4jApplicationFolder,
1947 'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder,
1948 'EXECUTABLE_NAME': install4jExecutableName,
1949 'EXTRA_SCHEME': install4jExtraScheme,
1950 'MAC_ICONS_FILE': install4jMacIconsFile,
1951 'WINDOWS_ICONS_FILE': install4jWindowsIconsFile,
1952 'PNG_ICON_FILE': install4jPngIconFile,
1953 'BACKGROUND': install4jBackground,
1957 //println("INSTALL4J VARIABLES:")
1958 //variables.each{k,v->println("${k}=${v}")}
1960 destination = "${jalviewDir}/${install4jBuildDir}"
1961 buildSelected = true
1963 if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
1965 disableSigning = true
1966 disableNotarization = true
1970 macKeystorePassword = OSX_KEYPASS
1973 if (OSX_ALTOOLPASS) {
1974 appleIdPassword = OSX_ALTOOLPASS
1975 disableNotarization = false
1977 disableNotarization = true
1981 println("Using projectFile "+projectFile)
1982 if (!disableNotarization) { println("Will notarize OSX App DMG") }
1986 inputs.dir(getdownWebsiteDir)
1987 inputs.file(install4jConfFile)
1988 inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
1989 inputs.dir(macosJavaVMDir)
1990 inputs.dir(windowsJavaVMDir)
1991 outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
1994 def writeInstallersJsonFile(File installersOutputTxt, File installersSha256, File installersJsonFile) {
1995 if ((!installersOutputTxt.exists()) || (install4jCheckSums && (!installersSha256))) {
1996 throw new GradleException("One of the required input files doesn't exist.")
2001 installersOutputTxt.readLines().each { def line ->
2002 if (line.startsWith("#")) {
2005 line.replaceAll("\n","")
2006 def vals = line.split("\t")
2007 def filename = vals[3]
2008 filename = filename.replaceAll(/^.*\//, "")
2009 hash[vals[0]] = [ "id" : vals[0], "os" : vals[1], "name" : vals[2], "file" : filename ]
2010 idHash."${filename}" = vals[0]
2012 if (install4jCheckSums) {
2013 installersSha256.readLines().each { def line ->
2014 if (line.startsWith("#")) {
2017 line.replaceAll("\n","")
2018 def vals = line.split(/\s+\*?/)
2019 def filename = vals[1]
2020 def innerHash = (hash.(idHash."${filename}"))."sha256" = vals[0]
2023 return installersJsonFile.write(new JsonBuilder(hash).toPrettyString())
2026 task makeInstallersJsonFile {
2027 dependsOn installerFiles
2029 def installersOutputTxt = file("${jalviewDir}/${install4jBuildDir}/output.txt")
2030 def installersSha256 = file("${jalviewDir}/${install4jBuildDir}/sha256sums")
2031 def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
2032 def installersJsonFile = file("${jalviewDir}/${install4jBuildDir}/installers-${VERSION_UNDERSCORES}.json")
2034 inputs.file(installersOutputTxt)
2035 if (install4jCheckSums) {
2036 inputs.file(installersSha256)
2038 outputs.file(installersJsonFile)
2041 writeInstallersJsonFile(installersOutputTxt, installersSha256, installersJsonFile)
2045 task staticMakeInstallersJsonFile {
2047 def output = findProperty("i4j_output")
2048 def sha256 = findProperty("i4j_sha256")
2049 def json = findProperty("i4j_json")
2050 if (output == null || sha256 == null || json == null) {
2051 throw new GradleException("Must provide paths to all of output.txt, sha256sums, and output.json with '-Pi4j_output=... -Pi4j_sha256=... -Pi4j_json=...")
2053 writeInstallersJsonFile(file(output), file(sha256), file(json))
2058 dependsOn installerFiles
2059 dependsOn makeInstallersJsonFile
2065 eclipse().configFile(eclipse_codestyle_file)
2070 task sourceDist(type: Tar) {
2071 group "distribution"
2072 description "Create a source .tar.gz file for distribution"
2074 dependsOn createBuildProperties
2075 dependsOn convertMdFiles
2077 def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
2078 def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
2079 archiveFileName = outputFileName
2081 compression Compression.GZIP
2096 "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
2098 "utils/InstallAnywhere",
2113 "gradle.properties",
2124 ".settings/org.eclipse.jdt.core.jalview.prefs",
2128 exclude (EXCLUDE_FILES)
2129 include (PROCESS_FILES)
2130 filter(ReplaceTokens,
2134 'Version-Rel': JALVIEW_VERSION,
2135 'Year-Rel': getDate("yyyy")
2140 exclude (EXCLUDE_FILES)
2141 exclude (PROCESS_FILES)
2142 exclude ("appletlib")
2143 exclude ("**/*locales")
2144 exclude ("*locales/**")
2145 exclude ("utils/InstallAnywhere")
2147 exclude (getdown_files_dir)
2148 exclude (getdown_website_dir)
2150 // exluding these as not using jars as modules yet
2151 exclude ("${j11modDir}/**/*.jar")
2154 include(INCLUDE_FILES)
2156 // from (jalviewDir) {
2157 // // explicit includes for stuff that seemed to not get included
2158 // include(fileTree("test/**/*."))
2159 // exclude(EXCLUDE_FILES)
2160 // exclude(PROCESS_FILES)
2163 from(file(buildProperties).getParent()) {
2164 include(file(buildProperties).getName())
2165 rename(file(buildProperties).getName(), "build_properties")
2167 line.replaceAll("^INSTALLATION=.*\$","INSTALLATION=Source Release"+" git-commit\\\\:"+gitHash+" ["+gitBranch+"]")
2176 dependsOn pubhtmlhelp
2178 inputs.dir("${helpBuildDir}/${help_dir}")
2179 outputs.dir("${buildDir}/distributions/${help_dir}")
2183 task j2sSetHeadlessBuild {
2190 task jalviewjsEnableAltFileProperty(type: WriteProperties) {
2192 description "Enable the alternative J2S Config file for headless build"
2194 outputFile = jalviewjsJ2sSettingsFileName
2195 def j2sPropsFile = file(jalviewjsJ2sSettingsFileName)
2196 def j2sProps = new Properties()
2197 if (j2sPropsFile.exists()) {
2199 def j2sPropsFileFIS = new FileInputStream(j2sPropsFile)
2200 j2sProps.load(j2sPropsFileFIS)
2201 j2sPropsFileFIS.close()
2203 j2sProps.each { prop, val ->
2206 } catch (Exception e) {
2207 println("Exception reading ${jalviewjsJ2sSettingsFileName}")
2211 if (! j2sProps.stringPropertyNames().contains(jalviewjs_j2s_alt_file_property_config)) {
2212 property(jalviewjs_j2s_alt_file_property_config, jalviewjs_j2s_alt_file_property)
2217 task jalviewjsSetEclipseWorkspace {
2218 def propKey = "jalviewjs_eclipse_workspace"
2220 if (project.hasProperty(propKey)) {
2221 propVal = project.getProperty(propKey)
2222 if (propVal.startsWith("~/")) {
2223 propVal = System.getProperty("user.home") + propVal.substring(1)
2226 def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
2227 def propsFile = file(propsFileName)
2228 def eclipseWsDir = propVal
2229 def props = new Properties()
2231 def writeProps = true
2232 if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
2233 def ins = new FileInputStream(propsFileName)
2236 if (props.getProperty(propKey, null) != null) {
2237 eclipseWsDir = props.getProperty(propKey)
2242 if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
2243 def tempDir = File.createTempDir()
2244 eclipseWsDir = tempDir.getAbsolutePath()
2247 eclipseWorkspace = file(eclipseWsDir)
2250 // do not run a headless transpile when we claim to be in Eclipse
2252 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2253 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2255 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2259 props.setProperty(propKey, eclipseWsDir)
2260 propsFile.parentFile.mkdirs()
2261 def bytes = new ByteArrayOutputStream()
2262 props.store(bytes, null)
2263 def propertiesString = bytes.toString()
2264 propsFile.text = propertiesString
2270 println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
2273 //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
2274 outputs.file(propsFileName)
2275 outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
2279 task jalviewjsEclipsePaths {
2282 def eclipseRoot = jalviewjs_eclipse_root
2283 if (eclipseRoot.startsWith("~/")) {
2284 eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
2286 if (OperatingSystem.current().isMacOsX()) {
2287 eclipseRoot += "/Eclipse.app"
2288 eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
2289 eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
2290 } else if (OperatingSystem.current().isWindows()) { // check these paths!!
2291 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2292 eclipseRoot += "/eclipse"
2294 eclipseBinary = "${eclipseRoot}/eclipse.exe"
2295 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2296 } else { // linux or unix
2297 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2298 eclipseRoot += "/eclipse"
2299 println("eclipseDir exists")
2301 eclipseBinary = "${eclipseRoot}/eclipse"
2302 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2305 eclipseVersion = "4.13" // default
2306 def assumedVersion = true
2307 if (file(eclipseProduct).exists()) {
2308 def fis = new FileInputStream(eclipseProduct)
2309 def props = new Properties()
2311 eclipseVersion = props.getProperty("version")
2313 assumedVersion = false
2316 def propKey = "eclipse_debug"
2317 eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
2320 // do not run a headless transpile when we claim to be in Eclipse
2322 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2323 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2325 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2328 if (!assumedVersion) {
2329 println("ECLIPSE VERSION=${eclipseVersion}")
2335 task printProperties {
2337 description "Output to console all System.properties"
2339 System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
2345 dependsOn eclipseProject
2346 dependsOn eclipseClasspath
2347 dependsOn eclipseJdt
2351 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
2352 task jalviewjsEclipseCopyDropins(type: Copy) {
2353 dependsOn jalviewjsEclipsePaths
2355 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
2356 inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
2357 def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
2364 // this eclipse -clean doesn't actually work
2365 task jalviewjsCleanEclipse(type: Exec) {
2366 dependsOn eclipseSetup
2367 dependsOn jalviewjsEclipsePaths
2368 dependsOn jalviewjsEclipseCopyDropins
2370 executable(eclipseBinary)
2371 args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
2377 def inputString = """exit
2380 def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
2381 standardInput = inputByteStream
2384 /* not really working yet
2385 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
2389 task jalviewjsTransferUnzipSwingJs {
2390 def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
2394 from zipTree(file_zip)
2395 into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2399 inputs.file file_zip
2400 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2404 task jalviewjsTransferUnzipLib {
2405 def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
2408 zipFiles.each { file_zip ->
2410 from zipTree(file_zip)
2411 into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2416 inputs.files zipFiles
2417 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2421 task jalviewjsTransferUnzipAllLibs {
2422 dependsOn jalviewjsTransferUnzipSwingJs
2423 dependsOn jalviewjsTransferUnzipLib
2427 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
2429 description "Create the alternative j2s file from the j2s.* properties"
2431 jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
2432 def siteDirProperty = "j2s.site.directory"
2433 def setSiteDir = false
2434 jalviewjsJ2sProps.each { prop, val ->
2436 if (prop == siteDirProperty) {
2437 if (!(val.startsWith('/') || val.startsWith("file://") )) {
2438 val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
2444 if (!setSiteDir) { // default site location, don't override specifically set property
2445 property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
2448 outputFile = jalviewjsJ2sAltSettingsFileName
2451 inputs.properties(jalviewjsJ2sProps)
2452 outputs.file(jalviewjsJ2sAltSettingsFileName)
2457 task jalviewjsEclipseSetup {
2458 dependsOn jalviewjsEclipseCopyDropins
2459 dependsOn jalviewjsSetEclipseWorkspace
2460 dependsOn jalviewjsCreateJ2sSettings
2464 task jalviewjsSyncAllLibs (type: Sync) {
2465 dependsOn jalviewjsTransferUnzipAllLibs
2466 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
2467 inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
2468 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2472 def outputFiles = []
2473 rename { filename ->
2474 outputFiles += "${outputDir}/${filename}"
2481 // should this be exclude really ?
2482 duplicatesStrategy "INCLUDE"
2484 outputs.files outputFiles
2485 inputs.files inputFiles
2489 task jalviewjsSyncResources (type: Sync) {
2490 dependsOn buildResources
2492 def inputFiles = fileTree(dir: resourcesBuildDir)
2493 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2497 def outputFiles = []
2498 rename { filename ->
2499 outputFiles += "${outputDir}/${filename}"
2505 outputs.files outputFiles
2506 inputs.files inputFiles
2510 task jalviewjsSyncSiteResources (type: Sync) {
2511 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
2512 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2516 def outputFiles = []
2517 rename { filename ->
2518 outputFiles += "${outputDir}/${filename}"
2524 outputs.files outputFiles
2525 inputs.files inputFiles
2529 task jalviewjsSyncBuildProperties (type: Sync) {
2530 dependsOn createBuildProperties
2531 def inputFiles = [file(buildProperties)]
2532 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2536 def outputFiles = []
2537 rename { filename ->
2538 outputFiles += "${outputDir}/${filename}"
2544 outputs.files outputFiles
2545 inputs.files inputFiles
2549 task jalviewjsProjectImport(type: Exec) {
2550 dependsOn eclipseSetup
2551 dependsOn jalviewjsEclipsePaths
2552 dependsOn jalviewjsEclipseSetup
2555 // do not run a headless import when we claim to be in Eclipse
2557 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2558 throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2560 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2564 //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
2565 def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
2566 executable(eclipseBinary)
2567 args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
2571 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2573 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2574 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
2577 inputs.file("${jalviewDir}/.project")
2578 outputs.upToDateWhen {
2579 file(projdir).exists()
2584 task jalviewjsTranspile(type: Exec) {
2585 dependsOn jalviewjsEclipseSetup
2586 dependsOn jalviewjsProjectImport
2587 dependsOn jalviewjsEclipsePaths
2589 dependsOn jalviewjsEnableAltFileProperty
2593 // do not run a headless transpile when we claim to be in Eclipse
2595 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2596 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2598 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2602 executable(eclipseBinary)
2603 args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
2607 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2609 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2610 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
2616 stdout = new ByteArrayOutputStream()
2617 stderr = new ByteArrayOutputStream()
2619 def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
2620 def logOutFile = file(logOutFileName)
2621 logOutFile.createNewFile()
2622 logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
2623 BINARY: ${eclipseBinary}
2624 VERSION: ${eclipseVersion}
2625 WORKSPACE: ${eclipseWorkspace}
2626 DEBUG: ${eclipseDebug}
2629 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2630 // combine stdout and stderr
2631 def logErrFOS = logOutFOS
2633 if (jalviewjs_j2s_to_console.equals("true")) {
2634 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2635 new org.apache.tools.ant.util.TeeOutputStream(
2639 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2640 new org.apache.tools.ant.util.TeeOutputStream(
2645 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2648 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2655 if (stdout.toString().contains("Error processing ")) {
2656 // j2s did not complete transpile
2657 //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2658 if (jalviewjs_ignore_transpile_errors.equals("true")) {
2659 println("IGNORING TRANSPILE ERRORS")
2660 println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2662 throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2667 inputs.dir("${jalviewDir}/${sourceDir}")
2668 outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
2669 outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
2673 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
2675 def stdout = new ByteArrayOutputStream()
2676 def stderr = new ByteArrayOutputStream()
2678 def coreFile = file(jsfile)
2680 msg = "Creating core for ${name}...\nGenerating ${jsfile}"
2682 logOutFile.createNewFile()
2683 logOutFile.append(msg+"\n")
2685 def coreTop = file(prefixFile)
2686 def coreBottom = file(suffixFile)
2687 coreFile.getParentFile().mkdirs()
2688 coreFile.createNewFile()
2689 coreFile.write( coreTop.getText("UTF-8") )
2693 def t = f.getText("UTF-8")
2694 t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
2695 coreFile.append( t )
2697 msg = "...file '"+f.getPath()+"' does not exist, skipping"
2699 logOutFile.append(msg+"\n")
2702 coreFile.append( coreBottom.getText("UTF-8") )
2704 msg = "Generating ${zjsfile}"
2706 logOutFile.append(msg+"\n")
2707 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2708 def logErrFOS = logOutFOS
2711 classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
2712 main = "com.google.javascript.jscomp.CommandLineRunner"
2713 jvmArgs = [ "-Dfile.encoding=UTF-8" ]
2714 args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
2717 msg = "\nRunning '"+commandLine.join(' ')+"'\n"
2719 logOutFile.append(msg+"\n")
2721 if (logOutConsole) {
2722 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2723 new org.apache.tools.ant.util.TeeOutputStream(
2727 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2728 new org.apache.tools.ant.util.TeeOutputStream(
2733 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2736 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2743 logOutFile.append(msg+"\n")
2747 task jalviewjsBuildAllCores {
2749 description "Build the core js lib closures listed in the classlists dir"
2750 dependsOn jalviewjsTranspile
2751 dependsOn jalviewjsTransferUnzipSwingJs
2753 def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
2754 def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
2755 def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
2756 def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
2757 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
2758 def prefixFile = "${jsDir}/core/coretop2.js"
2759 def suffixFile = "${jsDir}/core/corebottom2.js"
2761 inputs.file prefixFile
2762 inputs.file suffixFile
2764 def classlistFiles = []
2765 // add the classlists found int the jalviewjs_classlists_dir
2766 fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
2768 def name = file.getName() - ".txt"
2775 // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
2776 //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
2777 classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
2779 jalviewjsCoreClasslists = []
2781 classlistFiles.each {
2784 def file = hash['file']
2785 if (! file.exists()) {
2786 //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
2787 return false // this is a "continue" in groovy .each closure
2789 def name = hash['name']
2791 name = file.getName() - ".txt"
2799 def list = fileTree(dir: j2sDir, includes: filelist)
2801 def jsfile = "${outputDir}/core${name}.js"
2802 def zjsfile = "${outputDir}/core${name}.z.js"
2804 jalviewjsCoreClasslists += [
2813 outputs.file(jsfile)
2814 outputs.file(zjsfile)
2817 // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
2818 def stevesoftClasslistName = "_stevesoft"
2819 def stevesoftClasslist = [
2820 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
2821 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
2822 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
2823 'name': stevesoftClasslistName
2825 jalviewjsCoreClasslists += stevesoftClasslist
2826 inputs.files(stevesoftClasslist['list'])
2827 outputs.file(stevesoftClasslist['jsfile'])
2828 outputs.file(stevesoftClasslist['zjsfile'])
2831 def allClasslistName = "_all"
2832 def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
2833 allJsFiles += fileTree(
2837 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2838 "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
2839 "**/org/jmol/export/JSExporter.js"
2842 allJsFiles += fileTree(
2846 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2847 "**/sun/misc/Unsafe.js",
2848 "**/swingjs/jquery/jquery-editable-select.js",
2849 "**/swingjs/jquery/j2sComboBox.js",
2850 "**/sun/misc/FloatingDecimal.js"
2853 def allClasslist = [
2854 'jsfile': "${outputDir}/core${allClasslistName}.js",
2855 'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
2857 'name': allClasslistName
2859 // not including this version of "all" core at the moment
2860 //jalviewjsCoreClasslists += allClasslist
2861 inputs.files(allClasslist['list'])
2862 outputs.file(allClasslist['jsfile'])
2863 outputs.file(allClasslist['zjsfile'])
2866 def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
2867 logOutFile.getParentFile().mkdirs()
2868 logOutFile.createNewFile()
2869 logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
2871 jalviewjsCoreClasslists.each {
2872 jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
2879 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
2882 into file(outputFile).getParentFile()
2883 rename { filename ->
2884 if (filename.equals(inputFile.getName())) {
2885 return file(outputFile).getName()
2889 filter(ReplaceTokens,
2893 'MAIN': '"'+main_class+'"',
2895 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
2896 'COREKEY': jalviewjs_core_key,
2897 'CORENAME': coreName
2904 task jalviewjsPublishCoreTemplates {
2905 dependsOn jalviewjsBuildAllCores
2906 def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
2907 def inputFile = file(inputFileName)
2908 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2910 def outputFiles = []
2911 jalviewjsCoreClasslists.each { cl ->
2912 def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
2913 cl['outputfile'] = outputFile
2914 outputFiles += outputFile
2918 jalviewjsCoreClasslists.each { cl ->
2919 jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
2922 inputs.file(inputFile)
2923 outputs.files(outputFiles)
2927 task jalviewjsSyncCore (type: Sync) {
2928 dependsOn jalviewjsBuildAllCores
2929 dependsOn jalviewjsPublishCoreTemplates
2930 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
2931 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2935 def outputFiles = []
2936 rename { filename ->
2937 outputFiles += "${outputDir}/${filename}"
2943 outputs.files outputFiles
2944 inputs.files inputFiles
2948 // this Copy version of TransferSiteJs will delete anything else in the target dir
2949 task jalviewjsCopyTransferSiteJs(type: Copy) {
2950 dependsOn jalviewjsTranspile
2951 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2952 into "${jalviewDir}/${jalviewjsSiteDir}"
2956 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
2957 task jalviewjsSyncTransferSiteJs(type: Sync) {
2958 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2960 into "${jalviewDir}/${jalviewjsSiteDir}"
2967 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
2968 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
2969 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
2970 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
2972 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
2973 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
2974 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
2975 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
2978 task jalviewjsPrepareSite {
2980 description "Prepares the website folder including unzipping files and copying resources"
2981 dependsOn jalviewjsSyncAllLibs
2982 dependsOn jalviewjsSyncResources
2983 dependsOn jalviewjsSyncSiteResources
2984 dependsOn jalviewjsSyncBuildProperties
2985 dependsOn jalviewjsSyncCore
2989 task jalviewjsBuildSite {
2991 description "Builds the whole website including transpiled code"
2992 dependsOn jalviewjsCopyTransferSiteJs
2993 dependsOn jalviewjsPrepareSite
2997 task cleanJalviewjsTransferSite {
2999 delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
3000 delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
3001 delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
3002 delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
3007 task cleanJalviewjsSite {
3008 dependsOn cleanJalviewjsTransferSite
3010 delete "${jalviewDir}/${jalviewjsSiteDir}"
3015 task jalviewjsSiteTar(type: Tar) {
3017 description "Creates a tar.gz file for the website"
3018 dependsOn jalviewjsBuildSite
3019 def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
3020 archiveFileName = outputFilename
3022 compression Compression.GZIP
3024 from "${jalviewDir}/${jalviewjsSiteDir}"
3025 into jalviewjs_site_dir // this is inside the tar file
3027 inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
3031 task jalviewjsServer {
3033 def filename = "jalviewjsTest.html"
3034 description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
3035 def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
3040 def f = Class.forName("org.gradle.plugins.javascript.envjs.http.simple.SimpleHttpFileServerFactory")
3041 factory = f.newInstance()
3042 } catch (ClassNotFoundException e) {
3043 throw new GradleException("Unable to create SimpleHttpFileServerFactory")
3045 def port = Integer.valueOf(jalviewjs_server_port)
3050 while(port < start+1000 && !running) {
3052 def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
3053 jalviewjsServer = factory.start(doc_root, port)
3055 url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
3056 println("SERVER STARTED with document root ${doc_root}.")
3057 println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).")
3058 println("For debug: "+url+"?j2sdebug")
3059 println("For verbose: "+url+"?j2sverbose")
3060 } catch (Exception e) {
3065 <p><a href="${url}">JalviewJS Test. <${url}></a></p>
3066 <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
3067 <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
3069 jalviewjsCoreClasslists.each { cl ->
3070 def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
3072 <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></a></p>
3074 println("For core ${cl.name}: "+urlcore)
3077 file(htmlFile).text = htmlText
3080 outputs.file(htmlFile)
3081 outputs.upToDateWhen({false})
3085 task cleanJalviewjsAll {
3087 description "Delete all configuration and build artifacts to do with JalviewJS build"
3088 dependsOn cleanJalviewjsSite
3089 dependsOn jalviewjsEclipsePaths
3092 delete "${jalviewDir}/${jalviewjsBuildDir}"
3093 delete "${jalviewDir}/${eclipse_bin_dir}"
3094 if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
3095 delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
3097 delete jalviewjsJ2sAltSettingsFileName
3100 outputs.upToDateWhen( { false } )
3104 task jalviewjsIDE_checkJ2sPlugin {
3105 group "00 JalviewJS in Eclipse"
3106 description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
3109 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3110 def j2sPluginFile = file(j2sPlugin)
3111 def eclipseHome = System.properties["eclipse.home.location"]
3112 if (eclipseHome == null || ! IN_ECLIPSE) {
3113 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
3115 def eclipseJ2sPluginDirs = [ "${eclipseHome}/dropins" ]
3116 def altPluginsDir = System.properties["org.eclipse.equinox.p2.reconciler.dropins.directory"]
3117 if (altPluginsDir != null && file(altPluginsDir).exists()) {
3118 eclipseJ2sPluginDirs += altPluginsDir
3120 def foundPlugin = false
3121 def j2sPluginFileName = j2sPluginFile.getName()
3122 def eclipseJ2sPlugin
3123 def eclipseJ2sPluginFile
3124 eclipseJ2sPluginDirs.any { dir ->
3125 eclipseJ2sPlugin = "${dir}/${j2sPluginFileName}"
3126 eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3127 if (eclipseJ2sPluginFile.exists()) {
3133 def msg = "Eclipse J2S Plugin is not installed (could not find '${j2sPluginFileName}' in\n"+eclipseJ2sPluginDirs.join("\n")+"\n)\nTry running task jalviewjsIDE_copyJ2sPlugin"
3134 System.err.println(msg)
3135 throw new StopExecutionException(msg)
3138 def digest = MessageDigest.getInstance("MD5")
3140 digest.update(j2sPluginFile.text.bytes)
3141 def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3143 digest.update(eclipseJ2sPluginFile.text.bytes)
3144 def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3146 if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
3147 def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
3148 System.err.println(msg)
3149 throw new StopExecutionException(msg)
3151 def msg = "Eclipse J2S Plugin '${eclipseJ2sPlugin}' is the same as '${j2sPlugin}' (this is good)"
3157 task jalviewjsIDE_copyJ2sPlugin {
3158 group "00 JalviewJS in Eclipse"
3159 description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
3162 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3163 def j2sPluginFile = file(j2sPlugin)
3164 def eclipseHome = System.properties["eclipse.home.location"]
3165 if (eclipseHome == null || ! IN_ECLIPSE) {
3166 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
3168 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
3169 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3170 def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
3171 System.err.println(msg)
3174 eclipseJ2sPluginFile.getParentFile().mkdirs()
3175 into eclipseJ2sPluginFile.getParent()
3181 task jalviewjsIDE_j2sFile {
3182 group "00 JalviewJS in Eclipse"
3183 description "Creates the .j2s file"
3184 dependsOn jalviewjsCreateJ2sSettings
3188 task jalviewjsIDE_SyncCore {
3189 group "00 JalviewJS in Eclipse"
3190 description "Build the core js lib closures listed in the classlists dir and publish core html from template"
3191 dependsOn jalviewjsSyncCore
3195 task jalviewjsIDE_SyncSiteAll {
3196 dependsOn jalviewjsSyncAllLibs
3197 dependsOn jalviewjsSyncResources
3198 dependsOn jalviewjsSyncSiteResources
3199 dependsOn jalviewjsSyncBuildProperties
3203 cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
3206 task jalviewjsIDE_PrepareSite {
3207 group "00 JalviewJS in Eclipse"
3208 description "Sync libs and resources to site dir, but not closure cores"
3210 dependsOn jalviewjsIDE_SyncSiteAll
3211 //dependsOn cleanJalviewjsTransferSite // not sure why this clean is here -- will slow down a re-run of this task
3215 task jalviewjsIDE_AssembleSite {
3216 group "00 JalviewJS in Eclipse"
3217 description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
3218 dependsOn jalviewjsPrepareSite
3222 task jalviewjsIDE_SiteClean {
3223 group "00 JalviewJS in Eclipse"
3224 description "Deletes the Eclipse transpiled site"
3225 dependsOn cleanJalviewjsSite
3229 task jalviewjsIDE_Server {
3230 group "00 JalviewJS in Eclipse"
3231 description "Starts a webserver on localhost to test the website"
3232 dependsOn jalviewjsServer
3236 // buildship runs this at import or gradle refresh
3237 task eclipseSynchronizationTask {
3238 //dependsOn eclipseSetup
3239 dependsOn createBuildProperties
3241 dependsOn jalviewjsIDE_j2sFile
3242 dependsOn jalviewjsIDE_checkJ2sPlugin
3243 dependsOn jalviewjsIDE_PrepareSite
3248 // buildship runs this at build time or project refresh
3249 task eclipseAutoBuildTask {
3250 //dependsOn jalviewjsIDE_checkJ2sPlugin
3251 //dependsOn jalviewjsIDE_PrepareSite
3257 description "Build the site"
3258 dependsOn jalviewjsBuildSite