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 java.util.regex.Matcher
13 import groovy.transform.ExternalizeMethods
14 import groovy.util.XmlParser
15 import groovy.xml.XmlUtil
16 import groovy.json.JsonBuilder
17 import com.vladsch.flexmark.util.ast.Node
18 import com.vladsch.flexmark.html.HtmlRenderer
19 import com.vladsch.flexmark.parser.Parser
20 import com.vladsch.flexmark.util.data.MutableDataSet
21 import com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension
22 import com.vladsch.flexmark.ext.tables.TablesExtension
23 import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension
24 import com.vladsch.flexmark.ext.autolink.AutolinkExtension
25 import com.vladsch.flexmark.ext.anchorlink.AnchorLinkExtension
26 import com.vladsch.flexmark.ext.toc.TocExtension
27 import com.google.common.hash.HashCode
28 import com.google.common.hash.Hashing
29 import com.google.common.io.Files
30 import org.jsoup.Jsoup
31 import org.jsoup.nodes.Element
39 classpath "com.vladsch.flexmark:flexmark-all:0.62.0"
40 classpath "org.jsoup:jsoup:1.14.3"
49 id "com.diffplug.gradle.spotless" version "3.28.0"
50 id 'com.github.johnrengelman.shadow' version '4.0.3'
51 id 'com.install4j.gradle' version '9.0.6'
52 id 'com.dorongold.task-tree' version '2.1.0' // only needed to display task dependency tree with gradle task1 [task2 ...] taskTree
53 id 'com.palantir.git-version' version '0.13.0' apply false
64 // in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use
65 def string(Object o) {
66 return o == null ? "" : o.toString()
69 def overrideProperties(String propsFileName, boolean output = false) {
70 if (propsFileName == null) {
73 def propsFile = file(propsFileName)
74 if (propsFile != null && propsFile.exists()) {
75 println("Using properties from file '${propsFileName}'")
77 def p = new Properties()
78 def localPropsFIS = new FileInputStream(propsFile)
84 if (project.hasProperty(key)) {
85 oldval = project.findProperty(key)
86 project.setProperty(key, val)
88 println("Overriding property '${key}' ('${oldval}') with ${file(propsFile).getName()} value '${val}'")
91 ext.setProperty(key, val)
93 println("Setting ext property '${key}' with ${file(propsFile).getName()}s value '${val}'")
97 } catch (Exception e) {
98 println("Exception reading local.properties")
105 jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
106 jalviewDirRelativePath = jalviewDir
109 getdownChannelName = CHANNEL.toLowerCase()
110 // default to "default". Currently only has different cosmetics for "develop", "release", "default"
111 propertiesChannelName = ["develop", "release", "test-release", "jalviewjs", "jalviewjs-release" ].contains(getdownChannelName) ? getdownChannelName : "default"
112 // Import channel_properties
113 if (getdownChannelName.startsWith("develop")) {
114 propertiesChannelName = file("${jalviewDir}/${channel_properties_dir}/${getdownChannelName}").exists() ? getdownChannelName : "develop"
115 println("SET propertiesChannelName to '${propertiesChannelName}'")
117 channelDir = string("${jalviewDir}/${channel_properties_dir}/${propertiesChannelName}")
118 channelGradleProperties = string("${channelDir}/channel_gradle.properties")
119 channelPropsFile = string("${channelDir}/${resource_dir}/${channel_props}")
120 overrideProperties(channelGradleProperties, false)
121 // local build environment properties
122 // can be "projectDir/local.properties"
123 overrideProperties("${projectDir}/local.properties", true)
124 // or "../projectDir_local.properties"
125 overrideProperties(projectDir.getParent() + "/" + projectDir.getName() + "_local.properties", true)
128 // Import releaseProps from the RELEASE file
129 // or a file specified via JALVIEW_RELEASE_FILE if defined
130 // Expect jalview.version and target release branch in jalview.release
131 releaseProps = new Properties();
132 def releasePropFile = findProperty("JALVIEW_RELEASE_FILE");
133 def defaultReleasePropFile = "${jalviewDirAbsolutePath}/RELEASE";
135 (new File(releasePropFile!=null ? releasePropFile : defaultReleasePropFile)).withInputStream {
136 releaseProps.load(it)
138 } catch (Exception fileLoadError) {
139 throw new Error("Couldn't load release properties file "+(releasePropFile==null ? defaultReleasePropFile : "from custom location: releasePropFile"),fileLoadError);
142 // Set JALVIEW_VERSION if it is not already set
143 if (findProperty("JALVIEW_VERSION")==null || "".equals(JALVIEW_VERSION)) {
144 JALVIEW_VERSION = releaseProps.get("jalview.version")
146 println("JALVIEW_VERSION is set to '${JALVIEW_VERSION}'")
148 // this property set when running Eclipse headlessly
149 j2sHeadlessBuildProperty = string("net.sf.j2s.core.headlessbuild")
150 // this property set by Eclipse
151 eclipseApplicationProperty = string("eclipse.application")
152 // CHECK IF RUNNING FROM WITHIN ECLIPSE
153 def eclipseApplicationPropertyVal = System.properties[eclipseApplicationProperty]
154 IN_ECLIPSE = eclipseApplicationPropertyVal != null && eclipseApplicationPropertyVal.startsWith("org.eclipse.ui.")
155 // BUT WITHOUT THE HEADLESS BUILD PROPERTY SET
156 if (System.properties[j2sHeadlessBuildProperty].equals("true")) {
157 println("Setting IN_ECLIPSE to ${IN_ECLIPSE} as System.properties['${j2sHeadlessBuildProperty}'] == '${System.properties[j2sHeadlessBuildProperty]}'")
161 println("WITHIN ECLIPSE IDE")
163 println("HEADLESS BUILD")
166 J2S_ENABLED = (project.hasProperty('j2s.compiler.status') && project['j2s.compiler.status'] != null && project['j2s.compiler.status'] == "enable")
168 println("J2S ENABLED")
171 System.properties.sort { it.key }.each {
172 key, val -> println("SYSTEM PROPERTY ${key}='${val}'")
175 if (false && IN_ECLIPSE) {
176 jalviewDir = jalviewDirAbsolutePath
181 buildDate = new Date().format("yyyyMMdd")
184 bareSourceDir = string(source_dir)
185 sourceDir = string("${jalviewDir}/${bareSourceDir}")
186 resourceDir = string("${jalviewDir}/${resource_dir}")
187 bareTestSourceDir = string(test_source_dir)
188 testDir = string("${jalviewDir}/${bareTestSourceDir}")
190 classesDir = string("${jalviewDir}/${classes_dir}")
193 useClover = clover.equals("true")
194 cloverBuildDir = "${buildDir}/clover"
195 cloverInstrDir = file("${cloverBuildDir}/clover-instr")
196 cloverClassesDir = file("${cloverBuildDir}/clover-classes")
197 cloverReportDir = file("${buildDir}/reports/clover")
198 cloverTestInstrDir = file("${cloverBuildDir}/clover-test-instr")
199 cloverTestClassesDir = file("${cloverBuildDir}/clover-test-classes")
200 //cloverTestClassesDir = cloverClassesDir
201 cloverDb = string("${cloverBuildDir}/clover.db")
203 testSourceDir = useClover ? cloverTestInstrDir : testDir
204 testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}"
206 getdownChannelDir = string("${getdown_website_dir}/${propertiesChannelName}")
207 getdownAppBaseDir = string("${jalviewDir}/${getdownChannelDir}/${JAVA_VERSION}")
208 getdownArchiveDir = string("${jalviewDir}/${getdown_archive_dir}")
209 getdownFullArchiveDir = null
210 getdownTextLines = []
211 getdownLaunchJvl = null
212 getdownVersionLaunchJvl = null
214 buildProperties = null
216 // the following values might be overridden by the CHANNEL switch
217 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
218 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
219 getdownArchiveAppBase = getdown_archive_base
220 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
221 getdownAppDistDir = getdown_app_dir_alt
222 getdownImagesDir = string("${jalviewDir}/${getdown_images_dir}")
223 getdownSetAppBaseProperty = false // whether to pass the appbase and appdistdir to the application
224 reportRsyncCommand = false
225 jvlChannelName = CHANNEL.toLowerCase()
226 install4jSuffix = CHANNEL.substring(0, 1).toUpperCase() + CHANNEL.substring(1).toLowerCase(); // BUILD -> Build
227 install4jDMGDSStore = "${install4j_images_dir}/${install4j_dmg_ds_store}"
228 install4jDMGBackgroundImage = "${install4j_images_dir}/${install4j_dmg_background}"
229 install4jInstallerName = "${jalview_name} Non-Release Installer"
230 install4jExecutableName = install4j_executable_name
231 install4jExtraScheme = "jalviewx"
232 install4jMacIconsFile = string("${install4j_images_dir}/${install4j_mac_icons_file}")
233 install4jWindowsIconsFile = string("${install4j_images_dir}/${install4j_windows_icons_file}")
234 install4jPngIconFile = string("${install4j_images_dir}/${install4j_png_icon_file}")
235 install4jBackground = string("${install4j_images_dir}/${install4j_background}")
236 install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
237 install4jCheckSums = true
239 applicationName = "${jalview_name}"
243 // TODO: get bamboo build artifact URL for getdown artifacts
244 getdown_channel_base = bamboo_channelbase
245 getdownChannelName = string("${bamboo_planKey}/${JAVA_VERSION}")
246 getdownAppBase = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
247 jvlChannelName += "_${getdownChannelName}"
248 // automatically add the test group Not-bamboo for exclusion
249 if ("".equals(testng_excluded_groups)) {
250 testng_excluded_groups = "Not-bamboo"
252 install4jExtraScheme = "jalviewb"
255 case [ "RELEASE", "JALVIEWJS-RELEASE" ]:
256 getdownAppDistDir = getdown_app_dir_release
257 getdownSetAppBaseProperty = true
258 reportRsyncCommand = true
260 install4jInstallerName = "${jalview_name} Installer"
264 getdownChannelName = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
265 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
266 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
267 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
268 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
270 package_dir = string("${ARCHIVEDIR}/${package_dir}")
271 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
274 reportRsyncCommand = true
275 install4jExtraScheme = "jalviewa"
279 getdownChannelName = string("archive/${JALVIEW_VERSION}")
280 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
281 getdownAppBase = file(getdownAppBaseDir).toURI().toString()
282 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
283 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
285 package_dir = string("${ARCHIVEDIR}/${package_dir}")
286 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
289 reportRsyncCommand = true
290 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
291 install4jSuffix = "Archive"
292 install4jExtraScheme = "jalviewa"
295 case ~/^DEVELOP-([\.\-\w]*)$/:
296 def suffix = Matcher.lastMatcher[0][1]
297 reportRsyncCommand = true
298 getdownSetAppBaseProperty = true
299 JALVIEW_VERSION=JALVIEW_VERSION+"-d${suffix}-${buildDate}"
300 install4jSuffix = "Develop ${suffix}"
301 install4jExtraScheme = "jalviewd"
302 install4jInstallerName = "${jalview_name} Develop ${suffix} Installer"
303 getdownChannelName = string("develop-${suffix}")
304 getdownChannelDir = string("${getdown_website_dir}/${getdownChannelName}")
305 getdownAppBaseDir = string("${jalviewDir}/${getdownChannelDir}/${JAVA_VERSION}")
306 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
307 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
311 reportRsyncCommand = true
312 getdownSetAppBaseProperty = true
313 // DEVELOP-RELEASE is usually associated with a Jalview release series so set the version
314 JALVIEW_VERSION=JALVIEW_VERSION+"-d${buildDate}"
316 install4jSuffix = "Develop"
317 install4jExtraScheme = "jalviewd"
318 install4jInstallerName = "${jalview_name} Develop Installer"
322 reportRsyncCommand = true
323 getdownSetAppBaseProperty = true
324 // Don't ignore transpile errors for release build
325 if (jalviewjs_ignore_transpile_errors.equals("true")) {
326 jalviewjs_ignore_transpile_errors = "false"
327 println("Setting jalviewjs_ignore_transpile_errors to 'false'")
329 JALVIEW_VERSION = JALVIEW_VERSION+"-test"
330 install4jSuffix = "Test"
331 install4jExtraScheme = "jalviewt"
332 install4jInstallerName = "${jalview_name} Test Installer"
335 case ~/^SCRATCH(|-[-\w]*)$/:
336 getdownChannelName = CHANNEL
337 JALVIEW_VERSION = JALVIEW_VERSION+"-"+CHANNEL
339 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
340 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
341 reportRsyncCommand = true
342 install4jSuffix = "Scratch"
346 if (!file("${LOCALDIR}").exists()) {
347 throw new GradleException("Must provide a LOCALDIR value to produce a local distribution")
349 getdownAppBase = file(file("${LOCALDIR}").getAbsolutePath()).toURI().toString()
350 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
352 JALVIEW_VERSION = "TEST"
353 install4jSuffix = "Test-Local"
354 install4jExtraScheme = "jalviewt"
355 install4jInstallerName = "${jalview_name} Test Installer"
358 case [ "LOCAL", "JALVIEWJS" ]:
359 JALVIEW_VERSION = "TEST"
360 getdownAppBase = file(getdownAppBaseDir).toURI().toString()
361 getdownArchiveAppBase = file("${jalviewDir}/${getdown_archive_dir}").toURI().toString()
362 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
363 install4jExtraScheme = "jalviewl"
364 install4jCheckSums = false
367 default: // something wrong specified
368 throw new GradleException("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
372 JALVIEW_VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
373 hugoDataJsonFile = file("${jalviewDir}/${hugo_build_dir}/${hugo_data_installers_dir}/installers-${JALVIEW_VERSION_UNDERSCORES}.json")
374 hugoArchiveMdFile = file("${jalviewDir}/${hugo_build_dir}/${hugo_version_archive_dir}/Version-${JALVIEW_VERSION_UNDERSCORES}/_index.md")
375 // override getdownAppBase if requested
376 if (findProperty("getdown_appbase_override") != null) {
377 // revert to LOCAL if empty string
378 if (string(getdown_appbase_override) == "") {
379 getdownAppBase = file(getdownAppBaseDir).toURI().toString()
380 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
381 } else if (string(getdown_appbase_override).startsWith("file://")) {
382 getdownAppBase = string(getdown_appbase_override)
383 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
385 getdownAppBase = string(getdown_appbase_override)
387 println("Overriding getdown appbase with '${getdownAppBase}'")
389 // sanitise file name for jalview launcher file for this channel
390 jvlChannelName = jvlChannelName.replaceAll("[^\\w\\-]+", "_")
391 // install4j application and folder names
392 if (install4jSuffix == "") {
393 install4jBundleId = "${install4j_bundle_id}"
394 install4jWinApplicationId = install4j_release_win_application_id
396 applicationName = "${jalview_name} ${install4jSuffix}"
397 install4jBundleId = "${install4j_bundle_id}-" + install4jSuffix.toLowerCase()
398 // add int hash of install4jSuffix to the last part of the application_id
399 def id = install4j_release_win_application_id
400 def idsplitreverse = id.split("-").reverse()
401 idsplitreverse[0] = idsplitreverse[0].toInteger() + install4jSuffix.hashCode()
402 install4jWinApplicationId = idsplitreverse.reverse().join("-")
404 // sanitise folder and id names
405 // install4jApplicationFolder = e.g. "Jalview Build"
406 install4jApplicationFolder = applicationName
407 .replaceAll("[\"'~:/\\\\\\s]", "_") // replace all awkward filename chars " ' ~ : / \
408 .replaceAll("_+", "_") // collapse __
409 install4jInternalId = applicationName
411 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
412 .replaceAll("_+", "") // collapse __
413 //.replaceAll("_*-_*", "-") // collapse _-_
414 install4jUnixApplicationFolder = applicationName
416 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
417 .replaceAll("_+", "_") // collapse __
418 .replaceAll("_*-_*", "-") // collapse _-_
421 getdownWrapperLink = install4jUnixApplicationFolder // e.g. "jalview_local"
422 getdownAppDir = string("${getdownAppBaseDir}/${getdownAppDistDir}")
423 //getdownJ11libDir = "${getdownAppBaseDir}/${getdown_j11lib_dir}"
424 getdownResourceDir = string("${getdownAppBaseDir}/${getdown_resource_dir}")
425 getdownInstallDir = string("${getdownAppBaseDir}/${getdown_install_dir}")
426 getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
427 getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
428 /* compile without modules -- using classpath libraries
429 modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
430 modules_runtimeClasspath = modules_compileClasspath
436 apply plugin: "com.palantir.git-version"
437 def details = versionDetails()
438 gitHash = details.gitHash
439 gitBranch = details.branchName
440 } catch(org.gradle.api.internal.plugins.PluginApplicationException e) {
441 println("Not in a git repository. Using git values from RELEASE properties file.")
442 gitHash = releaseProps.getProperty("git.hash")
443 gitBranch = releaseProps.getProperty("git.branch")
444 } catch(java.lang.RuntimeException e1) {
445 throw new GradleException("Error with git-version plugin. Directory '.git' exists but versionDetails() cannot be found.")
448 println("Using a ${CHANNEL} profile.")
450 additional_compiler_args = []
451 // configure classpath/args for j8/j11 compilation
452 if (JAVA_VERSION.equals("1.8")) {
453 JAVA_INTEGER_VERSION = string("8")
456 libDistDir = j8libDir
457 compile_source_compatibility = 1.8
458 compile_target_compatibility = 1.8
459 // these are getdown.txt properties defined dependent on the JAVA_VERSION
460 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java8_min_version"))
461 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java8_max_version"))
462 // this property is assigned below and expanded to multiple lines in the getdown task
463 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java8_txt_multi_java_location"))
464 // this property is for the Java library used in eclipse
465 eclipseJavaRuntimeName = string("JavaSE-1.8")
466 } else if (JAVA_VERSION.equals("11")) {
467 JAVA_INTEGER_VERSION = string("11")
469 libDistDir = j11libDir
470 compile_source_compatibility = 11
471 compile_target_compatibility = 11
472 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
473 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
474 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
475 eclipseJavaRuntimeName = string("JavaSE-11")
476 /* compile without modules -- using classpath libraries
477 additional_compiler_args += [
478 '--module-path', modules_compileClasspath.asPath,
479 '--add-modules', j11modules
482 } else if (JAVA_VERSION.equals("17")) {
483 JAVA_INTEGER_VERSION = string("17")
485 libDistDir = j17libDir
486 compile_source_compatibility = 17
487 compile_target_compatibility = 17
488 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
489 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
490 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
491 eclipseJavaRuntimeName = string("JavaSE-17")
492 /* compile without modules -- using classpath libraries
493 additional_compiler_args += [
494 '--module-path', modules_compileClasspath.asPath,
495 '--add-modules', j11modules
499 throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
504 JAVA_MIN_VERSION = JAVA_VERSION
505 JAVA_MAX_VERSION = JAVA_VERSION
506 def jreInstallsDir = string(jre_installs_dir)
507 if (jreInstallsDir.startsWith("~/")) {
508 jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1)
510 macosJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-mac-x64/jre")
511 windowsJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-windows-x64/jre")
512 linuxJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-linux-x64/jre")
513 macosJavaVMTgz = string("${jreInstallsDir}/tgz/jre_${JAVA_INTEGER_VERSION}_mac_x64.tar.gz")
514 windowsJavaVMTgz = string("${jreInstallsDir}/tgz/jre_${JAVA_INTEGER_VERSION}_windows_x64.tar.gz")
515 linuxJavaVMTgz = string("${jreInstallsDir}/tgz/jre_${JAVA_INTEGER_VERSION}_linux_x64.tar.gz")
516 install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
517 install4jConfFileName = string("jalview-install4j-conf.install4j")
518 install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
519 install4jHomeDir = install4j_home_dir
520 if (install4jHomeDir.startsWith("~/")) {
521 install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1)
524 resourceBuildDir = string("${buildDir}/resources")
525 resourcesBuildDir = string("${resourceBuildDir}/resources_build")
526 helpBuildDir = string("${resourceBuildDir}/help_build")
527 docBuildDir = string("${resourceBuildDir}/doc_build")
529 if (buildProperties == null) {
530 buildProperties = string("${resourcesBuildDir}/${build_properties_file}")
532 buildingHTML = string("${jalviewDir}/${doc_dir}/building.html")
533 helpParentDir = string("${jalviewDir}/${help_parent_dir}")
534 helpSourceDir = string("${helpParentDir}/${help_dir}")
535 helpFile = string("${helpBuildDir}/${help_dir}/help.jhm")
538 relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
539 jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
540 jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}")
542 jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
544 jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
546 jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
547 jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
548 jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
549 jalviewjsJalviewCoreHtmlFile = string("")
550 jalviewjsJalviewCoreName = string(jalviewjs_core_name)
551 jalviewjsCoreClasslists = []
552 jalviewjsJalviewTemplateName = string(jalviewjs_name)
553 jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
554 jalviewjsJ2sAltSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_alt_settings}")
555 jalviewjsJ2sProps = null
556 jalviewjsJ2sPlugin = jalviewjs_j2s_plugin
558 eclipseWorkspace = null
559 eclipseBinary = string("")
560 eclipseVersion = string("")
570 outputDir = file(classesDir)
574 srcDirs = [ resourcesBuildDir, docBuildDir, helpBuildDir ]
577 compileClasspath = files(sourceSets.main.java.outputDir)
578 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
580 runtimeClasspath = compileClasspath
581 runtimeClasspath += files(sourceSets.main.resources.srcDirs)
586 srcDirs cloverInstrDir
587 outputDir = cloverClassesDir
591 srcDirs = sourceSets.main.resources.srcDirs
594 compileClasspath = files( sourceSets.clover.java.outputDir )
595 //compileClasspath += files( testClassesDir )
596 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
597 compileClasspath += fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
598 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
600 runtimeClasspath = compileClasspath
605 srcDirs testSourceDir
606 outputDir = file(testClassesDir)
610 srcDirs = useClover ? sourceSets.clover.resources.srcDirs : sourceSets.main.resources.srcDirs
613 compileClasspath = files( sourceSets.test.java.outputDir )
614 compileClasspath += useClover ? sourceSets.clover.compileClasspath : sourceSets.main.compileClasspath
615 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
617 runtimeClasspath = compileClasspath
618 runtimeClasspath += files(sourceSets.test.resources.srcDirs)
624 // eclipse project and settings files creation, also used by buildship
627 name = eclipse_project_name
629 natures 'org.eclipse.jdt.core.javanature',
630 'org.eclipse.jdt.groovy.core.groovyNature',
631 'org.eclipse.buildship.core.gradleprojectnature'
633 buildCommand 'org.eclipse.jdt.core.javabuilder'
634 buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
638 //defaultOutputDir = sourceSets.main.java.outputDir
639 configurations.each{ c->
640 if (c.isCanBeResolved()) {
641 minusConfigurations += [c]
645 plusConfigurations = [ ]
649 def removeTheseToo = []
650 HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
651 cp.entries.each { entry ->
652 // This conditional removes all src classpathentries that a) have already been added or b) aren't "src" or "test".
653 // e.g. this removes the resources dir being copied into bin/main, bin/test AND bin/clover
654 // we add the resources and help/help dirs in as libs afterwards (see below)
655 if (entry.kind == 'src') {
656 if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) {
657 removeTheseToo += entry
659 alreadyAddedSrcPath.putAt(entry.path, true)
664 cp.entries.removeAll(removeTheseToo)
666 //cp.entries += new Output("${eclipse_bin_dir}/main")
667 if (file(helpParentDir).isDirectory()) {
668 cp.entries += new Library(fileReference(helpParentDir))
670 if (file(resourceDir).isDirectory()) {
671 cp.entries += new Library(fileReference(resourceDir))
674 HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
676 sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
677 //don't want to add outputDir as eclipse is using its own output dir in bin/main
678 if (it.isDirectory() || ! it.exists()) {
679 // don't add dirs to classpath, especially if they don't exist
680 return false // groovy "continue" in .any closure
682 def itPath = it.toString()
683 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
684 // make relative path
685 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
687 if (alreadyAddedLibPath.get(itPath)) {
688 //println("Not adding duplicate entry "+itPath)
690 //println("Adding entry "+itPath)
691 cp.entries += new Library(fileReference(itPath))
692 alreadyAddedLibPath.put(itPath, true)
696 sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
697 //no longer want to add outputDir as eclipse is using its own output dir in bin/main
698 if (it.isDirectory() || ! it.exists()) {
699 // don't add dirs to classpath
700 return false // groovy "continue" in .any closure
703 def itPath = it.toString()
704 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
705 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
707 if (alreadyAddedLibPath.get(itPath)) {
710 def lib = new Library(fileReference(itPath))
711 lib.entryAttributes["test"] = "true"
713 alreadyAddedLibPath.put(itPath, true)
721 containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
726 // for the IDE, use java 11 compatibility
727 sourceCompatibility = compile_source_compatibility
728 targetCompatibility = compile_target_compatibility
729 javaRuntimeName = eclipseJavaRuntimeName
731 // add in jalview project specific properties/preferences into eclipse core preferences
733 withProperties { props ->
734 def jalview_prefs = new Properties()
735 def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
736 jalview_prefs.load(ins)
738 jalview_prefs.forEach { t, v ->
739 if (props.getAt(t) == null) {
743 // codestyle file -- overrides previous formatter prefs
744 def csFile = file("${jalviewDirAbsolutePath}/${eclipse_codestyle_file}")
745 if (csFile.exists()) {
746 XmlParser parser = new XmlParser()
747 def profiles = parser.parse(csFile)
748 def profile = profiles.'profile'.find { p -> (p.'@kind' == "CodeFormatterProfile" && p.'@name' == "Jalview") }
749 if (profile != null) {
750 profile.'setting'.each { s ->
752 def value = s.'@value'
753 if (id != null && value != null) {
754 props.putAt(id, value)
765 // Don't want these to be activated if in headless build
766 synchronizationTasks "eclipseSynchronizationTask"
767 //autoBuildTasks "eclipseAutoBuildTask"
773 /* hack to change eclipse prefs in .settings files other than org.eclipse.jdt.core.prefs */
774 // Class to allow updating arbitrary properties files
775 class PropertiesFile extends PropertiesPersistableConfigurationObject {
776 public PropertiesFile(PropertiesTransformer t) { super(t); }
777 @Override protected void load(Properties properties) { }
778 @Override protected void store(Properties properties) { }
779 @Override protected String getDefaultResourceName() { return ""; }
780 // This is necessary, because PropertiesPersistableConfigurationObject fails
781 // if no default properties file exists.
782 @Override public void loadDefaults() { load(new StringBufferInputStream("")); }
785 // Task to update arbitrary properties files (set outputFile)
786 class PropertiesFileTask extends PropertiesGeneratorTask<PropertiesFile> {
787 private final PropertiesFileContentMerger file;
788 public PropertiesFileTask() { file = new PropertiesFileContentMerger(getTransformer()); }
789 protected PropertiesFile create() { return new PropertiesFile(getTransformer()); }
790 protected void configure(PropertiesFile props) {
791 file.getBeforeMerged().execute(props); file.getWhenMerged().execute(props);
793 public void file(Closure closure) { ConfigureUtil.configure(closure, file); }
796 task eclipseUIPreferences(type: PropertiesFileTask) {
797 description = "Generate Eclipse additional settings"
798 def filename = "org.eclipse.jdt.ui.prefs"
799 outputFile = "$projectDir/.settings/${filename}" as File
802 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
807 task eclipseGroovyCorePreferences(type: PropertiesFileTask) {
808 description = "Generate Eclipse additional settings"
809 def filename = "org.eclipse.jdt.groovy.core.prefs"
810 outputFile = "$projectDir/.settings/${filename}" as File
813 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
818 task eclipseAllPreferences {
820 dependsOn eclipseUIPreferences
821 dependsOn eclipseGroovyCorePreferences
824 eclipseUIPreferences.mustRunAfter eclipseJdt
825 eclipseGroovyCorePreferences.mustRunAfter eclipseJdt
827 /* end of eclipse preferences hack */
835 delete cloverBuildDir
836 delete cloverReportDir
841 task cloverInstrJava(type: JavaExec) {
842 group = "Verification"
843 description = "Create clover instrumented source java files"
845 dependsOn cleanClover
847 inputs.files(sourceSets.main.allJava)
848 outputs.dir(cloverInstrDir)
850 //classpath = fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
851 classpath = sourceSets.clover.compileClasspath
852 main = "com.atlassian.clover.CloverInstr"
860 cloverInstrDir.getPath(),
862 def srcFiles = sourceSets.main.allJava.files
865 { file -> file.absolutePath }
868 args argsList.toArray()
871 delete cloverInstrDir
872 println("Clover: About to instrument "+srcFiles.size() +" files")
877 task cloverInstrTests(type: JavaExec) {
878 group = "Verification"
879 description = "Create clover instrumented source test files"
881 dependsOn cleanClover
883 inputs.files(testDir)
884 outputs.dir(cloverTestInstrDir)
886 classpath = sourceSets.clover.compileClasspath
887 main = "com.atlassian.clover.CloverInstr"
897 cloverTestInstrDir.getPath(),
899 args argsList.toArray()
902 delete cloverTestInstrDir
903 println("Clover: About to instrument test files")
909 group = "Verification"
910 description = "Create clover instrumented all source files"
912 dependsOn cloverInstrJava
913 dependsOn cloverInstrTests
917 cloverClasses.dependsOn cloverInstr
920 task cloverConsoleReport(type: JavaExec) {
921 group = "Verification"
922 description = "Creates clover console report"
925 file(cloverDb).exists()
928 inputs.dir cloverClassesDir
930 classpath = sourceSets.clover.runtimeClasspath
931 main = "com.atlassian.clover.reporters.console.ConsoleReporter"
933 if (cloverreport_mem.length() > 0) {
934 maxHeapSize = cloverreport_mem
936 if (cloverreport_jvmargs.length() > 0) {
937 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
947 args argsList.toArray()
951 task cloverHtmlReport(type: JavaExec) {
952 group = "Verification"
953 description = "Creates clover HTML report"
956 file(cloverDb).exists()
959 def cloverHtmlDir = cloverReportDir
960 inputs.dir cloverClassesDir
961 outputs.dir cloverHtmlDir
963 classpath = sourceSets.clover.runtimeClasspath
964 main = "com.atlassian.clover.reporters.html.HtmlReporter"
966 if (cloverreport_mem.length() > 0) {
967 maxHeapSize = cloverreport_mem
969 if (cloverreport_jvmargs.length() > 0) {
970 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
981 if (cloverreport_html_options.length() > 0) {
982 argsList += cloverreport_html_options.split(" ")
985 args argsList.toArray()
989 task cloverXmlReport(type: JavaExec) {
990 group = "Verification"
991 description = "Creates clover XML report"
994 file(cloverDb).exists()
997 def cloverXmlFile = "${cloverReportDir}/clover.xml"
998 inputs.dir cloverClassesDir
999 outputs.file cloverXmlFile
1001 classpath = sourceSets.clover.runtimeClasspath
1002 main = "com.atlassian.clover.reporters.xml.XMLReporter"
1004 if (cloverreport_mem.length() > 0) {
1005 maxHeapSize = cloverreport_mem
1007 if (cloverreport_jvmargs.length() > 0) {
1008 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
1019 if (cloverreport_xml_options.length() > 0) {
1020 argsList += cloverreport_xml_options.split(" ")
1023 args argsList.toArray()
1028 group = "Verification"
1029 description = "Creates clover reports"
1031 dependsOn cloverXmlReport
1032 dependsOn cloverHtmlReport
1039 sourceCompatibility = compile_source_compatibility
1040 targetCompatibility = compile_target_compatibility
1041 options.compilerArgs += additional_compiler_args
1042 print ("Setting target compatibility to "+targetCompatibility+"\n")
1044 //classpath += configurations.cloverRuntime
1050 // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ?
1051 sourceCompatibility = compile_source_compatibility
1052 targetCompatibility = compile_target_compatibility
1053 options.compilerArgs = additional_compiler_args
1054 options.encoding = "UTF-8"
1056 print ("Setting target compatibility to "+compile_target_compatibility+"\n")
1063 sourceCompatibility = compile_source_compatibility
1064 targetCompatibility = compile_target_compatibility
1065 options.compilerArgs = additional_compiler_args
1067 print ("Setting target compatibility to "+targetCompatibility+"\n")
1074 delete sourceSets.main.java.outputDir
1080 dependsOn cleanClover
1082 delete sourceSets.test.java.outputDir
1087 // format is a string like date.format("dd MMMM yyyy")
1088 def getDate(format) {
1089 return date.format(format)
1093 def convertMdToHtml (FileTree mdFiles, File cssFile) {
1094 MutableDataSet options = new MutableDataSet()
1096 def extensions = new ArrayList<>()
1097 extensions.add(AnchorLinkExtension.create())
1098 extensions.add(AutolinkExtension.create())
1099 extensions.add(StrikethroughExtension.create())
1100 extensions.add(TaskListExtension.create())
1101 extensions.add(TablesExtension.create())
1102 extensions.add(TocExtension.create())
1104 options.set(Parser.EXTENSIONS, extensions)
1106 // set GFM table parsing options
1107 options.set(TablesExtension.WITH_CAPTION, false)
1108 options.set(TablesExtension.COLUMN_SPANS, false)
1109 options.set(TablesExtension.MIN_HEADER_ROWS, 1)
1110 options.set(TablesExtension.MAX_HEADER_ROWS, 1)
1111 options.set(TablesExtension.APPEND_MISSING_COLUMNS, true)
1112 options.set(TablesExtension.DISCARD_EXTRA_COLUMNS, true)
1113 options.set(TablesExtension.HEADER_SEPARATOR_COLUMN_MATCH, true)
1115 options.set(AnchorLinkExtension.ANCHORLINKS_SET_ID, false)
1116 options.set(AnchorLinkExtension.ANCHORLINKS_ANCHOR_CLASS, "anchor")
1117 options.set(AnchorLinkExtension.ANCHORLINKS_SET_NAME, true)
1118 options.set(AnchorLinkExtension.ANCHORLINKS_TEXT_PREFIX, "<span class=\"octicon octicon-link\"></span>")
1120 Parser parser = Parser.builder(options).build()
1121 HtmlRenderer renderer = HtmlRenderer.builder(options).build()
1123 mdFiles.each { mdFile ->
1124 // add table of contents
1125 def mdText = "[TOC]\n"+mdFile.text
1127 // grab the first top-level title
1129 def titleRegex = /(?m)^#(\s+|([^#]))(.*)/
1130 def matcher = mdText =~ titleRegex
1131 if (matcher.size() > 0) {
1132 // matcher[0][2] is the first character of the title if there wasn't any whitespace after the #
1133 title = (matcher[0][2] != null ? matcher[0][2] : "")+matcher[0][3]
1135 // or use the filename if none found
1136 if (title == null) {
1137 title = mdFile.getName()
1140 Node document = parser.parse(mdText)
1141 String htmlBody = renderer.render(document)
1142 def htmlText = '''<html>
1143 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1144 <html xmlns="http://www.w3.org/1999/xhtml">
1146 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
1147 <meta http-equiv="Content-Style-Type" content="text/css" />
1148 <meta name="generator" content="flexmark" />
1150 htmlText += ((title != null) ? " <title>${title}</title>" : '' )
1152 <style type="text/css">code{white-space: pre;}</style>
1154 htmlText += ((cssFile != null) ? cssFile.text : '')
1155 htmlText += '''</head>
1158 htmlText += htmlBody
1164 def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
1165 def htmlFile = file(htmlFilePath)
1166 println("Creating ${htmlFilePath}")
1167 htmlFile.text = htmlText
1172 task copyDocs(type: Copy) {
1173 def inputDir = "${jalviewDir}/${doc_dir}"
1174 def outputDir = "${docBuildDir}/${doc_dir}"
1178 include('**/*.html')
1180 filter(ReplaceTokens,
1184 'Version-Rel': JALVIEW_VERSION,
1185 'Year-Rel': getDate("yyyy")
1192 exclude('**/*.html')
1197 inputs.dir(inputDir)
1198 outputs.dir(outputDir)
1202 task convertMdFiles {
1204 def mdFiles = fileTree(dir: docBuildDir, include: "**/*.md")
1205 def cssFile = file("${jalviewDir}/${flexmark_css}")
1208 convertMdToHtml(mdFiles, cssFile)
1211 inputs.files(mdFiles)
1212 inputs.file(cssFile)
1215 mdFiles.each { mdFile ->
1216 def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html")
1217 htmlFiles.add(file(htmlFilePath))
1219 outputs.files(htmlFiles)
1223 def hugoTemplateSubstitutions(String input, Map extras=null) {
1224 def replacements = [
1225 DATE: getDate("yyyy-MM-dd"),
1226 CHANNEL: propertiesChannelName,
1227 APPLICATION_NAME: applicationName,
1229 GIT_BRANCH: gitBranch,
1230 VERSION: JALVIEW_VERSION,
1231 JAVA_VERSION: JAVA_VERSION,
1232 VERSION_UNDERSCORES: JALVIEW_VERSION_UNDERSCORES,
1237 if (extras != null) {
1238 extras.each{ k, v ->
1239 output = output.replaceAll("__${k}__", ((v == null)?"":v))
1242 replacements.each{ k, v ->
1243 output = output.replaceAll("__${k}__", ((v == null)?"":v))
1248 def mdFileComponents(File mdFile, def dateOnly=false) {
1251 if (mdFile.exists()) {
1252 def inFrontMatter = false
1253 def firstLine = true
1254 mdFile.eachLine { line ->
1255 if (line.matches("---")) {
1256 def prev = inFrontMatter
1257 inFrontMatter = firstLine
1258 if (inFrontMatter != prev)
1261 if (inFrontMatter) {
1263 if (m = line =~ /^date:\s*(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/) {
1264 map["date"] = new Date().parse("yyyy-MM-dd HH:mm:ss", m[0][1])
1265 } else if (m = line =~ /^date:\s*(\d{4}-\d{2}-\d{2})/) {
1266 map["date"] = new Date().parse("yyyy-MM-dd", m[0][1])
1267 } else if (m = line =~ /^channel:\s*(\S+)/) {
1268 map["channel"] = m[0][1]
1269 } else if (m = line =~ /^version:\s*(\S+)/) {
1270 map["version"] = m[0][1]
1271 } else if (m = line =~ /^\s*([^:]+)\s*:\s*(\S.*)/) {
1272 map[ m[0][1] ] = m[0][2]
1274 if (dateOnly && map["date"] != null) {
1280 content += line+"\n"
1285 return dateOnly ? map["date"] : [map, content]
1288 task hugoTemplates {
1290 description "Create partially populated md pages for hugo website build"
1292 def hugoTemplatesDir = file("${jalviewDir}/${hugo_templates_dir}")
1293 def hugoBuildDir = "${jalviewDir}/${hugo_build_dir}"
1294 def templateFiles = fileTree(dir: hugoTemplatesDir)
1295 def releaseMdFile = file("${jalviewDir}/${releases_dir}/release-${JALVIEW_VERSION_UNDERSCORES}.md")
1296 def whatsnewMdFile = file("${jalviewDir}/${whatsnew_dir}/whatsnew-${JALVIEW_VERSION_UNDERSCORES}.md")
1297 def oldJvlFile = file("${jalviewDir}/${hugo_old_jvl}")
1298 def jalviewjsFile = file("${jalviewDir}/${hugo_jalviewjs}")
1301 // specific release template for version archive
1304 def givenDate = null
1305 def givenChannel = null
1306 def givenVersion = null
1307 if (CHANNEL == "RELEASE") {
1308 def (map, content) = mdFileComponents(releaseMdFile)
1309 givenDate = map.date
1310 givenChannel = map.channel
1311 givenVersion = map.version
1313 if (givenVersion != null && givenVersion != JALVIEW_VERSION) {
1314 throw new GradleException("'version' header (${givenVersion}) found in ${releaseMdFile} does not match JALVIEW_VERSION (${JALVIEW_VERSION})")
1317 if (whatsnewMdFile.exists())
1318 whatsnew = whatsnewMdFile.text
1321 def oldJvl = oldJvlFile.exists() ? oldJvlFile.collect{it} : []
1322 def jalviewjsLink = jalviewjsFile.exists() ? jalviewjsFile.collect{it} : []
1324 def changesHugo = null
1325 if (changes != null) {
1326 changesHugo = '<div class="release_notes">\n\n'
1327 def inSection = false
1328 changes.eachLine { line ->
1330 if (m = line =~ /^##([^#].*)$/) {
1332 changesHugo += "</div>\n\n"
1334 def section = m[0][1].trim()
1335 section = section.toLowerCase()
1336 section = section.replaceAll(/ +/, "_")
1337 section = section.replaceAll(/[^a-z0-9_\-]/, "")
1338 changesHugo += "<div class=\"${section}\">\n\n"
1340 } else if (m = line =~ /^(\s*-\s*)<!--([^>]+)-->(.*?)(<br\/?>)?\s*$/) {
1341 def comment = m[0][2].trim()
1342 if (comment != "") {
1343 comment = comment.replaceAll('"', """)
1345 comment.eachMatch(/JAL-\d+/) { jal -> issuekeys += jal }
1346 def newline = m[0][1]
1347 if (comment.trim() != "")
1348 newline += "{{<comment>}}${comment}{{</comment>}} "
1349 newline += m[0][3].trim()
1350 if (issuekeys.size() > 0)
1351 newline += " {{< jal issue=\"${issuekeys.join(",")}\" alt=\"${comment}\" >}}"
1352 if (m[0][4] != null)
1357 changesHugo += line+"\n"
1360 changesHugo += "\n</div>\n\n"
1362 changesHugo += '</div>'
1365 templateFiles.each{ templateFile ->
1366 def newFileName = string(hugoTemplateSubstitutions(templateFile.getName()))
1367 def relPath = hugoTemplatesDir.toPath().relativize(templateFile.toPath()).getParent()
1368 def newRelPathName = hugoTemplateSubstitutions( relPath.toString() )
1370 def outPathName = string("${hugoBuildDir}/$newRelPathName")
1374 rename(templateFile.getName(), newFileName)
1378 def newFile = file("${outPathName}/${newFileName}".toString())
1379 def content = newFile.text
1380 newFile.text = hugoTemplateSubstitutions(content,
1383 CHANGES: changesHugo,
1384 DATE: givenDate == null ? "" : givenDate.format("yyyy-MM-dd"),
1385 DRAFT: givenDate == null ? "true" : "false",
1386 JALVIEWJSLINK: jalviewjsLink.contains(JALVIEW_VERSION) ? "true" : "false",
1387 JVL_HEADER: oldJvl.contains(JALVIEW_VERSION) ? "jvl: true" : ""
1394 inputs.file(oldJvlFile)
1395 inputs.dir(hugoTemplatesDir)
1396 inputs.property("JALVIEW_VERSION", { JALVIEW_VERSION })
1397 inputs.property("CHANNEL", { CHANNEL })
1400 def getMdDate(File mdFile) {
1401 return mdFileComponents(mdFile, true)
1404 def getMdSections(String content) {
1406 def sectionContent = ""
1407 def sectionName = null
1408 content.eachLine { line ->
1410 if (m = line =~ /^##([^#].*)$/) {
1411 if (sectionName != null) {
1412 sections[sectionName] = sectionContent
1416 sectionName = m[0][1].trim()
1417 sectionName = sectionName.toLowerCase()
1418 sectionName = sectionName.replaceAll(/ +/, "_")
1419 sectionName = sectionName.replaceAll(/[^a-z0-9_\-]/, "")
1420 } else if (sectionName != null) {
1421 sectionContent += line+"\n"
1424 if (sectionContent != null) {
1425 sections[sectionName] = sectionContent
1431 task copyHelp(type: Copy) {
1432 def inputDir = helpSourceDir
1433 def outputDir = "${helpBuildDir}/${help_dir}"
1437 include('**/*.html')
1441 filter(ReplaceTokens,
1445 'Version-Rel': JALVIEW_VERSION,
1446 'Year-Rel': getDate("yyyy")
1453 exclude('**/*.html')
1460 inputs.dir(inputDir)
1461 outputs.files(helpFile)
1462 outputs.dir(outputDir)
1466 task releasesTemplates {
1468 description "Recreate whatsNew.html and releases.html from markdown files and templates in help"
1472 def releasesTemplateFile = file("${jalviewDir}/${releases_template}")
1473 def whatsnewTemplateFile = file("${jalviewDir}/${whatsnew_template}")
1474 def releasesHtmlFile = file("${helpBuildDir}/${help_dir}/${releases_html}")
1475 def whatsnewHtmlFile = file("${helpBuildDir}/${help_dir}/${whatsnew_html}")
1476 def releasesMdDir = "${jalviewDir}/${releases_dir}"
1477 def whatsnewMdDir = "${jalviewDir}/${whatsnew_dir}"
1480 def releaseMdFile = file("${releasesMdDir}/release-${JALVIEW_VERSION_UNDERSCORES}.md")
1481 def whatsnewMdFile = file("${whatsnewMdDir}/whatsnew-${JALVIEW_VERSION_UNDERSCORES}.md")
1483 if (CHANNEL == "RELEASE") {
1484 if (!releaseMdFile.exists()) {
1485 throw new GradleException("File ${releaseMdFile} must be created for RELEASE")
1487 if (!whatsnewMdFile.exists()) {
1488 throw new GradleException("File ${whatsnewMdFile} must be created for RELEASE")
1492 def releaseFiles = fileTree(dir: releasesMdDir, include: "release-*.md")
1493 def releaseFilesDates = releaseFiles.collectEntries {
1494 [(it): getMdDate(it)]
1496 releaseFiles = releaseFiles.sort { a,b -> releaseFilesDates[a].compareTo(releaseFilesDates[b]) }
1498 def releasesTemplate = releasesTemplateFile.text
1499 def m = releasesTemplate =~ /(?s)__VERSION_LOOP_START__(.*)__VERSION_LOOP_END__/
1500 def versionTemplate = m[0][1]
1502 MutableDataSet options = new MutableDataSet()
1504 def extensions = new ArrayList<>()
1505 options.set(Parser.EXTENSIONS, extensions)
1506 options.set(Parser.HTML_BLOCK_COMMENT_ONLY_FULL_LINE, true)
1508 Parser parser = Parser.builder(options).build()
1509 HtmlRenderer renderer = HtmlRenderer.builder(options).build()
1511 def actualVersions = releaseFiles.collect { rf ->
1512 def (rfMap, rfContent) = mdFileComponents(rf)
1513 return rfMap.version
1515 def versionsHtml = ""
1516 def linkedVersions = []
1517 releaseFiles.reverse().each { rFile ->
1518 def (rMap, rContent) = mdFileComponents(rFile)
1520 def versionLink = ""
1521 def partialVersion = ""
1522 def firstPart = true
1523 rMap.version.split("\\.").each { part ->
1524 def displayPart = ( firstPart ? "" : "." ) + part
1525 partialVersion += displayPart
1527 linkedVersions.contains(partialVersion)
1528 || ( actualVersions.contains(partialVersion) && partialVersion != rMap.version )
1530 versionLink += displayPart
1532 versionLink += "<a id=\"Jalview.${partialVersion}\">${displayPart}</a>"
1533 linkedVersions += partialVersion
1537 def displayDate = releaseFilesDates[rFile].format("dd/MM/yyyy")
1540 def rContentProcessed = ""
1541 rContent.eachLine { line ->
1542 if (lm = line =~ /^(\s*-)(\s*<!--[^>]*?-->)(.*)$/) {
1543 line = "${lm[0][1]}${lm[0][3]}${lm[0][2]}"
1544 } else if (lm = line =~ /^###([^#]+.*)$/) {
1545 line = "_${lm[0][1].trim()}_"
1547 rContentProcessed += line + "\n"
1550 def rContentSections = getMdSections(rContentProcessed)
1551 def rVersion = versionTemplate
1552 if (rVersion != "") {
1553 def rNewFeatures = rContentSections["new_features"]
1554 def rIssuesResolved = rContentSections["issues_resolved"]
1555 Node newFeaturesNode = parser.parse(rNewFeatures)
1556 String newFeaturesHtml = renderer.render(newFeaturesNode)
1557 Node issuesResolvedNode = parser.parse(rIssuesResolved)
1558 String issuesResolvedHtml = renderer.render(issuesResolvedNode)
1559 rVersion = hugoTemplateSubstitutions(rVersion,
1561 VERSION: rMap.version,
1562 VERSION_LINK: versionLink,
1563 DISPLAY_DATE: displayDate,
1564 NEW_FEATURES: newFeaturesHtml,
1565 ISSUES_RESOLVED: issuesResolvedHtml
1568 versionsHtml += rVersion
1572 releasesTemplate = releasesTemplate.replaceAll("(?s)__VERSION_LOOP_START__.*__VERSION_LOOP_END__", versionsHtml)
1573 releasesTemplate = hugoTemplateSubstitutions(releasesTemplate)
1574 releasesHtmlFile.text = releasesTemplate
1576 if (whatsnewMdFile.exists()) {
1577 def wnDisplayDate = releaseFilesDates[releaseMdFile] != null ? releaseFilesDates[releaseMdFile].format("dd MMMM yyyy") : ""
1578 def whatsnewMd = hugoTemplateSubstitutions(whatsnewMdFile.text)
1579 Node whatsnewNode = parser.parse(whatsnewMd)
1580 String whatsnewHtml = renderer.render(whatsnewNode)
1581 whatsnewHtml = whatsnewTemplateFile.text.replaceAll("__WHATS_NEW__", whatsnewHtml)
1582 whatsnewHtmlFile.text = hugoTemplateSubstitutions(whatsnewHtml,
1584 VERSION: JALVIEW_VERSION,
1585 DISPLAY_DATE: wnDisplayDate
1588 } else if (gradle.taskGraph.hasTask(":linkCheck")) {
1589 whatsnewHtmlFile.text = "Development build " + getDate("yyyy-MM-dd HH:mm:ss")
1594 inputs.file(releasesTemplateFile)
1595 inputs.file(whatsnewTemplateFile)
1596 inputs.dir(releasesMdDir)
1597 inputs.dir(whatsnewMdDir)
1598 outputs.file(releasesHtmlFile)
1599 outputs.file(whatsnewHtmlFile)
1603 task copyResources(type: Copy) {
1605 description = "Copy (and make text substitutions in) the resources dir to the build area"
1607 def inputDir = resourceDir
1608 def outputDir = resourcesBuildDir
1612 include('**/*.html')
1614 filter(ReplaceTokens,
1618 'Version-Rel': JALVIEW_VERSION,
1619 'Year-Rel': getDate("yyyy")
1626 exclude('**/*.html')
1631 inputs.dir(inputDir)
1632 outputs.dir(outputDir)
1635 task copyChannelResources(type: Copy) {
1636 dependsOn copyResources
1638 description = "Copy the channel resources dir to the build resources area"
1640 def inputDir = "${channelDir}/${resource_dir}"
1641 def outputDir = resourcesBuildDir
1645 inputs.dir(inputDir)
1646 outputs.dir(outputDir)
1649 task createBuildProperties(type: WriteProperties) {
1650 dependsOn copyResources
1652 description = "Create the ${buildProperties} file"
1654 inputs.dir(sourceDir)
1655 inputs.dir(resourcesBuildDir)
1656 outputFile (buildProperties)
1657 // taking time specific comment out to allow better incremental builds
1658 comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
1659 //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
1660 property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
1661 property "VERSION", JALVIEW_VERSION
1662 property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
1663 property "JAVA_COMPILE_VERSION", JAVA_INTEGER_VERSION
1664 if (getdownSetAppBaseProperty) {
1665 property "GETDOWNAPPBASE", getdownAppBase
1666 property "GETDOWNAPPDISTDIR", getdownAppDistDir
1668 outputs.file(outputFile)
1672 task buildIndices(type: JavaExec) {
1674 classpath = sourceSets.main.compileClasspath
1675 main = "com.sun.java.help.search.Indexer"
1676 workingDir = "${helpBuildDir}/${help_dir}"
1679 inputs.dir("${workingDir}/${argDir}")
1681 outputs.dir("${classesDir}/doc")
1682 outputs.dir("${classesDir}/help")
1683 outputs.file("${workingDir}/JavaHelpSearch/DOCS")
1684 outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
1685 outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
1686 outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
1687 outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
1688 outputs.file("${workingDir}/JavaHelpSearch/TMAP")
1691 task buildResources {
1692 dependsOn copyResources
1693 dependsOn copyChannelResources
1694 dependsOn createBuildProperties
1698 dependsOn buildResources
1701 dependsOn releasesTemplates
1702 dependsOn convertMdFiles
1703 dependsOn buildIndices
1707 compileJava.dependsOn prepare
1708 run.dependsOn compileJava
1709 //run.dependsOn prepare
1712 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
1717 dependsOn cloverClasses
1719 dependsOn compileJava //?
1723 includeGroups testng_groups
1724 excludeGroups testng_excluded_groups
1726 useDefaultListeners=true
1729 maxHeapSize = "1024m"
1731 workingDir = jalviewDir
1732 def testLaf = project.findProperty("test_laf")
1733 if (testLaf != null) {
1734 println("Setting Test LaF to '${testLaf}'")
1735 systemProperty "laf", testLaf
1737 def testHiDPIScale = project.findProperty("test_HiDPIScale")
1738 if (testHiDPIScale != null) {
1739 println("Setting Test HiDPI Scale to '${testHiDPIScale}'")
1740 systemProperty "sun.java2d.uiScale", testHiDPIScale
1742 sourceCompatibility = compile_source_compatibility
1743 targetCompatibility = compile_target_compatibility
1744 jvmArgs += additional_compiler_args
1748 println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
1754 task compileLinkCheck(type: JavaCompile) {
1756 classpath = files("${jalviewDir}/${utils_dir}")
1757 destinationDir = file("${jalviewDir}/${utils_dir}")
1758 source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
1760 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1761 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1762 outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
1763 outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
1767 task linkCheck(type: JavaExec) {
1769 dependsOn compileLinkCheck
1771 def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
1772 classpath = files("${jalviewDir}/${utils_dir}")
1773 main = "HelpLinksChecker"
1774 workingDir = "${helpBuildDir}"
1775 args = [ "${helpBuildDir}/${help_dir}", "-nointernet" ]
1777 def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
1778 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1781 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1785 inputs.dir(helpBuildDir)
1786 outputs.file(helpLinksCheckerOutFile)
1790 // import the pubhtmlhelp target
1791 ant.properties.basedir = "${jalviewDir}"
1792 ant.properties.helpBuildDir = "${helpBuildDir}/${help_dir}"
1793 ant.importBuild "${utils_dir}/publishHelp.xml"
1796 task cleanPackageDir(type: Delete) {
1798 delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
1808 attributes "Main-Class": main_class,
1809 "Permissions": "all-permissions",
1810 "Application-Name": applicationName,
1811 "Codebase": application_codebase,
1812 "Implementation-Version": JALVIEW_VERSION
1815 def outputDir = "${jalviewDir}/${package_dir}"
1816 destinationDirectory = file(outputDir)
1817 archiveFileName = rootProject.name+".jar"
1818 duplicatesStrategy "EXCLUDE"
1825 exclude "**/*.jar.*"
1827 inputs.dir(sourceSets.main.java.outputDir)
1828 sourceSets.main.resources.srcDirs.each{ dir ->
1831 outputs.file("${outputDir}/${archiveFileName}")
1835 task copyJars(type: Copy) {
1836 from fileTree(dir: classesDir, include: "**/*.jar").files
1837 into "${jalviewDir}/${package_dir}"
1841 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
1842 task syncJars(type: Sync) {
1844 from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
1845 into "${jalviewDir}/${package_dir}"
1847 include jar.archiveFileName.getOrNull()
1854 description = "Put all required libraries in dist"
1855 // order of "cleanPackageDir", "copyJars", "jar" important!
1856 jar.mustRunAfter cleanPackageDir
1857 syncJars.mustRunAfter cleanPackageDir
1858 dependsOn cleanPackageDir
1861 outputs.dir("${jalviewDir}/${package_dir}")
1866 dependsOn cleanPackageDir
1873 group = "distribution"
1874 description = "Create a single jar file with all dependency libraries merged. Can be run with java -jar"
1878 from ("${jalviewDir}/${libDistDir}") {
1882 attributes "Implementation-Version": JALVIEW_VERSION,
1883 "Application-Name": applicationName
1886 duplicatesStrategy "INCLUDE"
1888 mainClassName = shadow_jar_main_class
1890 classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
1895 task getdownWebsite() {
1896 group = "distribution"
1897 description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
1902 def getdownWebsiteResourceFilenames = []
1903 def getdownResourceDir = getdownResourceDir
1904 def getdownResourceFilenames = []
1907 // clean the getdown website and files dir before creating getdown folders
1908 delete getdownAppBaseDir
1909 delete getdownFilesDir
1912 from buildProperties
1913 rename(file(buildProperties).getName(), getdown_build_properties)
1916 getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
1919 from channelPropsFile
1920 into getdownAppBaseDir
1922 getdownWebsiteResourceFilenames += file(channelPropsFile).getName()
1924 // set some getdownTxt_ properties then go through all properties looking for getdownTxt_...
1925 def props = project.properties.sort { it.key }
1926 if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
1927 props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
1929 if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) {
1930 props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion)
1932 if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
1933 props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
1935 if (getdownImagesDir != null && file(getdownImagesDir).exists()) {
1936 props.put("getdown_txt_ui.background_image", "${getdownImagesDir}/${getdown_background_image}")
1937 props.put("getdown_txt_ui.instant_background_image", "${getdownImagesDir}/${getdown_instant_background_image}")
1938 props.put("getdown_txt_ui.error_background", "${getdownImagesDir}/${getdown_error_background}")
1939 props.put("getdown_txt_ui.progress_image", "${getdownImagesDir}/${getdown_progress_image}")
1940 props.put("getdown_txt_ui.icon", "${getdownImagesDir}/${getdown_icon}")
1941 props.put("getdown_txt_ui.mac_dock_icon", "${getdownImagesDir}/${getdown_mac_dock_icon}")
1944 props.put("getdown_txt_title", jalview_name)
1945 props.put("getdown_txt_ui.name", applicationName)
1947 // start with appbase
1948 getdownTextLines += "appbase = ${getdownAppBase}"
1949 props.each{ prop, val ->
1950 if (prop.startsWith("getdown_txt_") && val != null) {
1951 if (prop.startsWith("getdown_txt_multi_")) {
1952 def key = prop.substring(18)
1953 val.split(",").each{ v ->
1954 def line = "${key} = ${v}"
1955 getdownTextLines += line
1958 // file values rationalised
1959 if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1961 if (val.indexOf('/') == 0) {
1964 } else if (val.indexOf('/') > 0) {
1965 // relative path (relative to jalviewDir)
1966 r = file( "${jalviewDir}/${val}" )
1969 val = "${getdown_resource_dir}/" + r.getName()
1970 getdownWebsiteResourceFilenames += val
1971 getdownResourceFilenames += r.getPath()
1974 if (! prop.startsWith("getdown_txt_resource")) {
1975 def line = prop.substring(12) + " = ${val}"
1976 getdownTextLines += line
1982 getdownWebsiteResourceFilenames.each{ filename ->
1983 getdownTextLines += "resource = ${filename}"
1985 getdownResourceFilenames.each{ filename ->
1988 into getdownResourceDir
1992 def getdownWrapperScripts = [ getdown_bash_wrapper_script, getdown_powershell_wrapper_script, getdown_batch_wrapper_script ]
1993 getdownWrapperScripts.each{ script ->
1994 def s = file( "${jalviewDir}/utils/getdown/${getdown_wrapper_script_dir}/${script}" )
1998 into "${getdownAppBaseDir}/${getdown_wrapper_script_dir}"
2000 getdownTextLines += "resource = ${getdown_wrapper_script_dir}/${script}"
2005 fileTree(file(package_dir)).each{ f ->
2006 if (f.isDirectory()) {
2007 def files = fileTree(dir: f, include: ["*"]).getFiles()
2009 } else if (f.exists()) {
2013 def jalviewJar = jar.archiveFileName.getOrNull()
2014 // put jalview.jar first for CLASSPATH and .properties files reasons
2015 codeFiles.sort{a, b -> ( a.getName() == jalviewJar ? -1 : ( b.getName() == jalviewJar ? 1 : a <=> b ) ) }.each{f ->
2016 def name = f.getName()
2017 def line = "code = ${getdownAppDistDir}/${name}"
2018 getdownTextLines += line
2025 // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
2027 if (JAVA_VERSION.equals("11")) {
2028 def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
2029 j11libFiles.sort().each{f ->
2030 def name = f.getName()
2031 def line = "code = ${getdown_j11lib_dir}/${name}"
2032 getdownTextLines += line
2035 into getdownJ11libDir
2041 // 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.
2042 //getdownTextLines += "class = " + file(getdownLauncher).getName()
2043 getdownTextLines += "resource = ${getdown_launcher_new}"
2044 getdownTextLines += "class = ${main_class}"
2045 // Not setting these properties in general so that getdownappbase and getdowndistdir will default to release version in jalview.bin.Cache
2046 if (getdownSetAppBaseProperty) {
2047 getdownTextLines += "jvmarg = -Dgetdowndistdir=${getdownAppDistDir}"
2048 getdownTextLines += "jvmarg = -Dgetdownappbase=${getdownAppBase}"
2051 def getdownTxt = file("${getdownAppBaseDir}/getdown.txt")
2052 getdownTxt.write(getdownTextLines.join("\n"))
2054 getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
2055 def launchJvl = file("${getdownAppBaseDir}/${getdownLaunchJvl}")
2056 launchJvl.write("appbase=${getdownAppBase}")
2058 // files going into the getdown website dir: getdown-launcher.jar
2060 from getdownLauncher
2061 rename(file(getdownLauncher).getName(), getdown_launcher_new)
2062 into getdownAppBaseDir
2065 // files going into the getdown website dir: getdown-launcher(-local).jar
2067 from getdownLauncher
2068 if (file(getdownLauncher).getName() != getdown_launcher) {
2069 rename(file(getdownLauncher).getName(), getdown_launcher)
2071 into getdownAppBaseDir
2074 // files going into the getdown website dir: ./install dir and files
2075 if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
2078 from getdownLauncher
2079 from "${getdownAppDir}/${getdown_build_properties}"
2080 if (file(getdownLauncher).getName() != getdown_launcher) {
2081 rename(file(getdownLauncher).getName(), getdown_launcher)
2083 into getdownInstallDir
2086 // and make a copy in the getdown files dir (these are not downloaded by getdown)
2088 from getdownInstallDir
2089 into getdownFilesInstallDir
2093 // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties
2097 from getdownLauncher
2098 from "${getdownAppBaseDir}/${getdown_build_properties}"
2099 from "${getdownAppBaseDir}/${channel_props}"
2100 if (file(getdownLauncher).getName() != getdown_launcher) {
2101 rename(file(getdownLauncher).getName(), getdown_launcher)
2103 into getdownFilesDir
2106 // and ./resource (not all downloaded by getdown)
2108 from getdownResourceDir
2109 into "${getdownFilesDir}/${getdown_resource_dir}"
2114 inputs.dir("${jalviewDir}/${package_dir}")
2116 outputs.dir(getdownAppBaseDir)
2117 outputs.dir(getdownFilesDir)
2121 // a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
2122 task getdownDigestDir(type: JavaExec) {
2124 description "A task to run a getdown Digest on a dir with getdown.txt. Provide a DIGESTDIR property via -PDIGESTDIR=..."
2126 def digestDirPropertyName = "DIGESTDIR"
2128 classpath = files(getdownLauncher)
2129 def digestDir = findProperty(digestDirPropertyName)
2130 if (digestDir == null) {
2131 throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest")
2135 main = "com.threerings.getdown.tools.Digester"
2139 task getdownDigest(type: JavaExec) {
2140 group = "distribution"
2141 description = "Digest the getdown website folder"
2142 dependsOn getdownWebsite
2144 classpath = files(getdownLauncher)
2146 main = "com.threerings.getdown.tools.Digester"
2147 args getdownAppBaseDir
2148 inputs.dir(getdownAppBaseDir)
2149 outputs.file("${getdownAppBaseDir}/digest2.txt")
2154 group = "distribution"
2155 description = "Create the minimal and full getdown app folder for installers and website and create digest file"
2156 dependsOn getdownDigest
2158 if (reportRsyncCommand) {
2159 def fromDir = getdownAppBaseDir + (getdownAppBaseDir.endsWith('/')?'':'/')
2160 def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
2161 println "LIKELY RSYNC COMMAND:"
2162 println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
2163 if (RUNRSYNC == "true") {
2165 commandLine "mkdir", "-p", toDir
2168 commandLine "rsync", "-avh", "--delete", fromDir, toDir
2176 task getdownArchiveBuild() {
2177 group = "distribution"
2178 description = "Put files in the archive dir to go on the website"
2180 dependsOn getdownWebsite
2182 def v = "v${JALVIEW_VERSION_UNDERSCORES}"
2183 def vDir = "${getdownArchiveDir}/${v}"
2184 getdownFullArchiveDir = "${vDir}/getdown"
2185 getdownVersionLaunchJvl = "${vDir}/jalview-${v}.jvl"
2187 def vAltDir = "alt_${v}"
2188 def archiveImagesDir = "${jalviewDir}/${channel_properties_dir}/old/images"
2191 // cleanup old "old" dir
2192 delete getdownArchiveDir
2194 def getdownArchiveTxt = file("${getdownFullArchiveDir}/getdown.txt")
2195 getdownArchiveTxt.getParentFile().mkdirs()
2196 def getdownArchiveTextLines = []
2197 def getdownFullArchiveAppBase = "${getdownArchiveAppBase}${getdownArchiveAppBase.endsWith("/")?"":"/"}${v}/getdown/"
2201 from "${getdownAppBaseDir}/${getdownAppDistDir}"
2202 into "${getdownFullArchiveDir}/${vAltDir}"
2205 getdownTextLines.each { line ->
2206 line = line.replaceAll("^(?<s>appbase\\s*=\\s*).*", '${s}'+getdownFullArchiveAppBase)
2207 line = line.replaceAll("^(?<s>(resource|code)\\s*=\\s*)${getdownAppDistDir}/", '${s}'+vAltDir+"/")
2208 line = line.replaceAll("^(?<s>ui.background_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background.png")
2209 line = line.replaceAll("^(?<s>ui.instant_background_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background_initialising.png")
2210 line = line.replaceAll("^(?<s>ui.error_background\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background_error.png")
2211 line = line.replaceAll("^(?<s>ui.progress_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_progress_bar.png")
2212 // remove the existing resource = resource/ or bin/ lines
2213 if (! line.matches("resource\\s*=\\s*(resource|bin)/.*")) {
2214 getdownArchiveTextLines += line
2218 // the resource dir -- add these files as resource lines in getdown.txt
2220 from "${archiveImagesDir}"
2221 into "${getdownFullArchiveDir}/${getdown_resource_dir}"
2223 getdownArchiveTextLines += "resource = ${getdown_resource_dir}/${file.getName()}"
2227 getdownArchiveTxt.write(getdownArchiveTextLines.join("\n"))
2229 def vLaunchJvl = file(getdownVersionLaunchJvl)
2230 vLaunchJvl.getParentFile().mkdirs()
2231 vLaunchJvl.write("appbase=${getdownFullArchiveAppBase}\n")
2232 def vLaunchJvlPath = vLaunchJvl.toPath().toAbsolutePath()
2233 def jvlLinkPath = file("${vDir}/jalview.jvl").toPath().toAbsolutePath()
2234 // for some reason filepath.relativize(fileInSameDirPath) gives a path to "../" which is wrong
2235 //java.nio.file.Files.createSymbolicLink(jvlLinkPath, jvlLinkPath.relativize(vLaunchJvlPath));
2236 java.nio.file.Files.createSymbolicLink(jvlLinkPath, java.nio.file.Paths.get(".",vLaunchJvl.getName()));
2238 // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties
2240 from getdownLauncher
2241 from "${getdownAppBaseDir}/${getdownLaunchJvl}"
2242 from "${getdownAppBaseDir}/${getdown_launcher_new}"
2243 from "${getdownAppBaseDir}/${channel_props}"
2244 if (file(getdownLauncher).getName() != getdown_launcher) {
2245 rename(file(getdownLauncher).getName(), getdown_launcher)
2247 into getdownFullArchiveDir
2253 task getdownArchiveDigest(type: JavaExec) {
2254 group = "distribution"
2255 description = "Digest the getdown archive folder"
2257 dependsOn getdownArchiveBuild
2260 classpath = files(getdownLauncher)
2261 args getdownFullArchiveDir
2263 main = "com.threerings.getdown.tools.Digester"
2264 inputs.dir(getdownFullArchiveDir)
2265 outputs.file("${getdownFullArchiveDir}/digest2.txt")
2268 task getdownArchive() {
2269 group = "distribution"
2270 description = "Build the website archive dir with getdown digest"
2272 dependsOn getdownArchiveBuild
2273 dependsOn getdownArchiveDigest
2276 tasks.withType(JavaCompile) {
2277 options.encoding = 'UTF-8'
2283 delete getdownAppBaseDir
2284 delete getdownFilesDir
2285 delete getdownArchiveDir
2291 if (file(install4jHomeDir).exists()) {
2293 } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
2294 install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
2295 } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
2296 install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
2298 installDir(file(install4jHomeDir))
2300 mediaTypes = Arrays.asList(install4j_media_types.split(","))
2304 task copyInstall4jTemplate {
2305 def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
2306 def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
2307 inputs.file(install4jTemplateFile)
2308 inputs.file(install4jFileAssociationsFile)
2309 inputs.property("CHANNEL", { CHANNEL })
2310 outputs.file(install4jConfFile)
2313 def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
2315 // turn off code signing if no OSX_KEYPASS
2316 if (OSX_KEYPASS == "") {
2317 install4jConfigXml.'**'.codeSigning.each { codeSigning ->
2318 codeSigning.'@macEnabled' = "false"
2320 install4jConfigXml.'**'.windows.each { windows ->
2321 windows.'@runPostProcessor' = "false"
2325 // disable install screen for OSX dmg (for 2.11.2.0)
2326 install4jConfigXml.'**'.macosArchive.each { macosArchive ->
2327 macosArchive.attributes().remove('executeSetupApp')
2328 macosArchive.attributes().remove('setupAppId')
2331 // turn off checksum creation for LOCAL channel
2332 def e = install4jConfigXml.application[0]
2333 e.'@createChecksums' = string(install4jCheckSums)
2335 // put file association actions where placeholder action is
2336 def install4jFileAssociationsText = install4jFileAssociationsFile.text
2337 def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
2338 install4jConfigXml.'**'.action.any { a -> // .any{} stops after the first one that returns true
2339 if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
2340 def parent = a.parent()
2342 fileAssociationActions.each { faa ->
2345 // don't need to continue in .any loop once replacements have been made
2350 // use Windows Program Group with Examples folder for RELEASE, and Program Group without Examples for everything else
2351 // NB we're deleting the /other/ one!
2352 // Also remove the examples subdir from non-release versions
2353 def customizedIdToDelete = "PROGRAM_GROUP_RELEASE"
2354 // 2.11.1.0 NOT releasing with the Examples folder in the Program Group
2355 if (false && CHANNEL=="RELEASE") { // remove 'false && ' to include Examples folder in RELEASE channel
2356 customizedIdToDelete = "PROGRAM_GROUP_NON_RELEASE"
2358 // remove the examples subdir from Full File Set
2359 def files = install4jConfigXml.files[0]
2360 def fileset = files.filesets.fileset.find { fs -> fs.'@customizedId' == "FULL_FILE_SET" }
2361 def root = files.roots.root.find { r -> r.'@fileset' == fileset.'@id' }
2362 def mountPoint = files.mountPoints.mountPoint.find { mp -> mp.'@root' == root.'@id' }
2363 def dirEntry = files.entries.dirEntry.find { de -> de.'@mountPoint' == mountPoint.'@id' && de.'@subDirectory' == "examples" }
2364 dirEntry.parent().remove(dirEntry)
2366 install4jConfigXml.'**'.action.any { a ->
2367 if (a.'@customizedId' == customizedIdToDelete) {
2368 def parent = a.parent()
2374 // write install4j file
2375 install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
2382 delete install4jConfFile
2386 task cleanInstallersDataFiles {
2387 def installersOutputTxt = file("${jalviewDir}/${install4jBuildDir}/output.txt")
2388 def installersSha256 = file("${jalviewDir}/${install4jBuildDir}/sha256sums")
2389 def hugoDataJsonFile = file("${jalviewDir}/${install4jBuildDir}/installers-${JALVIEW_VERSION_UNDERSCORES}.json")
2391 delete installersOutputTxt
2392 delete installersSha256
2393 delete hugoDataJsonFile
2397 task installerFiles(type: com.install4j.gradle.Install4jTask) {
2398 group = "distribution"
2399 description = "Create the install4j installers"
2401 dependsOn copyInstall4jTemplate
2402 dependsOn cleanInstallersDataFiles
2404 projectFile = install4jConfFile
2406 // create an md5 for the input files to use as version for install4j conf file
2407 def digest = MessageDigest.getInstance("MD5")
2409 (file("${install4jDir}/${install4j_template}").text +
2410 file("${install4jDir}/${install4j_info_plist_file_associations}").text +
2411 file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
2412 def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
2413 if (filesMd5.length() >= 8) {
2414 filesMd5 = filesMd5.substring(0,8)
2416 def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
2419 'JALVIEW_NAME': jalview_name,
2420 'JALVIEW_APPLICATION_NAME': applicationName,
2421 'JALVIEW_DIR': "../..",
2422 'OSX_KEYSTORE': OSX_KEYSTORE,
2423 'OSX_APPLEID': OSX_APPLEID,
2424 'OSX_ALTOOLPASS': OSX_ALTOOLPASS,
2425 'JSIGN_SH': JSIGN_SH,
2426 'JRE_DIR': getdown_app_dir_java,
2427 'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
2428 'JALVIEW_VERSION': JALVIEW_VERSION,
2429 'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
2430 'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
2431 'JAVA_VERSION': JAVA_VERSION,
2432 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
2433 'VERSION': JALVIEW_VERSION,
2434 'MACOS_JAVA_VM_DIR': macosJavaVMDir,
2435 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
2436 'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
2437 'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
2438 'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
2439 'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
2440 'COPYRIGHT_MESSAGE': install4j_copyright_message,
2441 'BUNDLE_ID': install4jBundleId,
2442 'INTERNAL_ID': install4jInternalId,
2443 'WINDOWS_APPLICATION_ID': install4jWinApplicationId,
2444 'MACOS_DMG_DS_STORE': install4jDMGDSStore,
2445 'MACOS_DMG_BG_IMAGE': install4jDMGBackgroundImage,
2446 'WRAPPER_LINK': getdownWrapperLink,
2447 'BASH_WRAPPER_SCRIPT': getdown_bash_wrapper_script,
2448 'POWERSHELL_WRAPPER_SCRIPT': getdown_powershell_wrapper_script,
2449 'WRAPPER_SCRIPT_BIN_DIR': getdown_wrapper_script_dir,
2450 'INSTALLER_NAME': install4jInstallerName,
2451 'INSTALL4J_UTILS_DIR': install4j_utils_dir,
2452 'GETDOWN_CHANNEL_DIR': getdownChannelDir,
2453 'GETDOWN_FILES_DIR': getdown_files_dir,
2454 'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
2455 'GETDOWN_DIST_DIR': getdownAppDistDir,
2456 'GETDOWN_ALT_DIR': getdown_app_dir_alt,
2457 'GETDOWN_INSTALL_DIR': getdown_install_dir,
2458 'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
2459 'BUILD_DIR': install4jBuildDir,
2460 'APPLICATION_CATEGORIES': install4j_application_categories,
2461 'APPLICATION_FOLDER': install4jApplicationFolder,
2462 'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder,
2463 'EXECUTABLE_NAME': install4jExecutableName,
2464 'EXTRA_SCHEME': install4jExtraScheme,
2465 'MAC_ICONS_FILE': install4jMacIconsFile,
2466 'WINDOWS_ICONS_FILE': install4jWindowsIconsFile,
2467 'PNG_ICON_FILE': install4jPngIconFile,
2468 'BACKGROUND': install4jBackground,
2472 //println("INSTALL4J VARIABLES:")
2473 //variables.each{k,v->println("${k}=${v}")}
2475 destination = "${jalviewDir}/${install4jBuildDir}"
2476 buildSelected = true
2478 if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
2480 disableSigning = true
2481 disableNotarization = true
2485 macKeystorePassword = OSX_KEYPASS
2488 if (OSX_ALTOOLPASS) {
2489 appleIdPassword = OSX_ALTOOLPASS
2490 disableNotarization = false
2492 disableNotarization = true
2496 println("Using projectFile "+projectFile)
2497 if (!disableNotarization) { println("Will notarize OSX App DMG") }
2501 inputs.dir(getdownAppBaseDir)
2502 inputs.file(install4jConfFile)
2503 inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
2504 inputs.dir(macosJavaVMDir)
2505 inputs.dir(windowsJavaVMDir)
2506 outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
2509 def getDataHash(File myFile) {
2510 HashCode hash = Files.asByteSource(myFile).hash(Hashing.sha256())
2511 return myFile.exists()
2513 "file" : myFile.getName(),
2514 "filesize" : myFile.length(),
2515 "sha256" : hash.toString()
2520 def writeDataJsonFile(File installersOutputTxt, File installersSha256, File dataJsonFile) {
2522 "channel" : getdownChannelName,
2523 "date" : getDate("yyyy-MM-dd HH:mm:ss"),
2524 "git-commit" : "${gitHash} [${gitBranch}]",
2525 "version" : JALVIEW_VERSION
2527 // install4j installer files
2528 if (installersOutputTxt.exists()) {
2530 installersOutputTxt.readLines().each { def line ->
2531 if (line.startsWith("#")) {
2534 line.replaceAll("\n","")
2535 def vals = line.split("\t")
2536 def filename = vals[3]
2537 def filesize = file(filename).length()
2538 filename = filename.replaceAll(/^.*\//, "")
2539 hash[vals[0]] = [ "id" : vals[0], "os" : vals[1], "name" : vals[2], "file" : filename, "filesize" : filesize ]
2540 idHash."${filename}" = vals[0]
2542 if (install4jCheckSums && installersSha256.exists()) {
2543 installersSha256.readLines().each { def line ->
2544 if (line.startsWith("#")) {
2547 line.replaceAll("\n","")
2548 def vals = line.split(/\s+\*?/)
2549 def filename = vals[1]
2550 def innerHash = (hash.(idHash."${filename}"))."sha256" = vals[0]
2556 "JAR": shadowJar.archiveFile, // executable JAR
2557 "JVL": getdownVersionLaunchJvl, // version JVL
2558 "SOURCE": sourceDist.archiveFile // source TGZ
2559 ].each { key, value ->
2560 def file = file(value)
2561 if (file.exists()) {
2562 def fileHash = getDataHash(file)
2563 if (fileHash != null) {
2564 hash."${key}" = fileHash;
2568 return dataJsonFile.write(new JsonBuilder(hash).toPrettyString())
2571 task staticMakeInstallersJsonFile {
2573 def output = findProperty("i4j_output")
2574 def sha256 = findProperty("i4j_sha256")
2575 def json = findProperty("i4j_json")
2576 if (output == null || sha256 == null || json == null) {
2577 throw new GradleException("Must provide paths to all of output.txt, sha256sums, and output.json with '-Pi4j_output=... -Pi4j_sha256=... -Pi4j_json=...")
2579 writeDataJsonFile(file(output), file(sha256), file(json))
2584 dependsOn installerFiles
2590 eclipse().configFile(eclipse_codestyle_file)
2594 task createSourceReleaseProperties(type: WriteProperties) {
2595 group = "distribution"
2596 description = "Create the source RELEASE properties file"
2598 def sourceTarBuildDir = "${buildDir}/sourceTar"
2599 def sourceReleasePropertiesFile = "${sourceTarBuildDir}/RELEASE"
2600 outputFile (sourceReleasePropertiesFile)
2603 releaseProps.each{ key, val -> property key, val }
2604 property "git.branch", gitBranch
2605 property "git.hash", gitHash
2608 outputs.file(outputFile)
2611 task sourceDist(type: Tar) {
2612 group "distribution"
2613 description "Create a source .tar.gz file for distribution"
2615 dependsOn createBuildProperties
2616 dependsOn convertMdFiles
2617 dependsOn eclipseAllPreferences
2618 dependsOn createSourceReleaseProperties
2621 def outputFileName = "${project.name}_${JALVIEW_VERSION_UNDERSCORES}.tar.gz"
2622 archiveFileName = outputFileName
2624 compression Compression.GZIP
2639 "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
2641 "utils/InstallAnywhere",
2656 "gradle.properties",
2668 ".settings/org.eclipse.buildship.core.prefs",
2669 ".settings/org.eclipse.jdt.core.prefs"
2673 exclude (EXCLUDE_FILES)
2674 include (PROCESS_FILES)
2675 filter(ReplaceTokens,
2679 'Version-Rel': JALVIEW_VERSION,
2680 'Year-Rel': getDate("yyyy")
2685 exclude (EXCLUDE_FILES)
2686 exclude (PROCESS_FILES)
2687 exclude ("appletlib")
2688 exclude ("**/*locales")
2689 exclude ("*locales/**")
2690 exclude ("utils/InstallAnywhere")
2692 exclude (getdown_files_dir)
2693 // getdown_website_dir and getdown_archive_dir moved to build/website/docroot/getdown
2694 //exclude (getdown_website_dir)
2695 //exclude (getdown_archive_dir)
2697 // exluding these as not using jars as modules yet
2698 exclude ("${j11modDir}/**/*.jar")
2701 include(INCLUDE_FILES)
2703 // from (jalviewDir) {
2704 // // explicit includes for stuff that seemed to not get included
2705 // include(fileTree("test/**/*."))
2706 // exclude(EXCLUDE_FILES)
2707 // exclude(PROCESS_FILES)
2710 from(file(buildProperties).getParent()) {
2711 include(file(buildProperties).getName())
2712 rename(file(buildProperties).getName(), "build_properties")
2714 line.replaceAll("^INSTALLATION=.*\$","INSTALLATION=Source Release"+" git-commit\\\\:"+gitHash+" ["+gitBranch+"]")
2718 def sourceTarBuildDir = "${buildDir}/sourceTar"
2719 from(sourceTarBuildDir) {
2720 // this includes the appended RELEASE properties file
2724 task dataInstallersJson {
2726 description "Create the installers-VERSION.json data file for installer files created"
2728 mustRunAfter installers
2729 mustRunAfter shadowJar
2730 mustRunAfter sourceDist
2731 mustRunAfter getdownArchive
2733 def installersOutputTxt = file("${jalviewDir}/${install4jBuildDir}/output.txt")
2734 def installersSha256 = file("${jalviewDir}/${install4jBuildDir}/sha256sums")
2736 if (installersOutputTxt.exists()) {
2737 inputs.file(installersOutputTxt)
2739 if (install4jCheckSums && installersSha256.exists()) {
2740 inputs.file(installersSha256)
2743 shadowJar.archiveFile, // executable JAR
2744 getdownVersionLaunchJvl, // version JVL
2745 sourceDist.archiveFile // source TGZ
2746 ].each { fileName ->
2747 if (file(fileName).exists()) {
2748 inputs.file(fileName)
2752 outputs.file(hugoDataJsonFile)
2755 writeDataJsonFile(installersOutputTxt, installersSha256, hugoDataJsonFile)
2761 description "Copies all help pages to build dir. Runs ant task 'pubhtmlhelp'."
2764 dependsOn pubhtmlhelp
2766 inputs.dir("${helpBuildDir}/${help_dir}")
2767 outputs.dir("${buildDir}/distributions/${help_dir}")
2771 task j2sSetHeadlessBuild {
2778 task jalviewjsEnableAltFileProperty(type: WriteProperties) {
2780 description "Enable the alternative J2S Config file for headless build"
2782 outputFile = jalviewjsJ2sSettingsFileName
2783 def j2sPropsFile = file(jalviewjsJ2sSettingsFileName)
2784 def j2sProps = new Properties()
2785 if (j2sPropsFile.exists()) {
2787 def j2sPropsFileFIS = new FileInputStream(j2sPropsFile)
2788 j2sProps.load(j2sPropsFileFIS)
2789 j2sPropsFileFIS.close()
2791 j2sProps.each { prop, val ->
2794 } catch (Exception e) {
2795 println("Exception reading ${jalviewjsJ2sSettingsFileName}")
2799 if (! j2sProps.stringPropertyNames().contains(jalviewjs_j2s_alt_file_property_config)) {
2800 property(jalviewjs_j2s_alt_file_property_config, jalviewjs_j2s_alt_file_property)
2805 task jalviewjsSetEclipseWorkspace {
2806 def propKey = "jalviewjs_eclipse_workspace"
2808 if (project.hasProperty(propKey)) {
2809 propVal = project.getProperty(propKey)
2810 if (propVal.startsWith("~/")) {
2811 propVal = System.getProperty("user.home") + propVal.substring(1)
2814 def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
2815 def propsFile = file(propsFileName)
2816 def eclipseWsDir = propVal
2817 def props = new Properties()
2819 def writeProps = true
2820 if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
2821 def ins = new FileInputStream(propsFileName)
2824 if (props.getProperty(propKey, null) != null) {
2825 eclipseWsDir = props.getProperty(propKey)
2830 if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
2831 def tempDir = File.createTempDir()
2832 eclipseWsDir = tempDir.getAbsolutePath()
2835 eclipseWorkspace = file(eclipseWsDir)
2838 // do not run a headless transpile when we claim to be in Eclipse
2840 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2841 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2843 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2847 props.setProperty(propKey, eclipseWsDir)
2848 propsFile.parentFile.mkdirs()
2849 def bytes = new ByteArrayOutputStream()
2850 props.store(bytes, null)
2851 def propertiesString = bytes.toString()
2852 propsFile.text = propertiesString
2858 println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
2861 //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
2862 outputs.file(propsFileName)
2863 outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
2867 task jalviewjsEclipsePaths {
2870 def eclipseRoot = jalviewjs_eclipse_root
2871 if (eclipseRoot.startsWith("~/")) {
2872 eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
2874 if (OperatingSystem.current().isMacOsX()) {
2875 eclipseRoot += "/Eclipse.app"
2876 eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
2877 eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
2878 } else if (OperatingSystem.current().isWindows()) { // check these paths!!
2879 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2880 eclipseRoot += "/eclipse"
2882 eclipseBinary = "${eclipseRoot}/eclipse.exe"
2883 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2884 } else { // linux or unix
2885 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
2886 eclipseRoot += "/eclipse"
2887 println("eclipseDir exists")
2889 eclipseBinary = "${eclipseRoot}/eclipse"
2890 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
2893 eclipseVersion = "4.13" // default
2894 def assumedVersion = true
2895 if (file(eclipseProduct).exists()) {
2896 def fis = new FileInputStream(eclipseProduct)
2897 def props = new Properties()
2899 eclipseVersion = props.getProperty("version")
2901 assumedVersion = false
2904 def propKey = "eclipse_debug"
2905 eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
2908 // do not run a headless transpile when we claim to be in Eclipse
2910 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2911 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2913 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2916 if (!assumedVersion) {
2917 println("ECLIPSE VERSION=${eclipseVersion}")
2923 task printProperties {
2925 description "Output to console all System.properties"
2927 System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
2933 dependsOn eclipseProject
2934 dependsOn eclipseClasspath
2935 dependsOn eclipseJdt
2939 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
2940 task jalviewjsEclipseCopyDropins(type: Copy) {
2941 dependsOn jalviewjsEclipsePaths
2943 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
2944 inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
2945 def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
2952 // this eclipse -clean doesn't actually work
2953 task jalviewjsCleanEclipse(type: Exec) {
2954 dependsOn eclipseSetup
2955 dependsOn jalviewjsEclipsePaths
2956 dependsOn jalviewjsEclipseCopyDropins
2958 executable(eclipseBinary)
2959 args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
2965 def inputString = """exit
2968 def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
2969 standardInput = inputByteStream
2972 /* not really working yet
2973 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
2977 task jalviewjsTransferUnzipSwingJs {
2978 def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
2982 from zipTree(file_zip)
2983 into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2987 inputs.file file_zip
2988 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2992 task jalviewjsTransferUnzipLib {
2993 def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
2996 zipFiles.each { file_zip ->
2998 from zipTree(file_zip)
2999 into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
3004 inputs.files zipFiles
3005 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
3009 task jalviewjsTransferUnzipAllLibs {
3010 dependsOn jalviewjsTransferUnzipSwingJs
3011 dependsOn jalviewjsTransferUnzipLib
3015 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
3017 description "Create the alternative j2s file from the j2s.* properties"
3019 jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
3020 def siteDirProperty = "j2s.site.directory"
3021 def setSiteDir = false
3022 jalviewjsJ2sProps.each { prop, val ->
3024 if (prop == siteDirProperty) {
3025 if (!(val.startsWith('/') || val.startsWith("file://") )) {
3026 val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
3032 if (!setSiteDir) { // default site location, don't override specifically set property
3033 property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
3036 outputFile = jalviewjsJ2sAltSettingsFileName
3039 inputs.properties(jalviewjsJ2sProps)
3040 outputs.file(jalviewjsJ2sAltSettingsFileName)
3045 task jalviewjsEclipseSetup {
3046 dependsOn jalviewjsEclipseCopyDropins
3047 dependsOn jalviewjsSetEclipseWorkspace
3048 dependsOn jalviewjsCreateJ2sSettings
3052 task jalviewjsSyncAllLibs (type: Sync) {
3053 dependsOn jalviewjsTransferUnzipAllLibs
3054 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
3055 inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
3056 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
3060 def outputFiles = []
3061 rename { filename ->
3062 outputFiles += "${outputDir}/${filename}"
3069 // should this be exclude really ?
3070 duplicatesStrategy "INCLUDE"
3072 outputs.files outputFiles
3073 inputs.files inputFiles
3077 task jalviewjsSyncResources (type: Sync) {
3078 dependsOn buildResources
3080 def inputFiles = fileTree(dir: resourcesBuildDir)
3081 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
3085 def outputFiles = []
3086 rename { filename ->
3087 outputFiles += "${outputDir}/${filename}"
3093 outputs.files outputFiles
3094 inputs.files inputFiles
3098 task jalviewjsSyncSiteResources (type: Sync) {
3099 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
3100 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
3104 def outputFiles = []
3105 rename { filename ->
3106 outputFiles += "${outputDir}/${filename}"
3112 outputs.files outputFiles
3113 inputs.files inputFiles
3117 task jalviewjsSyncBuildProperties (type: Sync) {
3118 dependsOn createBuildProperties
3119 def inputFiles = [file(buildProperties)]
3120 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
3124 def outputFiles = []
3125 rename { filename ->
3126 outputFiles += "${outputDir}/${filename}"
3132 outputs.files outputFiles
3133 inputs.files inputFiles
3137 task jalviewjsProjectImport(type: Exec) {
3138 dependsOn eclipseSetup
3139 dependsOn jalviewjsEclipsePaths
3140 dependsOn jalviewjsEclipseSetup
3143 // do not run a headless import when we claim to be in Eclipse
3145 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
3146 throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
3148 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
3152 //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
3153 def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
3154 executable(eclipseBinary)
3155 args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
3159 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
3161 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
3162 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
3165 inputs.file("${jalviewDir}/.project")
3166 outputs.upToDateWhen {
3167 file(projdir).exists()
3172 task jalviewjsTranspile(type: Exec) {
3173 dependsOn jalviewjsEclipseSetup
3174 dependsOn jalviewjsProjectImport
3175 dependsOn jalviewjsEclipsePaths
3177 dependsOn jalviewjsEnableAltFileProperty
3181 // do not run a headless transpile when we claim to be in Eclipse
3183 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
3184 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
3186 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
3190 executable(eclipseBinary)
3191 args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
3195 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
3197 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
3198 args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ]
3204 stdout = new ByteArrayOutputStream()
3205 stderr = new ByteArrayOutputStream()
3207 def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
3208 def logOutFile = file(logOutFileName)
3209 logOutFile.createNewFile()
3210 logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
3211 BINARY: ${eclipseBinary}
3212 VERSION: ${eclipseVersion}
3213 WORKSPACE: ${eclipseWorkspace}
3214 DEBUG: ${eclipseDebug}
3217 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
3218 // combine stdout and stderr
3219 def logErrFOS = logOutFOS
3221 if (jalviewjs_j2s_to_console.equals("true")) {
3222 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
3223 new org.apache.tools.ant.util.TeeOutputStream(
3227 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
3228 new org.apache.tools.ant.util.TeeOutputStream(
3233 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
3236 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
3243 if (stdout.toString().contains("Error processing ")) {
3244 // j2s did not complete transpile
3245 //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
3246 if (jalviewjs_ignore_transpile_errors.equals("true")) {
3247 println("IGNORING TRANSPILE ERRORS")
3248 println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
3250 throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
3255 inputs.dir("${jalviewDir}/${sourceDir}")
3256 outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
3257 outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
3261 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
3263 def stdout = new ByteArrayOutputStream()
3264 def stderr = new ByteArrayOutputStream()
3266 def coreFile = file(jsfile)
3268 msg = "Creating core for ${name}...\nGenerating ${jsfile}"
3270 logOutFile.createNewFile()
3271 logOutFile.append(msg+"\n")
3273 def coreTop = file(prefixFile)
3274 def coreBottom = file(suffixFile)
3275 coreFile.getParentFile().mkdirs()
3276 coreFile.createNewFile()
3277 coreFile.write( coreTop.getText("UTF-8") )
3281 def t = f.getText("UTF-8")
3282 t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
3283 coreFile.append( t )
3285 msg = "...file '"+f.getPath()+"' does not exist, skipping"
3287 logOutFile.append(msg+"\n")
3290 coreFile.append( coreBottom.getText("UTF-8") )
3292 msg = "Generating ${zjsfile}"
3294 logOutFile.append(msg+"\n")
3295 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
3296 def logErrFOS = logOutFOS
3299 classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
3300 main = "com.google.javascript.jscomp.CommandLineRunner"
3301 jvmArgs = [ "-Dfile.encoding=UTF-8" ]
3302 args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
3305 msg = "\nRunning '"+commandLine.join(' ')+"'\n"
3307 logOutFile.append(msg+"\n")
3309 if (logOutConsole) {
3310 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
3311 new org.apache.tools.ant.util.TeeOutputStream(
3315 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
3316 new org.apache.tools.ant.util.TeeOutputStream(
3321 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
3324 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
3331 logOutFile.append(msg+"\n")
3335 task jalviewjsBuildAllCores {
3337 description "Build the core js lib closures listed in the classlists dir"
3338 dependsOn jalviewjsTranspile
3339 dependsOn jalviewjsTransferUnzipSwingJs
3341 def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
3342 def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
3343 def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
3344 def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
3345 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
3346 def prefixFile = "${jsDir}/core/coretop2.js"
3347 def suffixFile = "${jsDir}/core/corebottom2.js"
3349 inputs.file prefixFile
3350 inputs.file suffixFile
3352 def classlistFiles = []
3353 // add the classlists found int the jalviewjs_classlists_dir
3354 fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
3356 def name = file.getName() - ".txt"
3363 // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
3364 //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
3365 classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
3367 jalviewjsCoreClasslists = []
3369 classlistFiles.each {
3372 def file = hash['file']
3373 if (! file.exists()) {
3374 //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
3375 return false // this is a "continue" in groovy .each closure
3377 def name = hash['name']
3379 name = file.getName() - ".txt"
3387 def list = fileTree(dir: j2sDir, includes: filelist)
3389 def jsfile = "${outputDir}/core${name}.js"
3390 def zjsfile = "${outputDir}/core${name}.z.js"
3392 jalviewjsCoreClasslists += [
3401 outputs.file(jsfile)
3402 outputs.file(zjsfile)
3405 // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
3406 def stevesoftClasslistName = "_stevesoft"
3407 def stevesoftClasslist = [
3408 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
3409 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
3410 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
3411 'name': stevesoftClasslistName
3413 jalviewjsCoreClasslists += stevesoftClasslist
3414 inputs.files(stevesoftClasslist['list'])
3415 outputs.file(stevesoftClasslist['jsfile'])
3416 outputs.file(stevesoftClasslist['zjsfile'])
3419 def allClasslistName = "_all"
3420 def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
3421 allJsFiles += fileTree(
3425 // these exlusions are files that the closure-compiler produces errors for. Should fix them
3426 "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
3427 "**/org/jmol/export/JSExporter.js"
3430 allJsFiles += fileTree(
3434 // these exlusions are files that the closure-compiler produces errors for. Should fix them
3435 "**/sun/misc/Unsafe.js",
3436 "**/swingjs/jquery/jquery-editable-select.js",
3437 "**/swingjs/jquery/j2sComboBox.js",
3438 "**/sun/misc/FloatingDecimal.js"
3441 def allClasslist = [
3442 'jsfile': "${outputDir}/core${allClasslistName}.js",
3443 'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
3445 'name': allClasslistName
3447 // not including this version of "all" core at the moment
3448 //jalviewjsCoreClasslists += allClasslist
3449 inputs.files(allClasslist['list'])
3450 outputs.file(allClasslist['jsfile'])
3451 outputs.file(allClasslist['zjsfile'])
3454 def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
3455 logOutFile.getParentFile().mkdirs()
3456 logOutFile.createNewFile()
3457 logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
3459 jalviewjsCoreClasslists.each {
3460 jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
3467 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
3470 into file(outputFile).getParentFile()
3471 rename { filename ->
3472 if (filename.equals(inputFile.getName())) {
3473 return file(outputFile).getName()
3477 filter(ReplaceTokens,
3481 'MAIN': '"'+main_class+'"',
3483 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
3484 'COREKEY': jalviewjs_core_key,
3485 'CORENAME': coreName
3492 task jalviewjsPublishCoreTemplates {
3493 dependsOn jalviewjsBuildAllCores
3494 def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
3495 def inputFile = file(inputFileName)
3496 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
3498 def outputFiles = []
3499 jalviewjsCoreClasslists.each { cl ->
3500 def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
3501 cl['outputfile'] = outputFile
3502 outputFiles += outputFile
3506 jalviewjsCoreClasslists.each { cl ->
3507 jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
3510 inputs.file(inputFile)
3511 outputs.files(outputFiles)
3515 task jalviewjsSyncCore (type: Sync) {
3516 dependsOn jalviewjsBuildAllCores
3517 dependsOn jalviewjsPublishCoreTemplates
3518 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
3519 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
3523 def outputFiles = []
3524 rename { filename ->
3525 outputFiles += "${outputDir}/${filename}"
3531 outputs.files outputFiles
3532 inputs.files inputFiles
3536 // this Copy version of TransferSiteJs will delete anything else in the target dir
3537 task jalviewjsCopyTransferSiteJs(type: Copy) {
3538 dependsOn jalviewjsTranspile
3539 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
3540 into "${jalviewDir}/${jalviewjsSiteDir}"
3544 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
3545 task jalviewjsSyncTransferSiteJs(type: Sync) {
3546 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
3548 into "${jalviewDir}/${jalviewjsSiteDir}"
3555 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
3556 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
3557 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
3558 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
3560 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
3561 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
3562 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
3563 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
3566 task jalviewjsPrepareSite {
3568 description "Prepares the website folder including unzipping files and copying resources"
3569 dependsOn jalviewjsSyncAllLibs
3570 dependsOn jalviewjsSyncResources
3571 dependsOn jalviewjsSyncSiteResources
3572 dependsOn jalviewjsSyncBuildProperties
3573 dependsOn jalviewjsSyncCore
3577 task jalviewjsBuildSite {
3579 description "Builds the whole website including transpiled code"
3580 dependsOn jalviewjsCopyTransferSiteJs
3581 dependsOn jalviewjsPrepareSite
3585 task cleanJalviewjsTransferSite {
3587 delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
3588 delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
3589 delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
3590 delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
3595 task cleanJalviewjsSite {
3596 dependsOn cleanJalviewjsTransferSite
3598 delete "${jalviewDir}/${jalviewjsSiteDir}"
3603 task jalviewjsSiteTar(type: Tar) {
3605 description "Creates a tar.gz file for the website"
3606 dependsOn jalviewjsBuildSite
3607 def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
3608 archiveFileName = outputFilename
3610 compression Compression.GZIP
3612 from "${jalviewDir}/${jalviewjsSiteDir}"
3613 into jalviewjs_site_dir // this is inside the tar file
3615 inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
3619 task jalviewjsServer {
3621 def filename = "jalviewjsTest.html"
3622 description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
3623 def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
3628 def f = Class.forName("org.gradle.plugins.javascript.envjs.http.simple.SimpleHttpFileServerFactory")
3629 factory = f.newInstance()
3630 } catch (ClassNotFoundException e) {
3631 throw new GradleException("Unable to create SimpleHttpFileServerFactory")
3633 def port = Integer.valueOf(jalviewjs_server_port)
3638 while(port < start+1000 && !running) {
3640 def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
3641 jalviewjsServer = factory.start(doc_root, port)
3643 url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
3644 println("SERVER STARTED with document root ${doc_root}.")
3645 println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).")
3646 println("For debug: "+url+"?j2sdebug")
3647 println("For verbose: "+url+"?j2sverbose")
3648 } catch (Exception e) {
3653 <p><a href="${url}">JalviewJS Test. <${url}></a></p>
3654 <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
3655 <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
3657 jalviewjsCoreClasslists.each { cl ->
3658 def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
3660 <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></a></p>
3662 println("For core ${cl.name}: "+urlcore)
3665 file(htmlFile).text = htmlText
3668 outputs.file(htmlFile)
3669 outputs.upToDateWhen({false})
3673 task cleanJalviewjsAll {
3675 description "Delete all configuration and build artifacts to do with JalviewJS build"
3676 dependsOn cleanJalviewjsSite
3677 dependsOn jalviewjsEclipsePaths
3680 delete "${jalviewDir}/${jalviewjsBuildDir}"
3681 delete "${jalviewDir}/${eclipse_bin_dir}"
3682 if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
3683 delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
3685 delete jalviewjsJ2sAltSettingsFileName
3688 outputs.upToDateWhen( { false } )
3692 task jalviewjsIDE_checkJ2sPlugin {
3693 group "00 JalviewJS in Eclipse"
3694 description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
3697 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3698 def j2sPluginFile = file(j2sPlugin)
3699 def eclipseHome = System.properties["eclipse.home.location"]
3700 if (eclipseHome == null || ! IN_ECLIPSE) {
3701 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
3703 def eclipseJ2sPluginDirs = [ "${eclipseHome}/dropins" ]
3704 def altPluginsDir = System.properties["org.eclipse.equinox.p2.reconciler.dropins.directory"]
3705 if (altPluginsDir != null && file(altPluginsDir).exists()) {
3706 eclipseJ2sPluginDirs += altPluginsDir
3708 def foundPlugin = false
3709 def j2sPluginFileName = j2sPluginFile.getName()
3710 def eclipseJ2sPlugin
3711 def eclipseJ2sPluginFile
3712 eclipseJ2sPluginDirs.any { dir ->
3713 eclipseJ2sPlugin = "${dir}/${j2sPluginFileName}"
3714 eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3715 if (eclipseJ2sPluginFile.exists()) {
3721 def msg = "Eclipse J2S Plugin is not installed (could not find '${j2sPluginFileName}' in\n"+eclipseJ2sPluginDirs.join("\n")+"\n)\nTry running task jalviewjsIDE_copyJ2sPlugin"
3722 System.err.println(msg)
3723 throw new StopExecutionException(msg)
3726 def digest = MessageDigest.getInstance("MD5")
3728 digest.update(j2sPluginFile.text.bytes)
3729 def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3731 digest.update(eclipseJ2sPluginFile.text.bytes)
3732 def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
3734 if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
3735 def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
3736 System.err.println(msg)
3737 throw new StopExecutionException(msg)
3739 def msg = "Eclipse J2S Plugin '${eclipseJ2sPlugin}' is the same as '${j2sPlugin}' (this is good)"
3745 task jalviewjsIDE_copyJ2sPlugin {
3746 group "00 JalviewJS in Eclipse"
3747 description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
3750 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
3751 def j2sPluginFile = file(j2sPlugin)
3752 def eclipseHome = System.properties["eclipse.home.location"]
3753 if (eclipseHome == null || ! IN_ECLIPSE) {
3754 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
3756 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
3757 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
3758 def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
3759 System.err.println(msg)
3762 eclipseJ2sPluginFile.getParentFile().mkdirs()
3763 into eclipseJ2sPluginFile.getParent()
3769 task jalviewjsIDE_j2sFile {
3770 group "00 JalviewJS in Eclipse"
3771 description "Creates the .j2s file"
3772 dependsOn jalviewjsCreateJ2sSettings
3776 task jalviewjsIDE_SyncCore {
3777 group "00 JalviewJS in Eclipse"
3778 description "Build the core js lib closures listed in the classlists dir and publish core html from template"
3779 dependsOn jalviewjsSyncCore
3783 task jalviewjsIDE_SyncSiteAll {
3784 dependsOn jalviewjsSyncAllLibs
3785 dependsOn jalviewjsSyncResources
3786 dependsOn jalviewjsSyncSiteResources
3787 dependsOn jalviewjsSyncBuildProperties
3791 cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
3794 task jalviewjsIDE_PrepareSite {
3795 group "00 JalviewJS in Eclipse"
3796 description "Sync libs and resources to site dir, but not closure cores"
3798 dependsOn jalviewjsIDE_SyncSiteAll
3799 //dependsOn cleanJalviewjsTransferSite // not sure why this clean is here -- will slow down a re-run of this task
3803 task jalviewjsIDE_AssembleSite {
3804 group "00 JalviewJS in Eclipse"
3805 description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
3806 dependsOn jalviewjsPrepareSite
3810 task jalviewjsIDE_SiteClean {
3811 group "00 JalviewJS in Eclipse"
3812 description "Deletes the Eclipse transpiled site"
3813 dependsOn cleanJalviewjsSite
3817 task jalviewjsIDE_Server {
3818 group "00 JalviewJS in Eclipse"
3819 description "Starts a webserver on localhost to test the website"
3820 dependsOn jalviewjsServer
3824 // buildship runs this at import or gradle refresh
3825 task eclipseSynchronizationTask {
3826 //dependsOn eclipseSetup
3827 dependsOn createBuildProperties
3829 dependsOn jalviewjsIDE_j2sFile
3830 dependsOn jalviewjsIDE_checkJ2sPlugin
3831 dependsOn jalviewjsIDE_PrepareSite
3836 // buildship runs this at build time or project refresh
3837 task eclipseAutoBuildTask {
3838 //dependsOn jalviewjsIDE_checkJ2sPlugin
3839 //dependsOn jalviewjsIDE_PrepareSite
3845 description "Build the site"
3846 dependsOn jalviewjsBuildSite