1 /* Convention for properties. Read from this file, 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")
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
740 task cloverInstrJava(type: JavaExec) {
741 group = "Verification"
742 description = "Create clover instrumented source java files"
744 dependsOn cleanClover
746 inputs.files(sourceSets.main.allJava)
747 outputs.dir(cloverInstrDir)
749 //classpath = fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"])
750 classpath = sourceSets.clover.compileClasspath
751 main = "com.atlassian.clover.CloverInstr"
759 cloverInstrDir.getPath(),
761 def srcFiles = sourceSets.main.allJava.files
764 { file -> file.absolutePath }
767 args argsList.toArray()
770 delete cloverInstrDir
771 println("Clover: About to instrument "+srcFiles.size() +" files")
776 task cloverInstrTests(type: JavaExec) {
777 group = "Verification"
778 description = "Create clover instrumented source test files"
780 dependsOn cleanClover
782 inputs.files(testDir)
783 outputs.dir(cloverTestInstrDir)
785 classpath = sourceSets.clover.compileClasspath
786 main = "com.atlassian.clover.CloverInstr"
796 cloverTestInstrDir.getPath(),
798 args argsList.toArray()
801 delete cloverTestInstrDir
802 println("Clover: About to instrument test files")
808 group = "Verification"
809 description = "Create clover instrumented all source files"
811 dependsOn cloverInstrJava
812 dependsOn cloverInstrTests
816 cloverClasses.dependsOn cloverInstr
819 task cloverConsoleReport(type: JavaExec) {
820 group = "Verification"
821 description = "Creates clover console report"
824 file(cloverDb).exists()
827 inputs.dir cloverClassesDir
829 classpath = sourceSets.clover.runtimeClasspath
830 main = "com.atlassian.clover.reporters.console.ConsoleReporter"
832 if (cloverreport_mem.length() > 0) {
833 maxHeapSize = cloverreport_mem
835 if (cloverreport_jvmargs.length() > 0) {
836 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
846 args argsList.toArray()
850 task cloverHtmlReport(type: JavaExec) {
851 group = "Verification"
852 description = "Creates clover HTML report"
855 file(cloverDb).exists()
858 def cloverHtmlDir = "${cloverReportDir}/clover"
859 inputs.dir cloverClassesDir
860 outputs.dir cloverHtmlDir
862 classpath = sourceSets.clover.runtimeClasspath
863 main = "com.atlassian.clover.reporters.html.HtmlReporter"
865 if (cloverreport_mem.length() > 0) {
866 maxHeapSize = cloverreport_mem
868 if (cloverreport_jvmargs.length() > 0) {
869 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
880 if (cloverreport_html_options.length() > 0) {
881 argsList += cloverreport_html_options.split(" ")
884 args argsList.toArray()
888 task cloverXmlReport(type: JavaExec) {
889 group = "Verification"
890 description = "Creates clover XML report"
893 file(cloverDb).exists()
896 def cloverXmlFile = "${cloverReportDir}/clover.xml"
897 inputs.dir cloverClassesDir
898 outputs.file cloverXmlFile
900 classpath = sourceSets.clover.runtimeClasspath
901 main = "com.atlassian.clover.reporters.xml.XMLReporter"
903 if (cloverreport_mem.length() > 0) {
904 maxHeapSize = cloverreport_mem
906 if (cloverreport_jvmargs.length() > 0) {
907 jvmArgs Arrays.asList(cloverreport_jvmargs.split(" "))
918 if (cloverreport_xml_options.length() > 0) {
919 argsList += cloverreport_xml_options.split(" ")
922 args argsList.toArray()
927 group = "Verification"
928 description = "Creates clover reports"
930 dependsOn cloverXmlReport
931 dependsOn cloverHtmlReport
938 sourceCompatibility = compile_source_compatibility
939 targetCompatibility = compile_target_compatibility
940 options.compilerArgs += additional_compiler_args
941 print ("Setting target compatibility to "+targetCompatibility+"\n")
943 //classpath += configurations.cloverRuntime
949 // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ?
950 sourceCompatibility = compile_source_compatibility
951 targetCompatibility = compile_target_compatibility
952 options.compilerArgs = additional_compiler_args
953 options.encoding = "UTF-8"
955 print ("Setting target compatibility to "+compile_target_compatibility+"\n")
962 sourceCompatibility = compile_source_compatibility
963 targetCompatibility = compile_target_compatibility
964 options.compilerArgs = additional_compiler_args
966 print ("Setting target compatibility to "+targetCompatibility+"\n")
973 delete sourceSets.main.java.outputDir
979 dependsOn cleanClover
981 delete sourceSets.test.java.outputDir
986 // format is a string like date.format("dd MMMM yyyy")
987 def getDate(format) {
988 def date = new Date()
989 return date.format(format)
994 def hashStdOut = new ByteArrayOutputStream()
996 commandLine "git", "rev-parse", "--short", "HEAD"
997 standardOutput = hashStdOut
1001 def branchStdOut = new ByteArrayOutputStream()
1003 commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
1004 standardOutput = branchStdOut
1005 ignoreExitValue true
1008 gitHash = hashStdOut.toString().trim()
1009 gitBranch = branchStdOut.toString().trim()
1011 outputs.upToDateWhen { false }
1015 task createBuildProperties(type: WriteProperties) {
1017 description = "Create the ${buildProperties} file"
1019 dependsOn setGitVals
1020 inputs.dir(sourceDir)
1021 inputs.dir(resourceDir)
1022 file(buildProperties).getParentFile().mkdirs()
1023 outputFile (buildProperties)
1024 // taking time specific comment out to allow better incremental builds
1025 comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss")
1026 //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd")
1027 property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy")
1028 property "VERSION", JALVIEW_VERSION
1029 property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]"
1030 outputs.file(outputFile)
1036 delete buildProperties
1041 task cleanBuildingHTML(type: Delete) {
1048 task convertBuildingMD(type: Exec) {
1049 dependsOn cleanBuildingHTML
1050 def buildingMD = "${jalviewDir}/${doc_dir}/building.md"
1051 def css = "${jalviewDir}/${doc_dir}/github.css"
1054 pandoc_exec.split(",").each {
1055 if (file(it.trim()).exists()) {
1061 def buildtoolsPandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
1062 if ((pandoc == null || ! file(pandoc).exists()) && file(buildtoolsPandoc).exists()) {
1063 pandoc = System.getProperty("user.home")+"/buildtools/pandoc/bin/pandoc"
1067 if (pandoc != null && file(pandoc).exists()) {
1068 commandLine pandoc, '-s', '-o', buildingHTML, '--metadata', 'pagetitle="Building Jalview from Source"', '--toc', '-H', css, buildingMD
1070 println("Cannot find pandoc. Skipping convert building.md to HTML")
1071 throw new StopExecutionException("Cannot find pandoc. Skipping convert building.md to HTML")
1075 ignoreExitValue true
1077 inputs.file(buildingMD)
1079 outputs.file(buildingHTML)
1083 task syncDocs(type: Sync) {
1084 dependsOn convertBuildingMD
1085 def syncDir = "${classesDir}/${doc_dir}"
1086 from fileTree("${jalviewDir}/${doc_dir}")
1092 task copyHelp(type: Copy) {
1093 def inputDir = helpSourceDir
1094 def outputDir = "${resourceClassesDir}/${help_dir}"
1099 filter(ReplaceTokens,
1103 'Version-Rel': JALVIEW_VERSION,
1104 'Year-Rel': getDate("yyyy")
1115 inputs.dir(inputDir)
1116 outputs.files(helpFile)
1117 outputs.dir(outputDir)
1121 task syncLib(type: Sync) {
1122 def syncDir = "${resourceClassesDir}/${libDistDir}"
1123 from fileTree("${jalviewDir}/${libDistDir}")
1128 task syncResources(type: Sync) {
1129 dependsOn createBuildProperties
1132 into "${resourceClassesDir}"
1140 dependsOn syncResources
1146 //testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
1149 //dependsOn compileJava ////? DELETE
1152 dependsOn cloverClasses
1154 dependsOn compileJava //?
1158 includeGroups testng_groups
1159 excludeGroups testng_excluded_groups
1161 useDefaultListeners=true
1164 maxHeapSize = "1024m"
1166 workingDir = jalviewDir
1167 //systemProperties 'clover.jar' System.properties.clover.jar
1168 sourceCompatibility = compile_source_compatibility
1169 targetCompatibility = compile_target_compatibility
1170 jvmArgs += additional_compiler_args
1174 println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
1180 task buildIndices(type: JavaExec) {
1182 classpath = sourceSets.main.compileClasspath
1183 main = "com.sun.java.help.search.Indexer"
1184 workingDir = "${classesDir}/${help_dir}"
1187 inputs.dir("${workingDir}/${argDir}")
1189 outputs.dir("${classesDir}/doc")
1190 outputs.dir("${classesDir}/help")
1191 outputs.file("${workingDir}/JavaHelpSearch/DOCS")
1192 outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
1193 outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
1194 outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
1195 outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
1196 outputs.file("${workingDir}/JavaHelpSearch/TMAP")
1200 task compileLinkCheck(type: JavaCompile) {
1202 classpath = files("${jalviewDir}/${utils_dir}")
1203 destinationDir = file("${jalviewDir}/${utils_dir}")
1204 source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
1206 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1207 inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
1208 outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
1209 outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
1213 task linkCheck(type: JavaExec) {
1214 dependsOn prepare, compileLinkCheck
1216 def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
1217 classpath = files("${jalviewDir}/${utils_dir}")
1218 main = "HelpLinksChecker"
1219 workingDir = jalviewDir
1220 args = [ "${classesDir}/${help_dir}", "-nointernet" ]
1222 def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
1224 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
1227 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
1231 inputs.dir("${classesDir}/${help_dir}")
1232 outputs.file(helpLinksCheckerOutFile)
1235 // import the pubhtmlhelp target
1236 ant.properties.basedir = "${jalviewDir}"
1237 ant.properties.helpBuildDir = "${jalviewDirAbsolutePath}/${classes_dir}/${help_dir}"
1238 ant.importBuild "${utils_dir}/publishHelp.xml"
1241 task cleanPackageDir(type: Delete) {
1243 delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
1250 dependsOn buildIndices
1251 dependsOn createBuildProperties
1254 attributes "Main-Class": main_class,
1255 "Permissions": "all-permissions",
1256 "Application-Name": "Jalview Desktop",
1257 "Codebase": application_codebase
1260 destinationDir = file("${jalviewDir}/${package_dir}")
1261 archiveName = rootProject.name+".jar"
1267 exclude "**/*.jar.*"
1269 inputs.dir(classesDir)
1270 outputs.file("${jalviewDir}/${package_dir}/${archiveName}")
1274 task copyJars(type: Copy) {
1275 from fileTree(dir: classesDir, include: "**/*.jar").files
1276 into "${jalviewDir}/${package_dir}"
1280 // doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well
1281 task syncJars(type: Sync) {
1282 from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files
1283 into "${jalviewDir}/${package_dir}"
1285 include jar.archiveName
1292 description = "Put all required libraries in dist"
1293 // order of "cleanPackageDir", "copyJars", "jar" important!
1294 jar.mustRunAfter cleanPackageDir
1295 syncJars.mustRunAfter cleanPackageDir
1296 dependsOn cleanPackageDir
1299 outputs.dir("${jalviewDir}/${package_dir}")
1304 dependsOn cleanPackageDir
1310 group = "distribution"
1314 from ("${jalviewDir}/${libDistDir}") {
1318 attributes 'Implementation-Version': JALVIEW_VERSION
1320 mainClassName = shadow_jar_main_class
1322 classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION
1327 task getdownWebsite() {
1328 group = "distribution"
1329 description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer"
1334 def getdownWebsiteResourceFilenames = []
1335 def getdownTextString = ""
1336 def getdownResourceDir = getdownResourceDir
1337 def getdownResourceFilenames = []
1340 // clean the getdown website and files dir before creating getdown folders
1341 delete getdownWebsiteDir
1342 delete getdownFilesDir
1345 from buildProperties
1346 rename(build_properties_file, getdown_build_properties)
1349 getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}"
1351 // set some getdown_txt_ properties then go through all properties looking for getdown_txt_...
1352 def props = project.properties.sort { it.key }
1353 if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) {
1354 props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion)
1356 if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) {
1357 props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion)
1359 if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) {
1360 props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation)
1363 props.put("getdown_txt_title", jalview_name)
1364 props.put("getdown_txt_ui.name", install4jApplicationName)
1366 // start with appbase
1367 getdownTextString += "appbase = ${getdownAppBase}\n"
1368 props.each{ prop, val ->
1369 if (prop.startsWith("getdown_txt_") && val != null) {
1370 if (prop.startsWith("getdown_txt_multi_")) {
1371 def key = prop.substring(18)
1372 val.split(",").each{ v ->
1373 def line = "${key} = ${v}\n"
1374 getdownTextString += line
1377 // file values rationalised
1378 if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) {
1380 if (val.indexOf('/') == 0) {
1383 } else if (val.indexOf('/') > 0) {
1384 // relative path (relative to jalviewDir)
1385 r = file( "${jalviewDir}/${val}" )
1388 val = "${getdown_resource_dir}/" + r.getName()
1389 getdownWebsiteResourceFilenames += val
1390 getdownResourceFilenames += r.getPath()
1393 if (! prop.startsWith("getdown_txt_resource")) {
1394 def line = prop.substring(12) + " = ${val}\n"
1395 getdownTextString += line
1401 getdownWebsiteResourceFilenames.each{ filename ->
1402 getdownTextString += "resource = ${filename}\n"
1404 getdownResourceFilenames.each{ filename ->
1407 into getdownResourceDir
1412 fileTree(file(package_dir)).each{ f ->
1413 if (f.isDirectory()) {
1414 def files = fileTree(dir: f, include: ["*"]).getFiles()
1416 } else if (f.exists()) {
1420 codeFiles.sort().each{f ->
1421 def name = f.getName()
1422 def line = "code = ${getdownAppDistDir}/${name}\n"
1423 getdownTextString += line
1430 // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist
1432 if (JAVA_VERSION.equals("11")) {
1433 def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles()
1434 j11libFiles.sort().each{f ->
1435 def name = f.getName()
1436 def line = "code = ${getdown_j11lib_dir}/${name}\n"
1437 getdownTextString += line
1440 into getdownJ11libDir
1446 // 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.
1447 //getdownTextString += "class = " + file(getdownLauncher).getName() + "\n"
1448 getdownTextString += "resource = ${getdown_launcher_new}\n"
1449 getdownTextString += "class = ${main_class}\n"
1451 def getdown_txt = file("${getdownWebsiteDir}/getdown.txt")
1452 getdown_txt.write(getdownTextString)
1454 def getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl"
1455 def launchJvl = file("${getdownWebsiteDir}/${getdownLaunchJvl}")
1456 launchJvl.write("appbase=${getdownAppBase}")
1459 from getdownLauncher
1460 rename(file(getdownLauncher).getName(), getdown_launcher_new)
1461 into getdownWebsiteDir
1465 from getdownLauncher
1466 if (file(getdownLauncher).getName() != getdown_launcher) {
1467 rename(file(getdownLauncher).getName(), getdown_launcher)
1469 into getdownWebsiteDir
1472 if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) {
1475 from getdownLauncher
1476 from "${getdownWebsiteDir}/${getdown_build_properties}"
1477 if (file(getdownLauncher).getName() != getdown_launcher) {
1478 rename(file(getdownLauncher).getName(), getdown_launcher)
1480 into getdownInstallDir
1484 from getdownInstallDir
1485 into getdownFilesInstallDir
1492 from getdownLauncher
1493 from "${getdownWebsiteDir}/${getdown_build_properties}"
1494 if (file(getdownLauncher).getName() != getdown_launcher) {
1495 rename(file(getdownLauncher).getName(), getdown_launcher)
1497 into getdownFilesDir
1501 from getdownResourceDir
1502 into "${getdownFilesDir}/${getdown_resource_dir}"
1507 inputs.dir("${jalviewDir}/${package_dir}")
1509 outputs.dir(getdownWebsiteDir)
1510 outputs.dir(getdownFilesDir)
1514 // a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir
1515 task getdownDigestDir(type: JavaExec) {
1517 description "A task to run a getdown Digest on a dir with getdown.txt. Provide a DIGESTDIR property via -PDIGESTDIR=..."
1519 def digestDirPropertyName = "DIGESTDIR"
1521 classpath = files(getdownLauncher)
1522 def digestDir = findProperty(digestDirPropertyName)
1523 if (digestDir == null) {
1524 throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest")
1528 main = "com.threerings.getdown.tools.Digester"
1532 task getdownDigest(type: JavaExec) {
1533 group = "distribution"
1534 description = "Digest the getdown website folder"
1535 dependsOn getdownWebsite
1537 classpath = files(getdownLauncher)
1539 main = "com.threerings.getdown.tools.Digester"
1540 args getdownWebsiteDir
1541 inputs.dir(getdownWebsiteDir)
1542 outputs.file("${getdownWebsiteDir}/digest2.txt")
1547 group = "distribution"
1548 description = "Create the minimal and full getdown app folder for installers and website and create digest file"
1549 dependsOn getdownDigest
1551 if (reportRsyncCommand) {
1552 def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/')
1553 def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/')
1554 println "LIKELY RSYNC COMMAND:"
1555 println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'"
1556 if (RUNRSYNC == "true") {
1558 commandLine "mkdir", "-p", toDir
1561 commandLine "rsync", "-avh", "--delete", fromDir, toDir
1569 tasks.withType(JavaCompile) {
1570 options.encoding = 'UTF-8'
1576 delete getdownWebsiteDir
1577 delete getdownFilesDir
1583 if (file(install4jHomeDir).exists()) {
1585 } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) {
1586 install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j"
1587 } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) {
1588 install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app"
1590 installDir(file(install4jHomeDir))
1592 mediaTypes = Arrays.asList(install4j_media_types.split(","))
1596 task copyInstall4jTemplate {
1597 def install4jTemplateFile = file("${install4jDir}/${install4j_template}")
1598 def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}")
1599 inputs.file(install4jTemplateFile)
1600 inputs.file(install4jFileAssociationsFile)
1601 inputs.property("CHANNEL", { CHANNEL })
1602 outputs.file(install4jConfFile)
1605 def install4jConfigXml = new XmlParser().parse(install4jTemplateFile)
1607 // turn off code signing if no OSX_KEYPASS
1608 if (OSX_KEYPASS == "") {
1609 install4jConfigXml.'**'.codeSigning.each { codeSigning ->
1610 codeSigning.'@macEnabled' = "false"
1612 install4jConfigXml.'**'.windows.each { windows ->
1613 windows.'@runPostProcessor' = "false"
1617 // turn off checksum creation for LOCAL channel
1618 def e = install4jConfigXml.application[0]
1619 if (CHANNEL == "LOCAL") {
1620 e.'@createChecksums' = "false"
1622 e.'@createChecksums' = "true"
1625 // put file association actions where placeholder action is
1626 def install4jFileAssociationsText = install4jFileAssociationsFile.text
1627 def fileAssociationActions = new XmlParser().parseText("<actions>${install4jFileAssociationsText}</actions>")
1628 install4jConfigXml.'**'.action.any { a -> // .any{} stops after the first one that returns true
1629 if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') {
1630 def parent = a.parent()
1632 fileAssociationActions.each { faa ->
1635 // don't need to continue in .any loop once replacements have been made
1640 // use Windows Program Group with Examples folder for RELEASE, and Program Group without Examples for everything else
1641 // NB we're deleting the /other/ one!
1642 // Also remove the examples subdir from non-release versions
1643 def customizedIdToDelete = "PROGRAM_GROUP_RELEASE"
1644 // 2.11.1.0 NOT releasing with the Examples folder in the Program Group
1645 if (false && CHANNEL=="RELEASE") { // remove 'false && ' to include Examples folder in RELEASE channel
1646 customizedIdToDelete = "PROGRAM_GROUP_NON_RELEASE"
1648 // remove the examples subdir from Full File Set
1649 def files = install4jConfigXml.files[0]
1650 def fileset = files.filesets.fileset.find { fs -> fs.'@customizedId' == "FULL_FILE_SET" }
1651 def root = files.roots.root.find { r -> r.'@fileset' == fileset.'@id' }
1652 def mountPoint = files.mountPoints.mountPoint.find { mp -> mp.'@root' == root.'@id' }
1653 def dirEntry = files.entries.dirEntry.find { de -> de.'@mountPoint' == mountPoint.'@id' && de.'@subDirectory' == "examples" }
1654 dirEntry.parent().remove(dirEntry)
1656 install4jConfigXml.'**'.action.any { a ->
1657 if (a.'@customizedId' == customizedIdToDelete) {
1658 def parent = a.parent()
1664 // remove the "Uninstall Old Jalview (optional)" symlink from DMG for non-release DS_Stores
1665 if (! (CHANNEL == "RELEASE" || CHANNEL == "TEST-RELEASE" ) ) {
1666 def symlink = install4jConfigXml.'**'.topLevelFiles.symlink.find { sl -> sl.'@name' == "Uninstall Old Jalview (optional).app" }
1667 symlink.parent().remove(symlink)
1670 // write install4j file
1671 install4jConfFile.text = XmlUtil.serialize(install4jConfigXml)
1678 delete install4jConfFile
1683 task installers(type: com.install4j.gradle.Install4jTask) {
1684 group = "distribution"
1685 description = "Create the install4j installers"
1686 dependsOn setGitVals
1688 dependsOn copyInstall4jTemplate
1690 projectFile = install4jConfFile
1692 // create an md5 for the input files to use as version for install4j conf file
1693 def digest = MessageDigest.getInstance("MD5")
1695 (file("${install4jDir}/${install4j_template}").text +
1696 file("${install4jDir}/${install4j_info_plist_file_associations}").text +
1697 file("${install4jDir}/${install4j_installer_file_associations}").text).bytes)
1698 def filesMd5 = new BigInteger(1, digest.digest()).toString(16)
1699 if (filesMd5.length() >= 8) {
1700 filesMd5 = filesMd5.substring(0,8)
1702 def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}"
1703 // make install4jBuildDir relative to jalviewDir
1704 def install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}"
1707 'JALVIEW_NAME': jalview_name,
1708 'JALVIEW_APPLICATION_NAME': install4jApplicationName,
1709 'JALVIEW_DIR': "../..",
1710 'OSX_KEYSTORE': OSX_KEYSTORE,
1711 'JSIGN_SH': JSIGN_SH,
1712 'JRE_DIR': getdown_app_dir_java,
1713 'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion,
1714 'JALVIEW_VERSION': JALVIEW_VERSION,
1715 'JAVA_MIN_VERSION': JAVA_MIN_VERSION,
1716 'JAVA_MAX_VERSION': JAVA_MAX_VERSION,
1717 'JAVA_VERSION': JAVA_VERSION,
1718 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION,
1719 'VERSION': JALVIEW_VERSION,
1720 'MACOS_JAVA_VM_DIR': macosJavaVMDir,
1721 'WINDOWS_JAVA_VM_DIR': windowsJavaVMDir,
1722 'LINUX_JAVA_VM_DIR': linuxJavaVMDir,
1723 'MACOS_JAVA_VM_TGZ': macosJavaVMTgz,
1724 'WINDOWS_JAVA_VM_TGZ': windowsJavaVMTgz,
1725 'LINUX_JAVA_VM_TGZ': linuxJavaVMTgz,
1726 'COPYRIGHT_MESSAGE': install4j_copyright_message,
1727 'BUNDLE_ID': install4jBundleId,
1728 'INTERNAL_ID': install4jInternalId,
1729 'WINDOWS_APPLICATION_ID': install4jWinApplicationId,
1730 'MACOS_DS_STORE': install4jDSStore,
1731 'MACOS_DMG_BG_IMAGE': install4jDMGBackgroundImage,
1732 'INSTALLER_NAME': install4jInstallerName,
1733 'INSTALL4J_UTILS_DIR': install4j_utils_dir,
1734 'GETDOWN_WEBSITE_DIR': getdown_website_dir,
1735 'GETDOWN_FILES_DIR': getdown_files_dir,
1736 'GETDOWN_RESOURCE_DIR': getdown_resource_dir,
1737 'GETDOWN_DIST_DIR': getdownAppDistDir,
1738 'GETDOWN_ALT_DIR': getdown_app_dir_alt,
1739 'GETDOWN_INSTALL_DIR': getdown_install_dir,
1740 'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations,
1741 'BUILD_DIR': install4jBuildDir,
1742 'APPLICATION_CATEGORIES': install4j_application_categories,
1743 'APPLICATION_FOLDER': install4jApplicationFolder,
1744 'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder,
1745 'EXECUTABLE_NAME': install4jExecutableName,
1746 'EXTRA_SCHEME': install4jExtraScheme,
1749 //println("INSTALL4J VARIABLES:")
1750 //variables.each{k,v->println("${k}=${v}")}
1752 destination = "${jalviewDir}/${install4jBuildDir}"
1753 buildSelected = true
1755 if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) {
1757 disableSigning = true
1761 macKeystorePassword = OSX_KEYPASS
1765 println("Using projectFile "+projectFile)
1768 inputs.dir(getdownWebsiteDir)
1769 inputs.file(install4jConfFile)
1770 inputs.file("${install4jDir}/${install4j_info_plist_file_associations}")
1771 inputs.dir(macosJavaVMDir)
1772 inputs.dir(windowsJavaVMDir)
1773 outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}")
1779 eclipse().configFile(eclipse_codestyle_file)
1784 task sourceDist(type: Tar) {
1786 def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_")
1787 def outputFileName = "${project.name}_${VERSION_UNDERSCORES}.tar.gz"
1788 // cater for buildship < 3.1 [3.0.1 is max version in eclipse 2018-09]
1790 archiveFileName = outputFileName
1791 } catch (Exception e) {
1792 archiveName = outputFileName
1795 compression Compression.GZIP
1810 "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales",
1812 "utils/InstallAnywhere",
1827 "gradle.properties",
1838 ".settings/org.eclipse.jdt.core.jalview.prefs",
1842 exclude (EXCLUDE_FILES)
1843 include (PROCESS_FILES)
1844 filter(ReplaceTokens,
1848 'Version-Rel': JALVIEW_VERSION,
1849 'Year-Rel': getDate("yyyy")
1854 exclude (EXCLUDE_FILES)
1855 exclude (PROCESS_FILES)
1856 exclude ("appletlib")
1857 exclude ("**/*locales")
1858 exclude ("*locales/**")
1859 exclude ("utils/InstallAnywhere")
1861 exclude (getdown_files_dir)
1862 exclude (getdown_website_dir)
1864 // exluding these as not using jars as modules yet
1865 exclude ("${j11modDir}/**/*.jar")
1868 include(INCLUDE_FILES)
1870 // from (jalviewDir) {
1871 // // explicit includes for stuff that seemed to not get included
1872 // include(fileTree("test/**/*."))
1873 // exclude(EXCLUDE_FILES)
1874 // exclude(PROCESS_FILES)
1881 dependsOn pubhtmlhelp
1883 inputs.dir("${classesDir}/${help_dir}")
1884 outputs.dir("${buildDir}/distributions/${help_dir}")
1888 task j2sSetHeadlessBuild {
1895 task jalviewjsSetEclipseWorkspace {
1896 def propKey = "jalviewjs_eclipse_workspace"
1898 if (project.hasProperty(propKey)) {
1899 propVal = project.getProperty(propKey)
1900 if (propVal.startsWith("~/")) {
1901 propVal = System.getProperty("user.home") + propVal.substring(1)
1904 def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}"
1905 def propsFile = file(propsFileName)
1906 def eclipseWsDir = propVal
1907 def props = new Properties()
1909 def writeProps = true
1910 if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) {
1911 def ins = new FileInputStream(propsFileName)
1914 if (props.getProperty(propKey, null) != null) {
1915 eclipseWsDir = props.getProperty(propKey)
1920 if (eclipseWsDir == null || !file(eclipseWsDir).exists()) {
1921 def tempDir = File.createTempDir()
1922 eclipseWsDir = tempDir.getAbsolutePath()
1925 eclipseWorkspace = file(eclipseWsDir)
1928 // do not run a headless transpile when we claim to be in Eclipse
1930 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1931 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
1933 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
1937 props.setProperty(propKey, eclipseWsDir)
1938 propsFile.parentFile.mkdirs()
1939 def bytes = new ByteArrayOutputStream()
1940 props.store(bytes, null)
1941 def propertiesString = bytes.toString()
1942 propsFile.text = propertiesString
1948 println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath())
1951 //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date
1952 outputs.file(propsFileName)
1953 outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() }
1957 task jalviewjsEclipsePaths {
1960 def eclipseRoot = jalviewjs_eclipse_root
1961 if (eclipseRoot.startsWith("~/")) {
1962 eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1)
1964 if (OperatingSystem.current().isMacOsX()) {
1965 eclipseRoot += "/Eclipse.app"
1966 eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse"
1967 eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct"
1968 } else if (OperatingSystem.current().isWindows()) { // check these paths!!
1969 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1970 eclipseRoot += "/eclipse"
1972 eclipseBinary = "${eclipseRoot}/eclipse.exe"
1973 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1974 } else { // linux or unix
1975 if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) {
1976 eclipseRoot += "/eclipse"
1977 println("eclipseDir exists")
1979 eclipseBinary = "${eclipseRoot}/eclipse"
1980 eclipseProduct = "${eclipseRoot}/.eclipseproduct"
1983 eclipseVersion = "4.13" // default
1984 def assumedVersion = true
1985 if (file(eclipseProduct).exists()) {
1986 def fis = new FileInputStream(eclipseProduct)
1987 def props = new Properties()
1989 eclipseVersion = props.getProperty("version")
1991 assumedVersion = false
1994 def propKey = "eclipse_debug"
1995 eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true"))
1998 // do not run a headless transpile when we claim to be in Eclipse
2000 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2001 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2003 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2006 if (!assumedVersion) {
2007 println("ECLIPSE VERSION=${eclipseVersion}")
2013 task printProperties {
2015 description "Output to console all System.properties"
2017 System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") }
2023 dependsOn eclipseProject
2024 dependsOn eclipseClasspath
2025 dependsOn eclipseJdt
2029 // this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir
2030 task jalviewjsEclipseCopyDropins(type: Copy) {
2031 dependsOn jalviewjsEclipsePaths
2033 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar")
2034 inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}")
2035 def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}"
2042 // this eclipse -clean doesn't actually work
2043 task jalviewjsCleanEclipse(type: Exec) {
2044 dependsOn eclipseSetup
2045 dependsOn jalviewjsEclipsePaths
2046 dependsOn jalviewjsEclipseCopyDropins
2048 executable(eclipseBinary)
2049 args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"])
2055 def inputString = """exit
2058 def inputByteStream = new ByteArrayInputStream(inputString.getBytes())
2059 standardInput = inputByteStream
2062 /* not really working yet
2063 jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse
2067 task jalviewjsTransferUnzipSwingJs {
2068 def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}"
2072 from zipTree(file_zip)
2073 into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2077 inputs.file file_zip
2078 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2082 task jalviewjsTransferUnzipLib {
2083 def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip")
2086 zipFiles.each { file_zip ->
2088 from zipTree(file_zip)
2089 into "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2094 inputs.files zipFiles
2095 outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2099 task jalviewjsTransferUnzipAllLibs {
2100 dependsOn jalviewjsTransferUnzipSwingJs
2101 dependsOn jalviewjsTransferUnzipLib
2105 task jalviewjsCreateJ2sSettings(type: WriteProperties) {
2107 description "Create the .j2s file from the j2s.* properties"
2109 jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key }
2110 def siteDirProperty = "j2s.site.directory"
2111 def setSiteDir = false
2112 jalviewjsJ2sProps.each { prop, val ->
2114 if (prop == siteDirProperty) {
2115 if (!(val.startsWith('/') || val.startsWith("file://") )) {
2116 val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}"
2122 if (!setSiteDir) { // default site location, don't override specifically set property
2123 property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}")
2126 outputFile = jalviewjsJ2sSettingsFileName
2129 inputs.properties(jalviewjsJ2sProps)
2130 outputs.file(jalviewjsJ2sSettingsFileName)
2135 task jalviewjsEclipseSetup {
2136 dependsOn jalviewjsEclipseCopyDropins
2137 dependsOn jalviewjsSetEclipseWorkspace
2138 dependsOn jalviewjsCreateJ2sSettings
2142 task jalviewjsSyncAllLibs (type: Sync) {
2143 dependsOn jalviewjsTransferUnzipAllLibs
2144 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}")
2145 inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}")
2146 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2150 def outputFiles = []
2151 rename { filename ->
2152 outputFiles += "${outputDir}/${filename}"
2158 outputs.files outputFiles
2159 inputs.files inputFiles
2163 task jalviewjsSyncResources (type: Sync) {
2164 def inputFiles = fileTree(dir: resourceDir)
2165 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2169 def outputFiles = []
2170 rename { filename ->
2171 outputFiles += "${outputDir}/${filename}"
2177 outputs.files outputFiles
2178 inputs.files inputFiles
2182 task jalviewjsSyncSiteResources (type: Sync) {
2183 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}")
2184 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2188 def outputFiles = []
2189 rename { filename ->
2190 outputFiles += "${outputDir}/${filename}"
2196 outputs.files outputFiles
2197 inputs.files inputFiles
2201 task jalviewjsSyncBuildProperties (type: Sync) {
2202 dependsOn createBuildProperties
2203 def inputFiles = [file(buildProperties)]
2204 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}"
2208 def outputFiles = []
2209 rename { filename ->
2210 outputFiles += "${outputDir}/${filename}"
2216 outputs.files outputFiles
2217 inputs.files inputFiles
2221 task jalviewjsProjectImport(type: Exec) {
2222 dependsOn eclipseSetup
2223 dependsOn jalviewjsEclipsePaths
2224 dependsOn jalviewjsEclipseSetup
2227 // do not run a headless import when we claim to be in Eclipse
2229 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2230 throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2232 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2236 //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core"
2237 def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview"
2238 executable(eclipseBinary)
2239 args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath])
2243 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2245 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2248 inputs.file("${jalviewDir}/.project")
2249 outputs.upToDateWhen {
2250 file(projdir).exists()
2255 task jalviewjsTranspile(type: Exec) {
2256 dependsOn jalviewjsEclipseSetup
2257 dependsOn jalviewjsProjectImport
2258 dependsOn jalviewjsEclipsePaths
2261 // do not run a headless transpile when we claim to be in Eclipse
2263 println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2264 throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'")
2266 println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}")
2270 executable(eclipseBinary)
2271 args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ])
2275 args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ]
2277 args += [ "-D${j2sHeadlessBuildProperty}=true" ]
2283 stdout = new ByteArrayOutputStream()
2284 stderr = new ByteArrayOutputStream()
2286 def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}"
2287 def logOutFile = file(logOutFileName)
2288 logOutFile.createNewFile()
2289 logOutFile.text = """ROOT: ${jalviewjs_eclipse_root}
2290 BINARY: ${eclipseBinary}
2291 VERSION: ${eclipseVersion}
2292 WORKSPACE: ${eclipseWorkspace}
2293 DEBUG: ${eclipseDebug}
2296 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2297 // combine stdout and stderr
2298 def logErrFOS = logOutFOS
2300 if (jalviewjs_j2s_to_console.equals("true")) {
2301 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2302 new org.apache.tools.ant.util.TeeOutputStream(
2306 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2307 new org.apache.tools.ant.util.TeeOutputStream(
2312 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2315 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2322 if (stdout.toString().contains("Error processing ")) {
2323 // j2s did not complete transpile
2324 //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2325 if (jalviewjs_ignore_transpile_errors.equals("true")) {
2326 println("IGNORING TRANSPILE ERRORS")
2327 println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2329 throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'")
2334 inputs.dir("${jalviewDir}/${sourceDir}")
2335 outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}")
2336 outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } )
2340 def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) {
2342 def stdout = new ByteArrayOutputStream()
2343 def stderr = new ByteArrayOutputStream()
2345 def coreFile = file(jsfile)
2347 msg = "Creating core for ${name}...\nGenerating ${jsfile}"
2349 logOutFile.createNewFile()
2350 logOutFile.append(msg+"\n")
2352 def coreTop = file(prefixFile)
2353 def coreBottom = file(suffixFile)
2354 coreFile.getParentFile().mkdirs()
2355 coreFile.createNewFile()
2356 coreFile.write( coreTop.getText("UTF-8") )
2360 def t = f.getText("UTF-8")
2361 t.replaceAll("Clazz\\.([^_])","Clazz_${1}")
2362 coreFile.append( t )
2364 msg = "...file '"+f.getPath()+"' does not exist, skipping"
2366 logOutFile.append(msg+"\n")
2369 coreFile.append( coreBottom.getText("UTF-8") )
2371 msg = "Generating ${zjsfile}"
2373 logOutFile.append(msg+"\n")
2374 def logOutFOS = new FileOutputStream(logOutFile, true) // true == append
2375 def logErrFOS = logOutFOS
2378 classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"])
2379 main = "com.google.javascript.jscomp.CommandLineRunner"
2380 jvmArgs = [ "-Dfile.encoding=UTF-8" ]
2381 args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ]
2384 msg = "\nRunning '"+commandLine.join(' ')+"'\n"
2386 logOutFile.append(msg+"\n")
2388 if (logOutConsole) {
2389 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2390 new org.apache.tools.ant.util.TeeOutputStream(
2394 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2395 new org.apache.tools.ant.util.TeeOutputStream(
2400 standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
2403 errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
2410 logOutFile.append(msg+"\n")
2414 task jalviewjsBuildAllCores {
2416 description "Build the core js lib closures listed in the classlists dir"
2417 dependsOn jalviewjsTranspile
2418 dependsOn jalviewjsTransferUnzipSwingJs
2420 def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}"
2421 def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}"
2422 def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}"
2423 def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}"
2424 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core"
2425 def prefixFile = "${jsDir}/core/coretop2.js"
2426 def suffixFile = "${jsDir}/core/corebottom2.js"
2428 inputs.file prefixFile
2429 inputs.file suffixFile
2431 def classlistFiles = []
2432 // add the classlists found int the jalviewjs_classlists_dir
2433 fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each {
2435 def name = file.getName() - ".txt"
2442 // _jmol and _jalview cores. Add any other peculiar classlist.txt files here
2443 //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ]
2444 classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ]
2446 jalviewjsCoreClasslists = []
2448 classlistFiles.each {
2451 def file = hash['file']
2452 if (! file.exists()) {
2453 //println("...classlist file '"+file.getPath()+"' does not exist, skipping")
2454 return false // this is a "continue" in groovy .each closure
2456 def name = hash['name']
2458 name = file.getName() - ".txt"
2466 def list = fileTree(dir: j2sDir, includes: filelist)
2468 def jsfile = "${outputDir}/core${name}.js"
2469 def zjsfile = "${outputDir}/core${name}.z.js"
2471 jalviewjsCoreClasslists += [
2480 outputs.file(jsfile)
2481 outputs.file(zjsfile)
2484 // _stevesoft core. add any cores without a classlist here (and the inputs and outputs)
2485 def stevesoftClasslistName = "_stevesoft"
2486 def stevesoftClasslist = [
2487 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js",
2488 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js",
2489 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"),
2490 'name': stevesoftClasslistName
2492 jalviewjsCoreClasslists += stevesoftClasslist
2493 inputs.files(stevesoftClasslist['list'])
2494 outputs.file(stevesoftClasslist['jsfile'])
2495 outputs.file(stevesoftClasslist['zjsfile'])
2498 def allClasslistName = "_all"
2499 def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js")
2500 allJsFiles += fileTree(
2504 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2505 "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js",
2506 "**/org/jmol/export/JSExporter.js"
2509 allJsFiles += fileTree(
2513 // these exlusions are files that the closure-compiler produces errors for. Should fix them
2514 "**/sun/misc/Unsafe.js",
2515 "**/swingjs/jquery/jquery-editable-select.js",
2516 "**/swingjs/jquery/j2sComboBox.js",
2517 "**/sun/misc/FloatingDecimal.js"
2520 def allClasslist = [
2521 'jsfile': "${outputDir}/core${allClasslistName}.js",
2522 'zjsfile': "${outputDir}/core${allClasslistName}.z.js",
2524 'name': allClasslistName
2526 // not including this version of "all" core at the moment
2527 //jalviewjsCoreClasslists += allClasslist
2528 inputs.files(allClasslist['list'])
2529 outputs.file(allClasslist['jsfile'])
2530 outputs.file(allClasslist['zjsfile'])
2533 def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}")
2534 logOutFile.getParentFile().mkdirs()
2535 logOutFile.createNewFile()
2536 logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n")
2538 jalviewjsCoreClasslists.each {
2539 jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true"))
2546 def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) {
2549 into file(outputFile).getParentFile()
2550 rename { filename ->
2551 if (filename.equals(inputFile.getName())) {
2552 return file(outputFile).getName()
2556 filter(ReplaceTokens,
2560 'MAIN': '"'+main_class+'"',
2562 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]",
2563 'COREKEY': jalviewjs_core_key,
2564 'CORENAME': coreName
2571 task jalviewjsPublishCoreTemplates {
2572 dependsOn jalviewjsBuildAllCores
2573 def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}"
2574 def inputFile = file(inputFileName)
2575 def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2577 def outputFiles = []
2578 jalviewjsCoreClasslists.each { cl ->
2579 def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html"
2580 cl['outputfile'] = outputFile
2581 outputFiles += outputFile
2585 jalviewjsCoreClasslists.each { cl ->
2586 jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile)
2589 inputs.file(inputFile)
2590 outputs.files(outputFiles)
2594 task jalviewjsSyncCore (type: Sync) {
2595 dependsOn jalviewjsBuildAllCores
2596 dependsOn jalviewjsPublishCoreTemplates
2597 def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}")
2598 def outputDir = "${jalviewDir}/${jalviewjsSiteDir}"
2602 def outputFiles = []
2603 rename { filename ->
2604 outputFiles += "${outputDir}/${filename}"
2610 outputs.files outputFiles
2611 inputs.files inputFiles
2615 // this Copy version of TransferSiteJs will delete anything else in the target dir
2616 task jalviewjsCopyTransferSiteJs(type: Copy) {
2617 dependsOn jalviewjsTranspile
2618 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2619 into "${jalviewDir}/${jalviewjsSiteDir}"
2623 // this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes
2624 task jalviewjsSyncTransferSiteJs(type: Sync) {
2625 from "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2627 into "${jalviewDir}/${jalviewjsSiteDir}"
2634 jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs
2635 jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs
2636 jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs
2637 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs
2639 jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs
2640 jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs
2641 jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs
2642 jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs
2645 task jalviewjsPrepareSite {
2647 description "Prepares the website folder including unzipping files and copying resources"
2648 dependsOn jalviewjsSyncAllLibs
2649 dependsOn jalviewjsSyncResources
2650 dependsOn jalviewjsSyncSiteResources
2651 dependsOn jalviewjsSyncBuildProperties
2652 dependsOn jalviewjsSyncCore
2656 task jalviewjsBuildSite {
2658 description "Builds the whole website including transpiled code"
2659 dependsOn jalviewjsCopyTransferSiteJs
2660 dependsOn jalviewjsPrepareSite
2664 task cleanJalviewjsTransferSite {
2666 delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}"
2667 delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}"
2668 delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}"
2669 delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}"
2674 task cleanJalviewjsSite {
2675 dependsOn cleanJalviewjsTransferSite
2677 delete "${jalviewDir}/${jalviewjsSiteDir}"
2682 task jalviewjsSiteTar(type: Tar) {
2684 description "Creates a tar.gz file for the website"
2685 dependsOn jalviewjsBuildSite
2686 def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz"
2688 archiveFileName = outputFilename
2689 } catch (Exception e) {
2690 archiveName = outputFilename
2693 compression Compression.GZIP
2695 from "${jalviewDir}/${jalviewjsSiteDir}"
2696 into jalviewjs_site_dir // this is inside the tar file
2698 inputs.dir("${jalviewDir}/${jalviewjsSiteDir}")
2702 task jalviewjsServer {
2704 def filename = "jalviewjsTest.html"
2705 description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port."
2706 def htmlFile = "${jalviewDirAbsolutePath}/${filename}"
2709 SimpleHttpFileServerFactory factory = new SimpleHttpFileServerFactory()
2710 def port = Integer.valueOf(jalviewjs_server_port)
2715 while(port < start+1000 && !running) {
2717 def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}")
2718 jalviewjsServer = factory.start(doc_root, port)
2720 url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource)
2721 println("SERVER STARTED with document root ${doc_root}.")
2722 println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).")
2723 println("For debug: "+url+"?j2sdebug")
2724 println("For verbose: "+url+"?j2sverbose")
2725 } catch (Exception e) {
2730 <p><a href="${url}">JalviewJS Test. <${url}></a></p>
2731 <p><a href="${url}?j2sdebug">JalviewJS Test with debug. <${url}?j2sdebug></a></p>
2732 <p><a href="${url}?j2sverbose">JalviewJS Test with verbose. <${url}?j2sdebug></a></p>
2734 jalviewjsCoreClasslists.each { cl ->
2735 def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName())
2737 <p><a href="${urlcore}">${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}></a></p>
2739 println("For core ${cl.name}: "+urlcore)
2742 file(htmlFile).text = htmlText
2745 outputs.file(htmlFile)
2746 outputs.upToDateWhen({false})
2750 task cleanJalviewjsAll {
2752 description "Delete all configuration and build artifacts to do with JalviewJS build"
2753 dependsOn cleanJalviewjsSite
2754 dependsOn jalviewjsEclipsePaths
2757 delete "${jalviewDir}/${jalviewjsBuildDir}"
2758 delete "${jalviewDir}/${eclipse_bin_dir}"
2759 if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) {
2760 delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata")
2762 delete "${jalviewDir}/${jalviewjs_j2s_settings}"
2765 outputs.upToDateWhen( { false } )
2769 task jalviewjsIDE_checkJ2sPlugin {
2770 group "00 JalviewJS in Eclipse"
2771 description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)"
2774 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
2775 def j2sPluginFile = file(j2sPlugin)
2776 def eclipseHome = System.properties["eclipse.home.location"]
2777 if (eclipseHome == null || ! IN_ECLIPSE) {
2778 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.")
2780 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
2781 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
2782 if (!eclipseJ2sPluginFile.exists()) {
2783 def msg = "Eclipse J2S Plugin is not installed (could not find '${eclipseJ2sPlugin}')\nTry running task jalviewjsIDE_copyJ2sPlugin"
2784 System.err.println(msg)
2785 throw new StopExecutionException(msg)
2788 def digest = MessageDigest.getInstance("MD5")
2790 digest.update(j2sPluginFile.text.bytes)
2791 def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
2793 digest.update(eclipseJ2sPluginFile.text.bytes)
2794 def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0')
2796 if (j2sPluginMd5 != eclipseJ2sPluginMd5) {
2797 def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'"
2798 System.err.println(msg)
2799 throw new StopExecutionException(msg)
2801 def msg = "Eclipse J2S Plugin is the same as '${j2sPlugin}' (this is good)"
2807 task jalviewjsIDE_copyJ2sPlugin {
2808 group "00 JalviewJS in Eclipse"
2809 description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir"
2812 def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}")
2813 def j2sPluginFile = file(j2sPlugin)
2814 def eclipseHome = System.properties["eclipse.home.location"]
2815 if (eclipseHome == null || ! IN_ECLIPSE) {
2816 throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.")
2818 def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}"
2819 def eclipseJ2sPluginFile = file(eclipseJ2sPlugin)
2820 def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart"
2821 System.err.println(msg)
2824 eclipseJ2sPluginFile.getParentFile().mkdirs()
2825 into eclipseJ2sPluginFile.getParent()
2831 task jalviewjsIDE_j2sFile {
2832 group "00 JalviewJS in Eclipse"
2833 description "Creates the .j2s file"
2834 dependsOn jalviewjsCreateJ2sSettings
2838 task jalviewjsIDE_SyncCore {
2839 group "00 JalviewJS in Eclipse"
2840 description "Build the core js lib closures listed in the classlists dir and publish core html from template"
2841 dependsOn jalviewjsSyncCore
2845 task jalviewjsIDE_SyncSiteAll {
2846 dependsOn jalviewjsSyncAllLibs
2847 dependsOn jalviewjsSyncResources
2848 dependsOn jalviewjsSyncSiteResources
2849 dependsOn jalviewjsSyncBuildProperties
2853 cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll
2856 task jalviewjsIDE_PrepareSite {
2857 group "00 JalviewJS in Eclipse"
2858 description "Sync libs and resources to site dir, but not closure cores"
2860 dependsOn jalviewjsIDE_SyncSiteAll
2861 dependsOn cleanJalviewjsTransferSite
2865 task jalviewjsIDE_AssembleSite {
2866 group "00 JalviewJS in Eclipse"
2867 description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site"
2868 dependsOn jalviewjsPrepareSite
2872 task jalviewjsIDE_SiteClean {
2873 group "00 JalviewJS in Eclipse"
2874 description "Deletes the Eclipse transpiled site"
2875 dependsOn cleanJalviewjsSite
2879 task jalviewjsIDE_Server {
2880 group "00 JalviewJS in Eclipse"
2881 description "Starts a webserver on localhost to test the website"
2882 dependsOn jalviewjsServer
2886 // buildship runs this at import or gradle refresh
2887 task eclipseSynchronizationTask {
2888 //dependsOn eclipseSetup
2889 dependsOn createBuildProperties
2891 dependsOn jalviewjsIDE_j2sFile
2892 dependsOn jalviewjsIDE_checkJ2sPlugin
2893 dependsOn jalviewjsIDE_PrepareSite
2898 // buildship runs this at build time or project refresh
2899 task eclipseAutoBuildTask {
2900 //dependsOn jalviewjsIDE_checkJ2sPlugin
2901 //dependsOn jalviewjsIDE_PrepareSite
2907 description "Build the site"
2908 dependsOn jalviewjsBuildSite