diff --git a/build.gradle b/build.gradle index ca599a85a..ce7f13634 100644 --- a/build.gradle +++ b/build.gradle @@ -2,66 +2,12 @@ * For properties set within build.gradle, use camelCaseNoSpace. */ import org.apache.tools.ant.filters.ReplaceTokens -import org.gradle.internal.os.OperatingSystem -import org.gradle.plugins.ide.internal.generator.PropertiesPersistableConfigurationObject -import org.gradle.api.internal.PropertiesTransformer -import org.gradle.util.ConfigureUtil -import org.gradle.plugins.ide.eclipse.model.Output -import org.gradle.plugins.ide.eclipse.model.Library -import java.security.MessageDigest -import java.util.regex.Matcher -import groovy.transform.ExternalizeMethods -import groovy.util.XmlParser -import groovy.xml.XmlUtil -import groovy.json.JsonBuilder -import com.vladsch.flexmark.util.ast.Node -import com.vladsch.flexmark.html.HtmlRenderer -import com.vladsch.flexmark.parser.Parser -import com.vladsch.flexmark.util.data.MutableDataSet -import com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension -import com.vladsch.flexmark.ext.tables.TablesExtension -import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension -import com.vladsch.flexmark.ext.autolink.AutolinkExtension -import com.vladsch.flexmark.ext.anchorlink.AnchorLinkExtension -import com.vladsch.flexmark.ext.toc.TocExtension -import com.google.common.hash.HashCode -import com.google.common.hash.Hashing -import com.google.common.io.Files -import org.jsoup.Jsoup -import org.jsoup.nodes.Element - -buildscript { - repositories { - mavenCentral() - mavenLocal() - } - dependencies { - classpath "com.vladsch.flexmark:flexmark-all:0.62.0" - classpath "org.jsoup:jsoup:1.14.3" - classpath "com.eowise:gradle-imagemagick:0.5.1" - } -} - plugins { id 'java' id 'application' - id 'eclipse' - id "com.diffplug.gradle.spotless" version "3.28.0" - id 'com.github.johnrengelman.shadow' version '4.0.3' - id 'com.install4j.gradle' version '10.0.3' - id 'com.dorongold.task-tree' version '2.1.1' // only needed to display task dependency tree with gradle task1 [task2 ...] taskTree - id 'com.palantir.git-version' version '0.13.0' apply false -} - -repositories { - jcenter() - mavenCentral() - mavenLocal() } - - // in ext the values are cast to Object. Ensure string values are cast as String (and not GStringImpl) for later use def string(Object o) { return o == null ? "" : o.toString() @@ -102,34 +48,20 @@ def overrideProperties(String propsFileName, boolean output = false) { } } -ext { +project.ext { jalviewDirAbsolutePath = file(jalviewDir).getAbsolutePath() jalviewDirRelativePath = jalviewDir - date = new Date() - getdownChannelName = CHANNEL.toLowerCase() - // default to "default". Currently only has different cosmetics for "develop", "release", "default" - propertiesChannelName = ["develop", "release", "test-release", "jalviewjs", "jalviewjs-release" ].contains(getdownChannelName) ? getdownChannelName : "default" - channelDirName = propertiesChannelName - // Import channel_properties - if (getdownChannelName.startsWith("develop-")) { - channelDirName = "develop-SUFFIX" - } - channelDir = string("${jalviewDir}/${channel_properties_dir}/${channelDirName}") + propertiesChannelName = "release" + channelDir = string("${jalviewDir}/${channel_properties_dir}/${propertiesChannelName}") channelGradleProperties = string("${channelDir}/channel_gradle.properties") - channelPropsFile = string("${channelDir}/${resource_dir}/${channel_props}") overrideProperties(channelGradleProperties, false) - // local build environment properties - // can be "projectDir/local.properties" - overrideProperties("${projectDir}/local.properties", true) - // or "../projectDir_local.properties" - overrideProperties(projectDir.getParent() + "/" + projectDir.getName() + "_local.properties", true) - + //// // Import releaseProps from the RELEASE file // or a file specified via JALVIEW_RELEASE_FILE if defined // Expect jalview.version and target release branch in jalview.release - releaseProps = new Properties(); + def releaseProps = new Properties(); def releasePropFile = findProperty("JALVIEW_RELEASE_FILE"); def defaultReleasePropFile = "${jalviewDirAbsolutePath}/RELEASE"; try { @@ -144,42 +76,6 @@ ext { if (findProperty("JALVIEW_VERSION")==null || "".equals(JALVIEW_VERSION)) { JALVIEW_VERSION = releaseProps.get("jalview.version") } - println("JALVIEW_VERSION is set to '${JALVIEW_VERSION}'") - - // this property set when running Eclipse headlessly - j2sHeadlessBuildProperty = string("net.sf.j2s.core.headlessbuild") - // this property set by Eclipse - eclipseApplicationProperty = string("eclipse.application") - // CHECK IF RUNNING FROM WITHIN ECLIPSE - def eclipseApplicationPropertyVal = System.properties[eclipseApplicationProperty] - IN_ECLIPSE = eclipseApplicationPropertyVal != null && eclipseApplicationPropertyVal.startsWith("org.eclipse.ui.") - // BUT WITHOUT THE HEADLESS BUILD PROPERTY SET - if (System.properties[j2sHeadlessBuildProperty].equals("true")) { - println("Setting IN_ECLIPSE to ${IN_ECLIPSE} as System.properties['${j2sHeadlessBuildProperty}'] == '${System.properties[j2sHeadlessBuildProperty]}'") - IN_ECLIPSE = false - } - if (IN_ECLIPSE) { - println("WITHIN ECLIPSE IDE") - } else { - println("HEADLESS BUILD") - } - - J2S_ENABLED = (project.hasProperty('j2s.compiler.status') && project['j2s.compiler.status'] != null && project['j2s.compiler.status'] == "enable") - if (J2S_ENABLED) { - println("J2S ENABLED") - } - /* *-/ - System.properties.sort { it.key }.each { - key, val -> println("SYSTEM PROPERTY ${key}='${val}'") - } - /-* *-/ - if (false && IN_ECLIPSE) { - jalviewDir = jalviewDirAbsolutePath - } - */ - - // datestamp - buildDate = new Date().format("yyyyMMdd") // essentials bareSourceDir = string(source_dir) @@ -190,273 +86,18 @@ ext { classesDir = string("${jalviewDir}/${classes_dir}") - // clover - useClover = clover.equals("true") - cloverBuildDir = "${buildDir}/clover" - cloverInstrDir = file("${cloverBuildDir}/clover-instr") - cloverClassesDir = file("${cloverBuildDir}/clover-classes") - cloverReportDir = file("${buildDir}/reports/clover") - cloverTestInstrDir = file("${cloverBuildDir}/clover-test-instr") - cloverTestClassesDir = file("${cloverBuildDir}/clover-test-classes") - //cloverTestClassesDir = cloverClassesDir - cloverDb = string("${cloverBuildDir}/clover.db") + useClover = false - testSourceDir = useClover ? cloverTestInstrDir : testDir - testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}" + resourceClassesDir = classesDir - channelSuffix = "" - backgroundImageText = BACKGROUNDIMAGETEXT - getdownChannelDir = string("${getdown_website_dir}/${propertiesChannelName}") - getdownAppBaseDir = string("${jalviewDir}/${getdownChannelDir}/${JAVA_VERSION}") - getdownArchiveDir = string("${jalviewDir}/${getdown_archive_dir}") - getdownFullArchiveDir = null - getdownTextLines = [] - getdownLaunchJvl = null - getdownVersionLaunchJvl = null - buildDist = true - buildProperties = null + testSourceDir = testDir + testClassesDir = "${jalviewDir}/${test_output_dir}" - // the following values might be overridden by the CHANNEL switch - getdownDir = string("${getdownChannelName}/${JAVA_VERSION}") - getdownAppBase = string("${getdown_channel_base}/${getdownDir}") - getdownArchiveAppBase = getdown_archive_base - getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}") - getdownAppDistDir = getdown_app_dir_alt - getdownImagesDir = string("${jalviewDir}/${getdown_images_dir}") - getdownImagesBuildDir = string("${buildDir}/imagemagick/getdown") + buildProperties = string("${classesDir}/${build_properties_file}") getdownSetAppBaseProperty = false // whether to pass the appbase and appdistdir to the application - reportRsyncCommand = false - jvlChannelName = CHANNEL.toLowerCase() - install4jSuffix = CHANNEL.substring(0, 1).toUpperCase() + CHANNEL.substring(1).toLowerCase(); // BUILD -> Build - install4jDMGDSStore = "${install4j_images_dir}/${install4j_dmg_ds_store}" - install4jDMGBackgroundImageDir = "${install4j_images_dir}" - install4jDMGBackgroundImageBuildDir = "build/imagemagick/install4j" - install4jDMGBackgroundImageFile = "${install4j_dmg_background}" - install4jInstallerName = "${jalview_name} Non-Release Installer" - install4jExecutableName = install4j_executable_name - install4jExtraScheme = "jalviewx" - install4jMacIconsFile = string("${install4j_images_dir}/${install4j_mac_icons_file}") - install4jWindowsIconsFile = string("${install4j_images_dir}/${install4j_windows_icons_file}") - install4jPngIconFile = string("${install4j_images_dir}/${install4j_png_icon_file}") - install4jBackground = string("${install4j_images_dir}/${install4j_background}") - install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}" - install4jCheckSums = true - - applicationName = "${jalview_name}" - switch (CHANNEL) { - - case "BUILD": - // TODO: get bamboo build artifact URL for getdown artifacts - getdown_channel_base = bamboo_channelbase - getdownChannelName = string("${bamboo_planKey}/${JAVA_VERSION}") - getdownAppBase = string("${bamboo_channelbase}/${bamboo_planKey}${bamboo_getdown_channel_suffix}/${JAVA_VERSION}") - jvlChannelName += "_${getdownChannelName}" - // automatically add the test group Not-bamboo for exclusion - if ("".equals(testng_excluded_groups)) { - testng_excluded_groups = "Not-bamboo" - } - install4jExtraScheme = "jalviewb" - backgroundImageText = true - break - - case [ "RELEASE", "JALVIEWJS-RELEASE" ]: - getdownAppDistDir = getdown_app_dir_release - getdownSetAppBaseProperty = true - reportRsyncCommand = true - install4jSuffix = "" - install4jInstallerName = "${jalview_name} Installer" - break - - case "ARCHIVE": - getdownChannelName = CHANNEL.toLowerCase()+"/${JALVIEW_VERSION}" - getdownDir = string("${getdownChannelName}/${JAVA_VERSION}") - getdownAppBase = string("${getdown_channel_base}/${getdownDir}") - if (!file("${ARCHIVEDIR}/${package_dir}").exists()) { - throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution") - } else { - package_dir = string("${ARCHIVEDIR}/${package_dir}") - buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}") - buildDist = false - } - reportRsyncCommand = true - install4jExtraScheme = "jalviewa" - break - - case "ARCHIVELOCAL": - getdownChannelName = string("archive/${JALVIEW_VERSION}") - getdownDir = string("${getdownChannelName}/${JAVA_VERSION}") - getdownAppBase = file(getdownAppBaseDir).toURI().toString() - if (!file("${ARCHIVEDIR}/${package_dir}").exists()) { - throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution [did not find '${ARCHIVEDIR}/${package_dir}']") - } else { - package_dir = string("${ARCHIVEDIR}/${package_dir}") - buildProperties = string("${ARCHIVEDIR}/${classes_dir}/${build_properties_file}") - buildDist = false - } - reportRsyncCommand = true - getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}") - install4jSuffix = "Archive" - install4jExtraScheme = "jalviewa" - break - - case ~/^DEVELOP-([\.\-\w]*)$/: - def suffix = Matcher.lastMatcher[0][1] - reportRsyncCommand = true - getdownSetAppBaseProperty = true - JALVIEW_VERSION=JALVIEW_VERSION+"-d${suffix}-${buildDate}" - install4jSuffix = "Develop ${suffix}" - install4jExtraScheme = "jalviewd" - install4jInstallerName = "${jalview_name} Develop ${suffix} Installer" - getdownChannelName = string("develop-${suffix}") - getdownChannelDir = string("${getdown_website_dir}/${getdownChannelName}") - getdownAppBaseDir = string("${jalviewDir}/${getdownChannelDir}/${JAVA_VERSION}") - getdownDir = string("${getdownChannelName}/${JAVA_VERSION}") - getdownAppBase = string("${getdown_channel_base}/${getdownDir}") - channelSuffix = string(suffix) - backgroundImageText = true - break - - case "DEVELOP": - reportRsyncCommand = true - getdownSetAppBaseProperty = true - // DEVELOP-RELEASE is usually associated with a Jalview release series so set the version - JALVIEW_VERSION=JALVIEW_VERSION+"-d${buildDate}" - - install4jSuffix = "Develop" - install4jExtraScheme = "jalviewd" - install4jInstallerName = "${jalview_name} Develop Installer" - backgroundImageText = true - break - - case "TEST-RELEASE": - reportRsyncCommand = true - getdownSetAppBaseProperty = true - // Don't ignore transpile errors for release build - if (jalviewjs_ignore_transpile_errors.equals("true")) { - jalviewjs_ignore_transpile_errors = "false" - println("Setting jalviewjs_ignore_transpile_errors to 'false'") - } - JALVIEW_VERSION = JALVIEW_VERSION+"-test" - install4jSuffix = "Test" - install4jExtraScheme = "jalviewt" - install4jInstallerName = "${jalview_name} Test Installer" - backgroundImageText = true - break - - case ~/^SCRATCH(|-[-\w]*)$/: - getdownChannelName = CHANNEL - JALVIEW_VERSION = JALVIEW_VERSION+"-"+CHANNEL - - getdownDir = string("${getdownChannelName}/${JAVA_VERSION}") - getdownAppBase = string("${getdown_channel_base}/${getdownDir}") - reportRsyncCommand = true - install4jSuffix = "Scratch" - break - - case "TEST-LOCAL": - if (!file("${LOCALDIR}").exists()) { - throw new GradleException("Must provide a LOCALDIR value to produce a local distribution") - } else { - getdownAppBase = file(file("${LOCALDIR}").getAbsolutePath()).toURI().toString() - getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}") - } - JALVIEW_VERSION = "TEST" - install4jSuffix = "Test-Local" - install4jExtraScheme = "jalviewt" - install4jInstallerName = "${jalview_name} Test Installer" - backgroundImageText = true - break - - case [ "LOCAL", "JALVIEWJS" ]: - JALVIEW_VERSION = "TEST" - getdownAppBase = file(getdownAppBaseDir).toURI().toString() - getdownArchiveAppBase = file("${jalviewDir}/${getdown_archive_dir}").toURI().toString() - getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}") - install4jExtraScheme = "jalviewl" - install4jCheckSums = false - break - - default: // something wrong specified - throw new GradleException("CHANNEL must be one of BUILD, RELEASE, ARCHIVE, DEVELOP, TEST-RELEASE, SCRATCH-..., LOCAL [default]") - break - - } - JALVIEW_VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_") - hugoDataJsonFile = file("${jalviewDir}/${hugo_build_dir}/${hugo_data_installers_dir}/installers-${JALVIEW_VERSION_UNDERSCORES}.json") - hugoArchiveMdFile = file("${jalviewDir}/${hugo_build_dir}/${hugo_version_archive_dir}/Version-${JALVIEW_VERSION_UNDERSCORES}/_index.md") - // override getdownAppBase if requested - if (findProperty("getdown_appbase_override") != null) { - // revert to LOCAL if empty string - if (string(getdown_appbase_override) == "") { - getdownAppBase = file(getdownAppBaseDir).toURI().toString() - getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}") - } else if (string(getdown_appbase_override).startsWith("file://")) { - getdownAppBase = string(getdown_appbase_override) - getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}") - } else { - getdownAppBase = string(getdown_appbase_override) - } - println("Overriding getdown appbase with '${getdownAppBase}'") - } - // sanitise file name for jalview launcher file for this channel - jvlChannelName = jvlChannelName.replaceAll("[^\\w\\-]+", "_") - // install4j application and folder names - if (install4jSuffix == "") { - install4jBundleId = "${install4j_bundle_id}" - install4jWinApplicationId = install4j_release_win_application_id - } else { - applicationName = "${jalview_name} ${install4jSuffix}" - install4jBundleId = "${install4j_bundle_id}-" + install4jSuffix.toLowerCase() - // add int hash of install4jSuffix to the last part of the application_id - def id = install4j_release_win_application_id - def idsplitreverse = id.split("-").reverse() - idsplitreverse[0] = idsplitreverse[0].toInteger() + install4jSuffix.hashCode() - install4jWinApplicationId = idsplitreverse.reverse().join("-") - } - // sanitise folder and id names - // install4jApplicationFolder = e.g. "Jalview Build" - install4jApplicationFolder = applicationName - .replaceAll("[\"'~:/\\\\\\s]", "_") // replace all awkward filename chars " ' ~ : / \ - .replaceAll("_+", "_") // collapse __ - install4jInternalId = applicationName - .replaceAll(" ","_") - .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.] - .replaceAll("_+", "") // collapse __ - //.replaceAll("_*-_*", "-") // collapse _-_ - install4jUnixApplicationFolder = applicationName - .replaceAll(" ","_") - .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.] - .replaceAll("_+", "_") // collapse __ - .replaceAll("_*-_*", "-") // collapse _-_ - .toLowerCase() - - getdownWrapperLink = install4jUnixApplicationFolder // e.g. "jalview_local" - getdownAppDir = string("${getdownAppBaseDir}/${getdownAppDistDir}") - //getdownJ11libDir = "${getdownAppBaseDir}/${getdown_j11lib_dir}" - getdownResourceDir = string("${getdownAppBaseDir}/${getdown_resource_dir}") - getdownInstallDir = string("${getdownAppBaseDir}/${getdown_install_dir}") - getdownFilesDir = string("${jalviewDir}/${getdown_files_dir}/${JAVA_VERSION}/") - getdownFilesInstallDir = string("${getdownFilesDir}/${getdown_install_dir}") - /* compile without modules -- using classpath libraries - modules_compileClasspath = fileTree(dir: "${jalviewDir}/${j11modDir}", include: ["*.jar"]) - modules_runtimeClasspath = modules_compileClasspath - */ - - gitHash = "SOURCE" - gitBranch = "Source" - try { - apply plugin: "com.palantir.git-version" - def details = versionDetails() - gitHash = details.gitHash - gitBranch = details.branchName - } catch(org.gradle.api.internal.plugins.PluginApplicationException e) { - println("Not in a git repository. Using git values from RELEASE properties file.") - gitHash = releaseProps.getProperty("git.hash") - gitBranch = releaseProps.getProperty("git.branch") - } catch(java.lang.RuntimeException e1) { - throw new GradleException("Error with git-version plugin. Directory '.git' exists but versionDetails() cannot be found.") - } + install4jApplicationName = "${jalview_name}" + println("Using a ${CHANNEL} profile.") additional_compiler_args = [] @@ -468,65 +109,16 @@ ext { libDistDir = j8libDir compile_source_compatibility = 1.8 compile_target_compatibility = 1.8 - // these are getdown.txt properties defined dependent on the JAVA_VERSION - getdownAltJavaMinVersion = string(findProperty("getdown_alt_java8_min_version")) - getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java8_max_version")) - // this property is assigned below and expanded to multiple lines in the getdown task - getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java8_txt_multi_java_location")) - // this property is for the Java library used in eclipse - eclipseJavaRuntimeName = string("JavaSE-1.8") } else if (JAVA_VERSION.equals("11")) { JAVA_INTEGER_VERSION = string("11") libDir = j11libDir libDistDir = j11libDir compile_source_compatibility = 11 compile_target_compatibility = 11 - getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version")) - getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version")) - getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location")) - eclipseJavaRuntimeName = string("JavaSE-11") - /* compile without modules -- using classpath libraries - additional_compiler_args += [ - '--module-path', modules_compileClasspath.asPath, - '--add-modules', j11modules - ] - */ - } else if (JAVA_VERSION.equals("17")) { - JAVA_INTEGER_VERSION = string("17") - libDir = j17libDir - libDistDir = j17libDir - compile_source_compatibility = 17 - compile_target_compatibility = 17 - getdownAltJavaMinVersion = string(findProperty("getdown_alt_java11_min_version")) - getdownAltJavaMaxVersion = string(findProperty("getdown_alt_java11_max_version")) - getdownAltMultiJavaLocation = string(findProperty("getdown_alt_java11_txt_multi_java_location")) - eclipseJavaRuntimeName = string("JavaSE-17") - /* compile without modules -- using classpath libraries - additional_compiler_args += [ - '--module-path', modules_compileClasspath.asPath, - '--add-modules', j11modules - ] - */ } else { throw new GradleException("JAVA_VERSION=${JAVA_VERSION} not currently supported by Jalview") } - - // for install4j - JAVA_MIN_VERSION = JAVA_VERSION - JAVA_MAX_VERSION = JAVA_VERSION - jreInstallsDir = string(jre_installs_dir) - if (jreInstallsDir.startsWith("~/")) { - jreInstallsDir = System.getProperty("user.home") + jreInstallsDir.substring(1) - } - install4jDir = string("${jalviewDir}/${install4j_utils_dir}") - install4jConfFileName = string("jalview-install4j-conf.install4j") - install4jConfFile = file("${install4jDir}/${install4jConfFileName}") - install4jHomeDir = install4j_home_dir - if (install4jHomeDir.startsWith("~/")) { - install4jHomeDir = System.getProperty("user.home") + install4jHomeDir.substring(1) - } - resourceBuildDir = string("${buildDir}/resources") resourcesBuildDir = string("${resourceBuildDir}/resources_build") helpBuildDir = string("${resourceBuildDir}/help_build") @@ -540,39 +132,6 @@ ext { helpSourceDir = string("${helpParentDir}/${help_dir}") helpFile = string("${helpBuildDir}/${help_dir}/help.jhm") - convertBinary = null - convertBinaryExpectedLocation = imagemagick_convert - if (convertBinaryExpectedLocation.startsWith("~/")) { - convertBinaryExpectedLocation = System.getProperty("user.home") + convertBinaryExpectedLocation.substring(1) - } - if (file(convertBinaryExpectedLocation).exists()) { - convertBinary = convertBinaryExpectedLocation - } - - relativeBuildDir = file(jalviewDirAbsolutePath).toPath().relativize(buildDir.toPath()) - jalviewjsBuildDir = string("${relativeBuildDir}/jalviewjs") - jalviewjsSiteDir = string("${jalviewjsBuildDir}/${jalviewjs_site_dir}") - if (IN_ECLIPSE) { - jalviewjsTransferSiteJsDir = string(jalviewjsSiteDir) - } else { - jalviewjsTransferSiteJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_js") - } - jalviewjsTransferSiteLibDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_lib") - jalviewjsTransferSiteSwingJsDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_swingjs") - jalviewjsTransferSiteCoreDir = string("${jalviewjsBuildDir}/tmp/${jalviewjs_site_dir}_core") - jalviewjsJalviewCoreHtmlFile = string("") - jalviewjsJalviewCoreName = string(jalviewjs_core_name) - jalviewjsCoreClasslists = [] - jalviewjsJalviewTemplateName = string(jalviewjs_name) - jalviewjsJ2sSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_settings}") - jalviewjsJ2sAltSettingsFileName = string("${jalviewDir}/${jalviewjs_j2s_alt_settings}") - jalviewjsJ2sProps = null - jalviewjsJ2sPlugin = jalviewjs_j2s_plugin - - eclipseWorkspace = null - eclipseBinary = string("") - eclipseVersion = string("") - eclipseDebug = false // ENDEXT } @@ -591,27 +150,12 @@ sourceSets { compileClasspath = files(sourceSets.main.java.outputDir) compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"]) - runtimeClasspath = compileClasspath - runtimeClasspath += files(sourceSets.main.resources.srcDirs) - } - - clover { - java { - srcDirs cloverInstrDir - outputDir = cloverClassesDir - } - - resources { - srcDirs = sourceSets.main.resources.srcDirs - } - compileClasspath = files( sourceSets.clover.java.outputDir ) - //compileClasspath += files( testClassesDir ) + compileClasspath = files(sourceSets.main.java.outputDir) compileClasspath += fileTree(dir: "${jalviewDir}/${libDir}", include: ["*.jar"]) - compileClasspath += fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"]) - compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["**/*.jar"]) runtimeClasspath = compileClasspath + runtimeClasspath += files(sourceSets.main.resources.srcDirs) } test { @@ -631,453 +175,41 @@ sourceSets { runtimeClasspath = compileClasspath runtimeClasspath += files(sourceSets.test.resources.srcDirs) } - -} - - -// eclipse project and settings files creation, also used by buildship -eclipse { - project { - name = eclipse_project_name - - natures 'org.eclipse.jdt.core.javanature', - 'org.eclipse.jdt.groovy.core.groovyNature', - 'org.eclipse.buildship.core.gradleprojectnature' - - buildCommand 'org.eclipse.jdt.core.javabuilder' - buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder' - } - - classpath { - //defaultOutputDir = sourceSets.main.java.outputDir - configurations.each{ c-> - if (c.isCanBeResolved()) { - minusConfigurations += [c] - } - } - - plusConfigurations = [ ] - file { - - whenMerged { cp -> - def removeTheseToo = [] - HashMap alreadyAddedSrcPath = new HashMap<>(); - cp.entries.each { entry -> - // This conditional removes all src classpathentries that a) have already been added or b) aren't "src" or "test". - // e.g. this removes the resources dir being copied into bin/main, bin/test AND bin/clover - // we add the resources and help/help dirs in as libs afterwards (see below) - if (entry.kind == 'src') { - if (alreadyAddedSrcPath.getAt(entry.path) || !(entry.path == bareSourceDir || entry.path == bareTestSourceDir)) { - removeTheseToo += entry - } else { - alreadyAddedSrcPath.putAt(entry.path, true) - } - } - - } - cp.entries.removeAll(removeTheseToo) - - //cp.entries += new Output("${eclipse_bin_dir}/main") - if (file(helpParentDir).isDirectory()) { - cp.entries += new Library(fileReference(helpParentDir)) - } - if (file(resourceDir).isDirectory()) { - cp.entries += new Library(fileReference(resourceDir)) - } - - HashMap alreadyAddedLibPath = new HashMap<>(); - - sourceSets.main.compileClasspath.findAll { it.name.endsWith(".jar") }.any { - //don't want to add outputDir as eclipse is using its own output dir in bin/main - if (it.isDirectory() || ! it.exists()) { - // don't add dirs to classpath, especially if they don't exist - return false // groovy "continue" in .any closure - } - def itPath = it.toString() - if (itPath.startsWith("${jalviewDirAbsolutePath}/")) { - // make relative path - itPath = itPath.substring(jalviewDirAbsolutePath.length()+1) - } - if (alreadyAddedLibPath.get(itPath)) { - //println("Not adding duplicate entry "+itPath) - } else { - //println("Adding entry "+itPath) - cp.entries += new Library(fileReference(itPath)) - alreadyAddedLibPath.put(itPath, true) - } - } - - sourceSets.test.compileClasspath.findAll { it.name.endsWith(".jar") }.any { - //no longer want to add outputDir as eclipse is using its own output dir in bin/main - if (it.isDirectory() || ! it.exists()) { - // don't add dirs to classpath - return false // groovy "continue" in .any closure - } - - def itPath = it.toString() - if (itPath.startsWith("${jalviewDirAbsolutePath}/")) { - itPath = itPath.substring(jalviewDirAbsolutePath.length()+1) - } - if (alreadyAddedLibPath.get(itPath)) { - // don't duplicate - } else { - def lib = new Library(fileReference(itPath)) - lib.entryAttributes["test"] = "true" - cp.entries += lib - alreadyAddedLibPath.put(itPath, true) - } - } - - } // whenMerged - - } // file - - containers 'org.eclipse.buildship.core.gradleclasspathcontainer' - - } // classpath - - jdt { - // for the IDE, use java 11 compatibility - sourceCompatibility = compile_source_compatibility - targetCompatibility = compile_target_compatibility - javaRuntimeName = eclipseJavaRuntimeName - - // add in jalview project specific properties/preferences into eclipse core preferences - file { - withProperties { props -> - def jalview_prefs = new Properties() - def ins = new FileInputStream("${jalviewDirAbsolutePath}/${eclipse_extra_jdt_prefs_file}") - jalview_prefs.load(ins) - ins.close() - jalview_prefs.forEach { t, v -> - if (props.getAt(t) == null) { - props.putAt(t, v) - } - } - // codestyle file -- overrides previous formatter prefs - def csFile = file("${jalviewDirAbsolutePath}/${eclipse_codestyle_file}") - if (csFile.exists()) { - XmlParser parser = new XmlParser() - def profiles = parser.parse(csFile) - def profile = profiles.'profile'.find { p -> (p.'@kind' == "CodeFormatterProfile" && p.'@name' == "Jalview") } - if (profile != null) { - profile.'setting'.each { s -> - def id = s.'@id' - def value = s.'@value' - if (id != null && value != null) { - props.putAt(id, value) - } - } - } - } - } - } - - } // jdt - - if (IN_ECLIPSE) { - // Don't want these to be activated if in headless build - synchronizationTasks "eclipseSynchronizationTask" - //autoBuildTasks "eclipseAutoBuildTask" - - } -} - - -/* hack to change eclipse prefs in .settings files other than org.eclipse.jdt.core.prefs */ -// Class to allow updating arbitrary properties files -class PropertiesFile extends PropertiesPersistableConfigurationObject { - public PropertiesFile(PropertiesTransformer t) { super(t); } - @Override protected void load(Properties properties) { } - @Override protected void store(Properties properties) { } - @Override protected String getDefaultResourceName() { return ""; } - // This is necessary, because PropertiesPersistableConfigurationObject fails - // if no default properties file exists. - @Override public void loadDefaults() { load(new StringBufferInputStream("")); } -} - -// Task to update arbitrary properties files (set outputFile) -class PropertiesFileTask extends PropertiesGeneratorTask { - private final PropertiesFileContentMerger file; - public PropertiesFileTask() { file = new PropertiesFileContentMerger(getTransformer()); } - protected PropertiesFile create() { return new PropertiesFile(getTransformer()); } - protected void configure(PropertiesFile props) { - file.getBeforeMerged().execute(props); file.getWhenMerged().execute(props); - } - public void file(Closure closure) { ConfigureUtil.configure(closure, file); } -} - -task eclipseUIPreferences(type: PropertiesFileTask) { - description = "Generate Eclipse additional settings" - def filename = "org.eclipse.jdt.ui.prefs" - outputFile = "$projectDir/.settings/${filename}" as File - file { - withProperties { - it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String) + /* test { + java { + srcDirs testSourceDir + outputDir = file(testClassesDir) } - } -} -task eclipseGroovyCorePreferences(type: PropertiesFileTask) { - description = "Generate Eclipse additional settings" - def filename = "org.eclipse.jdt.groovy.core.prefs" - outputFile = "$projectDir/.settings/${filename}" as File - file { - withProperties { - it.load new FileInputStream("$projectDir/utils/eclipse/${filename}" as String) + resources { + srcDirs = sourceSets.main.resources.srcDirs } - } -} - -task eclipseAllPreferences { - dependsOn eclipseJdt - dependsOn eclipseUIPreferences - dependsOn eclipseGroovyCorePreferences -} - -eclipseUIPreferences.mustRunAfter eclipseJdt -eclipseGroovyCorePreferences.mustRunAfter eclipseJdt - -/* end of eclipse preferences hack */ - - -// clover bits - - -task cleanClover { - doFirst { - delete cloverBuildDir - delete cloverReportDir - } -} - - -task cloverInstrJava(type: JavaExec) { - group = "Verification" - description = "Create clover instrumented source java files" - - dependsOn cleanClover - - inputs.files(sourceSets.main.allJava) - outputs.dir(cloverInstrDir) - - //classpath = fileTree(dir: "${jalviewDir}/${clover_lib_dir}", include: ["*.jar"]) - classpath = sourceSets.clover.compileClasspath - main = "com.atlassian.clover.CloverInstr" - - def argsList = [ - "--encoding", - "UTF-8", - "--initstring", - cloverDb, - "--destdir", - cloverInstrDir.getPath(), - ] - def srcFiles = sourceSets.main.allJava.files - argsList.addAll( - srcFiles.collect( - { file -> file.absolutePath } - ) - ) - args argsList.toArray() - - doFirst { - delete cloverInstrDir - println("Clover: About to instrument "+srcFiles.size() +" files") - } -} - - -task cloverInstrTests(type: JavaExec) { - group = "Verification" - description = "Create clover instrumented source test files" - - dependsOn cleanClover - - inputs.files(testDir) - outputs.dir(cloverTestInstrDir) - - classpath = sourceSets.clover.compileClasspath - main = "com.atlassian.clover.CloverInstr" - - def argsList = [ - "--encoding", - "UTF-8", - "--initstring", - cloverDb, - "--srcdir", - testDir, - "--destdir", - cloverTestInstrDir.getPath(), - ] - args argsList.toArray() - - doFirst { - delete cloverTestInstrDir - println("Clover: About to instrument test files") - } -} - - -task cloverInstr { - group = "Verification" - description = "Create clover instrumented all source files" - - dependsOn cloverInstrJava - dependsOn cloverInstrTests -} - - -cloverClasses.dependsOn cloverInstr - - -task cloverConsoleReport(type: JavaExec) { - group = "Verification" - description = "Creates clover console report" - - onlyIf { - file(cloverDb).exists() - } - - inputs.dir cloverClassesDir - - classpath = sourceSets.clover.runtimeClasspath - main = "com.atlassian.clover.reporters.console.ConsoleReporter" - - if (cloverreport_mem.length() > 0) { - maxHeapSize = cloverreport_mem - } - if (cloverreport_jvmargs.length() > 0) { - jvmArgs Arrays.asList(cloverreport_jvmargs.split(" ")) - } - - def argsList = [ - "--alwaysreport", - "--initstring", - cloverDb, - "--unittests" - ] - - args argsList.toArray() -} - - -task cloverHtmlReport(type: JavaExec) { - group = "Verification" - description = "Creates clover HTML report" - - onlyIf { - file(cloverDb).exists() - } - - def cloverHtmlDir = cloverReportDir - inputs.dir cloverClassesDir - outputs.dir cloverHtmlDir - - classpath = sourceSets.clover.runtimeClasspath - main = "com.atlassian.clover.reporters.html.HtmlReporter" - - if (cloverreport_mem.length() > 0) { - maxHeapSize = cloverreport_mem - } - if (cloverreport_jvmargs.length() > 0) { - jvmArgs Arrays.asList(cloverreport_jvmargs.split(" ")) - } - def argsList = [ - "--alwaysreport", - "--initstring", - cloverDb, - "--outputdir", - cloverHtmlDir - ] - - if (cloverreport_html_options.length() > 0) { - argsList += cloverreport_html_options.split(" ") - } - - args argsList.toArray() -} - - -task cloverXmlReport(type: JavaExec) { - group = "Verification" - description = "Creates clover XML report" - - onlyIf { - file(cloverDb).exists() - } - - def cloverXmlFile = "${cloverReportDir}/clover.xml" - inputs.dir cloverClassesDir - outputs.file cloverXmlFile - - classpath = sourceSets.clover.runtimeClasspath - main = "com.atlassian.clover.reporters.xml.XMLReporter" - - if (cloverreport_mem.length() > 0) { - maxHeapSize = cloverreport_mem - } - if (cloverreport_jvmargs.length() > 0) { - jvmArgs Arrays.asList(cloverreport_jvmargs.split(" ")) - } - - def argsList = [ - "--alwaysreport", - "--initstring", - cloverDb, - "--outfile", - cloverXmlFile - ] - - if (cloverreport_xml_options.length() > 0) { - argsList += cloverreport_xml_options.split(" ") - } - - args argsList.toArray() -} - - -task cloverReport { - group = "Verification" - description = "Creates clover reports" - - dependsOn cloverXmlReport - dependsOn cloverHtmlReport -} - - -compileCloverJava { + compileClasspath = files( sourceSets.test.java.outputDir ) + compileClasspath += sourceSets.main.compileClasspath + compileClasspath += fileTree(dir: "${jalviewDir}/${utils_dir}/testnglibs", include: ["** REMOVE_THIS_GAP /*.jar"]) - doFirst { - sourceCompatibility = compile_source_compatibility - targetCompatibility = compile_target_compatibility - options.compilerArgs += additional_compiler_args - print ("Setting target compatibility to "+targetCompatibility+"\n") + runtimeClasspath = compileClasspath } - //classpath += configurations.cloverRuntime +*/ } -// end clover bits compileJava { - // JBP->BS should the print statement in doFirst refer to compile_target_compatibility ? sourceCompatibility = compile_source_compatibility targetCompatibility = compile_target_compatibility - options.compilerArgs += additional_compiler_args - options.encoding = "UTF-8" + options.compilerArgs = additional_compiler_args doFirst { print ("Setting target compatibility to "+compile_target_compatibility+"\n") } - } compileTestJava { - sourceCompatibility = compile_source_compatibility - targetCompatibility = compile_target_compatibility - options.compilerArgs += additional_compiler_args doFirst { + sourceCompatibility = compile_source_compatibility + targetCompatibility = compile_target_compatibility + options.compilerArgs = additional_compiler_args print ("Setting target compatibility to "+targetCompatibility+"\n") } } @@ -1091,7 +223,6 @@ clean { cleanTest { - dependsOn cleanClover doFirst { delete sourceSets.test.java.outputDir } @@ -1100,89 +231,11 @@ cleanTest { // format is a string like date.format("dd MMMM yyyy") def getDate(format) { + def date = new Date() return date.format(format) } -def convertMdToHtml (FileTree mdFiles, File cssFile) { - MutableDataSet options = new MutableDataSet() - - def extensions = new ArrayList<>() - extensions.add(AnchorLinkExtension.create()) - extensions.add(AutolinkExtension.create()) - extensions.add(StrikethroughExtension.create()) - extensions.add(TaskListExtension.create()) - extensions.add(TablesExtension.create()) - extensions.add(TocExtension.create()) - - options.set(Parser.EXTENSIONS, extensions) - - // set GFM table parsing options - options.set(TablesExtension.WITH_CAPTION, false) - options.set(TablesExtension.COLUMN_SPANS, false) - options.set(TablesExtension.MIN_HEADER_ROWS, 1) - options.set(TablesExtension.MAX_HEADER_ROWS, 1) - options.set(TablesExtension.APPEND_MISSING_COLUMNS, true) - options.set(TablesExtension.DISCARD_EXTRA_COLUMNS, true) - options.set(TablesExtension.HEADER_SEPARATOR_COLUMN_MATCH, true) - // GFM anchor links - options.set(AnchorLinkExtension.ANCHORLINKS_SET_ID, false) - options.set(AnchorLinkExtension.ANCHORLINKS_ANCHOR_CLASS, "anchor") - options.set(AnchorLinkExtension.ANCHORLINKS_SET_NAME, true) - options.set(AnchorLinkExtension.ANCHORLINKS_TEXT_PREFIX, "") - - Parser parser = Parser.builder(options).build() - HtmlRenderer renderer = HtmlRenderer.builder(options).build() - - mdFiles.each { mdFile -> - // add table of contents - def mdText = "[TOC]\n"+mdFile.text - - // grab the first top-level title - def title = null - def titleRegex = /(?m)^#(\s+|([^#]))(.*)/ - def matcher = mdText =~ titleRegex - if (matcher.size() > 0) { - // matcher[0][2] is the first character of the title if there wasn't any whitespace after the # - title = (matcher[0][2] != null ? matcher[0][2] : "")+matcher[0][3] - } - // or use the filename if none found - if (title == null) { - title = mdFile.getName() - } - - Node document = parser.parse(mdText) - String htmlBody = renderer.render(document) - def htmlText = ''' - - - - - - -''' - htmlText += ((title != null) ? " ${title}" : '' ) - htmlText += ''' - -''' - htmlText += ((cssFile != null) ? cssFile.text : '') - htmlText += ''' - -''' - htmlText += htmlBody - htmlText += ''' - - -''' - - def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html") - def htmlFile = file(htmlFilePath) - println("Creating ${htmlFilePath}") - htmlFile.text = htmlText - } -} - - task copyDocs(type: Copy) { def inputDir = "${jalviewDir}/${doc_dir}" def outputDir = "${docBuildDir}/${doc_dir}" @@ -1213,235 +266,6 @@ task copyDocs(type: Copy) { } -task convertMdFiles { - dependsOn copyDocs - def mdFiles = fileTree(dir: docBuildDir, include: "**/*.md") - def cssFile = file("${jalviewDir}/${flexmark_css}") - - doLast { - convertMdToHtml(mdFiles, cssFile) - } - - inputs.files(mdFiles) - inputs.file(cssFile) - - def htmlFiles = [] - mdFiles.each { mdFile -> - def htmlFilePath = mdFile.getPath().replaceAll(/\..*?$/, ".html") - htmlFiles.add(file(htmlFilePath)) - } - outputs.files(htmlFiles) -} - - -def hugoTemplateSubstitutions(String input, Map extras=null) { - def replacements = [ - DATE: getDate("yyyy-MM-dd"), - CHANNEL: propertiesChannelName, - APPLICATION_NAME: applicationName, - GIT_HASH: gitHash, - GIT_BRANCH: gitBranch, - VERSION: JALVIEW_VERSION, - JAVA_VERSION: JAVA_VERSION, - VERSION_UNDERSCORES: JALVIEW_VERSION_UNDERSCORES, - DRAFT: "false", - JVL_HEADER: "" - ] - def output = input - if (extras != null) { - extras.each{ k, v -> - output = output.replaceAll("__${k}__", ((v == null)?"":v)) - } - } - replacements.each{ k, v -> - output = output.replaceAll("__${k}__", ((v == null)?"":v)) - } - return output -} - -def mdFileComponents(File mdFile, def dateOnly=false) { - def map = [:] - def content = "" - if (mdFile.exists()) { - def inFrontMatter = false - def firstLine = true - mdFile.eachLine { line -> - if (line.matches("---")) { - def prev = inFrontMatter - inFrontMatter = firstLine - if (inFrontMatter != prev) - return false - } - if (inFrontMatter) { - def m = null - if (m = line =~ /^date:\s*(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/) { - map["date"] = new Date().parse("yyyy-MM-dd HH:mm:ss", m[0][1]) - } else if (m = line =~ /^date:\s*(\d{4}-\d{2}-\d{2})/) { - map["date"] = new Date().parse("yyyy-MM-dd", m[0][1]) - } else if (m = line =~ /^channel:\s*(\S+)/) { - map["channel"] = m[0][1] - } else if (m = line =~ /^version:\s*(\S+)/) { - map["version"] = m[0][1] - } else if (m = line =~ /^\s*([^:]+)\s*:\s*(\S.*)/) { - map[ m[0][1] ] = m[0][2] - } - if (dateOnly && map["date"] != null) { - return false - } - } else { - if (dateOnly) - return false - content += line+"\n" - } - firstLine = false - } - } - return dateOnly ? map["date"] : [map, content] -} - -task hugoTemplates { - group "website" - description "Create partially populated md pages for hugo website build" - - def hugoTemplatesDir = file("${jalviewDir}/${hugo_templates_dir}") - def hugoBuildDir = "${jalviewDir}/${hugo_build_dir}" - def templateFiles = fileTree(dir: hugoTemplatesDir) - def releaseMdFile = file("${jalviewDir}/${releases_dir}/release-${JALVIEW_VERSION_UNDERSCORES}.md") - def whatsnewMdFile = file("${jalviewDir}/${whatsnew_dir}/whatsnew-${JALVIEW_VERSION_UNDERSCORES}.md") - def oldJvlFile = file("${jalviewDir}/${hugo_old_jvl}") - def jalviewjsFile = file("${jalviewDir}/${hugo_jalviewjs}") - - doFirst { - // specific release template for version archive - def changes = "" - def whatsnew = null - def givenDate = null - def givenChannel = null - def givenVersion = null - if (CHANNEL == "RELEASE") { - def (map, content) = mdFileComponents(releaseMdFile) - givenDate = map.date - givenChannel = map.channel - givenVersion = map.version - changes = content - if (givenVersion != null && givenVersion != JALVIEW_VERSION) { - throw new GradleException("'version' header (${givenVersion}) found in ${releaseMdFile} does not match JALVIEW_VERSION (${JALVIEW_VERSION})") - } - - if (whatsnewMdFile.exists()) - whatsnew = whatsnewMdFile.text - } - - def oldJvl = oldJvlFile.exists() ? oldJvlFile.collect{it} : [] - def jalviewjsLink = jalviewjsFile.exists() ? jalviewjsFile.collect{it} : [] - - def changesHugo = null - if (changes != null) { - changesHugo = '
\n\n' - def inSection = false - changes.eachLine { line -> - def m = null - if (m = line =~ /^##([^#].*)$/) { - if (inSection) { - changesHugo += "
\n\n" - } - def section = m[0][1].trim() - section = section.toLowerCase() - section = section.replaceAll(/ +/, "_") - section = section.replaceAll(/[^a-z0-9_\-]/, "") - changesHugo += "
\n\n" - inSection = true - } else if (m = line =~ /^(\s*-\s*)(.*?)()?\s*$/) { - def comment = m[0][2].trim() - if (comment != "") { - comment = comment.replaceAll('"', """) - def issuekeys = [] - comment.eachMatch(/JAL-\d+/) { jal -> issuekeys += jal } - def newline = m[0][1] - if (comment.trim() != "") - newline += "{{}}${comment}{{}} " - newline += m[0][3].trim() - if (issuekeys.size() > 0) - newline += " {{< jal issue=\"${issuekeys.join(",")}\" alt=\"${comment}\" >}}" - if (m[0][4] != null) - newline += m[0][4] - line = newline - } - } - changesHugo += line+"\n" - } - if (inSection) { - changesHugo += "\n
\n\n" - } - changesHugo += '' - } - - templateFiles.each{ templateFile -> - def newFileName = string(hugoTemplateSubstitutions(templateFile.getName())) - def relPath = hugoTemplatesDir.toPath().relativize(templateFile.toPath()).getParent() - def newRelPathName = hugoTemplateSubstitutions( relPath.toString() ) - - def outPathName = string("${hugoBuildDir}/$newRelPathName") - - copy { - from templateFile - rename(templateFile.getName(), newFileName) - into outPathName - } - - def newFile = file("${outPathName}/${newFileName}".toString()) - def content = newFile.text - newFile.text = hugoTemplateSubstitutions(content, - [ - WHATSNEW: whatsnew, - CHANGES: changesHugo, - DATE: givenDate == null ? "" : givenDate.format("yyyy-MM-dd"), - DRAFT: givenDate == null ? "true" : "false", - JALVIEWJSLINK: jalviewjsLink.contains(JALVIEW_VERSION) ? "true" : "false", - JVL_HEADER: oldJvl.contains(JALVIEW_VERSION) ? "jvl: true" : "" - ] - ) - } - - } - - inputs.file(oldJvlFile) - inputs.dir(hugoTemplatesDir) - inputs.property("JALVIEW_VERSION", { JALVIEW_VERSION }) - inputs.property("CHANNEL", { CHANNEL }) -} - -def getMdDate(File mdFile) { - return mdFileComponents(mdFile, true) -} - -def getMdSections(String content) { - def sections = [:] - def sectionContent = "" - def sectionName = null - content.eachLine { line -> - def m = null - if (m = line =~ /^##([^#].*)$/) { - if (sectionName != null) { - sections[sectionName] = sectionContent - sectionName = null - sectionContent = "" - } - sectionName = m[0][1].trim() - sectionName = sectionName.toLowerCase() - sectionName = sectionName.replaceAll(/ +/, "_") - sectionName = sectionName.replaceAll(/[^a-z0-9_\-]/, "") - } else if (sectionName != null) { - sectionContent += line+"\n" - } - } - if (sectionContent != null) { - sections[sectionName] = sectionContent - } - return sections -} - - task copyHelp(type: Copy) { def inputDir = helpSourceDir def outputDir = "${helpBuildDir}/${help_dir}" @@ -1476,7 +300,6 @@ task copyHelp(type: Copy) { outputs.dir(outputDir) } - task releasesTemplates { group "help" description "Recreate whatsNew.html and releases.html from markdown files and templates in help" @@ -1491,6 +314,7 @@ task releasesTemplates { def whatsnewMdDir = "${jalviewDir}/${whatsnew_dir}" doFirst { + def JALVIEW_VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_") def releaseMdFile = file("${releasesMdDir}/release-${JALVIEW_VERSION_UNDERSCORES}.md") def whatsnewMdFile = file("${whatsnewMdDir}/whatsnew-${JALVIEW_VERSION_UNDERSCORES}.md") @@ -1505,7 +329,7 @@ task releasesTemplates { def releaseFiles = fileTree(dir: releasesMdDir, include: "release-*.md") def releaseFilesDates = releaseFiles.collectEntries { - [(it): getMdDate(it)] + [(it): getDate("")] } releaseFiles = releaseFiles.sort { a,b -> releaseFilesDates[a].compareTo(releaseFilesDates[b]) } @@ -1513,96 +337,13 @@ task releasesTemplates { def m = releasesTemplate =~ /(?s)__VERSION_LOOP_START__(.*)__VERSION_LOOP_END__/ def versionTemplate = m[0][1] - MutableDataSet options = new MutableDataSet() - - def extensions = new ArrayList<>() - options.set(Parser.EXTENSIONS, extensions) - options.set(Parser.HTML_BLOCK_COMMENT_ONLY_FULL_LINE, true) - - Parser parser = Parser.builder(options).build() - HtmlRenderer renderer = HtmlRenderer.builder(options).build() - - def actualVersions = releaseFiles.collect { rf -> - def (rfMap, rfContent) = mdFileComponents(rf) - return rfMap.version - } def versionsHtml = "" def linkedVersions = [] - releaseFiles.reverse().each { rFile -> - def (rMap, rContent) = mdFileComponents(rFile) - - def versionLink = "" - def partialVersion = "" - def firstPart = true - rMap.version.split("\\.").each { part -> - def displayPart = ( firstPart ? "" : "." ) + part - partialVersion += displayPart - if ( - linkedVersions.contains(partialVersion) - || ( actualVersions.contains(partialVersion) && partialVersion != rMap.version ) - ) { - versionLink += displayPart - } else { - versionLink += "${displayPart}" - linkedVersions += partialVersion - } - firstPart = false - } - def displayDate = releaseFilesDates[rFile].format("dd/MM/yyyy") - - def lm = null - def rContentProcessed = "" - rContent.eachLine { line -> - if (lm = line =~ /^(\s*-)(\s*)(.*)$/) { - line = "${lm[0][1]}${lm[0][3]}${lm[0][2]}" - } else if (lm = line =~ /^###([^#]+.*)$/) { - line = "_${lm[0][1].trim()}_" - } - rContentProcessed += line + "\n" - } - - def rContentSections = getMdSections(rContentProcessed) - def rVersion = versionTemplate - if (rVersion != "") { - def rNewFeatures = rContentSections["new_features"] - def rIssuesResolved = rContentSections["issues_resolved"] - Node newFeaturesNode = parser.parse(rNewFeatures) - String newFeaturesHtml = renderer.render(newFeaturesNode) - Node issuesResolvedNode = parser.parse(rIssuesResolved) - String issuesResolvedHtml = renderer.render(issuesResolvedNode) - rVersion = hugoTemplateSubstitutions(rVersion, - [ - VERSION: rMap.version, - VERSION_LINK: versionLink, - DISPLAY_DATE: displayDate, - NEW_FEATURES: newFeaturesHtml, - ISSUES_RESOLVED: issuesResolvedHtml - ] - ) - versionsHtml += rVersion - } - } releasesTemplate = releasesTemplate.replaceAll("(?s)__VERSION_LOOP_START__.*__VERSION_LOOP_END__", versionsHtml) - releasesTemplate = hugoTemplateSubstitutions(releasesTemplate) releasesHtmlFile.text = releasesTemplate - if (whatsnewMdFile.exists()) { - def wnDisplayDate = releaseFilesDates[releaseMdFile] != null ? releaseFilesDates[releaseMdFile].format("dd MMMM yyyy") : "" - def whatsnewMd = hugoTemplateSubstitutions(whatsnewMdFile.text) - Node whatsnewNode = parser.parse(whatsnewMd) - String whatsnewHtml = renderer.render(whatsnewNode) - whatsnewHtml = whatsnewTemplateFile.text.replaceAll("__WHATS_NEW__", whatsnewHtml) - whatsnewHtmlFile.text = hugoTemplateSubstitutions(whatsnewHtml, - [ - VERSION: JALVIEW_VERSION, - DISPLAY_DATE: wnDisplayDate - ] - ) - } else if (gradle.taskGraph.hasTask(":linkCheck")) { - whatsnewHtmlFile.text = "Development build " + getDate("yyyy-MM-dd HH:mm:ss") - } - + whatsnewHtmlFile.text = "Debian build " + getDate("yyyy-MM-dd HH:mm:ss") } inputs.file(releasesTemplateFile) @@ -1613,7 +354,6 @@ task releasesTemplates { outputs.file(whatsnewHtmlFile) } - task copyResources(type: Copy) { group = "build" description = "Copy (and make text substitutions in) the resources dir to the build area" @@ -1653,44 +393,22 @@ task copyChannelResources(type: Copy) { def inputDir = "${channelDir}/${resource_dir}" def outputDir = resourcesBuildDir - from(inputDir) { - include(channel_props) - filter(ReplaceTokens, - beginToken: '__', - endToken: '__', - tokens: [ - 'SUFFIX': channelSuffix - ] - ) - } - from(inputDir) { - exclude(channel_props) - } + from inputDir into outputDir inputs.dir(inputDir) outputs.dir(outputDir) } -task createBuildProperties(type: WriteProperties) { - dependsOn copyResources - group = "build" - description = "Create the ${buildProperties} file" - - inputs.dir(sourceDir) - inputs.dir(resourcesBuildDir) - outputFile (buildProperties) - // taking time specific comment out to allow better incremental builds - comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd HH:mm:ss") - //comment "--Jalview Build Details--\n"+getDate("yyyy-MM-dd") - property "BUILD_DATE", getDate("HH:mm:ss dd MMMM yyyy") - property "VERSION", JALVIEW_VERSION - property "INSTALLATION", INSTALLATION+" git-commit:"+gitHash+" ["+gitBranch+"]" - property "JAVA_COMPILE_VERSION", JAVA_INTEGER_VERSION - if (getdownSetAppBaseProperty) { - property "GETDOWNAPPBASE", getdownAppBase - property "GETDOWNAPPDISTDIR", getdownAppDistDir - } +task createBuildProperties(type: Copy) { + // using the build_properties already included in the source tarball + def inputFile = "build_properties" + def outputFile = buildProperties + from inputFile + into file(outputFile).getParent() + rename(file(inputFile).getName(), file(outputFile).getName()) + + inputs.file(inputFile) outputs.file(outputFile) } @@ -1725,123 +443,31 @@ task prepare { dependsOn copyDocs dependsOn copyHelp dependsOn releasesTemplates - dependsOn convertMdFiles dependsOn buildIndices } compileJava.dependsOn prepare run.dependsOn compileJava -compileTestJava.dependsOn compileJava - +//run.dependsOn prepare +//testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir test { - group = "Verification" - description = "Runs all testTaskN tasks)" - - if (useClover) { - dependsOn cloverClasses - } else { //? - dependsOn testClasses - } - - // not running tests in this task - exclude "**/*" -} -/* testTask0 is the main test task */ -task testTask0(type: Test) { - group = "Verification" - description = "The main test task. Runs all non-testTaskN-labelled tests (unless excluded)" - useTestNG() { - includeGroups testng_groups.split(",") - excludeGroups testng_excluded_groups.split(",") - tasks.withType(Test).matching {it.name.startsWith("testTask") && it.name != name}.all {t -> excludeGroups t.name} - preserveOrder true - useDefaultListeners=true - } -} - -/* separated tests */ -task testTask1(type: Test) { - group = "Verification" - description = "Tests that need to be isolated from the main test run" - useTestNG() { - includeGroups name - excludeGroups testng_excluded_groups.split(",") - preserveOrder true - useDefaultListeners=true - } -} + dependsOn prepare + dependsOn compileJava //? -/* insert more testTaskNs here -- change N to next digit or other string */ -/* -task testTaskN(type: Test) { - group = "Verification" - description = "Tests that need to be isolated from the main test run" useTestNG() { - includeGroups name - excludeGroups testng_excluded_groups.split(",") + includeGroups testng_groups + excludeGroups testng_excluded_groups preserveOrder true useDefaultListeners=true } -} -*/ - -/* - * adapted from https://medium.com/@wasyl/pretty-tests-summary-in-gradle-744804dd676c - * to summarise test results from all Test tasks - */ -/* START of test tasks results summary */ -import groovy.time.TimeCategory -import org.gradle.api.tasks.testing.logging.TestExceptionFormat -import org.gradle.api.tasks.testing.logging.TestLogEvent -rootProject.ext.testsResults = [] // Container for tests summaries - -tasks.withType(Test).matching {t -> t.getName().startsWith("testTask")}.all { testTask -> - - // from original test task - if (useClover) { - dependsOn cloverClasses - } else { //? - dependsOn testClasses //? - } - - // run main tests first - if (!testTask.name.equals("testTask0")) - testTask.mustRunAfter "testTask0" - - testTask.testLogging { logging -> - events TestLogEvent.FAILED -// TestLogEvent.SKIPPED, -// TestLogEvent.STANDARD_OUT, -// TestLogEvent.STANDARD_ERROR - - exceptionFormat TestExceptionFormat.FULL - showExceptions true - showCauses true - showStackTraces true - - info.events = [ TestLogEvent.FAILED ] - } - - - - ignoreFailures = true // Always try to run all tests for all modules - - afterSuite { desc, result -> - if (desc.parent) - return // Only summarize results for whole modules - - def resultsInfo = [testTask.project.name, testTask.name, result, TimeCategory.minus(new Date(result.endTime), new Date(result.startTime)), testTask.reports.html.entryPoint] - - rootProject.ext.testsResults.add(resultsInfo) - } - // from original test task maxHeapSize = "1024m" workingDir = jalviewDir + //systemProperties 'clover.jar' System.properties.clover.jar def testLaf = project.findProperty("test_laf") if (testLaf != null) { println("Setting Test LaF to '${testLaf}'") @@ -1857,143 +483,8 @@ tasks.withType(Test).matching {t -> t.getName().startsWith("testTask")}.all { te jvmArgs += additional_compiler_args doFirst { - // this is not perfect yet -- we should only add the commandLineIncludePatterns to the - // testTasks that include the tests, and exclude all from the others. - // get --test argument - filter.commandLineIncludePatterns = test.filter.commandLineIncludePatterns - // do something with testTask.getCandidateClassFiles() to see if the test should silently finish because of the - // commandLineIncludePatterns not matching anything. Instead we are doing setFailOnNoMatchingTests(false) below - - - if (useClover) { - println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover") - } - } - - - /* don't fail on no matching tests (so --tests will run across all testTasks) */ - testTask.filter.setFailOnNoMatchingTests(false) - - /* ensure the "test" task dependsOn all the testTasks */ - test.dependsOn testTask -} - -gradle.buildFinished { - def allResults = rootProject.ext.testsResults - - if (!allResults.isEmpty()) { - printResults allResults - allResults.each {r -> - if (r[2].resultType == TestResult.ResultType.FAILURE) - throw new GradleException("Failed tests!") - } - } -} - -private static String colString(styler, col, colour, text) { - return col?"${styler[colour](text)}":text -} - -private static String getSummaryLine(s, pn, tn, rt, rc, rs, rf, rsk, t, col) { - def colour = 'black' - def text = rt - def nocol = false - if (rc == 0) { - text = "-----" - nocol = true - } else { - switch(rt) { - case TestResult.ResultType.SUCCESS: - colour = 'green' - break; - case TestResult.ResultType.FAILURE: - colour = 'red' - break; - default: - nocol = true - break; - } } - StringBuilder sb = new StringBuilder() - sb.append("${pn}") - if (tn != null) - sb.append(":${tn}") - sb.append(" results: ") - sb.append(colString(s, col && !nocol, colour, text)) - sb.append(" (") - sb.append("${rc} tests, ") - sb.append(colString(s, col && rs > 0, 'green', rs)) - sb.append(" successes, ") - sb.append(colString(s, col && rf > 0, 'red', rf)) - sb.append(" failures, ") - sb.append("${rsk} skipped) in ${t}") - return sb.toString() -} - -private static void printResults(allResults) { - - // styler from https://stackoverflow.com/a/56139852 - def styler = 'black red green yellow blue magenta cyan white'.split().toList().withIndex(30).collectEntries { key, val -> [(key) : { "\033[${val}m${it}\033[0m" }] } - - def maxLength = 0 - def failedTests = false - def summaryLines = [] - def totalcount = 0 - def totalsuccess = 0 - def totalfail = 0 - def totalskip = 0 - def totaltime = TimeCategory.getSeconds(0) - // sort on project name then task name - allResults.sort {a, b -> a[0] == b[0]? a[1]<=>b[1]:a[0] <=> b[0]}.each { - def projectName = it[0] - def taskName = it[1] - def result = it[2] - def time = it[3] - def report = it[4] - def summaryCol = getSummaryLine(styler, projectName, taskName, result.resultType, result.testCount, result.successfulTestCount, result.failedTestCount, result.skippedTestCount, time, true) - def summaryPlain = getSummaryLine(styler, projectName, taskName, result.resultType, result.testCount, result.successfulTestCount, result.failedTestCount, result.skippedTestCount, time, false) - def reportLine = "Report file: ${report}" - def ls = summaryPlain.length() - def lr = reportLine.length() - def m = [ls, lr].max() - if (m > maxLength) - maxLength = m - def info = [ls, summaryCol, reportLine] - summaryLines.add(info) - failedTests |= result.resultType == TestResult.ResultType.FAILURE - totalcount += result.testCount - totalsuccess += result.successfulTestCount - totalfail += result.failedTestCount - totalskip += result.skippedTestCount - totaltime += time - } - def totalSummaryCol = getSummaryLine(styler, "OVERALL", "", failedTests?TestResult.ResultType.FAILURE:TestResult.ResultType.SUCCESS, totalcount, totalsuccess, totalfail, totalskip, totaltime, true) - def totalSummaryPlain = getSummaryLine(styler, "OVERALL", "", failedTests?TestResult.ResultType.FAILURE:TestResult.ResultType.SUCCESS, totalcount, totalsuccess, totalfail, totalskip, totaltime, false) - def tls = totalSummaryPlain.length() - if (tls > maxLength) - maxLength = tls - def info = [tls, totalSummaryCol, null] - summaryLines.add(info) - - def allSummaries = [] - for(sInfo : summaryLines) { - def ls = sInfo[0] - def summary = sInfo[1] - def report = sInfo[2] - - StringBuilder sb = new StringBuilder() - sb.append("│" + summary + " " * (maxLength - ls) + "│") - if (report != null) { - sb.append("\n│" + report + " " * (maxLength - report.length()) + "│") - } - allSummaries += sb.toString() - } - - println "┌${"${"─" * maxLength}"}┐" - println allSummaries.join("\n├${"${"─" * maxLength}"}┤\n") - println "└${"${"─" * maxLength}"}┘" } -/* END of test tasks results summary */ task compileLinkCheck(type: JavaCompile) { @@ -2052,7 +543,7 @@ jar { manifest { attributes "Main-Class": main_class, "Permissions": "all-permissions", - "Application-Name": applicationName, + "Application-Name": install4jApplicationName, "Codebase": application_codebase, "Implementation-Version": JALVIEW_VERSION } @@ -2060,8 +551,6 @@ jar { def outputDir = "${jalviewDir}/${package_dir}" destinationDirectory = file(outputDir) archiveFileName = rootProject.name+".jar" - duplicatesStrategy "EXCLUDE" - exclude "cache*/**" exclude "*.jar" @@ -2073,2137 +562,7 @@ jar { sourceSets.main.resources.srcDirs.each{ dir -> inputs.dir(dir) } - outputs.file("${outputDir}/${archiveFileName}") -} - - -task copyJars(type: Copy) { - from fileTree(dir: classesDir, include: "**/*.jar").files - into "${jalviewDir}/${package_dir}" -} - - -// doing a Sync instead of Copy as Copy doesn't deal with "outputs" very well -task syncJars(type: Sync) { - dependsOn jar - from fileTree(dir: "${jalviewDir}/${libDistDir}", include: "**/*.jar").files - into "${jalviewDir}/${package_dir}" - preserve { - include jar.archiveFileName.getOrNull() - } -} - - -task makeDist { - group = "build" - description = "Put all required libraries in dist" - // order of "cleanPackageDir", "copyJars", "jar" important! - jar.mustRunAfter cleanPackageDir - syncJars.mustRunAfter cleanPackageDir - dependsOn cleanPackageDir - dependsOn syncJars - dependsOn jar - outputs.dir("${jalviewDir}/${package_dir}") -} - - -task cleanDist { - dependsOn cleanPackageDir - dependsOn cleanTest - dependsOn clean -} - - -shadowJar { - group = "distribution" - description = "Create a single jar file with all dependency libraries merged. Can be run with java -jar" - if (buildDist) { - dependsOn makeDist - } - from ("${jalviewDir}/${libDistDir}") { - include("*.jar") - } - manifest { - attributes "Implementation-Version": JALVIEW_VERSION, - "Application-Name": applicationName - } - - duplicatesStrategy "INCLUDE" - - mainClassName = shadow_jar_main_class - mergeServiceFiles() - classifier = "all-"+JALVIEW_VERSION+"-j"+JAVA_VERSION - minimize() -} - -task getdownImagesCopy() { - inputs.dir getdownImagesDir - outputs.dir getdownImagesBuildDir - - doFirst { - copy { - from(getdownImagesDir) { - include("*getdown*.png") - } - into getdownImagesBuildDir - } - } -} - -task getdownImagesProcess() { - dependsOn getdownImagesCopy - - doFirst { - if (backgroundImageText) { - if (convertBinary == null) { - throw new StopExecutionException("No ImageMagick convert binary installed at '${convertBinaryExpectedLocation}'") - } - if (!project.hasProperty("getdown_background_image_text_suffix_cmd")) { - throw new StopExecutionException("No property 'getdown_background_image_text_suffix_cmd' defined. See channel_gradle.properties for channel ${CHANNEL}") - } - fileTree(dir: getdownImagesBuildDir, include: "*background*.png").getFiles().each { file -> - exec { - executable convertBinary - args = [ - file.getPath(), - '-font', getdown_background_image_text_font, - '-fill', getdown_background_image_text_colour, - '-draw', sprintf(getdown_background_image_text_suffix_cmd, channelSuffix), - '-draw', sprintf(getdown_background_image_text_commit_cmd, "git-commit: ${gitHash}"), - '-draw', sprintf(getdown_background_image_text_date_cmd, getDate("yyyy-MM-dd HH:mm:ss")), - file.getPath() - ] - } - } - } - } -} - -task getdownImages() { - dependsOn getdownImagesProcess -} - -task getdownWebsite() { - group = "distribution" - description = "Create the getdown minimal app folder, and website folder for this version of jalview. Website folder also used for offline app installer" - - dependsOn getdownImages - if (buildDist) { - dependsOn makeDist - } - - def getdownWebsiteResourceFilenames = [] - def getdownResourceDir = getdownResourceDir - def getdownResourceFilenames = [] - - doFirst { - // clean the getdown website and files dir before creating getdown folders - delete getdownAppBaseDir - delete getdownFilesDir - - copy { - from buildProperties - rename(file(buildProperties).getName(), getdown_build_properties) - into getdownAppDir - } - getdownWebsiteResourceFilenames += "${getdownAppDistDir}/${getdown_build_properties}" - - copy { - from channelPropsFile - filter(ReplaceTokens, - beginToken: '__', - endToken: '__', - tokens: [ - 'SUFFIX': channelSuffix - ] - ) - into getdownAppBaseDir - } - getdownWebsiteResourceFilenames += file(channelPropsFile).getName() - - // set some getdownTxt_ properties then go through all properties looking for getdownTxt_... - def props = project.properties.sort { it.key } - if (getdownAltJavaMinVersion != null && getdownAltJavaMinVersion.length() > 0) { - props.put("getdown_txt_java_min_version", getdownAltJavaMinVersion) - } - if (getdownAltJavaMaxVersion != null && getdownAltJavaMaxVersion.length() > 0) { - props.put("getdown_txt_java_max_version", getdownAltJavaMaxVersion) - } - if (getdownAltMultiJavaLocation != null && getdownAltMultiJavaLocation.length() > 0) { - props.put("getdown_txt_multi_java_location", getdownAltMultiJavaLocation) - } - if (getdownImagesBuildDir != null && file(getdownImagesBuildDir).exists()) { - props.put("getdown_txt_ui.background_image", "${getdownImagesBuildDir}/${getdown_background_image}") - props.put("getdown_txt_ui.instant_background_image", "${getdownImagesBuildDir}/${getdown_instant_background_image}") - props.put("getdown_txt_ui.error_background", "${getdownImagesBuildDir}/${getdown_error_background}") - props.put("getdown_txt_ui.progress_image", "${getdownImagesBuildDir}/${getdown_progress_image}") - props.put("getdown_txt_ui.icon", "${getdownImagesDir}/${getdown_icon}") - props.put("getdown_txt_ui.mac_dock_icon", "${getdownImagesDir}/${getdown_mac_dock_icon}") - } - - props.put("getdown_txt_title", jalview_name) - props.put("getdown_txt_ui.name", applicationName) - - // start with appbase - getdownTextLines += "appbase = ${getdownAppBase}" - props.each{ prop, val -> - if (prop.startsWith("getdown_txt_") && val != null) { - if (prop.startsWith("getdown_txt_multi_")) { - def key = prop.substring(18) - val.split(",").each{ v -> - def line = "${key} = ${v}" - getdownTextLines += line - } - } else { - // file values rationalised - if (val.indexOf('/') > -1 || prop.startsWith("getdown_txt_resource")) { - def r = null - if (val.indexOf('/') == 0) { - // absolute path - r = file(val) - } else if (val.indexOf('/') > 0) { - // relative path (relative to jalviewDir) - r = file( "${jalviewDir}/${val}" ) - } - if (r.exists()) { - val = "${getdown_resource_dir}/" + r.getName() - getdownWebsiteResourceFilenames += val - getdownResourceFilenames += r.getPath() - } - } - if (! prop.startsWith("getdown_txt_resource")) { - def line = prop.substring(12) + " = ${val}" - getdownTextLines += line - } - } - } - } - - getdownWebsiteResourceFilenames.each{ filename -> - getdownTextLines += "resource = ${filename}" - } - getdownResourceFilenames.each{ filename -> - copy { - from filename - into getdownResourceDir - } - } - - def getdownWrapperScripts = [ getdown_bash_wrapper_script, getdown_powershell_wrapper_script, getdown_batch_wrapper_script ] - getdownWrapperScripts.each{ script -> - def s = file( "${jalviewDir}/utils/getdown/${getdown_wrapper_script_dir}/${script}" ) - if (s.exists()) { - copy { - from s - into "${getdownAppBaseDir}/${getdown_wrapper_script_dir}" - } - getdownTextLines += "resource = ${getdown_wrapper_script_dir}/${script}" - } - } - - def codeFiles = [] - fileTree(file(package_dir)).each{ f -> - if (f.isDirectory()) { - def files = fileTree(dir: f, include: ["*"]).getFiles() - codeFiles += files - } else if (f.exists()) { - codeFiles += f - } - } - def jalviewJar = jar.archiveFileName.getOrNull() - // put jalview.jar first for CLASSPATH and .properties files reasons - codeFiles.sort{a, b -> ( a.getName() == jalviewJar ? -1 : ( b.getName() == jalviewJar ? 1 : a <=> b ) ) }.each{f -> - def name = f.getName() - def line = "code = ${getdownAppDistDir}/${name}" - getdownTextLines += line - copy { - from f.getPath() - into getdownAppDir - } - } - - // NOT USING MODULES YET, EVERYTHING SHOULD BE IN dist - /* - if (JAVA_VERSION.equals("11")) { - def j11libFiles = fileTree(dir: "${jalviewDir}/${j11libDir}", include: ["*.jar"]).getFiles() - j11libFiles.sort().each{f -> - def name = f.getName() - def line = "code = ${getdown_j11lib_dir}/${name}" - getdownTextLines += line - copy { - from f.getPath() - into getdownJ11libDir - } - } - } - */ - - // 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. - //getdownTextLines += "class = " + file(getdownLauncher).getName() - getdownTextLines += "resource = ${getdown_launcher_new}" - getdownTextLines += "class = ${main_class}" - // Not setting these properties in general so that getdownappbase and getdowndistdir will default to release version in jalview.bin.Cache - if (getdownSetAppBaseProperty) { - getdownTextLines += "jvmarg = -Dgetdowndistdir=${getdownAppDistDir}" - getdownTextLines += "jvmarg = -Dgetdownappbase=${getdownAppBase}" - } - - def getdownTxt = file("${getdownAppBaseDir}/getdown.txt") - getdownTxt.write(getdownTextLines.join("\n")) - - getdownLaunchJvl = getdown_launch_jvl_name + ( (jvlChannelName != null && jvlChannelName.length() > 0)?"-${jvlChannelName}":"" ) + ".jvl" - def launchJvl = file("${getdownAppBaseDir}/${getdownLaunchJvl}") - launchJvl.write("appbase=${getdownAppBase}") - - // files going into the getdown website dir: getdown-launcher.jar - copy { - from getdownLauncher - rename(file(getdownLauncher).getName(), getdown_launcher_new) - into getdownAppBaseDir - } - - // files going into the getdown website dir: getdown-launcher(-local).jar - copy { - from getdownLauncher - if (file(getdownLauncher).getName() != getdown_launcher) { - rename(file(getdownLauncher).getName(), getdown_launcher) - } - into getdownAppBaseDir - } - - // files going into the getdown website dir: ./install dir and files - if (! (CHANNEL.startsWith("ARCHIVE") || CHANNEL.startsWith("DEVELOP"))) { - copy { - from getdownTxt - from getdownLauncher - from "${getdownAppDir}/${getdown_build_properties}" - if (file(getdownLauncher).getName() != getdown_launcher) { - rename(file(getdownLauncher).getName(), getdown_launcher) - } - into getdownInstallDir - } - - // and make a copy in the getdown files dir (these are not downloaded by getdown) - copy { - from getdownInstallDir - into getdownFilesInstallDir - } - } - - // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties - copy { - from getdownTxt - from launchJvl - from getdownLauncher - from "${getdownAppBaseDir}/${getdown_build_properties}" - from "${getdownAppBaseDir}/${channel_props}" - if (file(getdownLauncher).getName() != getdown_launcher) { - rename(file(getdownLauncher).getName(), getdown_launcher) - } - into getdownFilesDir - } - - // and ./resource (not all downloaded by getdown) - copy { - from getdownResourceDir - into "${getdownFilesDir}/${getdown_resource_dir}" - } - } - - if (buildDist) { - inputs.dir("${jalviewDir}/${package_dir}") - } - outputs.dir(getdownAppBaseDir) - outputs.dir(getdownFilesDir) -} - - -// a helper task to allow getdown digest of any dir: `gradle getdownDigestDir -PDIGESTDIR=/path/to/my/random/getdown/dir -task getdownDigestDir(type: JavaExec) { - group "Help" - description "A task to run a getdown Digest on a dir with getdown.txt. Provide a DIGESTDIR property via -PDIGESTDIR=..." - - def digestDirPropertyName = "DIGESTDIR" - doFirst { - classpath = files(getdownLauncher) - def digestDir = findProperty(digestDirPropertyName) - if (digestDir == null) { - throw new GradleException("Must provide a DIGESTDIR value to produce an alternative getdown digest") - } - args digestDir - } - main = "com.threerings.getdown.tools.Digester" -} - - -task getdownDigest(type: JavaExec) { - group = "distribution" - description = "Digest the getdown website folder" - dependsOn getdownWebsite - doFirst { - classpath = files(getdownLauncher) - } - main = "com.threerings.getdown.tools.Digester" - args getdownAppBaseDir - inputs.dir(getdownAppBaseDir) - outputs.file("${getdownAppBaseDir}/digest2.txt") -} - - -task getdown() { - group = "distribution" - description = "Create the minimal and full getdown app folder for installers and website and create digest file" - dependsOn getdownDigest - doLast { - if (reportRsyncCommand) { - def fromDir = getdownAppBaseDir + (getdownAppBaseDir.endsWith('/')?'':'/') - def toDir = "${getdown_rsync_dest}/${getdownDir}" + (getdownDir.endsWith('/')?'':'/') - println "LIKELY RSYNC COMMAND:" - println "mkdir -p '$toDir'\nrsync -avh --delete '$fromDir' '$toDir'" - if (RUNRSYNC == "true") { - exec { - commandLine "mkdir", "-p", toDir - } - exec { - commandLine "rsync", "-avh", "--delete", fromDir, toDir - } - } - } - } -} - -task getdownArchiveBuild() { - group = "distribution" - description = "Put files in the archive dir to go on the website" - - dependsOn getdownWebsite - - def v = "v${JALVIEW_VERSION_UNDERSCORES}" - def vDir = "${getdownArchiveDir}/${v}" - getdownFullArchiveDir = "${vDir}/getdown" - getdownVersionLaunchJvl = "${vDir}/jalview-${v}.jvl" - - def vAltDir = "alt_${v}" - def archiveImagesDir = "${jalviewDir}/${channel_properties_dir}/old/images" - - doFirst { - // cleanup old "old" dir - delete getdownArchiveDir - - def getdownArchiveTxt = file("${getdownFullArchiveDir}/getdown.txt") - getdownArchiveTxt.getParentFile().mkdirs() - def getdownArchiveTextLines = [] - def getdownFullArchiveAppBase = "${getdownArchiveAppBase}${getdownArchiveAppBase.endsWith("/")?"":"/"}${v}/getdown/" - - // the libdir - copy { - from "${getdownAppBaseDir}/${getdownAppDistDir}" - into "${getdownFullArchiveDir}/${vAltDir}" - } - - getdownTextLines.each { line -> - line = line.replaceAll("^(?appbase\\s*=\\s*).*", '${s}'+getdownFullArchiveAppBase) - line = line.replaceAll("^(?(resource|code)\\s*=\\s*)${getdownAppDistDir}/", '${s}'+vAltDir+"/") - line = line.replaceAll("^(?ui.background_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background.png") - line = line.replaceAll("^(?ui.instant_background_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background_initialising.png") - line = line.replaceAll("^(?ui.error_background\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_background_error.png") - line = line.replaceAll("^(?ui.progress_image\\s*=\\s*).*\\.png", '${s}'+"${getdown_resource_dir}/jalview_archive_getdown_progress_bar.png") - // remove the existing resource = resource/ or bin/ lines - if (! line.matches("resource\\s*=\\s*(resource|bin)/.*")) { - getdownArchiveTextLines += line - } - } - - // the resource dir -- add these files as resource lines in getdown.txt - copy { - from "${archiveImagesDir}" - into "${getdownFullArchiveDir}/${getdown_resource_dir}" - eachFile { file -> - getdownArchiveTextLines += "resource = ${getdown_resource_dir}/${file.getName()}" - } - } - - getdownArchiveTxt.write(getdownArchiveTextLines.join("\n")) - - def vLaunchJvl = file(getdownVersionLaunchJvl) - vLaunchJvl.getParentFile().mkdirs() - vLaunchJvl.write("appbase=${getdownFullArchiveAppBase}\n") - def vLaunchJvlPath = vLaunchJvl.toPath().toAbsolutePath() - def jvlLinkPath = file("${vDir}/jalview.jvl").toPath().toAbsolutePath() - // for some reason filepath.relativize(fileInSameDirPath) gives a path to "../" which is wrong - //java.nio.file.Files.createSymbolicLink(jvlLinkPath, jvlLinkPath.relativize(vLaunchJvlPath)); - java.nio.file.Files.createSymbolicLink(jvlLinkPath, java.nio.file.Paths.get(".",vLaunchJvl.getName())); - - // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties - copy { - from getdownLauncher - from "${getdownAppBaseDir}/${getdownLaunchJvl}" - from "${getdownAppBaseDir}/${getdown_launcher_new}" - from "${getdownAppBaseDir}/${channel_props}" - if (file(getdownLauncher).getName() != getdown_launcher) { - rename(file(getdownLauncher).getName(), getdown_launcher) - } - into getdownFullArchiveDir - } - - } -} - -task getdownArchiveDigest(type: JavaExec) { - group = "distribution" - description = "Digest the getdown archive folder" - - dependsOn getdownArchiveBuild - - doFirst { - classpath = files(getdownLauncher) - args getdownFullArchiveDir - } - main = "com.threerings.getdown.tools.Digester" - inputs.dir(getdownFullArchiveDir) - outputs.file("${getdownFullArchiveDir}/digest2.txt") -} - -task getdownArchive() { - group = "distribution" - description = "Build the website archive dir with getdown digest" - - dependsOn getdownArchiveBuild - dependsOn getdownArchiveDigest -} - -tasks.withType(JavaCompile) { - options.encoding = 'UTF-8' -} - - -clean { - doFirst { - delete getdownAppBaseDir - delete getdownFilesDir - delete getdownArchiveDir - } -} - - -install4j { - if (file(install4jHomeDir).exists()) { - // good to go! - } else if (file(System.getProperty("user.home")+"/buildtools/install4j").exists()) { - install4jHomeDir = System.getProperty("user.home")+"/buildtools/install4j" - } else if (file("/Applications/install4j.app/Contents/Resources/app").exists()) { - install4jHomeDir = "/Applications/install4j.app/Contents/Resources/app" - } - installDir(file(install4jHomeDir)) - - mediaTypes = Arrays.asList(install4j_media_types.split(",")) -} - - -task copyInstall4jTemplate { - def install4jTemplateFile = file("${install4jDir}/${install4j_template}") - def install4jFileAssociationsFile = file("${install4jDir}/${install4j_installer_file_associations}") - inputs.file(install4jTemplateFile) - inputs.file(install4jFileAssociationsFile) - inputs.property("CHANNEL", { CHANNEL }) - outputs.file(install4jConfFile) - - doLast { - def install4jConfigXml = new XmlParser().parse(install4jTemplateFile) - - // turn off code signing if no OSX_KEYPASS - if (OSX_KEYPASS == "") { - install4jConfigXml.'**'.codeSigning.each { codeSigning -> - codeSigning.'@macEnabled' = "false" - } - install4jConfigXml.'**'.windows.each { windows -> - windows.'@runPostProcessor' = "false" - } - } - - // disable install screen for OSX dmg (for 2.11.2.0) - install4jConfigXml.'**'.macosArchive.each { macosArchive -> - macosArchive.attributes().remove('executeSetupApp') - macosArchive.attributes().remove('setupAppId') - } - - // turn off checksum creation for LOCAL channel - def e = install4jConfigXml.application[0] - e.'@createChecksums' = string(install4jCheckSums) - - // put file association actions where placeholder action is - def install4jFileAssociationsText = install4jFileAssociationsFile.text - def fileAssociationActions = new XmlParser().parseText("${install4jFileAssociationsText}") - install4jConfigXml.'**'.action.any { a -> // .any{} stops after the first one that returns true - if (a.'@name' == 'EXTENSIONS_REPLACED_BY_GRADLE') { - def parent = a.parent() - parent.remove(a) - fileAssociationActions.each { faa -> - parent.append(faa) - } - // don't need to continue in .any loop once replacements have been made - return true - } - } - - // use Windows Program Group with Examples folder for RELEASE, and Program Group without Examples for everything else - // NB we're deleting the /other/ one! - // Also remove the examples subdir from non-release versions - def customizedIdToDelete = "PROGRAM_GROUP_RELEASE" - // 2.11.1.0 NOT releasing with the Examples folder in the Program Group - if (false && CHANNEL=="RELEASE") { // remove 'false && ' to include Examples folder in RELEASE channel - customizedIdToDelete = "PROGRAM_GROUP_NON_RELEASE" - } else { - // remove the examples subdir from Full File Set - def files = install4jConfigXml.files[0] - def fileset = files.filesets.fileset.find { fs -> fs.'@customizedId' == "FULL_FILE_SET" } - def root = files.roots.root.find { r -> r.'@fileset' == fileset.'@id' } - def mountPoint = files.mountPoints.mountPoint.find { mp -> mp.'@root' == root.'@id' } - def dirEntry = files.entries.dirEntry.find { de -> de.'@mountPoint' == mountPoint.'@id' && de.'@subDirectory' == "examples" } - dirEntry.parent().remove(dirEntry) - } - install4jConfigXml.'**'.action.any { a -> - if (a.'@customizedId' == customizedIdToDelete) { - def parent = a.parent() - parent.remove(a) - return true - } - } - - // write install4j file - install4jConfFile.text = XmlUtil.serialize(install4jConfigXml) - } -} - - -clean { - doFirst { - delete install4jConfFile - } -} - -task cleanInstallersDataFiles { - def installersOutputTxt = file("${jalviewDir}/${install4jBuildDir}/output.txt") - def installersSha256 = file("${jalviewDir}/${install4jBuildDir}/sha256sums") - def hugoDataJsonFile = file("${jalviewDir}/${install4jBuildDir}/installers-${JALVIEW_VERSION_UNDERSCORES}.json") - doFirst { - delete installersOutputTxt - delete installersSha256 - delete hugoDataJsonFile - } -} - -task install4jDMGBackgroundImageCopy { - inputs.file "${install4jDMGBackgroundImageDir}/${install4jDMGBackgroundImageFile}" - outputs.dir "${install4jDMGBackgroundImageBuildDir}" - doFirst { - copy { - from(install4jDMGBackgroundImageDir) { - include(install4jDMGBackgroundImageFile) - } - into install4jDMGBackgroundImageBuildDir - } - } -} - -task install4jDMGBackgroundImageProcess { - dependsOn install4jDMGBackgroundImageCopy - - doFirst { - if (backgroundImageText) { - if (convertBinary == null) { - throw new StopExecutionException("No ImageMagick convert binary installed at '${convertBinaryExpectedLocation}'") - } - if (!project.hasProperty("install4j_background_image_text_suffix_cmd")) { - throw new StopExecutionException("No property 'install4j_background_image_text_suffix_cmd' defined. See channel_gradle.properties for channel ${CHANNEL}") - } - fileTree(dir: install4jDMGBackgroundImageBuildDir, include: "*.png").getFiles().each { file -> - exec { - executable convertBinary - args = [ - file.getPath(), - '-font', install4j_background_image_text_font, - '-fill', install4j_background_image_text_colour, - '-draw', sprintf(install4j_background_image_text_suffix_cmd, channelSuffix), - '-draw', sprintf(install4j_background_image_text_commit_cmd, "git-commit: ${gitHash}"), - '-draw', sprintf(install4j_background_image_text_date_cmd, getDate("yyyy-MM-dd HH:mm:ss")), - file.getPath() - ] - } - } - } - } -} - -task install4jDMGBackgroundImage { - dependsOn install4jDMGBackgroundImageProcess -} - -task installerFiles(type: com.install4j.gradle.Install4jTask) { - group = "distribution" - description = "Create the install4j installers" - dependsOn getdown - dependsOn copyInstall4jTemplate - dependsOn cleanInstallersDataFiles - dependsOn install4jDMGBackgroundImage - - projectFile = install4jConfFile - - // create an md5 for the input files to use as version for install4j conf file - def digest = MessageDigest.getInstance("MD5") - digest.update( - (file("${install4jDir}/${install4j_template}").text + - file("${install4jDir}/${install4j_info_plist_file_associations}").text + - file("${install4jDir}/${install4j_installer_file_associations}").text).bytes) - def filesMd5 = new BigInteger(1, digest.digest()).toString(16) - if (filesMd5.length() >= 8) { - filesMd5 = filesMd5.substring(0,8) - } - def install4jTemplateVersion = "${JALVIEW_VERSION}_F${filesMd5}_C${gitHash}" - - variables = [ - 'JALVIEW_NAME': jalview_name, - 'JALVIEW_APPLICATION_NAME': applicationName, - 'JALVIEW_DIR': "../..", - 'OSX_KEYSTORE': OSX_KEYSTORE, - 'OSX_APPLEID': OSX_APPLEID, - 'OSX_ALTOOLPASS': OSX_ALTOOLPASS, - 'JSIGN_SH': JSIGN_SH, - 'JRE_DIR': getdown_app_dir_java, - 'INSTALLER_TEMPLATE_VERSION': install4jTemplateVersion, - 'JALVIEW_VERSION': JALVIEW_VERSION, - 'JAVA_MIN_VERSION': JAVA_MIN_VERSION, - 'JAVA_MAX_VERSION': JAVA_MAX_VERSION, - 'JAVA_VERSION': JAVA_VERSION, - 'JAVA_INTEGER_VERSION': JAVA_INTEGER_VERSION, - 'VERSION': JALVIEW_VERSION, - 'COPYRIGHT_MESSAGE': install4j_copyright_message, - 'BUNDLE_ID': install4jBundleId, - 'INTERNAL_ID': install4jInternalId, - 'WINDOWS_APPLICATION_ID': install4jWinApplicationId, - 'MACOS_DMG_DS_STORE': install4jDMGDSStore, - 'MACOS_DMG_BG_IMAGE': "${install4jDMGBackgroundImageBuildDir}/${install4jDMGBackgroundImageFile}", - 'WRAPPER_LINK': getdownWrapperLink, - 'BASH_WRAPPER_SCRIPT': getdown_bash_wrapper_script, - 'POWERSHELL_WRAPPER_SCRIPT': getdown_powershell_wrapper_script, - 'BATCH_WRAPPER_SCRIPT': getdown_batch_wrapper_script, - 'WRAPPER_SCRIPT_BIN_DIR': getdown_wrapper_script_dir, - 'INSTALLER_NAME': install4jInstallerName, - 'INSTALL4J_UTILS_DIR': install4j_utils_dir, - 'GETDOWN_CHANNEL_DIR': getdownChannelDir, - 'GETDOWN_FILES_DIR': getdown_files_dir, - 'GETDOWN_RESOURCE_DIR': getdown_resource_dir, - 'GETDOWN_DIST_DIR': getdownAppDistDir, - 'GETDOWN_ALT_DIR': getdown_app_dir_alt, - 'GETDOWN_INSTALL_DIR': getdown_install_dir, - 'INFO_PLIST_FILE_ASSOCIATIONS_FILE': install4j_info_plist_file_associations, - 'BUILD_DIR': install4jBuildDir, - 'APPLICATION_CATEGORIES': install4j_application_categories, - 'APPLICATION_FOLDER': install4jApplicationFolder, - 'UNIX_APPLICATION_FOLDER': install4jUnixApplicationFolder, - 'EXECUTABLE_NAME': install4jExecutableName, - 'EXTRA_SCHEME': install4jExtraScheme, - 'MAC_ICONS_FILE': install4jMacIconsFile, - 'WINDOWS_ICONS_FILE': install4jWindowsIconsFile, - 'PNG_ICON_FILE': install4jPngIconFile, - 'BACKGROUND': install4jBackground, - ] - - def varNameMap = [ - 'mac': 'MACOS', - 'windows': 'WINDOWS', - 'linux': 'LINUX' - ] - - // these are the bundled OS/architecture VMs needed by install4j - def osArch = [ - [ "mac", "x64" ], - [ "mac", "aarch64" ], - [ "windows", "x64" ], - [ "linux", "x64" ], - [ "linux", "aarch64" ] - ] - osArch.forEach { os, arch -> - variables[ sprintf("%s_%s_JAVA_VM_DIR", varNameMap[os], arch.toUpperCase(Locale.ROOT)) ] = sprintf("%s/jre-%s-%s-%s/jre", jreInstallsDir, JAVA_INTEGER_VERSION, os, arch) - // N.B. For some reason install4j requires the below filename to have underscores and not hyphens - // otherwise running `gradle installers` generates a non-useful error: - // `install4j: compilation failed. Reason: java.lang.NumberFormatException: For input string: "windows"` - variables[ sprintf("%s_%s_JAVA_VM_TGZ", varNameMap[os], arch.toUpperCase(Locale.ROOT)) ] = sprintf("%s/tgz/jre_%s_%s_%s.tar.gz", jreInstallsDir, JAVA_INTEGER_VERSION, os, arch) - } - - //println("INSTALL4J VARIABLES:") - //variables.each{k,v->println("${k}=${v}")} - - destination = "${jalviewDir}/${install4jBuildDir}" - buildSelected = true - - if (install4j_faster.equals("true") || CHANNEL.startsWith("LOCAL")) { - faster = true - disableSigning = true - disableNotarization = true - } - - if (OSX_KEYPASS) { - macKeystorePassword = OSX_KEYPASS - } - - if (OSX_ALTOOLPASS) { - appleIdPassword = OSX_ALTOOLPASS - disableNotarization = false - } else { - disableNotarization = true - } - - doFirst { - println("Using projectFile "+projectFile) - if (!disableNotarization) { println("Will notarize OSX App DMG") } - } - //verbose=true - - inputs.dir(getdownAppBaseDir) - inputs.file(install4jConfFile) - inputs.file("${install4jDir}/${install4j_info_plist_file_associations}") - outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}") -} - -def getDataHash(File myFile) { - HashCode hash = Files.asByteSource(myFile).hash(Hashing.sha256()) - return myFile.exists() - ? [ - "file" : myFile.getName(), - "filesize" : myFile.length(), - "sha256" : hash.toString() - ] - : null -} - -def writeDataJsonFile(File installersOutputTxt, File installersSha256, File dataJsonFile) { - def hash = [ - "channel" : getdownChannelName, - "date" : getDate("yyyy-MM-dd HH:mm:ss"), - "git-commit" : "${gitHash} [${gitBranch}]", - "version" : JALVIEW_VERSION - ] - // install4j installer files - if (installersOutputTxt.exists()) { - def idHash = [:] - installersOutputTxt.readLines().each { def line -> - if (line.startsWith("#")) { - return; - } - line.replaceAll("\n","") - def vals = line.split("\t") - def filename = vals[3] - def filesize = file(filename).length() - filename = filename.replaceAll(/^.*\//, "") - hash[vals[0]] = [ "id" : vals[0], "os" : vals[1], "name" : vals[2], "file" : filename, "filesize" : filesize ] - idHash."${filename}" = vals[0] - } - if (install4jCheckSums && installersSha256.exists()) { - installersSha256.readLines().each { def line -> - if (line.startsWith("#")) { - return; - } - line.replaceAll("\n","") - def vals = line.split(/\s+\*?/) - def filename = vals[1] - def innerHash = (hash.(idHash."${filename}"))."sha256" = vals[0] - } - } - } - - [ - "JAR": shadowJar.archiveFile, // executable JAR - "JVL": getdownVersionLaunchJvl, // version JVL - "SOURCE": sourceDist.archiveFile // source TGZ - ].each { key, value -> - def file = file(value) - if (file.exists()) { - def fileHash = getDataHash(file) - if (fileHash != null) { - hash."${key}" = fileHash; - } - } - } - return dataJsonFile.write(new JsonBuilder(hash).toPrettyString()) -} - -task staticMakeInstallersJsonFile { - doFirst { - def output = findProperty("i4j_output") - def sha256 = findProperty("i4j_sha256") - def json = findProperty("i4j_json") - if (output == null || sha256 == null || json == null) { - throw new GradleException("Must provide paths to all of output.txt, sha256sums, and output.json with '-Pi4j_output=... -Pi4j_sha256=... -Pi4j_json=...") - } - writeDataJsonFile(file(output), file(sha256), file(json)) - } -} - -task installers { - dependsOn installerFiles -} - - -spotless { - java { - eclipse().configFile(eclipse_codestyle_file) - } -} - -task createSourceReleaseProperties(type: WriteProperties) { - group = "distribution" - description = "Create the source RELEASE properties file" - - def sourceTarBuildDir = "${buildDir}/sourceTar" - def sourceReleasePropertiesFile = "${sourceTarBuildDir}/RELEASE" - outputFile (sourceReleasePropertiesFile) - - doFirst { - releaseProps.each{ key, val -> property key, val } - property "git.branch", gitBranch - property "git.hash", gitHash - } - - outputs.file(outputFile) -} - -task sourceDist(type: Tar) { - group "distribution" - description "Create a source .tar.gz file for distribution" - - dependsOn createBuildProperties - dependsOn convertMdFiles - dependsOn eclipseAllPreferences - dependsOn createSourceReleaseProperties - - - def outputFileName = "${project.name}_${JALVIEW_VERSION_UNDERSCORES}.tar.gz" - archiveFileName = outputFileName - - compression Compression.GZIP - - into project.name - - def EXCLUDE_FILES=[ - "build/*", - "bin/*", - "test-output/", - "test-reports", - "tests", - "clover*/*", - ".*", - "benchmarking/*", - "**/.*", - "*.class", - "**/*.class","$j11modDir/**/*.jar","appletlib","**/*locales", - "*locales/**", - "utils/InstallAnywhere", - "**/*.log", - "RELEASE", - ] - def PROCESS_FILES=[ - "AUTHORS", - "CITATION", - "FEATURETODO", - "JAVA-11-README", - "FEATURETODO", - "LICENSE", - "**/README", - "THIRDPARTYLIBS", - "TESTNG", - "build.gradle", - "gradle.properties", - "**/*.java", - "**/*.html", - "**/*.xml", - "**/*.gradle", - "**/*.groovy", - "**/*.properties", - "**/*.perl", - "**/*.sh", - ] - def INCLUDE_FILES=[ - ".classpath", - ".settings/org.eclipse.buildship.core.prefs", - ".settings/org.eclipse.jdt.core.prefs" - ] - - from(jalviewDir) { - exclude (EXCLUDE_FILES) - include (PROCESS_FILES) - filter(ReplaceTokens, - beginToken: '$$', - endToken: '$$', - tokens: [ - 'Version-Rel': JALVIEW_VERSION, - 'Year-Rel': getDate("yyyy") - ] - ) - } - from(jalviewDir) { - exclude (EXCLUDE_FILES) - exclude (PROCESS_FILES) - exclude ("appletlib") - exclude ("**/*locales") - exclude ("*locales/**") - exclude ("utils/InstallAnywhere") - - exclude (getdown_files_dir) - // getdown_website_dir and getdown_archive_dir moved to build/website/docroot/getdown - //exclude (getdown_website_dir) - //exclude (getdown_archive_dir) - - // exluding these as not using jars as modules yet - exclude ("${j11modDir}/**/*.jar") - } - from(jalviewDir) { - include(INCLUDE_FILES) - } -// from (jalviewDir) { -// // explicit includes for stuff that seemed to not get included -// include(fileTree("test/**/*.")) -// exclude(EXCLUDE_FILES) -// exclude(PROCESS_FILES) -// } - - from(file(buildProperties).getParent()) { - include(file(buildProperties).getName()) - rename(file(buildProperties).getName(), "build_properties") - filter({ line -> - line.replaceAll("^INSTALLATION=.*\$","INSTALLATION=Source Release"+" git-commit\\\\:"+gitHash+" ["+gitBranch+"]") - }) - } - - def sourceTarBuildDir = "${buildDir}/sourceTar" - from(sourceTarBuildDir) { - // this includes the appended RELEASE properties file - } -} - -task dataInstallersJson { - group "website" - description "Create the installers-VERSION.json data file for installer files created" - - mustRunAfter installers - mustRunAfter shadowJar - mustRunAfter sourceDist - mustRunAfter getdownArchive - - def installersOutputTxt = file("${jalviewDir}/${install4jBuildDir}/output.txt") - def installersSha256 = file("${jalviewDir}/${install4jBuildDir}/sha256sums") - - if (installersOutputTxt.exists()) { - inputs.file(installersOutputTxt) - } - if (install4jCheckSums && installersSha256.exists()) { - inputs.file(installersSha256) - } - [ - shadowJar.archiveFile, // executable JAR - getdownVersionLaunchJvl, // version JVL - sourceDist.archiveFile // source TGZ - ].each { fileName -> - if (file(fileName).exists()) { - inputs.file(fileName) - } - } - - outputs.file(hugoDataJsonFile) - - doFirst { - writeDataJsonFile(installersOutputTxt, installersSha256, hugoDataJsonFile) - } -} - -task helppages { - group "help" - description "Copies all help pages to build dir. Runs ant task 'pubhtmlhelp'." - - dependsOn copyHelp - dependsOn pubhtmlhelp - - inputs.dir("${helpBuildDir}/${help_dir}") - outputs.dir("${buildDir}/distributions/${help_dir}") -} - - -task j2sSetHeadlessBuild { - doFirst { - IN_ECLIPSE = false - } -} - - -task jalviewjsEnableAltFileProperty(type: WriteProperties) { - group "jalviewjs" - description "Enable the alternative J2S Config file for headless build" - - outputFile = jalviewjsJ2sSettingsFileName - def j2sPropsFile = file(jalviewjsJ2sSettingsFileName) - def j2sProps = new Properties() - if (j2sPropsFile.exists()) { - try { - def j2sPropsFileFIS = new FileInputStream(j2sPropsFile) - j2sProps.load(j2sPropsFileFIS) - j2sPropsFileFIS.close() - - j2sProps.each { prop, val -> - property(prop, val) - } - } catch (Exception e) { - println("Exception reading ${jalviewjsJ2sSettingsFileName}") - e.printStackTrace() - } - } - if (! j2sProps.stringPropertyNames().contains(jalviewjs_j2s_alt_file_property_config)) { - property(jalviewjs_j2s_alt_file_property_config, jalviewjs_j2s_alt_file_property) - } -} - - -task jalviewjsSetEclipseWorkspace { - def propKey = "jalviewjs_eclipse_workspace" - def propVal = null - if (project.hasProperty(propKey)) { - propVal = project.getProperty(propKey) - if (propVal.startsWith("~/")) { - propVal = System.getProperty("user.home") + propVal.substring(1) - } - } - def propsFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_workspace_location_file}" - def propsFile = file(propsFileName) - def eclipseWsDir = propVal - def props = new Properties() - - def writeProps = true - if (( eclipseWsDir == null || !file(eclipseWsDir).exists() ) && propsFile.exists()) { - def ins = new FileInputStream(propsFileName) - props.load(ins) - ins.close() - if (props.getProperty(propKey, null) != null) { - eclipseWsDir = props.getProperty(propKey) - writeProps = false - } - } - - if (eclipseWsDir == null || !file(eclipseWsDir).exists()) { - def tempDir = File.createTempDir() - eclipseWsDir = tempDir.getAbsolutePath() - writeProps = true - } - eclipseWorkspace = file(eclipseWsDir) - - doFirst { - // do not run a headless transpile when we claim to be in Eclipse - if (IN_ECLIPSE) { - println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}") - throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'") - } else { - println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}") - } - - if (writeProps) { - props.setProperty(propKey, eclipseWsDir) - propsFile.parentFile.mkdirs() - def bytes = new ByteArrayOutputStream() - props.store(bytes, null) - def propertiesString = bytes.toString() - propsFile.text = propertiesString - print("NEW ") - } else { - print("EXISTING ") - } - - println("ECLIPSE WORKSPACE: "+eclipseWorkspace.getPath()) - } - - //inputs.property(propKey, eclipseWsDir) // eclipseWsDir only gets set once this task runs, so will be out-of-date - outputs.file(propsFileName) - outputs.upToDateWhen { eclipseWorkspace.exists() && propsFile.exists() } -} - - -task jalviewjsEclipsePaths { - def eclipseProduct - - def eclipseRoot = jalviewjs_eclipse_root - if (eclipseRoot.startsWith("~/")) { - eclipseRoot = System.getProperty("user.home") + eclipseRoot.substring(1) - } - if (OperatingSystem.current().isMacOsX()) { - eclipseRoot += "/Eclipse.app" - eclipseBinary = "${eclipseRoot}/Contents/MacOS/eclipse" - eclipseProduct = "${eclipseRoot}/Contents/Eclipse/.eclipseproduct" - } else if (OperatingSystem.current().isWindows()) { // check these paths!! - if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) { - eclipseRoot += "/eclipse" - } - eclipseBinary = "${eclipseRoot}/eclipse.exe" - eclipseProduct = "${eclipseRoot}/.eclipseproduct" - } else { // linux or unix - if (file("${eclipseRoot}/eclipse").isDirectory() && file("${eclipseRoot}/eclipse/.eclipseproduct").exists()) { - eclipseRoot += "/eclipse" -println("eclipseDir exists") - } - eclipseBinary = "${eclipseRoot}/eclipse" - eclipseProduct = "${eclipseRoot}/.eclipseproduct" - } - - eclipseVersion = "4.13" // default - def assumedVersion = true - if (file(eclipseProduct).exists()) { - def fis = new FileInputStream(eclipseProduct) - def props = new Properties() - props.load(fis) - eclipseVersion = props.getProperty("version") - fis.close() - assumedVersion = false - } - - def propKey = "eclipse_debug" - eclipseDebug = (project.hasProperty(propKey) && project.getProperty(propKey).equals("true")) - - doFirst { - // do not run a headless transpile when we claim to be in Eclipse - if (IN_ECLIPSE) { - println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}") - throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'") - } else { - println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}") - } - - if (!assumedVersion) { - println("ECLIPSE VERSION=${eclipseVersion}") - } - } -} - - -task printProperties { - group "Debug" - description "Output to console all System.properties" - doFirst { - System.properties.each { key, val -> System.out.println("Property: ${key}=${val}") } - } -} - - -task eclipseSetup { - dependsOn eclipseProject - dependsOn eclipseClasspath - dependsOn eclipseJdt -} - - -// this version (type: Copy) will delete anything in the eclipse dropins folder that isn't in fromDropinsDir -task jalviewjsEclipseCopyDropins(type: Copy) { - dependsOn jalviewjsEclipsePaths - - def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_eclipse_dropins_dir}", include: "*.jar") - inputFiles += file("${jalviewDir}/${jalviewjsJ2sPlugin}") - def outputDir = "${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" - - from inputFiles - into outputDir -} - - -// this eclipse -clean doesn't actually work -task jalviewjsCleanEclipse(type: Exec) { - dependsOn eclipseSetup - dependsOn jalviewjsEclipsePaths - dependsOn jalviewjsEclipseCopyDropins - - executable(eclipseBinary) - args(["-nosplash", "--launcher.suppressErrors", "-data", eclipseWorkspace.getPath(), "-clean", "-console", "-consoleLog"]) - if (eclipseDebug) { - args += "-debug" - } - args += "-l" - - def inputString = """exit -y -""" - def inputByteStream = new ByteArrayInputStream(inputString.getBytes()) - standardInput = inputByteStream -} - -/* not really working yet -jalviewjsEclipseCopyDropins.finalizedBy jalviewjsCleanEclipse -*/ - - -task jalviewjsTransferUnzipSwingJs { - def file_zip = "${jalviewDir}/${jalviewjs_swingjs_zip}" - - doLast { - copy { - from zipTree(file_zip) - into "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}" - } - } - - inputs.file file_zip - outputs.dir "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}" -} - - -task jalviewjsTransferUnzipLib { - def zipFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_libjs_dir}", include: "*.zip") - - doLast { - zipFiles.each { file_zip -> - copy { - from zipTree(file_zip) - into "${jalviewDir}/${jalviewjsTransferSiteLibDir}" - } - } - } - - inputs.files zipFiles - outputs.dir "${jalviewDir}/${jalviewjsTransferSiteLibDir}" -} - - -task jalviewjsTransferUnzipAllLibs { - dependsOn jalviewjsTransferUnzipSwingJs - dependsOn jalviewjsTransferUnzipLib -} - - -task jalviewjsCreateJ2sSettings(type: WriteProperties) { - group "JalviewJS" - description "Create the alternative j2s file from the j2s.* properties" - - jalviewjsJ2sProps = project.properties.findAll { it.key.startsWith("j2s.") }.sort { it.key } - def siteDirProperty = "j2s.site.directory" - def setSiteDir = false - jalviewjsJ2sProps.each { prop, val -> - if (val != null) { - if (prop == siteDirProperty) { - if (!(val.startsWith('/') || val.startsWith("file://") )) { - val = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${val}" - } - setSiteDir = true - } - property(prop,val) - } - if (!setSiteDir) { // default site location, don't override specifically set property - property(siteDirProperty,"${jalviewDirRelativePath}/${jalviewjsTransferSiteJsDir}") - } - } - outputFile = jalviewjsJ2sAltSettingsFileName - - if (! IN_ECLIPSE) { - inputs.properties(jalviewjsJ2sProps) - outputs.file(jalviewjsJ2sAltSettingsFileName) - } -} - - -task jalviewjsEclipseSetup { - dependsOn jalviewjsEclipseCopyDropins - dependsOn jalviewjsSetEclipseWorkspace - dependsOn jalviewjsCreateJ2sSettings -} - - -task jalviewjsSyncAllLibs (type: Sync) { - dependsOn jalviewjsTransferUnzipAllLibs - def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteLibDir}") - inputFiles += fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}") - def outputDir = "${jalviewDir}/${jalviewjsSiteDir}" - - from inputFiles - into outputDir - def outputFiles = [] - rename { filename -> - outputFiles += "${outputDir}/${filename}" - null - } - preserve { - include "**" - } - - // should this be exclude really ? - duplicatesStrategy "INCLUDE" - - outputs.files outputFiles - inputs.files inputFiles -} - - -task jalviewjsSyncResources (type: Sync) { - dependsOn buildResources - - def inputFiles = fileTree(dir: resourcesBuildDir) - def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}" - - from inputFiles - into outputDir - def outputFiles = [] - rename { filename -> - outputFiles += "${outputDir}/${filename}" - null - } - preserve { - include "**" - } - outputs.files outputFiles - inputs.files inputFiles -} - - -task jalviewjsSyncSiteResources (type: Sync) { - def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjs_site_resource_dir}") - def outputDir = "${jalviewDir}/${jalviewjsSiteDir}" - - from inputFiles - into outputDir - def outputFiles = [] - rename { filename -> - outputFiles += "${outputDir}/${filename}" - null - } - preserve { - include "**" - } - outputs.files outputFiles - inputs.files inputFiles -} - - -task jalviewjsSyncBuildProperties (type: Sync) { - dependsOn createBuildProperties - def inputFiles = [file(buildProperties)] - def outputDir = "${jalviewDir}/${jalviewjsSiteDir}/${jalviewjs_j2s_subdir}" - - from inputFiles - into outputDir - def outputFiles = [] - rename { filename -> - outputFiles += "${outputDir}/${filename}" - null - } - preserve { - include "**" - } - outputs.files outputFiles - inputs.files inputFiles -} - - -task jalviewjsProjectImport(type: Exec) { - dependsOn eclipseSetup - dependsOn jalviewjsEclipsePaths - dependsOn jalviewjsEclipseSetup - - doFirst { - // do not run a headless import when we claim to be in Eclipse - if (IN_ECLIPSE) { - println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}") - throw new StopExecutionException("Not running headless import whilst IN_ECLIPSE is '${IN_ECLIPSE}'") - } else { - println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}") - } - } - - //def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview/org.eclipse.jdt.core" - def projdir = eclipseWorkspace.getPath()+"/.metadata/.plugins/org.eclipse.core.resources/.projects/jalview" - executable(eclipseBinary) - args(["-nosplash", "--launcher.suppressErrors", "-application", "com.seeq.eclipse.importprojects.headlessimport", "-data", eclipseWorkspace.getPath(), "-import", jalviewDirAbsolutePath]) - if (eclipseDebug) { - args += "-debug" - } - args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ] - if (!IN_ECLIPSE) { - args += [ "-D${j2sHeadlessBuildProperty}=true" ] - args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ] - } - - inputs.file("${jalviewDir}/.project") - outputs.upToDateWhen { - file(projdir).exists() - } -} - - -task jalviewjsTranspile(type: Exec) { - dependsOn jalviewjsEclipseSetup - dependsOn jalviewjsProjectImport - dependsOn jalviewjsEclipsePaths - if (!IN_ECLIPSE) { - dependsOn jalviewjsEnableAltFileProperty - } - - doFirst { - // do not run a headless transpile when we claim to be in Eclipse - if (IN_ECLIPSE) { - println("Skipping task ${name} as IN_ECLIPSE=${IN_ECLIPSE}") - throw new StopExecutionException("Not running headless transpile whilst IN_ECLIPSE is '${IN_ECLIPSE}'") - } else { - println("Running task ${name} as IN_ECLIPSE=${IN_ECLIPSE}") - } - } - - executable(eclipseBinary) - args(["-nosplash", "--launcher.suppressErrors", "-application", "org.eclipse.jdt.apt.core.aptBuild", "-data", eclipseWorkspace, "-${jalviewjs_eclipse_build_arg}", eclipse_project_name ]) - if (eclipseDebug) { - args += "-debug" - } - args += [ "--launcher.appendVmargs", "-vmargs", "-Dorg.eclipse.equinox.p2.reconciler.dropins.directory=${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_eclipse_tmp_dropins_dir}" ] - if (!IN_ECLIPSE) { - args += [ "-D${j2sHeadlessBuildProperty}=true" ] - args += [ "-D${jalviewjs_j2s_alt_file_property}=${jalviewjsJ2sAltSettingsFileName}" ] - } - - def stdout - def stderr - doFirst { - stdout = new ByteArrayOutputStream() - stderr = new ByteArrayOutputStream() - - def logOutFileName = "${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}" - def logOutFile = file(logOutFileName) - logOutFile.createNewFile() - logOutFile.text = """ROOT: ${jalviewjs_eclipse_root} -BINARY: ${eclipseBinary} -VERSION: ${eclipseVersion} -WORKSPACE: ${eclipseWorkspace} -DEBUG: ${eclipseDebug} ----- -""" - def logOutFOS = new FileOutputStream(logOutFile, true) // true == append - // combine stdout and stderr - def logErrFOS = logOutFOS - - if (jalviewjs_j2s_to_console.equals("true")) { - standardOutput = new org.apache.tools.ant.util.TeeOutputStream( - new org.apache.tools.ant.util.TeeOutputStream( - logOutFOS, - stdout), - System.out) - errorOutput = new org.apache.tools.ant.util.TeeOutputStream( - new org.apache.tools.ant.util.TeeOutputStream( - logErrFOS, - stderr), - System.err) - } else { - standardOutput = new org.apache.tools.ant.util.TeeOutputStream( - logOutFOS, - stdout) - errorOutput = new org.apache.tools.ant.util.TeeOutputStream( - logErrFOS, - stderr) - } - } - - doLast { - if (stdout.toString().contains("Error processing ")) { - // j2s did not complete transpile - //throw new TaskExecutionException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'") - if (jalviewjs_ignore_transpile_errors.equals("true")) { - println("IGNORING TRANSPILE ERRORS") - println("See eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'") - } else { - throw new GradleException("Error during transpilation:\n${stderr}\nSee eclipse transpile log file '${jalviewDir}/${jalviewjsBuildDir}/${jalviewjs_j2s_transpile_stdout}'") - } - } - } - - inputs.dir("${jalviewDir}/${sourceDir}") - outputs.dir("${jalviewDir}/${jalviewjsTransferSiteJsDir}") - outputs.upToDateWhen( { file("${jalviewDir}/${jalviewjsTransferSiteJsDir}${jalviewjs_server_resource}").exists() } ) -} - - -def jalviewjsCallCore(String name, FileCollection list, String prefixFile, String suffixFile, String jsfile, String zjsfile, File logOutFile, Boolean logOutConsole) { - - def stdout = new ByteArrayOutputStream() - def stderr = new ByteArrayOutputStream() - - def coreFile = file(jsfile) - def msg = "" - msg = "Creating core for ${name}...\nGenerating ${jsfile}" - println(msg) - logOutFile.createNewFile() - logOutFile.append(msg+"\n") - - def coreTop = file(prefixFile) - def coreBottom = file(suffixFile) - coreFile.getParentFile().mkdirs() - coreFile.createNewFile() - coreFile.write( coreTop.getText("UTF-8") ) - list.each { - f -> - if (f.exists()) { - def t = f.getText("UTF-8") - t.replaceAll("Clazz\\.([^_])","Clazz_${1}") - coreFile.append( t ) - } else { - msg = "...file '"+f.getPath()+"' does not exist, skipping" - println(msg) - logOutFile.append(msg+"\n") - } - } - coreFile.append( coreBottom.getText("UTF-8") ) - - msg = "Generating ${zjsfile}" - println(msg) - logOutFile.append(msg+"\n") - def logOutFOS = new FileOutputStream(logOutFile, true) // true == append - def logErrFOS = logOutFOS - - javaexec { - classpath = files(["${jalviewDir}/${jalviewjs_closure_compiler}"]) - main = "com.google.javascript.jscomp.CommandLineRunner" - jvmArgs = [ "-Dfile.encoding=UTF-8" ] - args = [ "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--charset", "UTF-8", "--js", jsfile, "--js_output_file", zjsfile ] - maxHeapSize = "2g" - - msg = "\nRunning '"+commandLine.join(' ')+"'\n" - println(msg) - logOutFile.append(msg+"\n") - - if (logOutConsole) { - standardOutput = new org.apache.tools.ant.util.TeeOutputStream( - new org.apache.tools.ant.util.TeeOutputStream( - logOutFOS, - stdout), - standardOutput) - errorOutput = new org.apache.tools.ant.util.TeeOutputStream( - new org.apache.tools.ant.util.TeeOutputStream( - logErrFOS, - stderr), - System.err) - } else { - standardOutput = new org.apache.tools.ant.util.TeeOutputStream( - logOutFOS, - stdout) - errorOutput = new org.apache.tools.ant.util.TeeOutputStream( - logErrFOS, - stderr) - } - } - msg = "--" - println(msg) - logOutFile.append(msg+"\n") -} - - -task jalviewjsBuildAllCores { - group "JalviewJS" - description "Build the core js lib closures listed in the classlists dir" - dependsOn jalviewjsTranspile - dependsOn jalviewjsTransferUnzipSwingJs - - def j2sDir = "${jalviewDir}/${jalviewjsTransferSiteJsDir}/${jalviewjs_j2s_subdir}" - def swingJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_j2s_subdir}" - def libJ2sDir = "${jalviewDir}/${jalviewjsTransferSiteLibDir}/${jalviewjs_j2s_subdir}" - def jsDir = "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}/${jalviewjs_js_subdir}" - def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}/${jalviewjs_j2s_subdir}/core" - def prefixFile = "${jsDir}/core/coretop2.js" - def suffixFile = "${jsDir}/core/corebottom2.js" - - inputs.file prefixFile - inputs.file suffixFile - - def classlistFiles = [] - // add the classlists found int the jalviewjs_classlists_dir - fileTree(dir: "${jalviewDir}/${jalviewjs_classlists_dir}", include: "*.txt").each { - file -> - def name = file.getName() - ".txt" - classlistFiles += [ - 'file': file, - 'name': name - ] - } - - // _jmol and _jalview cores. Add any other peculiar classlist.txt files here - //classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jmol}"), 'name': "_jvjmol" ] - classlistFiles += [ 'file': file("${jalviewDir}/${jalviewjs_classlist_jalview}"), 'name': jalviewjsJalviewCoreName ] - - jalviewjsCoreClasslists = [] - - classlistFiles.each { - hash -> - - def file = hash['file'] - if (! file.exists()) { - //println("...classlist file '"+file.getPath()+"' does not exist, skipping") - return false // this is a "continue" in groovy .each closure - } - def name = hash['name'] - if (name == null) { - name = file.getName() - ".txt" - } - - def filelist = [] - file.eachLine { - line -> - filelist += line - } - def list = fileTree(dir: j2sDir, includes: filelist) - - def jsfile = "${outputDir}/core${name}.js" - def zjsfile = "${outputDir}/core${name}.z.js" - - jalviewjsCoreClasslists += [ - 'jsfile': jsfile, - 'zjsfile': zjsfile, - 'list': list, - 'name': name - ] - - inputs.file(file) - inputs.files(list) - outputs.file(jsfile) - outputs.file(zjsfile) - } - - // _stevesoft core. add any cores without a classlist here (and the inputs and outputs) - def stevesoftClasslistName = "_stevesoft" - def stevesoftClasslist = [ - 'jsfile': "${outputDir}/core${stevesoftClasslistName}.js", - 'zjsfile': "${outputDir}/core${stevesoftClasslistName}.z.js", - 'list': fileTree(dir: j2sDir, include: "com/stevesoft/pat/**/*.js"), - 'name': stevesoftClasslistName - ] - jalviewjsCoreClasslists += stevesoftClasslist - inputs.files(stevesoftClasslist['list']) - outputs.file(stevesoftClasslist['jsfile']) - outputs.file(stevesoftClasslist['zjsfile']) - - // _all core - def allClasslistName = "_all" - def allJsFiles = fileTree(dir: j2sDir, include: "**/*.js") - allJsFiles += fileTree( - dir: libJ2sDir, - include: "**/*.js", - excludes: [ - // these exlusions are files that the closure-compiler produces errors for. Should fix them - "**/org/jmol/jvxl/readers/IsoIntersectFileReader.js", - "**/org/jmol/export/JSExporter.js" - ] - ) - allJsFiles += fileTree( - dir: swingJ2sDir, - include: "**/*.js", - excludes: [ - // these exlusions are files that the closure-compiler produces errors for. Should fix them - "**/sun/misc/Unsafe.js", - "**/swingjs/jquery/jquery-editable-select.js", - "**/swingjs/jquery/j2sComboBox.js", - "**/sun/misc/FloatingDecimal.js" - ] - ) - def allClasslist = [ - 'jsfile': "${outputDir}/core${allClasslistName}.js", - 'zjsfile': "${outputDir}/core${allClasslistName}.z.js", - 'list': allJsFiles, - 'name': allClasslistName - ] - // not including this version of "all" core at the moment - //jalviewjsCoreClasslists += allClasslist - inputs.files(allClasslist['list']) - outputs.file(allClasslist['jsfile']) - outputs.file(allClasslist['zjsfile']) - - doFirst { - def logOutFile = file("${jalviewDirAbsolutePath}/${jalviewjsBuildDir}/${jalviewjs_j2s_closure_stdout}") - logOutFile.getParentFile().mkdirs() - logOutFile.createNewFile() - logOutFile.write(getDate("yyyy-MM-dd HH:mm:ss")+" jalviewjsBuildAllCores\n----\n") - - jalviewjsCoreClasslists.each { - jalviewjsCallCore(it.name, it.list, prefixFile, suffixFile, it.jsfile, it.zjsfile, logOutFile, jalviewjs_j2s_to_console.equals("true")) - } - } - -} - - -def jalviewjsPublishCoreTemplate(String coreName, String templateName, File inputFile, String outputFile) { - copy { - from inputFile - into file(outputFile).getParentFile() - rename { filename -> - if (filename.equals(inputFile.getName())) { - return file(outputFile).getName() - } - return null - } - filter(ReplaceTokens, - beginToken: '_', - endToken: '_', - tokens: [ - 'MAIN': '"'+main_class+'"', - 'CODE': "null", - 'NAME': jalviewjsJalviewTemplateName+" [core ${coreName}]", - 'COREKEY': jalviewjs_core_key, - 'CORENAME': coreName - ] - ) - } -} - - -task jalviewjsPublishCoreTemplates { - dependsOn jalviewjsBuildAllCores - def inputFileName = "${jalviewDir}/${j2s_coretemplate_html}" - def inputFile = file(inputFileName) - def outputDir = "${jalviewDir}/${jalviewjsTransferSiteCoreDir}" - - def outputFiles = [] - jalviewjsCoreClasslists.each { cl -> - def outputFile = "${outputDir}/${jalviewjsJalviewTemplateName}_${cl.name}.html" - cl['outputfile'] = outputFile - outputFiles += outputFile - } - - doFirst { - jalviewjsCoreClasslists.each { cl -> - jalviewjsPublishCoreTemplate(cl.name, jalviewjsJalviewTemplateName, inputFile, cl.outputfile) - } - } - inputs.file(inputFile) - outputs.files(outputFiles) -} - - -task jalviewjsSyncCore (type: Sync) { - dependsOn jalviewjsBuildAllCores - dependsOn jalviewjsPublishCoreTemplates - def inputFiles = fileTree(dir: "${jalviewDir}/${jalviewjsTransferSiteCoreDir}") - def outputDir = "${jalviewDir}/${jalviewjsSiteDir}" - - from inputFiles - into outputDir - def outputFiles = [] - rename { filename -> - outputFiles += "${outputDir}/${filename}" - null - } - preserve { - include "**" - } - outputs.files outputFiles - inputs.files inputFiles -} - - -// this Copy version of TransferSiteJs will delete anything else in the target dir -task jalviewjsCopyTransferSiteJs(type: Copy) { - dependsOn jalviewjsTranspile - from "${jalviewDir}/${jalviewjsTransferSiteJsDir}" - into "${jalviewDir}/${jalviewjsSiteDir}" -} - - -// this Sync version of TransferSite is used by buildship to keep the website automatically up to date when a file changes -task jalviewjsSyncTransferSiteJs(type: Sync) { - from "${jalviewDir}/${jalviewjsTransferSiteJsDir}" - include "**/*.*" - into "${jalviewDir}/${jalviewjsSiteDir}" - preserve { - include "**" - } -} - - -jalviewjsSyncAllLibs.mustRunAfter jalviewjsCopyTransferSiteJs -jalviewjsSyncResources.mustRunAfter jalviewjsCopyTransferSiteJs -jalviewjsSyncSiteResources.mustRunAfter jalviewjsCopyTransferSiteJs -jalviewjsSyncBuildProperties.mustRunAfter jalviewjsCopyTransferSiteJs - -jalviewjsSyncAllLibs.mustRunAfter jalviewjsSyncTransferSiteJs -jalviewjsSyncResources.mustRunAfter jalviewjsSyncTransferSiteJs -jalviewjsSyncSiteResources.mustRunAfter jalviewjsSyncTransferSiteJs -jalviewjsSyncBuildProperties.mustRunAfter jalviewjsSyncTransferSiteJs - - -task jalviewjsPrepareSite { - group "JalviewJS" - description "Prepares the website folder including unzipping files and copying resources" - dependsOn jalviewjsSyncAllLibs - dependsOn jalviewjsSyncResources - dependsOn jalviewjsSyncSiteResources - dependsOn jalviewjsSyncBuildProperties - dependsOn jalviewjsSyncCore -} - - -task jalviewjsBuildSite { - group "JalviewJS" - description "Builds the whole website including transpiled code" - dependsOn jalviewjsCopyTransferSiteJs - dependsOn jalviewjsPrepareSite -} - - -task cleanJalviewjsTransferSite { - doFirst { - delete "${jalviewDir}/${jalviewjsTransferSiteJsDir}" - delete "${jalviewDir}/${jalviewjsTransferSiteLibDir}" - delete "${jalviewDir}/${jalviewjsTransferSiteSwingJsDir}" - delete "${jalviewDir}/${jalviewjsTransferSiteCoreDir}" - } -} - - -task cleanJalviewjsSite { - dependsOn cleanJalviewjsTransferSite - doFirst { - delete "${jalviewDir}/${jalviewjsSiteDir}" - } -} - - -task jalviewjsSiteTar(type: Tar) { - group "JalviewJS" - description "Creates a tar.gz file for the website" - dependsOn jalviewjsBuildSite - def outputFilename = "jalviewjs-site-${JALVIEW_VERSION}.tar.gz" - archiveFileName = outputFilename - - compression Compression.GZIP - - from "${jalviewDir}/${jalviewjsSiteDir}" - into jalviewjs_site_dir // this is inside the tar file - - inputs.dir("${jalviewDir}/${jalviewjsSiteDir}") -} - - -task jalviewjsServer { - group "JalviewJS" - def filename = "jalviewjsTest.html" - description "Starts a webserver on localhost to test the website. See ${filename} to access local site on most recently used port." - def htmlFile = "${jalviewDirAbsolutePath}/${filename}" - doLast { - - def factory - try { - def f = Class.forName("org.gradle.plugins.javascript.envjs.http.simple.SimpleHttpFileServerFactory") - factory = f.newInstance() - } catch (ClassNotFoundException e) { - throw new GradleException("Unable to create SimpleHttpFileServerFactory") - } - def port = Integer.valueOf(jalviewjs_server_port) - def start = port - def running = false - def url - def jalviewjsServer - while(port < start+1000 && !running) { - try { - def doc_root = new File("${jalviewDirAbsolutePath}/${jalviewjsSiteDir}") - jalviewjsServer = factory.start(doc_root, port) - running = true - url = jalviewjsServer.getResourceUrl(jalviewjs_server_resource) - println("SERVER STARTED with document root ${doc_root}.") - println("Go to "+url+" . Run gradle --stop to stop (kills all gradle daemons).") - println("For debug: "+url+"?j2sdebug") - println("For verbose: "+url+"?j2sverbose") - } catch (Exception e) { - port++; - } - } - def htmlText = """ -

JalviewJS Test. <${url}>

-

JalviewJS Test with debug. <${url}?j2sdebug>

-

JalviewJS Test with verbose. <${url}?j2sdebug>

- """ - jalviewjsCoreClasslists.each { cl -> - def urlcore = jalviewjsServer.getResourceUrl(file(cl.outputfile).getName()) - htmlText += """ -

${jalviewjsJalviewTemplateName} [core ${cl.name}]. <${urlcore}>

- """ - println("For core ${cl.name}: "+urlcore) - } - - file(htmlFile).text = htmlText - } - - outputs.file(htmlFile) - outputs.upToDateWhen({false}) -} - - -task cleanJalviewjsAll { - group "JalviewJS" - description "Delete all configuration and build artifacts to do with JalviewJS build" - dependsOn cleanJalviewjsSite - dependsOn jalviewjsEclipsePaths - - doFirst { - delete "${jalviewDir}/${jalviewjsBuildDir}" - delete "${jalviewDir}/${eclipse_bin_dir}" - if (eclipseWorkspace != null && file(eclipseWorkspace.getAbsolutePath()+"/.metadata").exists()) { - delete file(eclipseWorkspace.getAbsolutePath()+"/.metadata") - } - delete jalviewjsJ2sAltSettingsFileName - } - - outputs.upToDateWhen( { false } ) -} - - -task jalviewjsIDE_checkJ2sPlugin { - group "00 JalviewJS in Eclipse" - description "Compare the swingjs/net.sf.j2s.core(-j11)?.jar file with the Eclipse IDE's plugin version (found in the 'dropins' dir)" - - doFirst { - def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}") - def j2sPluginFile = file(j2sPlugin) - def eclipseHome = System.properties["eclipse.home.location"] - if (eclipseHome == null || ! IN_ECLIPSE) { - throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. Skipping J2S Plugin Check.") - } - def eclipseJ2sPluginDirs = [ "${eclipseHome}/dropins" ] - def altPluginsDir = System.properties["org.eclipse.equinox.p2.reconciler.dropins.directory"] - if (altPluginsDir != null && file(altPluginsDir).exists()) { - eclipseJ2sPluginDirs += altPluginsDir - } - def foundPlugin = false - def j2sPluginFileName = j2sPluginFile.getName() - def eclipseJ2sPlugin - def eclipseJ2sPluginFile - eclipseJ2sPluginDirs.any { dir -> - eclipseJ2sPlugin = "${dir}/${j2sPluginFileName}" - eclipseJ2sPluginFile = file(eclipseJ2sPlugin) - if (eclipseJ2sPluginFile.exists()) { - foundPlugin = true - return true - } - } - if (!foundPlugin) { - def msg = "Eclipse J2S Plugin is not installed (could not find '${j2sPluginFileName}' in\n"+eclipseJ2sPluginDirs.join("\n")+"\n)\nTry running task jalviewjsIDE_copyJ2sPlugin" - System.err.println(msg) - throw new StopExecutionException(msg) - } - - def digest = MessageDigest.getInstance("MD5") - - digest.update(j2sPluginFile.text.bytes) - def j2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0') - - digest.update(eclipseJ2sPluginFile.text.bytes) - def eclipseJ2sPluginMd5 = new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0') - - if (j2sPluginMd5 != eclipseJ2sPluginMd5) { - def msg = "WARNING! Eclipse J2S Plugin '${eclipseJ2sPlugin}' is different to this commit's version '${j2sPlugin}'" - System.err.println(msg) - throw new StopExecutionException(msg) - } else { - def msg = "Eclipse J2S Plugin '${eclipseJ2sPlugin}' is the same as '${j2sPlugin}' (this is good)" - println(msg) - } - } -} - -task jalviewjsIDE_copyJ2sPlugin { - group "00 JalviewJS in Eclipse" - description "Copy the swingjs/net.sf.j2s.core(-j11)?.jar file into the Eclipse IDE's 'dropins' dir" - - doFirst { - def j2sPlugin = string("${jalviewDir}/${jalviewjsJ2sPlugin}") - def j2sPluginFile = file(j2sPlugin) - def eclipseHome = System.properties["eclipse.home.location"] - if (eclipseHome == null || ! IN_ECLIPSE) { - throw new StopExecutionException("Cannot find running Eclipse home from System.properties['eclipse.home.location']. NOT copying J2S Plugin.") - } - def eclipseJ2sPlugin = "${eclipseHome}/dropins/${j2sPluginFile.getName()}" - def eclipseJ2sPluginFile = file(eclipseJ2sPlugin) - def msg = "WARNING! Copying this commit's j2s plugin '${j2sPlugin}' to Eclipse J2S Plugin '${eclipseJ2sPlugin}'\n* May require an Eclipse restart" - System.err.println(msg) - copy { - from j2sPlugin - eclipseJ2sPluginFile.getParentFile().mkdirs() - into eclipseJ2sPluginFile.getParent() - } - } -} - - -task jalviewjsIDE_j2sFile { - group "00 JalviewJS in Eclipse" - description "Creates the .j2s file" - dependsOn jalviewjsCreateJ2sSettings -} - - -task jalviewjsIDE_SyncCore { - group "00 JalviewJS in Eclipse" - description "Build the core js lib closures listed in the classlists dir and publish core html from template" - dependsOn jalviewjsSyncCore -} - - -task jalviewjsIDE_SyncSiteAll { - dependsOn jalviewjsSyncAllLibs - dependsOn jalviewjsSyncResources - dependsOn jalviewjsSyncSiteResources - dependsOn jalviewjsSyncBuildProperties -} - - -cleanJalviewjsTransferSite.mustRunAfter jalviewjsIDE_SyncSiteAll - - -task jalviewjsIDE_PrepareSite { - group "00 JalviewJS in Eclipse" - description "Sync libs and resources to site dir, but not closure cores" - - dependsOn jalviewjsIDE_SyncSiteAll - //dependsOn cleanJalviewjsTransferSite // not sure why this clean is here -- will slow down a re-run of this task -} - - -task jalviewjsIDE_AssembleSite { - group "00 JalviewJS in Eclipse" - description "Assembles unzipped supporting zipfiles, resources, site resources and closure cores into the Eclipse transpiled site" - dependsOn jalviewjsPrepareSite -} - - -task jalviewjsIDE_SiteClean { - group "00 JalviewJS in Eclipse" - description "Deletes the Eclipse transpiled site" - dependsOn cleanJalviewjsSite -} - - -task jalviewjsIDE_Server { - group "00 JalviewJS in Eclipse" - description "Starts a webserver on localhost to test the website" - dependsOn jalviewjsServer -} - - -// buildship runs this at import or gradle refresh -task eclipseSynchronizationTask { - //dependsOn eclipseSetup - dependsOn createBuildProperties - if (J2S_ENABLED) { - dependsOn jalviewjsIDE_j2sFile - dependsOn jalviewjsIDE_checkJ2sPlugin - dependsOn jalviewjsIDE_PrepareSite - } -} - - -// buildship runs this at build time or project refresh -task eclipseAutoBuildTask { - //dependsOn jalviewjsIDE_checkJ2sPlugin - //dependsOn jalviewjsIDE_PrepareSite -} - - -task jalviewjs { - group "JalviewJS" - description "Build the site" - dependsOn jalviewjsBuildSite + outputs.file("${outputDir}/${archiveFileName}") }