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