1 import org.apache.tools.ant.filters.ReplaceTokens
2 import org.gradle.internal.os.OperatingSystem
3 import org.gradle.plugins.ide.internal.generator.PropertiesPersistableConfigurationObject
4 import org.gradle.api.internal.PropertiesTransformer
5 import org.gradle.util.ConfigureUtil
6 import org.gradle.plugins.ide.eclipse.model.Output
7 import org.gradle.plugins.ide.eclipse.model.Library
8 import java.security.MessageDigest
9 import groovy.transform.ExternalizeMethods
10 import groovy.util.XmlParser
11 import groovy.xml.XmlUtil
20 classpath 'org.openclover:clover:4.4.1'
29 id "com.diffplug.gradle.spotless" version "3.28.0"
30 id 'com.github.johnrengelman.shadow' version '4.0.3'
31 id 'com.install4j.gradle' version '8.0.4'
32 id 'com.dorongold.task-tree' version '1.5' // only needed to display task dependency tree with gradle task1 [task2 ...] taskTree
42 // in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use
43 def string(Object o) {
44 return o == null ? "" : o.toString()
49 jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath()
50 jalviewDirRelativePath = jalviewDir
52 // local build environment properties
53 // can be "projectDir/local.properties"
54 def localProps = "${projectDir}/local.properties"
56 if (file(localProps).exists()) {
57 propsFile = localProps
59 // or "../projectDir_local.properties"
60 def dirLocalProps = projectDir.getParent() + "/" + projectDir.getName() + "_local.properties"
61 if (file(dirLocalProps).exists()) {
62 propsFile = dirLocalProps
64 if (propsFile != null) {
66 def p = new Properties()
67 def localPropsFIS = new FileInputStream(propsFile)
72 def oldval = findProperty(key)
75 println("Overriding property '${key}' ('${oldval}') with ${file(propsFile).getName()} value '${val}'")
77 println("Setting unknown property '${key}' with ${file(propsFile).getName()}s value '${val}'")
80 } catch (Exception e) {
81 System.out.println("Exception reading local.properties")
85 // this property set when running Eclipse headlessly
86 j2sHeadlessBuildProperty = string("net.sf.j2s.core.headlessbuild")
87 // this property set by Eclipse
88 eclipseApplicationProperty = string("eclipse.application")
89 // CHECK IF RUNNING FROM WITHIN ECLIPSE
90 def eclipseApplicationPropertyVal = System.properties[eclipseApplicationProperty]
91 IN_ECLIPSE = eclipseApplicationPropertyVal != null && eclipseApplicationPropertyVal.startsWith("org.eclipse.ui.")
92 // BUT WITHOUT THE HEADLESS BUILD PROPERTY SET
93 if (System.properties[j2sHeadlessBuildProperty].equals("true")) {
94 println("Setting IN_ECLIPSE to ${IN_ECLIPSE} as System.properties['${j2sHeadlessBuildProperty}'] == '${System.properties[j2sHeadlessBuildProperty]}'")
98 println("WITHIN ECLIPSE IDE")
100 println("HEADLESS BUILD")
103 J2S_ENABLED = (project.hasProperty('j2s.compiler.status') && project['j2s.compiler.status'] != null && project['j2s.compiler.status'] == "enable")
105 println("J2S ENABLED")
109 System.properties.sort { it.key }.each {
110 key, val -> println("SYSTEM PROPERTY ${key}='${val}'")
113 if (false && IN_ECLIPSE) {
114 jalviewDir = jalviewDirAbsolutePath
119 bareSourceDir = string(source_dir)
120 sourceDir = string("${jalviewDir}/${bareSourceDir}")
121 resourceDir = string("${jalviewDir}/${resource_dir}")
122 bareTestSourceDir = string(test_source_dir)
123 testSourceDir = string("${jalviewDir}/${bareTestSourceDir}")
126 cloverInstrDir = file("${buildDir}/${cloverSourcesInstrDir}")
127 cloverDb = string("${buildDir}/clover/clover.db")
128 classesDir = string("${jalviewDir}/${classes_dir}")
129 if (clover.equals("true")) {
131 classesDir = string("${buildDir}/${cloverClassesDir}")
134 classesDir = string("${jalviewDir}/${classes_dir}")
139 getdownWebsiteDir = string("${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}")
142 // the following values might be overridden by the CHANNEL switch
143 getdownChannelName = CHANNEL.toLowerCase()
144 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
145 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
146 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
147 getdownAppDistDir = getdown_app_dir_alt
148 buildProperties = string("${resourceDir}/${build_properties_file}")
149 reportRsyncCommand = false
150 jvlChannelName = CHANNEL.toLowerCase()
151 install4jSuffix = CHANNEL.substring(0, 1).toUpperCase() + CHANNEL.substring(1).toLowerCase(); // BUILD -> Build
152 install4jDSStore = "DS_Store-NON-RELEASE"
153 install4jDMGBackgroundImage = "jalview_dmg_background-NON-RELEASE.png"
154 install4jInstallerName = "${jalview_name} Non-Release Installer"
155 install4jExecutableName = jalview_name.replaceAll("[^\\w]+", "_").toLowerCase()
156 install4jExtraScheme = "jalviewx"
160 // TODO: get bamboo build artifact URL for getdown artifacts
161 getdown_channel_base = bamboo_channelbase
162 getdownChannelName = string("${bamboo_planKey}/${JAVA_VERSION}")
163 getdownAppBase = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
164 jvlChannelName += "_${getdownChannelName}"
165 // automatically add the test group Not-bamboo for exclusion
166 if ("".equals(testngExcludedGroups)) {
167 testngExcludedGroups = "Not-bamboo"
169 install4jExtraScheme = "jalviewb"
173 getdownAppDistDir = getdown_app_dir_release
174 reportRsyncCommand = true
175 // Don't ignore transpile errors for release build
176 if (jalviewjs_ignore_transpile_errors.equals("true")) {
177 jalviewjs_ignore_transpile_errors = "false"
178 println("Setting jalviewjs_ignore_transpile_errors to 'false'")
181 install4jDSStore = "DS_Store"
182 install4jDMGBackgroundImage = "jalview_dmg_background.png"
183 install4jInstallerName = "${jalview_name} Installer"
187 getdownChannelName = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
188 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
189 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
190 if (!file("${ARCHIVEDIR}/${packageDir}").exists()) {
191 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
193 packageDir = string("${ARCHIVEDIR}/${packageDir}")
194 buildProperties = string("${buildDir}/archive/${build_properties_file}")
197 reportRsyncCommand = true
198 install4jExtraScheme = "jalviewa"
202 getdownChannelName = string("archive/${JALVIEW_VERSION}")
203 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
204 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
205 if (!file("${ARCHIVEDIR}/${packageDir}").exists()) {
206 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
208 packageDir = string("${ARCHIVEDIR}/${packageDir}")
209 buildProperties = string("${buildDir}/archive/${build_properties_file}")
212 reportRsyncCommand = true
213 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
214 install4jSuffix = "Archive"
215 install4jExtraScheme = "jalviewa"
219 reportRsyncCommand = true
220 install4jDSStore = "DS_Store-DEVELOP"
221 install4jDMGBackgroundImage = "jalview_dmg_background-DEVELOP.png"
222 install4jExtraScheme = "jalviewd"
223 install4jInstallerName = "${jalview_name} Develop Installer"
227 reportRsyncCommand = true
228 // Don't ignore transpile errors for release build
229 if (jalviewjs_ignore_transpile_errors.equals("true")) {
230 jalviewjs_ignore_transpile_errors = "false"
231 println("Setting jalviewjs_ignore_transpile_errors to 'false'")
233 JALVIEW_VERSION = "TEST"
234 install4jSuffix = "Test"
235 install4jDSStore = "DS_Store-TEST-RELEASE"
236 install4jDMGBackgroundImage = "jalview_dmg_background-TEST.png"
237 install4jExtraScheme = "jalviewt"
238 install4jInstallerName = "${jalview_name} Test Installer"
241 case ~/^SCRATCH(|-[-\w]*)$/:
242 getdownChannelName = CHANNEL
243 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
244 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
245 reportRsyncCommand = true
246 install4jSuffix = "Scratch"
250 if (!file("${LOCALDIR}").exists()) {
251 throw new GradleException("Must provide a LOCALDIR value to produce a local distribution")
253 getdownAppBase = file(file("${LOCALDIR}").getAbsolutePath()).toURI().toString()
254 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
256 JALVIEW_VERSION = "TEST"
257 install4jSuffix = "Test-Local"
258 install4jDSStore = "DS_Store-TEST-RELEASE"
259 install4jDMGBackgroundImage = "jalview_dmg_background-TEST.png"
260 install4jExtraScheme = "jalviewt"
261 install4jInstallerName = "${jalview_name} Test Installer"
265 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
266 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
267 install4jExtraScheme = "jalviewl"
270 default: // something wrong specified
271 throw new GradleException("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
275 // override getdownAppBase if requested
276 if (findProperty("getdown_appbase_override") != null) {
277 getdownAppBase = string(getProperty("getdown_appbase_override"))
278 println("Overriding getdown appbase with '${getdownAppBase}'")
280 // sanitise file name for jalview launcher file for this channel
281 jvlChannelName = jvlChannelName.replaceAll("[^\\w\\-]+", "_")
282 // install4j application and folder names
283 if (install4jSuffix == "") {
284 install4jApplicationName = "${jalview_name}"
285 install4jBundleId = "${install4j_bundle_id}"
286 install4jWinApplicationId = install4j_release_win_application_id
288 install4jApplicationName = "${jalview_name} ${install4jSuffix}"
289 install4jBundleId = "${install4j_bundle_id}-" + install4jSuffix.toLowerCase()
290 // add int hash of install4jSuffix to the last part of the application_id
291 def id = install4j_release_win_application_id
292 def idsplitreverse = id.split("-").reverse()
293 idsplitreverse[0] = idsplitreverse[0].toInteger() + install4jSuffix.hashCode()
294 install4jWinApplicationId = idsplitreverse.reverse().join("-")
296 // sanitise folder and id names
297 // install4jApplicationFolder = e.g. "Jalview Build"
298 install4jApplicationFolder = install4jApplicationName
299 .replaceAll("[\"'~:/\\\\\\s]", "_") // replace all awkward filename chars " ' ~ : / \
300 .replaceAll("_+", "_") // collapse __
301 install4jInternalId = install4jApplicationName
303 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
304 .replaceAll("_+", "") // collapse __
305 //.replaceAll("_*-_*", "-") // collapse _-_
306 install4jUnixApplicationFolder = install4jApplicationName
308 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
309 .replaceAll("_+", "_") // collapse __
310 .replaceAll("_*-_*", "-") // collapse _-_
313 getdownAppDir = string("${getdownWebsiteDir}/${getdownAppDistDir}")
314 //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}"
315 getdownResourceDir = string("${getdownWebsiteDir}/${getdown_resource_dir}")
316 getdownInstallDir = string("${getdownWebsiteDir}/${getdown_install_dir}")
317 getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
318 getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
319 /* compile without modules -- using classpath libraries
320 modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
321 modules_runtimeClasspath = modules_compileClasspath
324 gitBranch = string("")
326 println("Using a ${CHANNEL} profile.")
328 additional_compiler_args = []
329 // configure classpath/args for j8/j11 compilation
330 if (JAVA_VERSION.equals("1.8")) {
331 JAVA_INTEGER_VERSION = string("8")
334 libDistDir = j8libDir
335 compile_source_compatibility = 1.8
336 compile_target_compatibility = 1.8
337 // these are getdown.txt properties defined dependent on the JAVA_VERSION
338 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java8_min_version"))
339 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java8_max_version"))
340 // this property is assigned below and expanded to multiple lines in the getdown task
341 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java8_txt_multi_java_location"))
342 // this property is for the Java library used in eclipse
343 eclipseJavaRuntimeName = string("JavaSE-1.8")
344 } else if (JAVA_VERSION.equals("11")) {
345 JAVA_INTEGER_VERSION = string("11")
347 libDistDir = j11libDir
348 compile_source_compatibility = 11
349 compile_target_compatibility = 11
350 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
351 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
352 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
353 eclipseJavaRuntimeName = string("JavaSE-11")
354 /* compile without modules -- using classpath libraries
355 additional_compiler_args += [
356 '--module-path', modules_compileClasspath.asPath,
357 '--add-modules', j11modules
360 } else if (JAVA_VERSION.equals("12") || JAVA_VERSION.equals("13")) {
361 JAVA_INTEGER_VERSION = JAVA_VERSION
363 libDistDir = j11libDir
364 compile_source_compatibility = JAVA_VERSION
365 compile_target_compatibility = JAVA_VERSION
366 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
367 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
368 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
369 eclipseJavaRuntimeName = string("JavaSE-11")
370 /* compile without modules -- using classpath libraries
371 additional_compiler_args += [
372 '--module-path', modules_compileClasspath.asPath,
373 '--add-modules', j11modules
377 throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
382 JAVA_MIN_VERSION = JAVA_VERSION
383 JAVA_MAX_VERSION = JAVA_VERSION
384 def jreInstallsDir = string(jre_installs_dir)
385 if (jreInstallsDir.startsWith("~/")) {
386 jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1)
388 macosJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-mac-x64/jre")
389 macosJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-mac-x64.tar.gz")
390 windowsJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-windows-x64/jre")
391 windowsJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-windows-x64.tar.gz")
392 linuxJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-linux-x64/jre")
393 linuxJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-linux-x64.tar.gz")
394 install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
395 install4jConfFileName = string("jalview-install4j-conf.install4j")
396 install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
397 install4jHomeDir = install4j_home_dir
398 if (install4jHomeDir.startsWith("~/")) {
399 install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1)
404 buildingHTML = string("${jalviewDir}/${docDir}/building.html")
405 helpFile = string("${classesDir}/${help_dir}/help.jhm")
406 helpParentDir = string("${jalviewDir}/${help_parent_dir}")
407 helpSourceDir = string("${helpParentDir}/${help_dir}")
410 relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
411 jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
412 jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}")
414 jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
416 jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
418 jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
419 jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
420 jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
421 jalviewjsJalviewCoreHtmlFile = string("")
422 jalviewjsJalviewCoreName = string(jalviewjs_core_name)
423 jalviewjsCoreClasslists = []
424 jalviewjsJalviewTemplateName = string(jalviewjs_name)
425 jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
426 jalviewjsJ2sProps = null
427 jalviewjsJ2sPlugin = jalviewjs_j2s_plugin
429 eclipseWorkspace = null
430 eclipseBinary = string("")
431 eclipseVersion = string("")
441 outputDir = file(classesDir)
446 srcDirs += helpParentDir
449 jar.destinationDir = file("${jalviewDir}/${packageDir}")
451 compileClasspath = files(sourceSets.main.java.outputDir)
452 //compileClasspath += files(sourceSets.main.resources.srcDirs)
453 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
455 runtimeClasspath = compileClasspath
460 srcDirs = [ cloverInstrDir ]
461 outputDir = file("${buildDir}/${cloverClassesDir}")
465 srcDirs = sourceSets.main.resources.srcDirs
467 compileClasspath = configurations.cloverRuntime + files( sourceSets.clover.java.outputDir )
468 compileClasspath += files(sourceSets.main.java.outputDir)
469 compileClasspath += sourceSets.main.compileClasspath
470 compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}", include: ["**/*.jar"])
471 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
473 runtimeClasspath = compileClasspath
478 srcDirs testSourceDir
479 outputDir = file("${jalviewDir}/${testOutputDir}")
483 srcDirs = sourceSets.main.resources.srcDirs
486 compileClasspath = files( sourceSets.test.java.outputDir )
489 compileClasspath = sourceSets.clover.compileClasspath
491 compileClasspath += files(sourceSets.main.java.outputDir)
494 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
495 compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}/testnglibs", include: ["**/*.jar"])
496 compileClasspath += fileTree(dir: "${jalviewDir}/${utilsDir}/testlibs", include: ["**/*.jar"])
498 runtimeClasspath = compileClasspath
506 cloverCompile 'org.openclover:clover:4.4.1'
507 testCompile 'org.openclover:clover:4.4.1'
514 cloverRuntime.extendsFrom cloverCompile
518 // eclipse project and settings files creation, also used by buildship
521 name = eclipse_project_name
523 natures 'org.eclipse.jdt.core.javanature',
524 'org.eclipse.jdt.groovy.core.groovyNature',
525 'org.eclipse.buildship.core.gradleprojectnature'
527 buildCommand 'org.eclipse.jdt.core.javabuilder'
528 buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
532 //defaultOutputDir = sourceSets.main.java.outputDir
535 if (it.isCanBeResolved()) {
540 minusConfigurations += removeThese
541 plusConfigurations = [ ]
545 def removeTheseToo = []
546 HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
547 cp.entries.each { entry ->
548 // This conditional removes all src classpathentries that a) have already been added or b) aren't "src" or "test".
549 // e.g. this removes the resources dir being copied into bin/main, bin/test AND bin/clover
550 // we add the resources and help/help dirs in as libs afterwards (see below)
551 if (entry.kind == 'src') {
552 if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) {
553 removeTheseToo += entry
555 alreadyAddedSrcPath.putAt(entry.path, true)
560 cp.entries.removeAll(removeTheseToo)
562 //cp.entries += new Output("${eclipse_bin_dir}/main")
563 if (file(helpParentDir).isDirectory()) {
564 cp.entries += new Library(fileReference(helpParentDir))
566 if (file(resourceDir).isDirectory()) {
567 cp.entries += new Library(fileReference(resourceDir))
570 HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
572 sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
573 //don't want to add outputDir as eclipse is using its own output dir in bin/main
574 if (it.isDirectory() || ! it.exists()) {
575 // don't add dirs to classpath, especially if they don't exist
576 return false // groovy "continue" in .any closure
578 def itPath = it.toString()
579 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
580 // make relative path
581 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
583 if (alreadyAddedLibPath.get(itPath)) {
584 //println("Not adding duplicate entry "+itPath)
586 //println("Adding entry "+itPath)
587 cp.entries += new Library(fileReference(itPath))
588 alreadyAddedLibPath.put(itPath, true)
592 sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
593 //no longer want to add outputDir as eclipse is using its own output dir in bin/main
594 if (it.isDirectory() || ! it.exists()) {
595 // don't add dirs to classpath
596 return false // groovy "continue" in .any closure
599 def itPath = it.toString()
600 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
601 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
603 if (alreadyAddedLibPath.get(itPath)) {
606 def lib = new Library(fileReference(itPath))
607 lib.entryAttributes["test"] = "true"
609 alreadyAddedLibPath.put(itPath, true)
617 containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
622 // for the IDE, use java 11 compatibility
623 sourceCompatibility = compile_source_compatibility
624 targetCompatibility = compile_target_compatibility
625 javaRuntimeName = eclipseJavaRuntimeName
627 // add in jalview project specific properties/preferences into eclipse core preferences
628 // and also the codestyle XML file
630 withProperties { props ->
631 def jalview_prefs = new Properties()
632 def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
633 jalview_prefs.load(ins)
635 jalview_prefs.forEach { t, v ->
636 if (props.getAt(t) == null) {
640 // codestyle file -- overrides previous formatter prefs
641 def csFile = file("${jalviewDirAbsolutePath}/${eclipse_codestyle_file}")
642 if (csFile.exists()) {
643 XmlParser parser = new XmlParser()
644 def profiles = parser.parse(csFile)
645 def profile = profiles.'profile'.find { p -> (p.'@kind' == "CodeFormatterProfile" && p.'@name' == "Jalview") }
646 if (profile != null) {
647 profile.'setting'.each { s ->
649 def value = s.'@value'
650 if (id != null && value != null) {
651 props.putAt(id, value)
662 // Don't want these to be activated if in headless build
663 synchronizationTasks "eclipseSynchronizationTask"
664 //autoBuildTasks "eclipseAutoBuildTask"
670 /* hack to change eclipse prefs in .settings files other than org.eclipse.jdt.core.prefs */
671 // Class to allow updating arbitrary properties files
672 class PropertiesFile extends PropertiesPersistableConfigurationObject {
673 public PropertiesFile(PropertiesTransformer t) { super(t); }
674 @Override protected void load(Properties properties) { }
675 @Override protected void store(Properties properties) { }
676 @Override protected String getDefaultResourceName() { return ""; }
677 // This is necessary, because PropertiesPersistableConfigurationObject fails
678 // if no default properties file exists.
679 @Override public void loadDefaults() { load(new StringBufferInputStream("")); }
682 // Task to update arbitrary properties files (set outputFile)
683 class PropertiesFileTask extends PropertiesGeneratorTask<PropertiesFile> {
684 private final PropertiesFileContentMerger file;
685 public PropertiesFileTask() { file = new PropertiesFileContentMerger(getTransformer()); }
686 protected PropertiesFile create() { return new PropertiesFile(getTransformer()); }
687 protected void configure(PropertiesFile props) {
688 file.getBeforeMerged().execute(props); file.getWhenMerged().execute(props);
690 public void file(Closure closure) { ConfigureUtil.configure(closure, file); }
693 task eclipseUIPreferences(type: PropertiesFileTask) {
694 description = "Generate Eclipse additional settings"
695 def filename = "org.eclipse.jdt.ui.prefs"
696 outputFile = "$projectDir/.settings/${filename}" as File
699 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
704 task eclipseGroovyCorePreferences(type: PropertiesFileTask) {
705 description = "Generate Eclipse additional settings"
706 def filename = "org.eclipse.jdt.groovy.core.prefs"
707 outputFile = "$projectDir/.settings/${filename}" as File
710 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
715 task eclipseAllPreferences {
717 dependsOn eclipseUIPreferences
718 dependsOn eclipseGroovyCorePreferences
721 eclipseUIPreferences.mustRunAfter eclipseJdt
722 eclipseGroovyCorePreferences.mustRunAfter eclipseJdt
724 /* end of eclipse preferences hack */
728 // only instrument source, we build test classes as normal
729 inputs.files files (sourceSets.main.allJava,sourceSets.test.allJava) // , fileTree(dir:"$jalviewDir/$testSourceDir", include: ["**/*.java"]))
730 outputs.dir cloverInstrDir
733 delete cloverInstrDir
738 cloverInstrDir.getPath(),
741 inputs.files.files.collect(
742 { file -> file.absolutePath }
745 String[] args = argsList.toArray()
746 println("About to instrument "+args.length +" files")
747 com.atlassian.clover.CloverInstr.mainImpl(args)
752 cloverClasses.dependsOn cloverInstr
756 group = "Verification"
757 description = "Creates the Clover report"
758 inputs.dir "${buildDir}/clover"
759 outputs.dir "${reportsDir}/clover"
761 file(cloverDb).exists()
768 "${reportsDir}/clover"
770 String[] args = argsList.toArray()
771 com.atlassian.clover.reporters.html.HtmlReporter.runReport(args)
773 // and generate ${reportsDir}/clover/clover.xml
778 "${reportsDir}/clover/clover.xml"
780 com.atlassian.clover.reporters.xml.XMLReporter.runReport(args)
788 sourceCompatibility = compile_source_compatibility
789 targetCompatibility = compile_target_compatibility
790 options.compilerArgs += additional_compiler_args
791 print ("Setting target compatibility to "+targetCompatibility+"\n")
793 classpath += configurations.cloverRuntime
799 delete cloverInstrDir
808 sourceCompatibility = compile_source_compatibility
809 targetCompatibility = compile_target_compatibility
810 options.compilerArgs = additional_compiler_args
811 options.encoding = "UTF-8"
813 print ("Setting target compatibility to "+targetCompatibility+"\n")
821 dependsOn compileCloverJava
822 classpath += configurations.cloverRuntime
824 classpath += sourceSets.main.runtimeClasspath
827 sourceCompatibility = compile_source_compatibility
828 targetCompatibility = compile_target_compatibility
829 options.compilerArgs = additional_compiler_args
830 print ("Setting target compatibility to "+targetCompatibility+"\n")
837 delete sourceSets.main.java.outputDir
843 dependsOn cleanClover
845 delete sourceSets.test.java.outputDir
850 // format is a string like date.format("dd MMMM yyyy")
851 def getDate(format) {
852 def date = new Date()
853 return date.format(format)
858 def hashStdOut = new ByteArrayOutputStream()
860 commandLine "git", "rev-parse", "--short", "HEAD"
861 standardOutput = hashStdOut
865 def branchStdOut = new ByteArrayOutputStream()
867 commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
868 standardOutput = branchStdOut
872 gitHash = hashStdOut.toString().trim()
873 gitBranch = branchStdOut.toString().trim()
875 outputs.upToDateWhen { false }
879 task createBuildProperties(type: WriteProperties) {
881 description = "Create the ${buildProperties} file"
884 inputs.dir(sourceDir)
885 inputs.dir(resourceDir)
886 file(buildProperties).getParentFile().mkdirs()
887 outputFile (buildProperties)
888 // taking time specific comment out to allow better incremental builds
889 comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
890 //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
891 property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
892 property "VERSION", JALVIEW_VERSION
893 property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
894 outputs.file(outputFile)
900 delete buildProperties
905 task cleanBuildingHTML(type: Delete) {
912 task convertBuildingMD(type: Exec) {
913 dependsOn cleanBuildingHTML
914 def buildingMD = "${jalviewDir}/${docDir}/building.md"
915 def css = "${jalviewDir}/${docDir}/github.css"
918 pandoc_exec.split(",").each {
919 if (file(it.trim()).exists()) {
925 def buildtoolsPandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
926 if ((pandoc == null || ! file(pandoc).exists()) && file(buildtoolsPandoc).exists()) {
927 pandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
931 if (pandoc != null && file(pandoc).exists()) {
932 commandLine pandoc, '-s', '-o', buildingHTML, '--metadata', 'pagetitle="Building Jalview from Source"', '--toc', '-H', css, buildingMD
934 println("Cannot find pandoc. Skipping convert building.md to HTML")
935 throw new StopExecutionException("Cannot find pandoc. Skipping convert building.md to HTML")
941 inputs.file(buildingMD)
943 outputs.file(buildingHTML)
947 task syncDocs(type: Sync) {
948 dependsOn convertBuildingMD
949 def syncDir = "${classesDir}/${docDir}"
950 from fileTree("${jalviewDir}/${docDir}")
956 task copyHelp(type: Copy) {
957 def inputDir = helpSourceDir
958 def outputDir = "${classesDir}/${help_dir}"
963 filter(ReplaceTokens,
967 'Version-Rel': JALVIEW_VERSION,
968 'Year-Rel': getDate("yyyy")
980 outputs.files(helpFile)
981 outputs.dir(outputDir)
985 task syncLib(type: Sync) {
986 def syncDir = "${classesDir}/${libDistDir}"
987 from fileTree("${jalviewDir}/${libDistDir}")
992 task syncResources(type: Sync) {
993 dependsOn createBuildProperties
1004 dependsOn syncResources
1010 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
1013 dependsOn compileJava
1015 dependsOn cloverInstr
1019 print("Running tests " + (use_clover?"WITH":"WITHOUT") + " clover [clover="+use_clover+"]\n")
1023 includeGroups testngGroups
1024 excludeGroups testngExcludedGroups
1026 useDefaultListeners=true
1029 maxHeapSize = "1024m"
1031 workingDir = jalviewDir
1032 //systemProperties 'clover.jar' System.properties.clover.jar
1033 def testLaf = project.findProperty("test_laf")
1034 if (testLaf != null) {
1035 println("Setting Test LaF to '${testLaf}'")
1036 systemProperty "laf", testLaf
1038 sourceCompatibility = compile_source_compatibility
1039 targetCompatibility = compile_target_compatibility
1040 jvmArgs += additional_compiler_args
1045 task buildIndices(type: JavaExec) {
1047 classpath = sourceSets.main.compileClasspath
1048 main = "com.sun.java.help.search.Indexer"
1049 workingDir = "${classesDir}/${help_dir}"
1052 inputs.dir("${workingDir}/${argDir}")
1054 outputs.dir("${classesDir}/doc")
1055 outputs.dir("${classesDir}/help")
1056 outputs.file("${workingDir}/JavaHelpSearch/DOCS")
1057 outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
1058 outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
1059 outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
1060 outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
1061 outputs.file("${workingDir}/JavaHelpSearch/TMAP")
1065 task compileLinkCheck(type: JavaCompile) {
1067 classpath = files("${jalviewDir}/${utilsDir}")
1068 destinationDir = file("${jalviewDir}/${utilsDir}")
1069 source = fileTree(dir: "${jalviewDir}/${utilsDir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
1071 inputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.java")
1072 inputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.java")
1073 outputs.file("${jalviewDir}/${utilsDir}/HelpLinksChecker.class")
1074 outputs.file("${jalviewDir}/${utilsDir}/BufferedLineReader.class")
1078 task linkCheck(type: JavaExec) {
1079 dependsOn prepare, compileLinkCheck
1081 def helpLinksCheckerOutFile = file("${jalviewDir}/${utilsDir}/HelpLinksChecker.out")
1082 classpath = files("${jalviewDir}/${utilsDir}")
1083 main = "HelpLinksChecker"
1084 workingDir = jalviewDir
1085 args = [ "${classesDir}/${help_dir}", "-nointernet" ]
1087 def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
1089 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1092 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1096 inputs.dir("${classesDir}/${help_dir}")
1097 outputs.file(helpLinksCheckerOutFile)
1100 // import the pubhtmlhelp target
1101 ant.properties.basedir = "${jalviewDir}"
1102 ant.properties.helpBuildDir = "${jalviewDirAbsolutePath}/${classes_dir}/${help_dir}"
1103 ant.importBuild "${utilsDir}/publishHelp.xml"
1106 task cleanPackageDir(type: Delete) {
1108 delete fileTree(dir: "${jalviewDir}/${packageDir}", include: "*.jar")
1115 dependsOn buildIndices
1116 dependsOn createBuildProperties
1119 attributes "Main-Class": mainClass,
1120 "Permissions": "all-permissions",
1121 "Application-Name": "Jalview Desktop",
1122 "Codebase": application_codebase
1125 destinationDir = file("${jalviewDir}/${packageDir}")
1126 archiveName = rootProject.name+".jar"
1132 exclude "**/*.jar.*"
1134 inputs.dir(classesDir)
1135 outputs.file("${jalviewDir}/${packageDir}/${archiveName}")
1139 task copyJars(type: Copy) {
1140 from fileTree(dir: classesDir, include: "**/*.jar").files
1141 into "${jalviewDir}/${packageDir}"
1145 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
1146 task syncJars(type: Sync) {
1147 from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
1148 into "${jalviewDir}/${packageDir}"
1150 include jar.archiveName
1157 description = "Put all required libraries in dist"
1158 // order of "cleanPackageDir", "copyJars", "jar" important!
1159 jar.mustRunAfter cleanPackageDir
1160 syncJars.mustRunAfter cleanPackageDir
1161 dependsOn cleanPackageDir
1164 outputs.dir("${jalviewDir}/${packageDir}")
1169 dependsOn cleanPackageDir
1175 group = "distribution"
1179 from ("${jalviewDir}/${libDistDir}") {
1183 attributes 'Implementation-Version': JALVIEW_VERSION
1185 mainClassName = shadowJarMainClass
1187 classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
1192 task getdownWebsite() {
1193 group = "distribution"
1194 description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
1199 def getdownWebsiteResourceFilenames = []
1200 def getdownTextString = ""
1201 def getdownResourceDir = getdownResourceDir
1202 def getdownResourceFilenames = []
1205 // clean the getdown website and files dir before creating getdown folders
1206 delete getdownWebsiteDir
1207 delete getdownFilesDir
1210 from buildProperties
1211 rename(build_properties_file, getdown_build_properties)
1214 getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
1216 // set some getdown_txt_ properties then go through all properties looking for getdown_txt_...
1217 def props = project.properties.sort { it.key }
1218 if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
1219 props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
1221 if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) {
1222 props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion)
1224 if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
1225 props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
1228 props.put("getdown_txt_title", jalview_name)
1229 props.put("getdown_txt_ui.name", install4jApplicationName)
1231 // start with appbase
1232 getdownTextString += "appbase = ${getdownAppBase}\n"
1233 props.each{ prop, val ->
1234 if (prop.startsWith("getdown_txt_") && val != null) {
1235 if (prop.startsWith("getdown_txt_multi_")) {
1236 def key = prop.substring(18)
1237 val.split(",").each{ v ->
1238 def line = "${key} = ${v}\n"
1239 getdownTextString += line
1242 // file values rationalised
1243 if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1245 if (val.indexOf('/') == 0) {
1248 } else if (val.indexOf('/') > 0) {
1249 // relative path (relative to jalviewDir)
1250 r = file( "${jalviewDir}/${val}" )
1253 val = "${getdown_resource_dir}/" + r.getName()
1254 getdownWebsiteResourceFilenames += val
1255 getdownResourceFilenames += r.getPath()
1258 if (! prop.startsWith("getdown_txt_resource")) {
1259 def line = prop.substring(12) + " = ${val}\n"
1260 getdownTextString += line
1266 getdownWebsiteResourceFilenames.each{ filename ->
1267 getdownTextString += "resource = ${filename}\n"
1269 getdownResourceFilenames.each{ filename ->
1272 into getdownResourceDir
1277 fileTree(file(packageDir)).each{ f ->
1278 if (f.isDirectory()) {
1279 def files = fileTree(dir: f, include: ["*"]).getFiles()
1281 } else if (f.exists()) {
1285 codeFiles.sort().each{f ->
1286 def name = f.getName()
1287 def line = "code = ${getdownAppDistDir}/${name}\n"
1288 getdownTextString += line
1295 // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
1297 if (JAVA_VERSION.equals("11")) {
1298 def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
1299 j11libFiles.sort().each{f ->
1300 def name = f.getName()
1301 def line = "code = ${getdown_j11lib_dir}/${name}\n"
1302 getdownTextString += line
1305 into getdownJ11libDir
1311 // 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.
1312 //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
1313 getdownTextString += "resource = ${getdown_launcher_new}\n"
1314 getdownTextString += "class = ${mainClass}\n"
1316 def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
1317 getdown_txt.write(getdownTextString)
1319 def getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
1320 def launchJvl = file("${getdownWebsiteDir}/${getdownLaunchJvl}")
1321 launchJvl.write("appbase=${getdownAppBase}")
1324 from getdownLauncher
1325 rename(file(getdownLauncher).getName(), getdown_launcher_new)
1326 into getdownWebsiteDir
1330 from getdownLauncher
1331 if (file(getdownLauncher).getName() != getdown_launcher) {
1332 rename(file(getdownLauncher).getName(), getdown_launcher)
1334 into getdownWebsiteDir
1337 if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
1340 from getdownLauncher
1341 from "${getdownWebsiteDir}/${getdown_build_properties}"
1342 if (file(getdownLauncher).getName() != getdown_launcher) {
1343 rename(file(getdownLauncher).getName(), getdown_launcher)
1345 into getdownInstallDir
1349 from getdownInstallDir
1350 into getdownFilesInstallDir
1357 from getdownLauncher
1358 from "${getdownWebsiteDir}/${getdown_build_properties}"
1359 if (file(getdownLauncher).getName() != getdown_launcher) {
1360 rename(file(getdownLauncher).getName(), getdown_launcher)
1362 into getdownFilesDir
1366 from getdownResourceDir
1367 into "${getdownFilesDir}/${getdown_resource_dir}"
1372 inputs.dir("${jalviewDir}/${packageDir}")
1374 outputs.dir(getdownWebsiteDir)
1375 outputs.dir(getdownFilesDir)
1379 // a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
1380 task getdownDigestDir(type: JavaExec) {
1381 def digestDirPropertyName = "DIGESTDIR"
1382 description = "Digest a local dir (-P${digestDirPropertyName}=...) for getdown"
1384 classpath = files(getdownLauncher)
1385 def digestDir = findProperty(digestDirPropertyName)
1386 if (digestDir == null) {
1387 throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest")
1391 main = "com.threerings.getdown.tools.Digester"
1395 task getdownDigest(type: JavaExec) {
1396 group = "distribution"
1397 description = "Digest the getdown website folder"
1398 dependsOn getdownWebsite
1400 classpath = files(getdownLauncher)
1402 main = "com.threerings.getdown.tools.Digester"
1403 args getdownWebsiteDir
1404 inputs.dir(getdownWebsiteDir)
1405 outputs.file("${getdownWebsiteDir}/digest2.txt")
1410 group = "distribution"
1411 description = "Create the minimal and full getdown app folder for installers and website and create digest file"
1412 dependsOn getdownDigest
1414 if (reportRsyncCommand) {
1415 def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
1416 def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
1417 println "LIKELY RSYNC COMMAND:"
1418 println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
1419 if (RUNRSYNC == "true") {
1421 commandLine "mkdir", "-p", toDir
1424 commandLine "rsync", "-avh", "--delete", fromDir, toDir
1432 tasks.withType(JavaCompile) {
1433 options.encoding = 'UTF-8'
1439 delete getdownWebsiteDir
1440 delete getdownFilesDir
1446 if (file(install4jHomeDir).exists()) {
1448 } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
1449 install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1450 } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
1451 install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
1453 installDir(file(install4jHomeDir))
1455 mediaTypes = Arrays.asList(install4j_media_types.split(","))
1459 task copyInstall4jTemplate {
1460 def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
1461 def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
1462 inputs.file(install4jTemplateFile)
1463 inputs.file(install4jFileAssociationsFile)
1464 inputs.property("CHANNEL", { CHANNEL })
1465 outputs.file(install4jConfFile)
1468 def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
1470 // turn off code signing if no OSX_KEYPASS
1471 if (OSX_KEYPASS == "") {
1472 install4jConfigXml.'**'.codeSigning.each { codeSigning ->
1473 codeSigning.'@macEnabled' = "false"
1475 install4jConfigXml.'**'.windows.each { windows ->
1476 windows.'@runPostProcessor' = "false"
1480 // turn off checksum creation for LOCAL channel
1481 def e = install4jConfigXml.application[0]
1482 if (CHANNEL == "LOCAL") {
1483 e.'@createChecksums' = "false"
1485 e.'@createChecksums' = "true"
1488 // put file association actions where placeholder action is
1489 def install4jFileAssociationsText = install4jFileAssociationsFile.text
1490 def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
1491 install4jConfigXml.'**'.action.any { a -> // .any{} stops after the first one that returns true
1492 if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
1493 def parent = a.parent()
1495 fileAssociationActions.each { faa ->
1498 // don't need to continue in .any loop once replacements have been made
1503 // use Windows Program Group with Examples folder for RELEASE, and Program Group without Examples for everything else
1504 // NB we're deleting the /other/ one!
1505 // Also remove the examples subdir from non-release versions
1506 def customizedIdToDelete = "PROGRAM_GROUP_RELEASE"
1507 if (CHANNEL=="RELEASE") {
1508 customizedIdToDelete = "PROGRAM_GROUP_NON_RELEASE"
1510 // remove the examples subdir from Full File Set
1511 def files = install4jConfigXml.files[0]
1512 def fileset = files.filesets.fileset.find { fs -> fs.'@customizedId' == "FULL_FILE_SET" }
1513 def root = files.roots.root.find { r -> r.'@fileset' == fileset.'@id' }
1514 def mountPoint = files.mountPoints.mountPoint.find { mp -> mp.'@root' == root.'@id' }
1515 def dirEntry = files.entries.dirEntry.find { de -> de.'@mountPoint' == mountPoint.'@id' && de.'@subDirectory' == "examples" }
1516 dirEntry.parent().remove(dirEntry)
1518 install4jConfigXml.'**'.action.any { a ->
1519 if (a.'@customizedId' == customizedIdToDelete) {
1520 def parent = a.parent()
1526 // remove the "Uninstall Old Jalview (optional)" symlink from DMG for non-release DS_Stores
1527 if (! (CHANNEL == "RELEASE" || CHANNEL == "TEST-RELEASE" ) ) {
1528 def symlink = install4jConfigXml.'**'.topLevelFiles.symlink.find { sl -> sl.'@name' == "Uninstall Old Jalview (optional).app" }
1529 symlink.parent().remove(symlink)
1532 // write install4j file
1533 install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
1540 delete install4jConfFile
1545 task installers(type: com.install4j.gradle.Install4jTask) {
1546 group = "distribution"
1547 description = "Create the install4j installers"
1548 dependsOn setGitVals
1550 dependsOn copyInstall4jTemplate
1552 projectFile = install4jConfFile
1554 // create an md5 for the input files to use as version for install4j conf file
1555 def digest = MessageDigest.getInstance("MD5")
1557 (file("${install4jDir}/${install4j_template}").text +
1558 file("${install4jDir}/${install4j_info_plist_file_associations}").text +
1559 file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
1560 def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
1561 if (filesMd5.length() >= 8) {
1562 filesMd5 = filesMd5.substring(0,8)
1564 def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
1565 // make install4jBuildDir relative to jalviewDir
1566 def install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
1569 'JALVIEW_NAME': jalview_name,
1570 'JALVIEW_APPLICATION_NAME': install4jApplicationName,
1571 'JALVIEW_DIR': "../..",
1572 'OSX_KEYSTORE': OSX_KEYSTORE,
1573 'JSIGN_SH': JSIGN_SH,
1574 'JRE_DIR': getdown_app_dir_java,
1575 'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
1576 'JALVIEW_VERSION': JALVIEW_VERSION,
1577 'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
1578 'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
1579 'JAVA_VERSION': JAVA_VERSION,
1580 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
1581 'VERSION': JALVIEW_VERSION,
1582 'MACOS_JAVA_VM_DIR': macosJavaVMDir,
1583 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
1584 'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
1585 'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
1586 'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
1587 'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
1588 'COPYRIGHT_MESSAGE': install4j_copyright_message,
1589 'BUNDLE_ID': install4jBundleId,
1590 'INTERNAL_ID': install4jInternalId,
1591 'WINDOWS_APPLICATION_ID': install4jWinApplicationId,
1592 'MACOS_DS_STORE': install4jDSStore,
1593 'MACOS_DMG_BG_IMAGE': install4jDMGBackgroundImage,
1594 'INSTALLER_NAME': install4jInstallerName,
1595 'INSTALL4J_UTILS_DIR': install4j_utils_dir,
1596 'GETDOWN_WEBSITE_DIR': getdown_website_dir,
1597 'GETDOWN_FILES_DIR': getdown_files_dir,
1598 'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
1599 'GETDOWN_DIST_DIR': getdownAppDistDir,
1600 'GETDOWN_ALT_DIR': getdown_app_dir_alt,
1601 'GETDOWN_INSTALL_DIR': getdown_install_dir,
1602 'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
1603 'BUILD_DIR': install4jBuildDir,
1604 'APPLICATION_CATEGORIES': install4j_application_categories,
1605 'APPLICATION_FOLDER': install4jApplicationFolder,
1606 'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder,
1607 'EXECUTABLE_NAME': install4jExecutableName,
1608 'EXTRA_SCHEME': install4jExtraScheme,
1611 //println("INSTALL4J VARIABLES:")
1612 //variables.each{k,v->println("${k}=${v}")}
1614 destination = "${jalviewDir}/${install4jBuildDir}"
1615 buildSelected = true
1617 if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
1619 disableSigning = true
1623 macKeystorePassword = OSX_KEYPASS
1627 println("Using projectFile "+projectFile)
1630 inputs.dir(getdownWebsiteDir)
1631 inputs.file(install4jConfFile)
1632 inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
1633 inputs.dir(macosJavaVMDir)
1634 inputs.dir(windowsJavaVMDir)
1635 outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
1641 eclipse().configFile(eclipse_codestyle_file)
1646 task sourceDist(type: Tar) {
1648 def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
1649 def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
1650 // cater for buildship < 3.1 [3.0.1 is max version in eclipse 2018-09]
1652 archiveFileName = outputFileName
1653 } catch (Exception e) {
1654 archiveName = outputFileName
1657 compression Compression.GZIP
1672 "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
1674 "utils/InstallAnywhere",
1689 "gradle.properties",
1700 ".settings/org.eclipse.jdt.core.jalview.prefs",
1704 exclude (EXCLUDE_FILES)
1705 include (PROCESS_FILES)
1706 filter(ReplaceTokens,
1710 'Version-Rel': JALVIEW_VERSION,
1711 'Year-Rel': getDate("yyyy")
1716 exclude (EXCLUDE_FILES)
1717 exclude (PROCESS_FILES)
1718 exclude ("appletlib")
1719 exclude ("**/*locales")
1720 exclude ("*locales/**")
1721 exclude ("utils/InstallAnywhere")
1723 exclude (getdown_files_dir)
1724 exclude (getdown_website_dir)
1726 // exluding these as not using jars as modules yet
1727 exclude ("${j11modDir}/**/*.jar")
1730 include(INCLUDE_FILES)
1732 // from (jalviewDir) {
1733 // // explicit includes for stuff that seemed to not get included
1734 // include(fileTree("test/**/*."))
1735 // exclude(EXCLUDE_FILES)
1736 // exclude(PROCESS_FILES)
1743 dependsOn pubhtmlhelp
1745 inputs.dir("${classesDir}/${help_dir}")
1746 outputs.dir("${buildDir}/distributions/${help_dir}")
1750 task j2sSetHeadlessBuild {
1757 task jalviewjsSetEclipseWorkspace {
1758 def propKey = "jalviewjs_eclipse_workspace"
1760 if (project.hasProperty(propKey)) {
1761 propVal = project.getProperty(propKey)
1762 if (propVal.startsWith("~/")) {
1763 propVal = System.getProperty("user.home") + propVal.substring(1)
1766 def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
1767 def propsFile = file(propsFileName)
1768 def eclipseWsDir = propVal
1769 def props = new Properties()
1771 def writeProps = true
1772 if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
1773 def ins = new FileInputStream(propsFileName)
1776 if (props.getProperty(propKey, null) != null) {
1777 eclipseWsDir = props.getProperty(propKey)
1782 if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
1783 def tempDir = File.createTempDir()
1784 eclipseWsDir = tempDir.getAbsolutePath()
1787 eclipseWorkspace = file(eclipseWsDir)
1790 // do not run a headless transpile when we claim to be in Eclipse
1792 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1793 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
1795 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1799 props.setProperty(propKey, eclipseWsDir)
1800 propsFile.parentFile.mkdirs()
1801 def bytes = new ByteArrayOutputStream()
1802 props.store(bytes, null)
1803 def propertiesString = bytes.toString()
1804 propsFile.text = propertiesString
1810 println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
1813 //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
1814 outputs.file(propsFileName)
1815 outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
1819 task jalviewjsEclipsePaths {
1822 def eclipseRoot = jalviewjs_eclipse_root
1823 if (eclipseRoot.startsWith("~/")) {
1824 eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
1826 if (OperatingSystem.current().isMacOsX()) {
1827 eclipseRoot += "/Eclipse.app"
1828 eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
1829 eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
1830 } else if (OperatingSystem.current().isWindows()) { // check these paths!!
1831 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1832 eclipseRoot += "/eclipse"
1834 eclipseBinary = "${eclipseRoot}/eclipse.exe"
1835 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1836 } else { // linux or unix
1837 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1838 eclipseRoot += "/eclipse"
1839 println("eclipseDir exists")
1841 eclipseBinary = "${eclipseRoot}/eclipse"
1842 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1845 eclipseVersion = "4.13" // default
1846 def assumedVersion = true
1847 if (file(eclipseProduct).exists()) {
1848 def fis = new FileInputStream(eclipseProduct)
1849 def props = new Properties()
1851 eclipseVersion = props.getProperty("version")
1853 assumedVersion = false
1856 def propKey = "eclipse_debug"
1857 eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
1860 // do not run a headless transpile when we claim to be in Eclipse
1862 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1863 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
1865 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1868 if (!assumedVersion) {
1869 println("ECLIPSE VERSION=${eclipseVersion}")
1875 task printProperties {
1877 description "Output to console all System.properties"
1879 System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
1885 dependsOn eclipseProject
1886 dependsOn eclipseClasspath
1887 dependsOn eclipseJdt
1891 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
1892 task jalviewjsEclipseCopyDropins(type: Copy) {
1893 dependsOn jalviewjsEclipsePaths
1895 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
1896 inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
1897 def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
1904 // this eclipse -clean doesn't actually work
1905 task jalviewjsCleanEclipse(type: Exec) {
1906 dependsOn eclipseSetup
1907 dependsOn jalviewjsEclipsePaths
1908 dependsOn jalviewjsEclipseCopyDropins
1910 executable(eclipseBinary)
1911 args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
1917 def inputString = """exit
1920 def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
1921 standardInput = inputByteStream
1924 /* not really working yet
1925 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
1929 task jalviewjsTransferUnzipSwingJs {
1930 def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
1934 from zipTree(file_zip)
1935 into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
1939 inputs.file file_zip
1940 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
1944 task jalviewjsTransferUnzipLib {
1945 def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
1948 zipFiles.each { file_zip ->
1950 from zipTree(file_zip)
1951 into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
1956 inputs.files zipFiles
1957 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
1961 task jalviewjsTransferUnzipAllLibs {
1962 dependsOn jalviewjsTransferUnzipSwingJs
1963 dependsOn jalviewjsTransferUnzipLib
1967 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
1969 description "Create the .j2s file from the j2s.* properties"
1971 jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
1972 def siteDirProperty = "j2s.site.directory"
1973 def setSiteDir = false
1974 jalviewjsJ2sProps.each { prop, val ->
1976 if (prop == siteDirProperty) {
1977 if (!(val.startsWith('/') || val.startsWith("file://") )) {
1978 val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
1984 if (!setSiteDir) { // default site location, don't override specifically set property
1985 property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
1988 outputFile = jalviewjsJ2sSettingsFileName
1991 inputs.properties(jalviewjsJ2sProps)
1992 outputs.file(jalviewjsJ2sSettingsFileName)
1997 task jalviewjsEclipseSetup {
1998 dependsOn jalviewjsEclipseCopyDropins
1999 dependsOn jalviewjsSetEclipseWorkspace
2000 dependsOn jalviewjsCreateJ2sSettings
2004 task jalviewjsSyncAllLibs (type: Sync) {
2005 dependsOn jalviewjsTransferUnzipAllLibs
2006 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
2007 inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
2008 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2012 def outputFiles = []
2013 rename { filename ->
2014 outputFiles += "${outputDir}/${filename}"
2020 outputs.files outputFiles
2021 inputs.files inputFiles
2025 task jalviewjsSyncResources (type: Sync) {
2026 def inputFiles = fileTree(dir: resourceDir)
2027 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2031 def outputFiles = []
2032 rename { filename ->
2033 outputFiles += "${outputDir}/${filename}"
2039 outputs.files outputFiles
2040 inputs.files inputFiles
2044 task jalviewjsSyncSiteResources (type: Sync) {
2045 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
2046 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2050 def outputFiles = []
2051 rename { filename ->
2052 outputFiles += "${outputDir}/${filename}"
2058 outputs.files outputFiles
2059 inputs.files inputFiles
2063 task jalviewjsSyncBuildProperties (type: Sync) {
2064 dependsOn createBuildProperties
2065 def inputFiles = [file(buildProperties)]
2066 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2070 def outputFiles = []
2071 rename { filename ->
2072 outputFiles += "${outputDir}/${filename}"
2078 outputs.files outputFiles
2079 inputs.files inputFiles
2083 task jalviewjsProjectImport(type: Exec) {
2084 dependsOn eclipseSetup
2085 dependsOn jalviewjsEclipsePaths
2086 dependsOn jalviewjsEclipseSetup
2089 // do not run a headless import when we claim to be in Eclipse
2091 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2092 throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2094 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2098 //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
2099 def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
2100 executable(eclipseBinary)
2101 args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
2105 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2107 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2110 inputs.file("${jalviewDir}/.project")
2111 outputs.upToDateWhen {
2112 file(projdir).exists()
2117 task jalviewjsTranspile(type: Exec) {
2118 dependsOn jalviewjsEclipseSetup
2119 dependsOn jalviewjsProjectImport
2120 dependsOn jalviewjsEclipsePaths
2123 // do not run a headless transpile when we claim to be in Eclipse
2125 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2126 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2128 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2132 executable(eclipseBinary)
2133 args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
2137 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2139 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2145 stdout = new ByteArrayOutputStream()
2146 stderr = new ByteArrayOutputStream()
2148 def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
2149 def logOutFile = file(logOutFileName)
2150 logOutFile.createNewFile()
2151 logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
2152 BINARY: ${eclipseBinary}
2153 VERSION: ${eclipseVersion}
2154 WORKSPACE: ${eclipseWorkspace}
2155 DEBUG: ${eclipseDebug}
2158 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2159 // combine stdout and stderr
2160 def logErrFOS = logOutFOS
2162 if (jalviewjs_j2s_to_console.equals("true")) {
2163 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2164 new org.apache.tools.ant.util.TeeOutputStream(
2168 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2169 new org.apache.tools.ant.util.TeeOutputStream(
2174 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2177 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2184 if (stdout.toString().contains("Error processing ")) {
2185 // j2s did not complete transpile
2186 //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2187 if (jalviewjs_ignore_transpile_errors.equals("true")) {
2188 println("IGNORING TRANSPILE ERRORS")
2189 println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2191 throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2196 inputs.dir("${jalviewDir}/${sourceDir}")
2197 outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
2198 outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
2202 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
2204 def stdout = new ByteArrayOutputStream()
2205 def stderr = new ByteArrayOutputStream()
2207 def coreFile = file(jsfile)
2209 msg = "Creating core for ${name}...\nGenerating ${jsfile}"
2211 logOutFile.createNewFile()
2212 logOutFile.append(msg+"\n")
2214 def coreTop = file(prefixFile)
2215 def coreBottom = file(suffixFile)
2216 coreFile.getParentFile().mkdirs()
2217 coreFile.createNewFile()
2218 coreFile.write( coreTop.getText("UTF-8") )
2222 def t = f.getText("UTF-8")
2223 t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
2224 coreFile.append( t )
2226 msg = "...file '"+f.getPath()+"' does not exist, skipping"
2228 logOutFile.append(msg+"\n")
2231 coreFile.append( coreBottom.getText("UTF-8") )
2233 msg = "Generating ${zjsfile}"
2235 logOutFile.append(msg+"\n")
2236 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2237 def logErrFOS = logOutFOS
2240 classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
2241 main = "com.google.javascript.jscomp.CommandLineRunner"
2242 jvmArgs = [ "-Dfile.encoding=UTF-8" ]
2243 args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
2246 msg = "\nRunning '"+commandLine.join(' ')+"'\n"
2248 logOutFile.append(msg+"\n")
2250 if (logOutConsole) {
2251 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2252 new org.apache.tools.ant.util.TeeOutputStream(
2256 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2257 new org.apache.tools.ant.util.TeeOutputStream(
2262 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2265 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2272 logOutFile.append(msg+"\n")
2276 task jalviewjsBuildAllCores {
2278 description "Build the core js lib closures listed in the classlists dir"
2279 dependsOn jalviewjsTranspile
2280 dependsOn jalviewjsTransferUnzipSwingJs
2282 def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
2283 def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
2284 def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
2285 def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
2286 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
2287 def prefixFile = "${jsDir}/core/coretop2.js"
2288 def suffixFile = "${jsDir}/core/corebottom2.js"
2290 inputs.file prefixFile
2291 inputs.file suffixFile
2293 def classlistFiles = []
2294 // add the classlists found int the jalviewjs_classlists_dir
2295 fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
2297 def name = file.getName() - ".txt"
2304 // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
2305 //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
2306 classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
2308 jalviewjsCoreClasslists = []
2310 classlistFiles.each {
2313 def file = hash['file']
2314 if (! file.exists()) {
2315 //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
2316 return false // this is a "continue" in groovy .each closure
2318 def name = hash['name']
2320 name = file.getName() - ".txt"
2328 def list = fileTree(dir: j2sDir, includes: filelist)
2330 def jsfile = "${outputDir}/core${name}.js"
2331 def zjsfile = "${outputDir}/core${name}.z.js"
2333 jalviewjsCoreClasslists += [
2342 outputs.file(jsfile)
2343 outputs.file(zjsfile)
2346 // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
2347 def stevesoftClasslistName = "_stevesoft"
2348 def stevesoftClasslist = [
2349 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
2350 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
2351 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
2352 'name': stevesoftClasslistName
2354 jalviewjsCoreClasslists += stevesoftClasslist
2355 inputs.files(stevesoftClasslist['list'])
2356 outputs.file(stevesoftClasslist['jsfile'])
2357 outputs.file(stevesoftClasslist['zjsfile'])
2360 def allClasslistName = "_all"
2361 def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
2362 allJsFiles += fileTree(
2366 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2367 "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
2368 "**/org/jmol/export/JSExporter.js"
2371 allJsFiles += fileTree(
2375 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2376 "**/sun/misc/Unsafe.js",
2377 "**/swingjs/jquery/jquery-editable-select.js",
2378 "**/swingjs/jquery/j2sComboBox.js",
2379 "**/sun/misc/FloatingDecimal.js"
2382 def allClasslist = [
2383 'jsfile': "${outputDir}/core${allClasslistName}.js",
2384 'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
2386 'name': allClasslistName
2388 // not including this version of "all" core at the moment
2389 //jalviewjsCoreClasslists += allClasslist
2390 inputs.files(allClasslist['list'])
2391 outputs.file(allClasslist['jsfile'])
2392 outputs.file(allClasslist['zjsfile'])
2395 def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
2396 logOutFile.getParentFile().mkdirs()
2397 logOutFile.createNewFile()
2398 logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
2400 jalviewjsCoreClasslists.each {
2401 jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
2408 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
2411 into file(outputFile).getParentFile()
2412 rename { filename ->
2413 if (filename.equals(inputFile.getName())) {
2414 return file(outputFile).getName()
2418 filter(ReplaceTokens,
2422 'MAIN': '"'+mainClass+'"',
2424 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
2425 'COREKEY': jalviewjs_core_key,
2426 'CORENAME': coreName
2433 task jalviewjsPublishCoreTemplates {
2434 dependsOn jalviewjsBuildAllCores
2435 def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
2436 def inputFile = file(inputFileName)
2437 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2439 def outputFiles = []
2440 jalviewjsCoreClasslists.each { cl ->
2441 def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
2442 cl['outputfile'] = outputFile
2443 outputFiles += outputFile
2447 jalviewjsCoreClasslists.each { cl ->
2448 jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
2451 inputs.file(inputFile)
2452 outputs.files(outputFiles)
2456 task jalviewjsSyncCore (type: Sync) {
2457 dependsOn jalviewjsBuildAllCores
2458 dependsOn jalviewjsPublishCoreTemplates
2459 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
2460 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2464 def outputFiles = []
2465 rename { filename ->
2466 outputFiles += "${outputDir}/${filename}"
2472 outputs.files outputFiles
2473 inputs.files inputFiles
2477 // this Copy version of TransferSiteJs will delete anything else in the target dir
2478 task jalviewjsCopyTransferSiteJs(type: Copy) {
2479 dependsOn jalviewjsTranspile
2480 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2481 into "${jalviewDir}/${jalviewjsSiteDir}"
2485 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
2486 task jalviewjsSyncTransferSiteJs(type: Sync) {
2487 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2489 into "${jalviewDir}/${jalviewjsSiteDir}"
2496 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
2497 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
2498 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
2499 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
2501 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
2502 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
2503 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
2504 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
2507 task jalviewjsPrepareSite {
2509 description "Prepares the website folder including unzipping files and copying resources"
2510 dependsOn jalviewjsSyncAllLibs
2511 dependsOn jalviewjsSyncResources
2512 dependsOn jalviewjsSyncSiteResources
2513 dependsOn jalviewjsSyncBuildProperties
2514 dependsOn jalviewjsSyncCore
2518 task jalviewjsBuildSite {
2520 description "Builds the whole website including transpiled code"
2521 dependsOn jalviewjsCopyTransferSiteJs
2522 dependsOn jalviewjsPrepareSite
2526 task cleanJalviewjsTransferSite {
2528 delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2529 delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2530 delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2531 delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2536 task cleanJalviewjsSite {
2537 dependsOn cleanJalviewjsTransferSite
2539 delete "${jalviewDir}/${jalviewjsSiteDir}"
2544 task jalviewjsSiteTar(type: Tar) {
2546 description "Creates a tar.gz file for the website"
2547 dependsOn jalviewjsBuildSite
2548 def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
2550 archiveFileName = outputFilename
2551 } catch (Exception e) {
2552 archiveName = outputFilename
2555 compression Compression.GZIP
2557 from "${jalviewDir}/${jalviewjsSiteDir}"
2558 into jalviewjs_site_dir // this is inside the tar file
2560 inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
2564 task jalviewjsServer {
2566 def filename = "jalviewjsTest.html"
2567 description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
2568 def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
2571 SimpleHttpFileServerFactory factory = new SimpleHttpFileServerFactory()
2572 def port = Integer.valueOf(jalviewjs_server_port)
2577 while(port < start+1000 && !running) {
2579 def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
2580 jalviewjsServer = factory.start(doc_root, port)
2582 url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
2583 println("SERVER STARTED with document root ${doc_root}.")
2584 println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).")
2585 println("For debug: "+url+"?j2sdebug")
2586 println("For verbose: "+url+"?j2sverbose")
2587 } catch (Exception e) {
2592 <p><a href="${url}">JalviewJS Test. <${url}></a></p>
2593 <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
2594 <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
2596 jalviewjsCoreClasslists.each { cl ->
2597 def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
2599 <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></a></p>
2601 println("For core ${cl.name}: "+urlcore)
2604 file(htmlFile).text = htmlText
2607 outputs.file(htmlFile)
2608 outputs.upToDateWhen({false})
2612 task cleanJalviewjsAll {
2614 description "Delete all configuration and build artifacts to do with JalviewJS build"
2615 dependsOn cleanJalviewjsSite
2616 dependsOn jalviewjsEclipsePaths
2619 delete "${jalviewDir}/${jalviewjsBuildDir}"
2620 delete "${jalviewDir}/${eclipse_bin_dir}"
2621 if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
2622 delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
2624 delete "${jalviewDir}/${jalviewjs_j2s_settings}"
2627 outputs.upToDateWhen( { false } )
2631 task jalviewjsIDE_checkJ2sPlugin {
2632 group "00 JalviewJS in Eclipse"
2633 description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
2636 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
2637 def j2sPluginFile = file(j2sPlugin)
2638 def eclipseHome = System.properties["eclipse.home.location"]
2639 if (eclipseHome == null || ! IN_ECLIPSE) {
2640 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
2642 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
2643 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
2644 if (!eclipseJ2sPluginFile.exists()) {
2645 def msg = "Eclipse J2S Plugin is not installed (could not find '${eclipseJ2sPlugin}')\nTry running task jalviewjsIDE_copyJ2sPlugin"
2646 System.err.println(msg)
2647 throw new StopExecutionException(msg)
2650 def digest = MessageDigest.getInstance("MD5")
2652 digest.update(j2sPluginFile.text.bytes)
2653 def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
2655 digest.update(eclipseJ2sPluginFile.text.bytes)
2656 def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
2658 if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
2659 def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
2660 System.err.println(msg)
2661 throw new StopExecutionException(msg)
2663 def msg = "Eclipse J2S Plugin is the same as '${j2sPlugin}' (this is good)"
2669 task jalviewjsIDE_copyJ2sPlugin {
2670 group "00 JalviewJS in Eclipse"
2671 description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
2674 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
2675 def j2sPluginFile = file(j2sPlugin)
2676 def eclipseHome = System.properties["eclipse.home.location"]
2677 if (eclipseHome == null || ! IN_ECLIPSE) {
2678 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
2680 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
2681 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
2682 def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
2683 System.err.println(msg)
2686 eclipseJ2sPluginFile.getParentFile().mkdirs()
2687 into eclipseJ2sPluginFile.getParent()
2693 task jalviewjsIDE_j2sFile {
2694 group "00 JalviewJS in Eclipse"
2695 description "Creates the .j2s file"
2696 dependsOn jalviewjsCreateJ2sSettings
2700 task jalviewjsIDE_SyncCore {
2701 group "00 JalviewJS in Eclipse"
2702 description "Build the core js lib closures listed in the classlists dir and publish core html from template"
2703 dependsOn jalviewjsSyncCore
2707 task jalviewjsIDE_SyncSiteAll {
2708 dependsOn jalviewjsSyncAllLibs
2709 dependsOn jalviewjsSyncResources
2710 dependsOn jalviewjsSyncSiteResources
2711 dependsOn jalviewjsSyncBuildProperties
2715 cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
2718 task jalviewjsIDE_PrepareSite {
2719 group "00 JalviewJS in Eclipse"
2720 description "Sync libs and resources to site dir, but not closure cores"
2722 dependsOn jalviewjsIDE_SyncSiteAll
2723 dependsOn cleanJalviewjsTransferSite
2727 task jalviewjsIDE_AssembleSite {
2728 group "00 JalviewJS in Eclipse"
2729 description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
2730 dependsOn jalviewjsPrepareSite
2734 task jalviewjsIDE_SiteClean {
2735 group "00 JalviewJS in Eclipse"
2736 description "Deletes the Eclipse transpiled site"
2737 dependsOn cleanJalviewjsSite
2741 task jalviewjsIDE_Server {
2742 group "00 JalviewJS in Eclipse"
2743 description "Starts a webserver on localhost to test the website"
2744 dependsOn jalviewjsServer
2748 // buildship runs this at import or gradle refresh
2749 task eclipseSynchronizationTask {
2750 //dependsOn eclipseSetup
2751 dependsOn createBuildProperties
2753 dependsOn jalviewjsIDE_j2sFile
2754 dependsOn jalviewjsIDE_checkJ2sPlugin
2755 dependsOn jalviewjsIDE_PrepareSite
2760 // buildship runs this at build time or project refresh
2761 task eclipseAutoBuildTask {
2762 //dependsOn jalviewjsIDE_checkJ2sPlugin
2763 //dependsOn jalviewjsIDE_PrepareSite
2769 description "Build the site"
2770 dependsOn jalviewjsBuildSite