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
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")
86 // Import releaseProps from the RELEASE file
87 // or a file specified via JALVIEW_RELEASE_FILE if defined
88 // Expect jalview.version and target release branch in jalview.release
89 def releaseProps = new Properties();
90 def releasePropFile = findProperty("JALVIEW_RELEASE_FILE");
91 def defaultReleasePropFile = "${jalviewDirAbsolutePath}/RELEASE";
93 (new File(releasePropFile!=null ? releasePropFile : defaultReleasePropFile)).withInputStream {
96 } catch (Exception fileLoadError) {
97 throw new Error("Couldn't load release properties file "+(releasePropFile==null ? defaultReleasePropFile : "from custom location: releasePropFile"),fileLoadError);
100 // Set JALVIEW_VERSION if it is not already set
101 if (findProperty(JALVIEW_VERSION)==null || "".equals(JALVIEW_VERSION)) {
102 JALVIEW_VERSION = releaseProps.get("jalview.version")
105 // this property set when running Eclipse headlessly
106 j2sHeadlessBuildProperty = string("net.sf.j2s.core.headlessbuild")
107 // this property set by Eclipse
108 eclipseApplicationProperty = string("eclipse.application")
109 // CHECK IF RUNNING FROM WITHIN ECLIPSE
110 def eclipseApplicationPropertyVal = System.properties[eclipseApplicationProperty]
111 IN_ECLIPSE = eclipseApplicationPropertyVal != null && eclipseApplicationPropertyVal.startsWith("org.eclipse.ui.")
112 // BUT WITHOUT THE HEADLESS BUILD PROPERTY SET
113 if (System.properties[j2sHeadlessBuildProperty].equals("true")) {
114 println("Setting IN_ECLIPSE to ${IN_ECLIPSE} as System.properties['${j2sHeadlessBuildProperty}'] == '${System.properties[j2sHeadlessBuildProperty]}'")
118 println("WITHIN ECLIPSE IDE")
120 println("HEADLESS BUILD")
123 J2S_ENABLED = (project.hasProperty('j2s.compiler.status') && project['j2s.compiler.status'] != null && project['j2s.compiler.status'] == "enable")
125 println("J2S ENABLED")
128 System.properties.sort { it.key }.each {
129 key, val -> println("SYSTEM PROPERTY ${key}='${val}'")
132 if (false && IN_ECLIPSE) {
133 jalviewDir = jalviewDirAbsolutePath
138 bareSourceDir = string(source_dir)
139 sourceDir = string("${jalviewDir}/${bareSourceDir}")
140 resourceDir = string("${jalviewDir}/${resource_dir}")
141 bareTestSourceDir = string(test_source_dir)
142 testDir = string("${jalviewDir}/${bareTestSourceDir}")
144 classesDir = string("${jalviewDir}/${classes_dir}")
147 useClover = clover.equals("true")
148 cloverBuildDir = "${buildDir}/clover"
149 cloverInstrDir = file("${cloverBuildDir}/clover-instr")
150 cloverClassesDir = file("${cloverBuildDir}/clover-classes")
151 cloverReportDir = file("${buildDir}/reports/clover")
152 cloverTestInstrDir = file("${cloverBuildDir}/clover-test-instr")
153 cloverTestClassesDir = file("${cloverBuildDir}/clover-test-classes")
154 //cloverTestClassesDir = cloverClassesDir
155 cloverDb = string("${cloverBuildDir}/clover.db")
157 resourceClassesDir = useClover ? cloverClassesDir : classesDir
159 testSourceDir = useClover ? cloverTestInstrDir : testDir
160 testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}"
162 getdownWebsiteDir = string("${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}")
165 // the following values might be overridden by the CHANNEL switch
166 getdownChannelName = CHANNEL.toLowerCase()
167 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
168 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
169 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}")
170 getdownAppDistDir = getdown_app_dir_alt
171 buildProperties = string("${resourceDir}/${build_properties_file}")
172 reportRsyncCommand = false
173 jvlChannelName = CHANNEL.toLowerCase()
174 install4jSuffix = CHANNEL.substring(0, 1).toUpperCase() + CHANNEL.substring(1).toLowerCase(); // BUILD -> Build
175 install4jDSStore = "DS_Store-NON-RELEASE"
176 install4jDMGBackgroundImage = "jalview_dmg_background-NON-RELEASE.png"
177 install4jInstallerName = "${jalview_name} Non-Release Installer"
178 install4jExecutableName = jalview_name.replaceAll("[^\\w]+", "_").toLowerCase()
179 install4jExtraScheme = "jalviewx"
183 // TODO: get bamboo build artifact URL for getdown artifacts
184 getdown_channel_base = bamboo_channelbase
185 getdownChannelName = string("${bamboo_planKey}/${JAVA_VERSION}")
186 getdownAppBase = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}")
187 jvlChannelName += "_${getdownChannelName}"
188 // automatically add the test group Not-bamboo for exclusion
189 if ("".equals(testng_excluded_groups)) {
190 testng_excluded_groups = "Not-bamboo"
192 install4jExtraScheme = "jalviewb"
196 getdownAppDistDir = getdown_app_dir_release
197 reportRsyncCommand = true
199 install4jDSStore = "DS_Store"
200 install4jDMGBackgroundImage = "jalview_dmg_background.png"
201 install4jInstallerName = "${jalview_name} Installer"
205 getdownChannelName = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}"
206 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
207 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
208 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
209 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
211 package_dir = string("${ARCHIVEDIR}/${package_dir}")
212 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
215 reportRsyncCommand = true
216 install4jExtraScheme = "jalviewa"
220 getdownChannelName = string("archive/${JALVIEW_VERSION}")
221 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
222 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
223 if (!file("${ARCHIVEDIR}/${package_dir}").exists()) {
224 throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution")
226 package_dir = string("${ARCHIVEDIR}/${package_dir}")
227 buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}")
230 reportRsyncCommand = true
231 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
232 install4jSuffix = "Archive"
233 install4jExtraScheme = "jalviewa"
237 reportRsyncCommand = true
239 // DEVELOP-RELEASE is usually associated with a Jalview release series so set the version
240 JALVIEW_VERSION=JALVIEW_VERSION+"-develop"
242 install4jSuffix = "Develop"
243 install4jDSStore = "DS_Store-DEVELOP"
244 install4jDMGBackgroundImage = "jalview_dmg_background-DEVELOP.png"
245 install4jExtraScheme = "jalviewd"
246 install4jInstallerName = "${jalview_name} Develop Installer"
250 reportRsyncCommand = true
251 // Don't ignore transpile errors for release build
252 if (jalviewjs_ignore_transpile_errors.equals("true")) {
253 jalviewjs_ignore_transpile_errors = "false"
254 println("Setting jalviewjs_ignore_transpile_errors to 'false'")
256 JALVIEW_VERSION = JALVIEW_VERSION+"-test"
257 install4jSuffix = "Test"
258 install4jDSStore = "DS_Store-TEST-RELEASE"
259 install4jDMGBackgroundImage = "jalview_dmg_background-TEST.png"
260 install4jExtraScheme = "jalviewt"
261 install4jInstallerName = "${jalview_name} Test Installer"
264 case ~/^SCRATCH(|-[-\w]*)$/:
265 getdownChannelName = CHANNEL
266 JALVIEW_VERSION = JALVIEW_VERSION+"-"+CHANNEL
268 getdownDir = string("${getdownChannelName}/${JAVA_VERSION}")
269 getdownAppBase = string("${getdown_channel_base}/${getdownDir}")
270 reportRsyncCommand = true
271 install4jSuffix = "Scratch"
275 if (!file("${LOCALDIR}").exists()) {
276 throw new GradleException("Must provide a LOCALDIR value to produce a local distribution")
278 getdownAppBase = file(file("${LOCALDIR}").getAbsolutePath()).toURI().toString()
279 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
281 JALVIEW_VERSION = "TEST"
282 install4jSuffix = "Test-Local"
283 install4jDSStore = "DS_Store-TEST-RELEASE"
284 install4jDMGBackgroundImage = "jalview_dmg_background-TEST.png"
285 install4jExtraScheme = "jalviewt"
286 install4jInstallerName = "${jalview_name} Test Installer"
290 JALVIEW_VERSION = "TEST"
291 getdownAppBase = file(getdownWebsiteDir).toURI().toString()
292 getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}")
293 install4jExtraScheme = "jalviewl"
296 default: // something wrong specified
297 throw new GradleException("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]")
301 // override getdownAppBase if requested
302 if (findProperty("getdown_appbase_override") != null) {
303 getdownAppBase = string(getProperty("getdown_appbase_override"))
304 println("Overriding getdown appbase with '${getdownAppBase}'")
306 // sanitise file name for jalview launcher file for this channel
307 jvlChannelName = jvlChannelName.replaceAll("[^\\w\\-]+", "_")
308 // install4j application and folder names
309 if (install4jSuffix == "") {
310 install4jApplicationName = "${jalview_name}"
311 install4jBundleId = "${install4j_bundle_id}"
312 install4jWinApplicationId = install4j_release_win_application_id
314 install4jApplicationName = "${jalview_name} ${install4jSuffix}"
315 install4jBundleId = "${install4j_bundle_id}-" + install4jSuffix.toLowerCase()
316 // add int hash of install4jSuffix to the last part of the application_id
317 def id = install4j_release_win_application_id
318 def idsplitreverse = id.split("-").reverse()
319 idsplitreverse[0] = idsplitreverse[0].toInteger() + install4jSuffix.hashCode()
320 install4jWinApplicationId = idsplitreverse.reverse().join("-")
322 // sanitise folder and id names
323 // install4jApplicationFolder = e.g. "Jalview Build"
324 install4jApplicationFolder = install4jApplicationName
325 .replaceAll("[\"'~:/\\\\\\s]", "_") // replace all awkward filename chars " ' ~ : / \
326 .replaceAll("_+", "_") // collapse __
327 install4jInternalId = install4jApplicationName
329 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
330 .replaceAll("_+", "") // collapse __
331 //.replaceAll("_*-_*", "-") // collapse _-_
332 install4jUnixApplicationFolder = install4jApplicationName
334 .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.]
335 .replaceAll("_+", "_") // collapse __
336 .replaceAll("_*-_*", "-") // collapse _-_
339 getdownAppDir = string("${getdownWebsiteDir}/${getdownAppDistDir}")
340 //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}"
341 getdownResourceDir = string("${getdownWebsiteDir}/${getdown_resource_dir}")
342 getdownInstallDir = string("${getdownWebsiteDir}/${getdown_install_dir}")
343 getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/")
344 getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}")
345 /* compile without modules -- using classpath libraries
346 modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"])
347 modules_runtimeClasspath = modules_compileClasspath
350 gitBranch = string("")
352 println("Using a ${CHANNEL} profile.")
354 additional_compiler_args = []
355 // configure classpath/args for j8/j11 compilation
356 if (JAVA_VERSION.equals("1.8")) {
357 JAVA_INTEGER_VERSION = string("8")
360 libDistDir = j8libDir
361 compile_source_compatibility = 1.8
362 compile_target_compatibility = 1.8
363 // these are getdown.txt properties defined dependent on the JAVA_VERSION
364 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java8_min_version"))
365 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java8_max_version"))
366 // this property is assigned below and expanded to multiple lines in the getdown task
367 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java8_txt_multi_java_location"))
368 // this property is for the Java library used in eclipse
369 eclipseJavaRuntimeName = string("JavaSE-1.8")
370 } else if (JAVA_VERSION.equals("11")) {
371 JAVA_INTEGER_VERSION = string("11")
373 libDistDir = j11libDir
374 compile_source_compatibility = 11
375 compile_target_compatibility = 11
376 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
377 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
378 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
379 eclipseJavaRuntimeName = string("JavaSE-11")
380 /* compile without modules -- using classpath libraries
381 additional_compiler_args += [
382 '--module-path', modules_compileClasspath.asPath,
383 '--add-modules', j11modules
386 } else if (JAVA_VERSION.equals("12") || JAVA_VERSION.equals("13")) {
387 JAVA_INTEGER_VERSION = JAVA_VERSION
389 libDistDir = j11libDir
390 compile_source_compatibility = JAVA_VERSION
391 compile_target_compatibility = JAVA_VERSION
392 getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version"))
393 getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version"))
394 getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location"))
395 eclipseJavaRuntimeName = string("JavaSE-11")
396 /* compile without modules -- using classpath libraries
397 additional_compiler_args += [
398 '--module-path', modules_compileClasspath.asPath,
399 '--add-modules', j11modules
403 throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview")
408 JAVA_MIN_VERSION = JAVA_VERSION
409 JAVA_MAX_VERSION = JAVA_VERSION
410 def jreInstallsDir = string(jre_installs_dir)
411 if (jreInstallsDir.startsWith("~/")) {
412 jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1)
414 macosJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-mac-x64/jre")
415 macosJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-mac-x64.tar.gz")
416 windowsJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-windows-x64/jre")
417 windowsJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-windows-x64.tar.gz")
418 linuxJavaVMDir = string("${jreInstallsDir}/jre-${JAVA_INTEGER_VERSION}-linux-x64/jre")
419 linuxJavaVMTgz = string("${jreInstallsDir}/tgz/jre-${JAVA_INTEGER_VERSION}-linux-x64.tar.gz")
420 install4jDir = string("${jalviewDir}/${install4j_utils_dir}")
421 install4jConfFileName = string("jalview-install4j-conf.install4j")
422 install4jConfFile = file("${install4jDir}/${install4jConfFileName}")
423 install4jHomeDir = install4j_home_dir
424 if (install4jHomeDir.startsWith("~/")) {
425 install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1)
430 buildingHTML = string("${jalviewDir}/${doc_dir}/building.html")
431 helpFile = string("${resourceClassesDir}/${help_dir}/help.jhm")
432 helpParentDir = string("${jalviewDir}/${help_parent_dir}")
433 helpSourceDir = string("${helpParentDir}/${help_dir}")
436 relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath())
437 jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs")
438 jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}")
440 jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir)
442 jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js")
444 jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib")
445 jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs")
446 jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core")
447 jalviewjsJalviewCoreHtmlFile = string("")
448 jalviewjsJalviewCoreName = string(jalviewjs_core_name)
449 jalviewjsCoreClasslists = []
450 jalviewjsJalviewTemplateName = string(jalviewjs_name)
451 jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}")
452 jalviewjsJ2sProps = null
453 jalviewjsJ2sPlugin = jalviewjs_j2s_plugin
455 eclipseWorkspace = null
456 eclipseBinary = string("")
457 eclipseVersion = string("")
467 outputDir = file(classesDir)
472 srcDirs += helpParentDir
475 jar.destinationDir = file("${jalviewDir}/${package_dir}")
477 compileClasspath = files(sourceSets.main.java.outputDir)
478 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
480 runtimeClasspath = compileClasspath
485 srcDirs cloverInstrDir
486 outputDir = cloverClassesDir
490 srcDirs = sourceSets.main.resources.srcDirs
493 compileClasspath = files( sourceSets.clover.java.outputDir )
494 //compileClasspath += files( testClassesDir )
495 compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"])
496 compileClasspath += fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
497 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
499 runtimeClasspath = compileClasspath
504 srcDirs testSourceDir
505 outputDir = file(testClassesDir)
509 srcDirs = useClover ? sourceSets.clover.resources.srcDirs : sourceSets.main.resources.srcDirs
512 compileClasspath = files( sourceSets.test.java.outputDir )
513 compileClasspath += useClover ? sourceSets.clover.compileClasspath : sourceSets.main.compileClasspath
514 compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"])
516 runtimeClasspath = compileClasspath
522 // eclipse project and settings files creation, also used by buildship
525 name = eclipse_project_name
527 natures 'org.eclipse.jdt.core.javanature',
528 'org.eclipse.jdt.groovy.core.groovyNature',
529 'org.eclipse.buildship.core.gradleprojectnature'
531 buildCommand 'org.eclipse.jdt.core.javabuilder'
532 buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
536 //defaultOutputDir = sourceSets.main.java.outputDir
539 if (it.isCanBeResolved()) {
544 minusConfigurations += removeThese
545 plusConfigurations = [ ]
549 def removeTheseToo = []
550 HashMap<String, Boolean> alreadyAddedSrcPath = new HashMap<>();
551 cp.entries.each { entry ->
552 // This conditional removes all src classpathentries that a) have already been added or b) aren't "src" or "test".
553 // e.g. this removes the resources dir being copied into bin/main, bin/test AND bin/clover
554 // we add the resources and help/help dirs in as libs afterwards (see below)
555 if (entry.kind == 'src') {
556 if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) {
557 removeTheseToo += entry
559 alreadyAddedSrcPath.putAt(entry.path, true)
564 cp.entries.removeAll(removeTheseToo)
566 //cp.entries += new Output("${eclipse_bin_dir}/main")
567 if (file(helpParentDir).isDirectory()) {
568 cp.entries += new Library(fileReference(helpParentDir))
570 if (file(resourceDir).isDirectory()) {
571 cp.entries += new Library(fileReference(resourceDir))
574 HashMap<String, Boolean> alreadyAddedLibPath = new HashMap<>();
576 sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
577 //don't want to add outputDir as eclipse is using its own output dir in bin/main
578 if (it.isDirectory() || ! it.exists()) {
579 // don't add dirs to classpath, especially if they don't exist
580 return false // groovy "continue" in .any closure
582 def itPath = it.toString()
583 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
584 // make relative path
585 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
587 if (alreadyAddedLibPath.get(itPath)) {
588 //println("Not adding duplicate entry "+itPath)
590 //println("Adding entry "+itPath)
591 cp.entries += new Library(fileReference(itPath))
592 alreadyAddedLibPath.put(itPath, true)
596 sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any {
597 //no longer want to add outputDir as eclipse is using its own output dir in bin/main
598 if (it.isDirectory() || ! it.exists()) {
599 // don't add dirs to classpath
600 return false // groovy "continue" in .any closure
603 def itPath = it.toString()
604 if (itPath.startsWith("${jalviewDirAbsolutePath}/")) {
605 itPath = itPath.substring(jalviewDirAbsolutePath.length()+1)
607 if (alreadyAddedLibPath.get(itPath)) {
610 def lib = new Library(fileReference(itPath))
611 lib.entryAttributes["test"] = "true"
613 alreadyAddedLibPath.put(itPath, true)
621 containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
626 // for the IDE, use java 11 compatibility
627 sourceCompatibility = compile_source_compatibility
628 targetCompatibility = compile_target_compatibility
629 javaRuntimeName = eclipseJavaRuntimeName
631 // add in jalview project specific properties/preferences into eclipse core preferences
633 withProperties { props ->
634 def jalview_prefs = new Properties()
635 def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}")
636 jalview_prefs.load(ins)
638 jalview_prefs.forEach { t, v ->
639 if (props.getAt(t) == null) {
643 // codestyle file -- overrides previous formatter prefs
644 def csFile = file("${jalviewDirAbsolutePath}/${eclipse_codestyle_file}")
645 if (csFile.exists()) {
646 XmlParser parser = new XmlParser()
647 def profiles = parser.parse(csFile)
648 def profile = profiles.'profile'.find { p -> (p.'@kind' == "CodeFormatterProfile" && p.'@name' == "Jalview") }
649 if (profile != null) {
650 profile.'setting'.each { s ->
652 def value = s.'@value'
653 if (id != null && value != null) {
654 props.putAt(id, value)
665 // Don't want these to be activated if in headless build
666 synchronizationTasks "eclipseSynchronizationTask"
667 //autoBuildTasks "eclipseAutoBuildTask"
673 /* hack to change eclipse prefs in .settings files other than org.eclipse.jdt.core.prefs */
674 // Class to allow updating arbitrary properties files
675 class PropertiesFile extends PropertiesPersistableConfigurationObject {
676 public PropertiesFile(PropertiesTransformer t) { super(t); }
677 @Override protected void load(Properties properties) { }
678 @Override protected void store(Properties properties) { }
679 @Override protected String getDefaultResourceName() { return ""; }
680 // This is necessary, because PropertiesPersistableConfigurationObject fails
681 // if no default properties file exists.
682 @Override public void loadDefaults() { load(new StringBufferInputStream("")); }
685 // Task to update arbitrary properties files (set outputFile)
686 class PropertiesFileTask extends PropertiesGeneratorTask<PropertiesFile> {
687 private final PropertiesFileContentMerger file;
688 public PropertiesFileTask() { file = new PropertiesFileContentMerger(getTransformer()); }
689 protected PropertiesFile create() { return new PropertiesFile(getTransformer()); }
690 protected void configure(PropertiesFile props) {
691 file.getBeforeMerged().execute(props); file.getWhenMerged().execute(props);
693 public void file(Closure closure) { ConfigureUtil.configure(closure, file); }
696 task eclipseUIPreferences(type: PropertiesFileTask) {
697 description = "Generate Eclipse additional settings"
698 def filename = "org.eclipse.jdt.ui.prefs"
699 outputFile = "$projectDir/.settings/${filename}" as File
702 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
707 task eclipseGroovyCorePreferences(type: PropertiesFileTask) {
708 description = "Generate Eclipse additional settings"
709 def filename = "org.eclipse.jdt.groovy.core.prefs"
710 outputFile = "$projectDir/.settings/${filename}" as File
713 it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String)
718 task eclipseAllPreferences {
720 dependsOn eclipseUIPreferences
721 dependsOn eclipseGroovyCorePreferences
724 eclipseUIPreferences.mustRunAfter eclipseJdt
725 eclipseGroovyCorePreferences.mustRunAfter eclipseJdt
727 /* end of eclipse preferences hack */
735 delete cloverBuildDir
736 delete cloverReportDir
741 task cloverInstrJava(type: JavaExec) {
742 group = "Verification"
743 description = "Create clover instrumented source java files"
745 dependsOn cleanClover
747 inputs.files(sourceSets.main.allJava)
748 outputs.dir(cloverInstrDir)
750 //classpath = fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
751 classpath = sourceSets.clover.compileClasspath
752 main = "com.atlassian.clover.CloverInstr"
760 cloverInstrDir.getPath(),
762 def srcFiles = sourceSets.main.allJava.files
765 { file -> file.absolutePath }
768 args argsList.toArray()
771 delete cloverInstrDir
772 println("Clover: About to instrument "+srcFiles.size() +" files")
777 task cloverInstrTests(type: JavaExec) {
778 group = "Verification"
779 description = "Create clover instrumented source test files"
781 dependsOn cleanClover
783 inputs.files(testDir)
784 outputs.dir(cloverTestInstrDir)
786 classpath = sourceSets.clover.compileClasspath
787 main = "com.atlassian.clover.CloverInstr"
797 cloverTestInstrDir.getPath(),
799 args argsList.toArray()
802 delete cloverTestInstrDir
803 println("Clover: About to instrument test files")
809 group = "Verification"
810 description = "Create clover instrumented all source files"
812 dependsOn cloverInstrJava
813 dependsOn cloverInstrTests
817 cloverClasses.dependsOn cloverInstr
820 task cloverConsoleReport(type: JavaExec) {
821 group = "Verification"
822 description = "Creates clover console report"
825 file(cloverDb).exists()
828 inputs.dir cloverClassesDir
830 classpath = sourceSets.clover.runtimeClasspath
831 main = "com.atlassian.clover.reporters.console.ConsoleReporter"
833 if (cloverreport_mem.length() > 0) {
834 maxHeapSize = cloverreport_mem
836 if (cloverreport_jvmargs.length() > 0) {
837 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
847 args argsList.toArray()
851 task cloverHtmlReport(type: JavaExec) {
852 group = "Verification"
853 description = "Creates clover HTML report"
856 file(cloverDb).exists()
859 def cloverHtmlDir = cloverReportDir
860 inputs.dir cloverClassesDir
861 outputs.dir cloverHtmlDir
863 classpath = sourceSets.clover.runtimeClasspath
864 main = "com.atlassian.clover.reporters.html.HtmlReporter"
866 if (cloverreport_mem.length() > 0) {
867 maxHeapSize = cloverreport_mem
869 if (cloverreport_jvmargs.length() > 0) {
870 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
881 if (cloverreport_html_options.length() > 0) {
882 argsList += cloverreport_html_options.split(" ")
885 args argsList.toArray()
889 task cloverXmlReport(type: JavaExec) {
890 group = "Verification"
891 description = "Creates clover XML report"
894 file(cloverDb).exists()
897 def cloverXmlFile = "${cloverReportDir}/clover.xml"
898 inputs.dir cloverClassesDir
899 outputs.file cloverXmlFile
901 classpath = sourceSets.clover.runtimeClasspath
902 main = "com.atlassian.clover.reporters.xml.XMLReporter"
904 if (cloverreport_mem.length() > 0) {
905 maxHeapSize = cloverreport_mem
907 if (cloverreport_jvmargs.length() > 0) {
908 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
919 if (cloverreport_xml_options.length() > 0) {
920 argsList += cloverreport_xml_options.split(" ")
923 args argsList.toArray()
928 group = "Verification"
929 description = "Creates clover reports"
931 dependsOn cloverXmlReport
932 dependsOn cloverHtmlReport
939 sourceCompatibility = compile_source_compatibility
940 targetCompatibility = compile_target_compatibility
941 options.compilerArgs += additional_compiler_args
942 print ("Setting target compatibility to "+targetCompatibility+"\n")
944 //classpath += configurations.cloverRuntime
950 // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ?
951 sourceCompatibility = compile_source_compatibility
952 targetCompatibility = compile_target_compatibility
953 options.compilerArgs = additional_compiler_args
954 options.encoding = "UTF-8"
956 print ("Setting target compatibility to "+compile_target_compatibility+"\n")
963 sourceCompatibility = compile_source_compatibility
964 targetCompatibility = compile_target_compatibility
965 options.compilerArgs = additional_compiler_args
967 print ("Setting target compatibility to "+targetCompatibility+"\n")
974 delete sourceSets.main.java.outputDir
980 dependsOn cleanClover
982 delete sourceSets.test.java.outputDir
987 // format is a string like date.format("dd MMMM yyyy")
988 def getDate(format) {
989 def date = new Date()
990 return date.format(format)
995 def hashStdOut = new ByteArrayOutputStream()
997 commandLine "git", "rev-parse", "--short", "HEAD"
998 standardOutput = hashStdOut
1002 def branchStdOut = new ByteArrayOutputStream()
1004 commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
1005 standardOutput = branchStdOut
1006 ignoreExitValue true
1009 gitHash = hashStdOut.toString().trim()
1010 gitBranch = branchStdOut.toString().trim()
1012 outputs.upToDateWhen { false }
1016 task createBuildProperties(type: WriteProperties) {
1018 description = "Create the ${buildProperties} file"
1020 dependsOn setGitVals
1021 inputs.dir(sourceDir)
1022 inputs.dir(resourceDir)
1023 file(buildProperties).getParentFile().mkdirs()
1024 outputFile (buildProperties)
1025 // taking time specific comment out to allow better incremental builds
1026 comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
1027 //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
1028 property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
1029 property "VERSION", JALVIEW_VERSION
1030 property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
1031 outputs.file(outputFile)
1037 delete buildProperties
1042 task cleanBuildingHTML(type: Delete) {
1049 task convertBuildingMD(type: Exec) {
1050 dependsOn cleanBuildingHTML
1051 def buildingMD = "${jalviewDir}/${doc_dir}/building.md"
1052 def css = "${jalviewDir}/${doc_dir}/github.css"
1055 pandoc_exec.split(",").each {
1056 if (file(it.trim()).exists()) {
1062 def buildtoolsPandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
1063 if ((pandoc == null || ! file(pandoc).exists()) && file(buildtoolsPandoc).exists()) {
1064 pandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
1068 if (pandoc != null && file(pandoc).exists()) {
1069 commandLine pandoc, '-s', '-o', buildingHTML, '--metadata', 'pagetitle="Building Jalview from Source"', '--toc', '-H', css, buildingMD
1071 println("Cannot find pandoc. Skipping convert building.md to HTML")
1072 throw new StopExecutionException("Cannot find pandoc. Skipping convert building.md to HTML")
1076 ignoreExitValue true
1078 inputs.file(buildingMD)
1080 outputs.file(buildingHTML)
1084 task syncDocs(type: Sync) {
1085 dependsOn convertBuildingMD
1086 def syncDir = "${classesDir}/${doc_dir}"
1087 from fileTree("${jalviewDir}/${doc_dir}")
1093 task copyHelp(type: Copy) {
1094 def inputDir = helpSourceDir
1095 def outputDir = "${resourceClassesDir}/${help_dir}"
1100 filter(ReplaceTokens,
1104 'Version-Rel': JALVIEW_VERSION,
1105 'Year-Rel': getDate("yyyy")
1116 inputs.dir(inputDir)
1117 outputs.files(helpFile)
1118 outputs.dir(outputDir)
1122 task syncLib(type: Sync) {
1123 def syncDir = "${resourceClassesDir}/${libDistDir}"
1124 from fileTree("${jalviewDir}/${libDistDir}")
1129 task syncResources(type: Sync) {
1130 dependsOn createBuildProperties
1133 into "${resourceClassesDir}"
1141 dependsOn syncResources
1147 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
1150 //dependsOn compileJava ////? DELETE
1153 dependsOn cloverClasses
1155 dependsOn compileJava //?
1159 includeGroups testng_groups
1160 excludeGroups testng_excluded_groups
1162 useDefaultListeners=true
1165 maxHeapSize = "1024m"
1167 workingDir = jalviewDir
1168 //systemProperties 'clover.jar' System.properties.clover.jar
1169 sourceCompatibility = compile_source_compatibility
1170 targetCompatibility = compile_target_compatibility
1171 jvmArgs += additional_compiler_args
1175 println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
1181 task buildIndices(type: JavaExec) {
1183 classpath = sourceSets.main.compileClasspath
1184 main = "com.sun.java.help.search.Indexer"
1185 workingDir = "${classesDir}/${help_dir}"
1188 inputs.dir("${workingDir}/${argDir}")
1190 outputs.dir("${classesDir}/doc")
1191 outputs.dir("${classesDir}/help")
1192 outputs.file("${workingDir}/JavaHelpSearch/DOCS")
1193 outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
1194 outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
1195 outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
1196 outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
1197 outputs.file("${workingDir}/JavaHelpSearch/TMAP")
1201 task compileLinkCheck(type: JavaCompile) {
1203 classpath = files("${jalviewDir}/${utils_dir}")
1204 destinationDir = file("${jalviewDir}/${utils_dir}")
1205 source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
1207 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1208 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1209 outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
1210 outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
1214 task linkCheck(type: JavaExec) {
1215 dependsOn prepare, compileLinkCheck
1217 def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
1218 classpath = files("${jalviewDir}/${utils_dir}")
1219 main = "HelpLinksChecker"
1220 workingDir = jalviewDir
1221 args = [ "${classesDir}/${help_dir}", "-nointernet" ]
1223 def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
1225 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1228 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1232 inputs.dir("${classesDir}/${help_dir}")
1233 outputs.file(helpLinksCheckerOutFile)
1236 // import the pubhtmlhelp target
1237 ant.properties.basedir = "${jalviewDir}"
1238 ant.properties.helpBuildDir = "${jalviewDirAbsolutePath}/${classes_dir}/${help_dir}"
1239 ant.importBuild "${utils_dir}/publishHelp.xml"
1242 task cleanPackageDir(type: Delete) {
1244 delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
1251 dependsOn buildIndices
1252 dependsOn createBuildProperties
1255 attributes "Main-Class": main_class,
1256 "Permissions": "all-permissions",
1257 "Application-Name": "Jalview Desktop",
1258 "Codebase": application_codebase
1261 destinationDir = file("${jalviewDir}/${package_dir}")
1262 archiveName = rootProject.name+".jar"
1268 exclude "**/*.jar.*"
1270 inputs.dir(classesDir)
1271 outputs.file("${jalviewDir}/${package_dir}/${archiveName}")
1275 task copyJars(type: Copy) {
1276 from fileTree(dir: classesDir, include: "**/*.jar").files
1277 into "${jalviewDir}/${package_dir}"
1281 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
1282 task syncJars(type: Sync) {
1283 from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
1284 into "${jalviewDir}/${package_dir}"
1286 include jar.archiveName
1293 description = "Put all required libraries in dist"
1294 // order of "cleanPackageDir", "copyJars", "jar" important!
1295 jar.mustRunAfter cleanPackageDir
1296 syncJars.mustRunAfter cleanPackageDir
1297 dependsOn cleanPackageDir
1300 outputs.dir("${jalviewDir}/${package_dir}")
1305 dependsOn cleanPackageDir
1311 group = "distribution"
1315 from ("${jalviewDir}/${libDistDir}") {
1319 attributes 'Implementation-Version': JALVIEW_VERSION
1321 mainClassName = shadow_jar_main_class
1323 classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
1328 task getdownWebsite() {
1329 group = "distribution"
1330 description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
1335 def getdownWebsiteResourceFilenames = []
1336 def getdownTextString = ""
1337 def getdownResourceDir = getdownResourceDir
1338 def getdownResourceFilenames = []
1341 // clean the getdown website and files dir before creating getdown folders
1342 delete getdownWebsiteDir
1343 delete getdownFilesDir
1346 from buildProperties
1347 rename(build_properties_file, getdown_build_properties)
1350 getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
1352 // set some getdown_txt_ properties then go through all properties looking for getdown_txt_...
1353 def props = project.properties.sort { it.key }
1354 if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
1355 props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
1357 if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) {
1358 props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion)
1360 if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
1361 props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
1364 props.put("getdown_txt_title", jalview_name)
1365 props.put("getdown_txt_ui.name", install4jApplicationName)
1367 // start with appbase
1368 getdownTextString += "appbase = ${getdownAppBase}\n"
1369 props.each{ prop, val ->
1370 if (prop.startsWith("getdown_txt_") && val != null) {
1371 if (prop.startsWith("getdown_txt_multi_")) {
1372 def key = prop.substring(18)
1373 val.split(",").each{ v ->
1374 def line = "${key} = ${v}\n"
1375 getdownTextString += line
1378 // file values rationalised
1379 if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1381 if (val.indexOf('/') == 0) {
1384 } else if (val.indexOf('/') > 0) {
1385 // relative path (relative to jalviewDir)
1386 r = file( "${jalviewDir}/${val}" )
1389 val = "${getdown_resource_dir}/" + r.getName()
1390 getdownWebsiteResourceFilenames += val
1391 getdownResourceFilenames += r.getPath()
1394 if (! prop.startsWith("getdown_txt_resource")) {
1395 def line = prop.substring(12) + " = ${val}\n"
1396 getdownTextString += line
1402 getdownWebsiteResourceFilenames.each{ filename ->
1403 getdownTextString += "resource = ${filename}\n"
1405 getdownResourceFilenames.each{ filename ->
1408 into getdownResourceDir
1413 fileTree(file(package_dir)).each{ f ->
1414 if (f.isDirectory()) {
1415 def files = fileTree(dir: f, include: ["*"]).getFiles()
1417 } else if (f.exists()) {
1421 codeFiles.sort().each{f ->
1422 def name = f.getName()
1423 def line = "code = ${getdownAppDistDir}/${name}\n"
1424 getdownTextString += line
1431 // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
1433 if (JAVA_VERSION.equals("11")) {
1434 def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
1435 j11libFiles.sort().each{f ->
1436 def name = f.getName()
1437 def line = "code = ${getdown_j11lib_dir}/${name}\n"
1438 getdownTextString += line
1441 into getdownJ11libDir
1447 // 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.
1448 //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
1449 getdownTextString += "resource = ${getdown_launcher_new}\n"
1450 getdownTextString += "class = ${main_class}\n"
1452 def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
1453 getdown_txt.write(getdownTextString)
1455 def getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
1456 def launchJvl = file("${getdownWebsiteDir}/${getdownLaunchJvl}")
1457 launchJvl.write("appbase=${getdownAppBase}")
1460 from getdownLauncher
1461 rename(file(getdownLauncher).getName(), getdown_launcher_new)
1462 into getdownWebsiteDir
1466 from getdownLauncher
1467 if (file(getdownLauncher).getName() != getdown_launcher) {
1468 rename(file(getdownLauncher).getName(), getdown_launcher)
1470 into getdownWebsiteDir
1473 if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
1476 from getdownLauncher
1477 from "${getdownWebsiteDir}/${getdown_build_properties}"
1478 if (file(getdownLauncher).getName() != getdown_launcher) {
1479 rename(file(getdownLauncher).getName(), getdown_launcher)
1481 into getdownInstallDir
1485 from getdownInstallDir
1486 into getdownFilesInstallDir
1493 from getdownLauncher
1494 from "${getdownWebsiteDir}/${getdown_build_properties}"
1495 if (file(getdownLauncher).getName() != getdown_launcher) {
1496 rename(file(getdownLauncher).getName(), getdown_launcher)
1498 into getdownFilesDir
1502 from getdownResourceDir
1503 into "${getdownFilesDir}/${getdown_resource_dir}"
1508 inputs.dir("${jalviewDir}/${package_dir}")
1510 outputs.dir(getdownWebsiteDir)
1511 outputs.dir(getdownFilesDir)
1515 // a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
1516 task getdownDigestDir(type: JavaExec) {
1518 description "A task to run a getdown Digest on a dir with getdown.txt. Provide a DIGESTDIR property via -PDIGESTDIR=..."
1520 def digestDirPropertyName = "DIGESTDIR"
1522 classpath = files(getdownLauncher)
1523 def digestDir = findProperty(digestDirPropertyName)
1524 if (digestDir == null) {
1525 throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest")
1529 main = "com.threerings.getdown.tools.Digester"
1533 task getdownDigest(type: JavaExec) {
1534 group = "distribution"
1535 description = "Digest the getdown website folder"
1536 dependsOn getdownWebsite
1538 classpath = files(getdownLauncher)
1540 main = "com.threerings.getdown.tools.Digester"
1541 args getdownWebsiteDir
1542 inputs.dir(getdownWebsiteDir)
1543 outputs.file("${getdownWebsiteDir}/digest2.txt")
1548 group = "distribution"
1549 description = "Create the minimal and full getdown app folder for installers and website and create digest file"
1550 dependsOn getdownDigest
1552 if (reportRsyncCommand) {
1553 def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
1554 def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
1555 println "LIKELY RSYNC COMMAND:"
1556 println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
1557 if (RUNRSYNC == "true") {
1559 commandLine "mkdir", "-p", toDir
1562 commandLine "rsync", "-avh", "--delete", fromDir, toDir
1570 tasks.withType(JavaCompile) {
1571 options.encoding = 'UTF-8'
1577 delete getdownWebsiteDir
1578 delete getdownFilesDir
1584 if (file(install4jHomeDir).exists()) {
1586 } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
1587 install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1588 } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
1589 install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
1591 installDir(file(install4jHomeDir))
1593 mediaTypes = Arrays.asList(install4j_media_types.split(","))
1597 task copyInstall4jTemplate {
1598 def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
1599 def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
1600 inputs.file(install4jTemplateFile)
1601 inputs.file(install4jFileAssociationsFile)
1602 inputs.property("CHANNEL", { CHANNEL })
1603 outputs.file(install4jConfFile)
1606 def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
1608 // turn off code signing if no OSX_KEYPASS
1609 if (OSX_KEYPASS == "") {
1610 install4jConfigXml.'**'.codeSigning.each { codeSigning ->
1611 codeSigning.'@macEnabled' = "false"
1613 install4jConfigXml.'**'.windows.each { windows ->
1614 windows.'@runPostProcessor' = "false"
1618 // turn off checksum creation for LOCAL channel
1619 def e = install4jConfigXml.application[0]
1620 if (CHANNEL == "LOCAL") {
1621 e.'@createChecksums' = "false"
1623 e.'@createChecksums' = "true"
1626 // put file association actions where placeholder action is
1627 def install4jFileAssociationsText = install4jFileAssociationsFile.text
1628 def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
1629 install4jConfigXml.'**'.action.any { a -> // .any{} stops after the first one that returns true
1630 if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
1631 def parent = a.parent()
1633 fileAssociationActions.each { faa ->
1636 // don't need to continue in .any loop once replacements have been made
1641 // use Windows Program Group with Examples folder for RELEASE, and Program Group without Examples for everything else
1642 // NB we're deleting the /other/ one!
1643 // Also remove the examples subdir from non-release versions
1644 def customizedIdToDelete = "PROGRAM_GROUP_RELEASE"
1645 // 2.11.1.0 NOT releasing with the Examples folder in the Program Group
1646 if (false && CHANNEL=="RELEASE") { // remove 'false && ' to include Examples folder in RELEASE channel
1647 customizedIdToDelete = "PROGRAM_GROUP_NON_RELEASE"
1649 // remove the examples subdir from Full File Set
1650 def files = install4jConfigXml.files[0]
1651 def fileset = files.filesets.fileset.find { fs -> fs.'@customizedId' == "FULL_FILE_SET" }
1652 def root = files.roots.root.find { r -> r.'@fileset' == fileset.'@id' }
1653 def mountPoint = files.mountPoints.mountPoint.find { mp -> mp.'@root' == root.'@id' }
1654 def dirEntry = files.entries.dirEntry.find { de -> de.'@mountPoint' == mountPoint.'@id' && de.'@subDirectory' == "examples" }
1655 dirEntry.parent().remove(dirEntry)
1657 install4jConfigXml.'**'.action.any { a ->
1658 if (a.'@customizedId' == customizedIdToDelete) {
1659 def parent = a.parent()
1665 // remove the "Uninstall Old Jalview (optional)" symlink from DMG for non-release DS_Stores
1666 if (! (CHANNEL == "RELEASE" || CHANNEL == "TEST-RELEASE" ) ) {
1667 def symlink = install4jConfigXml.'**'.topLevelFiles.symlink.find { sl -> sl.'@name' == "Uninstall Old Jalview (optional).app" }
1668 symlink.parent().remove(symlink)
1671 // write install4j file
1672 install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
1679 delete install4jConfFile
1684 task installers(type: com.install4j.gradle.Install4jTask) {
1685 group = "distribution"
1686 description = "Create the install4j installers"
1687 dependsOn setGitVals
1689 dependsOn copyInstall4jTemplate
1691 projectFile = install4jConfFile
1693 // create an md5 for the input files to use as version for install4j conf file
1694 def digest = MessageDigest.getInstance("MD5")
1696 (file("${install4jDir}/${install4j_template}").text +
1697 file("${install4jDir}/${install4j_info_plist_file_associations}").text +
1698 file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
1699 def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
1700 if (filesMd5.length() >= 8) {
1701 filesMd5 = filesMd5.substring(0,8)
1703 def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
1704 // make install4jBuildDir relative to jalviewDir
1705 def install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
1708 'JALVIEW_NAME': jalview_name,
1709 'JALVIEW_APPLICATION_NAME': install4jApplicationName,
1710 'JALVIEW_DIR': "../..",
1711 'OSX_KEYSTORE': OSX_KEYSTORE,
1712 'JSIGN_SH': JSIGN_SH,
1713 'JRE_DIR': getdown_app_dir_java,
1714 'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
1715 'JALVIEW_VERSION': JALVIEW_VERSION,
1716 'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
1717 'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
1718 'JAVA_VERSION': JAVA_VERSION,
1719 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
1720 'VERSION': JALVIEW_VERSION,
1721 'MACOS_JAVA_VM_DIR': macosJavaVMDir,
1722 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
1723 'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
1724 'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
1725 'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
1726 'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
1727 'COPYRIGHT_MESSAGE': install4j_copyright_message,
1728 'BUNDLE_ID': install4jBundleId,
1729 'INTERNAL_ID': install4jInternalId,
1730 'WINDOWS_APPLICATION_ID': install4jWinApplicationId,
1731 'MACOS_DS_STORE': install4jDSStore,
1732 'MACOS_DMG_BG_IMAGE': install4jDMGBackgroundImage,
1733 'INSTALLER_NAME': install4jInstallerName,
1734 'INSTALL4J_UTILS_DIR': install4j_utils_dir,
1735 'GETDOWN_WEBSITE_DIR': getdown_website_dir,
1736 'GETDOWN_FILES_DIR': getdown_files_dir,
1737 'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
1738 'GETDOWN_DIST_DIR': getdownAppDistDir,
1739 'GETDOWN_ALT_DIR': getdown_app_dir_alt,
1740 'GETDOWN_INSTALL_DIR': getdown_install_dir,
1741 'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
1742 'BUILD_DIR': install4jBuildDir,
1743 'APPLICATION_CATEGORIES': install4j_application_categories,
1744 'APPLICATION_FOLDER': install4jApplicationFolder,
1745 'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder,
1746 'EXECUTABLE_NAME': install4jExecutableName,
1747 'EXTRA_SCHEME': install4jExtraScheme,
1750 //println("INSTALL4J VARIABLES:")
1751 //variables.each{k,v->println("${k}=${v}")}
1753 destination = "${jalviewDir}/${install4jBuildDir}"
1754 buildSelected = true
1756 if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
1758 disableSigning = true
1762 macKeystorePassword = OSX_KEYPASS
1766 println("Using projectFile "+projectFile)
1769 inputs.dir(getdownWebsiteDir)
1770 inputs.file(install4jConfFile)
1771 inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
1772 inputs.dir(macosJavaVMDir)
1773 inputs.dir(windowsJavaVMDir)
1774 outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
1780 eclipse().configFile(eclipse_codestyle_file)
1785 task sourceDist(type: Tar) {
1787 def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
1788 def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
1789 // cater for buildship < 3.1 [3.0.1 is max version in eclipse 2018-09]
1791 archiveFileName = outputFileName
1792 } catch (Exception e) {
1793 archiveName = outputFileName
1796 compression Compression.GZIP
1811 "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
1813 "utils/InstallAnywhere",
1828 "gradle.properties",
1839 ".settings/org.eclipse.jdt.core.jalview.prefs",
1843 exclude (EXCLUDE_FILES)
1844 include (PROCESS_FILES)
1845 filter(ReplaceTokens,
1849 'Version-Rel': JALVIEW_VERSION,
1850 'Year-Rel': getDate("yyyy")
1855 exclude (EXCLUDE_FILES)
1856 exclude (PROCESS_FILES)
1857 exclude ("appletlib")
1858 exclude ("**/*locales")
1859 exclude ("*locales/**")
1860 exclude ("utils/InstallAnywhere")
1862 exclude (getdown_files_dir)
1863 exclude (getdown_website_dir)
1865 // exluding these as not using jars as modules yet
1866 exclude ("${j11modDir}/**/*.jar")
1869 include(INCLUDE_FILES)
1871 // from (jalviewDir) {
1872 // // explicit includes for stuff that seemed to not get included
1873 // include(fileTree("test/**/*."))
1874 // exclude(EXCLUDE_FILES)
1875 // exclude(PROCESS_FILES)
1882 dependsOn pubhtmlhelp
1884 inputs.dir("${classesDir}/${help_dir}")
1885 outputs.dir("${buildDir}/distributions/${help_dir}")
1889 task j2sSetHeadlessBuild {
1896 task jalviewjsSetEclipseWorkspace {
1897 def propKey = "jalviewjs_eclipse_workspace"
1899 if (project.hasProperty(propKey)) {
1900 propVal = project.getProperty(propKey)
1901 if (propVal.startsWith("~/")) {
1902 propVal = System.getProperty("user.home") + propVal.substring(1)
1905 def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
1906 def propsFile = file(propsFileName)
1907 def eclipseWsDir = propVal
1908 def props = new Properties()
1910 def writeProps = true
1911 if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
1912 def ins = new FileInputStream(propsFileName)
1915 if (props.getProperty(propKey, null) != null) {
1916 eclipseWsDir = props.getProperty(propKey)
1921 if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
1922 def tempDir = File.createTempDir()
1923 eclipseWsDir = tempDir.getAbsolutePath()
1926 eclipseWorkspace = file(eclipseWsDir)
1929 // do not run a headless transpile when we claim to be in Eclipse
1931 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1932 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
1934 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1938 props.setProperty(propKey, eclipseWsDir)
1939 propsFile.parentFile.mkdirs()
1940 def bytes = new ByteArrayOutputStream()
1941 props.store(bytes, null)
1942 def propertiesString = bytes.toString()
1943 propsFile.text = propertiesString
1949 println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
1952 //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
1953 outputs.file(propsFileName)
1954 outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
1958 task jalviewjsEclipsePaths {
1961 def eclipseRoot = jalviewjs_eclipse_root
1962 if (eclipseRoot.startsWith("~/")) {
1963 eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
1965 if (OperatingSystem.current().isMacOsX()) {
1966 eclipseRoot += "/Eclipse.app"
1967 eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
1968 eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
1969 } else if (OperatingSystem.current().isWindows()) { // check these paths!!
1970 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1971 eclipseRoot += "/eclipse"
1973 eclipseBinary = "${eclipseRoot}/eclipse.exe"
1974 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1975 } else { // linux or unix
1976 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1977 eclipseRoot += "/eclipse"
1978 println("eclipseDir exists")
1980 eclipseBinary = "${eclipseRoot}/eclipse"
1981 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1984 eclipseVersion = "4.13" // default
1985 def assumedVersion = true
1986 if (file(eclipseProduct).exists()) {
1987 def fis = new FileInputStream(eclipseProduct)
1988 def props = new Properties()
1990 eclipseVersion = props.getProperty("version")
1992 assumedVersion = false
1995 def propKey = "eclipse_debug"
1996 eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
1999 // do not run a headless transpile when we claim to be in Eclipse
2001 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2002 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2004 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2007 if (!assumedVersion) {
2008 println("ECLIPSE VERSION=${eclipseVersion}")
2014 task printProperties {
2016 description "Output to console all System.properties"
2018 System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
2024 dependsOn eclipseProject
2025 dependsOn eclipseClasspath
2026 dependsOn eclipseJdt
2030 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
2031 task jalviewjsEclipseCopyDropins(type: Copy) {
2032 dependsOn jalviewjsEclipsePaths
2034 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
2035 inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
2036 def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
2043 // this eclipse -clean doesn't actually work
2044 task jalviewjsCleanEclipse(type: Exec) {
2045 dependsOn eclipseSetup
2046 dependsOn jalviewjsEclipsePaths
2047 dependsOn jalviewjsEclipseCopyDropins
2049 executable(eclipseBinary)
2050 args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
2056 def inputString = """exit
2059 def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
2060 standardInput = inputByteStream
2063 /* not really working yet
2064 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
2068 task jalviewjsTransferUnzipSwingJs {
2069 def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
2073 from zipTree(file_zip)
2074 into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2078 inputs.file file_zip
2079 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2083 task jalviewjsTransferUnzipLib {
2084 def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
2087 zipFiles.each { file_zip ->
2089 from zipTree(file_zip)
2090 into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2095 inputs.files zipFiles
2096 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2100 task jalviewjsTransferUnzipAllLibs {
2101 dependsOn jalviewjsTransferUnzipSwingJs
2102 dependsOn jalviewjsTransferUnzipLib
2106 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
2108 description "Create the .j2s file from the j2s.* properties"
2110 jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
2111 def siteDirProperty = "j2s.site.directory"
2112 def setSiteDir = false
2113 jalviewjsJ2sProps.each { prop, val ->
2115 if (prop == siteDirProperty) {
2116 if (!(val.startsWith('/') || val.startsWith("file://") )) {
2117 val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
2123 if (!setSiteDir) { // default site location, don't override specifically set property
2124 property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
2127 outputFile = jalviewjsJ2sSettingsFileName
2130 inputs.properties(jalviewjsJ2sProps)
2131 outputs.file(jalviewjsJ2sSettingsFileName)
2136 task jalviewjsEclipseSetup {
2137 dependsOn jalviewjsEclipseCopyDropins
2138 dependsOn jalviewjsSetEclipseWorkspace
2139 dependsOn jalviewjsCreateJ2sSettings
2143 task jalviewjsSyncAllLibs (type: Sync) {
2144 dependsOn jalviewjsTransferUnzipAllLibs
2145 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
2146 inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
2147 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2151 def outputFiles = []
2152 rename { filename ->
2153 outputFiles += "${outputDir}/${filename}"
2159 outputs.files outputFiles
2160 inputs.files inputFiles
2164 task jalviewjsSyncResources (type: Sync) {
2165 def inputFiles = fileTree(dir: resourceDir)
2166 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2170 def outputFiles = []
2171 rename { filename ->
2172 outputFiles += "${outputDir}/${filename}"
2178 outputs.files outputFiles
2179 inputs.files inputFiles
2183 task jalviewjsSyncSiteResources (type: Sync) {
2184 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
2185 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2189 def outputFiles = []
2190 rename { filename ->
2191 outputFiles += "${outputDir}/${filename}"
2197 outputs.files outputFiles
2198 inputs.files inputFiles
2202 task jalviewjsSyncBuildProperties (type: Sync) {
2203 dependsOn createBuildProperties
2204 def inputFiles = [file(buildProperties)]
2205 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2209 def outputFiles = []
2210 rename { filename ->
2211 outputFiles += "${outputDir}/${filename}"
2217 outputs.files outputFiles
2218 inputs.files inputFiles
2222 task jalviewjsProjectImport(type: Exec) {
2223 dependsOn eclipseSetup
2224 dependsOn jalviewjsEclipsePaths
2225 dependsOn jalviewjsEclipseSetup
2228 // do not run a headless import when we claim to be in Eclipse
2230 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2231 throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2233 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2237 //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
2238 def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
2239 executable(eclipseBinary)
2240 args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
2244 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2246 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2249 inputs.file("${jalviewDir}/.project")
2250 outputs.upToDateWhen {
2251 file(projdir).exists()
2256 task jalviewjsTranspile(type: Exec) {
2257 dependsOn jalviewjsEclipseSetup
2258 dependsOn jalviewjsProjectImport
2259 dependsOn jalviewjsEclipsePaths
2262 // do not run a headless transpile when we claim to be in Eclipse
2264 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2265 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2267 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2271 executable(eclipseBinary)
2272 args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
2276 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2278 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2284 stdout = new ByteArrayOutputStream()
2285 stderr = new ByteArrayOutputStream()
2287 def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
2288 def logOutFile = file(logOutFileName)
2289 logOutFile.createNewFile()
2290 logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
2291 BINARY: ${eclipseBinary}
2292 VERSION: ${eclipseVersion}
2293 WORKSPACE: ${eclipseWorkspace}
2294 DEBUG: ${eclipseDebug}
2297 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2298 // combine stdout and stderr
2299 def logErrFOS = logOutFOS
2301 if (jalviewjs_j2s_to_console.equals("true")) {
2302 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2303 new org.apache.tools.ant.util.TeeOutputStream(
2307 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2308 new org.apache.tools.ant.util.TeeOutputStream(
2313 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2316 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2323 if (stdout.toString().contains("Error processing ")) {
2324 // j2s did not complete transpile
2325 //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2326 if (jalviewjs_ignore_transpile_errors.equals("true")) {
2327 println("IGNORING TRANSPILE ERRORS")
2328 println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2330 throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2335 inputs.dir("${jalviewDir}/${sourceDir}")
2336 outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
2337 outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
2341 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
2343 def stdout = new ByteArrayOutputStream()
2344 def stderr = new ByteArrayOutputStream()
2346 def coreFile = file(jsfile)
2348 msg = "Creating core for ${name}...\nGenerating ${jsfile}"
2350 logOutFile.createNewFile()
2351 logOutFile.append(msg+"\n")
2353 def coreTop = file(prefixFile)
2354 def coreBottom = file(suffixFile)
2355 coreFile.getParentFile().mkdirs()
2356 coreFile.createNewFile()
2357 coreFile.write( coreTop.getText("UTF-8") )
2361 def t = f.getText("UTF-8")
2362 t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
2363 coreFile.append( t )
2365 msg = "...file '"+f.getPath()+"' does not exist, skipping"
2367 logOutFile.append(msg+"\n")
2370 coreFile.append( coreBottom.getText("UTF-8") )
2372 msg = "Generating ${zjsfile}"
2374 logOutFile.append(msg+"\n")
2375 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2376 def logErrFOS = logOutFOS
2379 classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
2380 main = "com.google.javascript.jscomp.CommandLineRunner"
2381 jvmArgs = [ "-Dfile.encoding=UTF-8" ]
2382 args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
2385 msg = "\nRunning '"+commandLine.join(' ')+"'\n"
2387 logOutFile.append(msg+"\n")
2389 if (logOutConsole) {
2390 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2391 new org.apache.tools.ant.util.TeeOutputStream(
2395 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2396 new org.apache.tools.ant.util.TeeOutputStream(
2401 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2404 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2411 logOutFile.append(msg+"\n")
2415 task jalviewjsBuildAllCores {
2417 description "Build the core js lib closures listed in the classlists dir"
2418 dependsOn jalviewjsTranspile
2419 dependsOn jalviewjsTransferUnzipSwingJs
2421 def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
2422 def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
2423 def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
2424 def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
2425 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
2426 def prefixFile = "${jsDir}/core/coretop2.js"
2427 def suffixFile = "${jsDir}/core/corebottom2.js"
2429 inputs.file prefixFile
2430 inputs.file suffixFile
2432 def classlistFiles = []
2433 // add the classlists found int the jalviewjs_classlists_dir
2434 fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
2436 def name = file.getName() - ".txt"
2443 // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
2444 //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
2445 classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
2447 jalviewjsCoreClasslists = []
2449 classlistFiles.each {
2452 def file = hash['file']
2453 if (! file.exists()) {
2454 //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
2455 return false // this is a "continue" in groovy .each closure
2457 def name = hash['name']
2459 name = file.getName() - ".txt"
2467 def list = fileTree(dir: j2sDir, includes: filelist)
2469 def jsfile = "${outputDir}/core${name}.js"
2470 def zjsfile = "${outputDir}/core${name}.z.js"
2472 jalviewjsCoreClasslists += [
2481 outputs.file(jsfile)
2482 outputs.file(zjsfile)
2485 // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
2486 def stevesoftClasslistName = "_stevesoft"
2487 def stevesoftClasslist = [
2488 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
2489 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
2490 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
2491 'name': stevesoftClasslistName
2493 jalviewjsCoreClasslists += stevesoftClasslist
2494 inputs.files(stevesoftClasslist['list'])
2495 outputs.file(stevesoftClasslist['jsfile'])
2496 outputs.file(stevesoftClasslist['zjsfile'])
2499 def allClasslistName = "_all"
2500 def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
2501 allJsFiles += fileTree(
2505 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2506 "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
2507 "**/org/jmol/export/JSExporter.js"
2510 allJsFiles += fileTree(
2514 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2515 "**/sun/misc/Unsafe.js",
2516 "**/swingjs/jquery/jquery-editable-select.js",
2517 "**/swingjs/jquery/j2sComboBox.js",
2518 "**/sun/misc/FloatingDecimal.js"
2521 def allClasslist = [
2522 'jsfile': "${outputDir}/core${allClasslistName}.js",
2523 'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
2525 'name': allClasslistName
2527 // not including this version of "all" core at the moment
2528 //jalviewjsCoreClasslists += allClasslist
2529 inputs.files(allClasslist['list'])
2530 outputs.file(allClasslist['jsfile'])
2531 outputs.file(allClasslist['zjsfile'])
2534 def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
2535 logOutFile.getParentFile().mkdirs()
2536 logOutFile.createNewFile()
2537 logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
2539 jalviewjsCoreClasslists.each {
2540 jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
2547 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
2550 into file(outputFile).getParentFile()
2551 rename { filename ->
2552 if (filename.equals(inputFile.getName())) {
2553 return file(outputFile).getName()
2557 filter(ReplaceTokens,
2561 'MAIN': '"'+main_class+'"',
2563 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
2564 'COREKEY': jalviewjs_core_key,
2565 'CORENAME': coreName
2572 task jalviewjsPublishCoreTemplates {
2573 dependsOn jalviewjsBuildAllCores
2574 def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
2575 def inputFile = file(inputFileName)
2576 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2578 def outputFiles = []
2579 jalviewjsCoreClasslists.each { cl ->
2580 def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
2581 cl['outputfile'] = outputFile
2582 outputFiles += outputFile
2586 jalviewjsCoreClasslists.each { cl ->
2587 jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
2590 inputs.file(inputFile)
2591 outputs.files(outputFiles)
2595 task jalviewjsSyncCore (type: Sync) {
2596 dependsOn jalviewjsBuildAllCores
2597 dependsOn jalviewjsPublishCoreTemplates
2598 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
2599 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2603 def outputFiles = []
2604 rename { filename ->
2605 outputFiles += "${outputDir}/${filename}"
2611 outputs.files outputFiles
2612 inputs.files inputFiles
2616 // this Copy version of TransferSiteJs will delete anything else in the target dir
2617 task jalviewjsCopyTransferSiteJs(type: Copy) {
2618 dependsOn jalviewjsTranspile
2619 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2620 into "${jalviewDir}/${jalviewjsSiteDir}"
2624 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
2625 task jalviewjsSyncTransferSiteJs(type: Sync) {
2626 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2628 into "${jalviewDir}/${jalviewjsSiteDir}"
2635 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
2636 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
2637 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
2638 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
2640 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
2641 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
2642 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
2643 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
2646 task jalviewjsPrepareSite {
2648 description "Prepares the website folder including unzipping files and copying resources"
2649 dependsOn jalviewjsSyncAllLibs
2650 dependsOn jalviewjsSyncResources
2651 dependsOn jalviewjsSyncSiteResources
2652 dependsOn jalviewjsSyncBuildProperties
2653 dependsOn jalviewjsSyncCore
2657 task jalviewjsBuildSite {
2659 description "Builds the whole website including transpiled code"
2660 dependsOn jalviewjsCopyTransferSiteJs
2661 dependsOn jalviewjsPrepareSite
2665 task cleanJalviewjsTransferSite {
2667 delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2668 delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2669 delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2670 delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2675 task cleanJalviewjsSite {
2676 dependsOn cleanJalviewjsTransferSite
2678 delete "${jalviewDir}/${jalviewjsSiteDir}"
2683 task jalviewjsSiteTar(type: Tar) {
2685 description "Creates a tar.gz file for the website"
2686 dependsOn jalviewjsBuildSite
2687 def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
2689 archiveFileName = outputFilename
2690 } catch (Exception e) {
2691 archiveName = outputFilename
2694 compression Compression.GZIP
2696 from "${jalviewDir}/${jalviewjsSiteDir}"
2697 into jalviewjs_site_dir // this is inside the tar file
2699 inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
2703 task jalviewjsServer {
2705 def filename = "jalviewjsTest.html"
2706 description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
2707 def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
2710 SimpleHttpFileServerFactory factory = new SimpleHttpFileServerFactory()
2711 def port = Integer.valueOf(jalviewjs_server_port)
2716 while(port < start+1000 && !running) {
2718 def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
2719 jalviewjsServer = factory.start(doc_root, port)
2721 url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
2722 println("SERVER STARTED with document root ${doc_root}.")
2723 println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).")
2724 println("For debug: "+url+"?j2sdebug")
2725 println("For verbose: "+url+"?j2sverbose")
2726 } catch (Exception e) {
2731 <p><a href="${url}">JalviewJS Test. <${url}></a></p>
2732 <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
2733 <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
2735 jalviewjsCoreClasslists.each { cl ->
2736 def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
2738 <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></a></p>
2740 println("For core ${cl.name}: "+urlcore)
2743 file(htmlFile).text = htmlText
2746 outputs.file(htmlFile)
2747 outputs.upToDateWhen({false})
2751 task cleanJalviewjsAll {
2753 description "Delete all configuration and build artifacts to do with JalviewJS build"
2754 dependsOn cleanJalviewjsSite
2755 dependsOn jalviewjsEclipsePaths
2758 delete "${jalviewDir}/${jalviewjsBuildDir}"
2759 delete "${jalviewDir}/${eclipse_bin_dir}"
2760 if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
2761 delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
2763 delete "${jalviewDir}/${jalviewjs_j2s_settings}"
2766 outputs.upToDateWhen( { false } )
2770 task jalviewjsIDE_checkJ2sPlugin {
2771 group "00 JalviewJS in Eclipse"
2772 description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
2775 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
2776 def j2sPluginFile = file(j2sPlugin)
2777 def eclipseHome = System.properties["eclipse.home.location"]
2778 if (eclipseHome == null || ! IN_ECLIPSE) {
2779 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
2781 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
2782 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
2783 if (!eclipseJ2sPluginFile.exists()) {
2784 def msg = "Eclipse J2S Plugin is not installed (could not find '${eclipseJ2sPlugin}')\nTry running task jalviewjsIDE_copyJ2sPlugin"
2785 System.err.println(msg)
2786 throw new StopExecutionException(msg)
2789 def digest = MessageDigest.getInstance("MD5")
2791 digest.update(j2sPluginFile.text.bytes)
2792 def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
2794 digest.update(eclipseJ2sPluginFile.text.bytes)
2795 def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
2797 if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
2798 def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
2799 System.err.println(msg)
2800 throw new StopExecutionException(msg)
2802 def msg = "Eclipse J2S Plugin is the same as '${j2sPlugin}' (this is good)"
2808 task jalviewjsIDE_copyJ2sPlugin {
2809 group "00 JalviewJS in Eclipse"
2810 description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
2813 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
2814 def j2sPluginFile = file(j2sPlugin)
2815 def eclipseHome = System.properties["eclipse.home.location"]
2816 if (eclipseHome == null || ! IN_ECLIPSE) {
2817 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
2819 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
2820 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
2821 def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
2822 System.err.println(msg)
2825 eclipseJ2sPluginFile.getParentFile().mkdirs()
2826 into eclipseJ2sPluginFile.getParent()
2832 task jalviewjsIDE_j2sFile {
2833 group "00 JalviewJS in Eclipse"
2834 description "Creates the .j2s file"
2835 dependsOn jalviewjsCreateJ2sSettings
2839 task jalviewjsIDE_SyncCore {
2840 group "00 JalviewJS in Eclipse"
2841 description "Build the core js lib closures listed in the classlists dir and publish core html from template"
2842 dependsOn jalviewjsSyncCore
2846 task jalviewjsIDE_SyncSiteAll {
2847 dependsOn jalviewjsSyncAllLibs
2848 dependsOn jalviewjsSyncResources
2849 dependsOn jalviewjsSyncSiteResources
2850 dependsOn jalviewjsSyncBuildProperties
2854 cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
2857 task jalviewjsIDE_PrepareSite {
2858 group "00 JalviewJS in Eclipse"
2859 description "Sync libs and resources to site dir, but not closure cores"
2861 dependsOn jalviewjsIDE_SyncSiteAll
2862 //dependsOn cleanJalviewjsTransferSite // not sure why this clean is here -- will slow down a re-run of this task
2866 task jalviewjsIDE_AssembleSite {
2867 group "00 JalviewJS in Eclipse"
2868 description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
2869 dependsOn jalviewjsPrepareSite
2873 task jalviewjsIDE_SiteClean {
2874 group "00 JalviewJS in Eclipse"
2875 description "Deletes the Eclipse transpiled site"
2876 dependsOn cleanJalviewjsSite
2880 task jalviewjsIDE_Server {
2881 group "00 JalviewJS in Eclipse"
2882 description "Starts a webserver on localhost to test the website"
2883 dependsOn jalviewjsServer
2887 // buildship runs this at import or gradle refresh
2888 task eclipseSynchronizationTask {
2889 //dependsOn eclipseSetup
2890 dependsOn createBuildProperties
2892 dependsOn jalviewjsIDE_j2sFile
2893 dependsOn jalviewjsIDE_checkJ2sPlugin
2894 dependsOn jalviewjsIDE_PrepareSite
2899 // buildship runs this at build time or project refresh
2900 task eclipseAutoBuildTask {
2901 //dependsOn jalviewjsIDE_checkJ2sPlugin
2902 //dependsOn jalviewjsIDE_PrepareSite
2908 description "Build the site"
2909 dependsOn jalviewjsBuildSite