X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=build.gradle;h=d89f3edaaf21f77ce7f675a4393e85457cd3ca34;hb=07727bb7e06eb681af51a95e941cb035ac637d10;hp=420d37cf2a17888b6890573fd68cf3644138fd19;hpb=ecdae8027a9bad9e43f0ab12c54aec09fade15a1;p=jalview.git diff --git a/build.gradle b/build.gradle index 420d37c..d89f3ed 100644 --- a/build.gradle +++ b/build.gradle @@ -23,6 +23,11 @@ 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 { @@ -31,6 +36,7 @@ buildscript { } dependencies { classpath "com.vladsch.flexmark:flexmark-all:0.62.0" + classpath "org.jsoup:jsoup:1.14.3" } } @@ -97,6 +103,7 @@ def overrideProperties(String propsFileName, boolean output = false) { 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" @@ -190,18 +197,20 @@ ext { testSourceDir = useClover ? cloverTestInstrDir : testDir testClassesDir = useClover ? cloverTestClassesDir : "${jalviewDir}/${test_output_dir}" - getdownWebsiteDir = string("${jalviewDir}/${getdown_website_dir}/${JAVA_VERSION}") + 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 // the following values might be overridden by the CHANNEL switch getdownDir = string("${getdownChannelName}/${JAVA_VERSION}") getdownAppBase = string("${getdown_channel_base}/${getdownDir}") - getdownArchiveAppBase = null + getdownArchiveAppBase = getdown_archive_base getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher}") getdownAppDistDir = getdown_app_dir_alt getdownImagesDir = string("${jalviewDir}/${getdown_images_dir}") @@ -220,6 +229,8 @@ ext { install4jBackground = string("${install4j_images_dir}/${install4j_background}") install4jBuildDir = "${install4j_build_dir}/${JAVA_VERSION}" install4jCheckSums = true + + applicationName = "${jalview_name}" switch (CHANNEL) { case "BUILD": @@ -241,7 +252,6 @@ ext { reportRsyncCommand = true install4jSuffix = "" install4jInstallerName = "${jalview_name} Installer" - getdownArchiveAppBase = getdown_archive_base break case "ARCHIVE": @@ -262,7 +272,7 @@ ext { case "ARCHIVELOCAL": getdownChannelName = string("archive/${JALVIEW_VERSION}") getdownDir = string("${getdownChannelName}/${JAVA_VERSION}") - getdownAppBase = file(getdownWebsiteDir).toURI().toString() + getdownAppBase = file(getdownAppBaseDir).toURI().toString() if (!file("${ARCHIVEDIR}/${package_dir}").exists()) { throw new GradleException("Must provide an ARCHIVEDIR value to produce an archive distribution") } else { @@ -326,7 +336,7 @@ ext { case [ "LOCAL", "JALVIEWJS" ]: JALVIEW_VERSION = "TEST" - getdownAppBase = file(getdownWebsiteDir).toURI().toString() + getdownAppBase = file(getdownAppBaseDir).toURI().toString() getdownArchiveAppBase = file("${jalviewDir}/${getdown_archive_dir}").toURI().toString() getdownLauncher = string("${jalviewDir}/${getdown_lib_dir}/${getdown_launcher_local}") install4jExtraScheme = "jalviewl" @@ -339,11 +349,13 @@ ext { } 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(getdownWebsiteDir).toURI().toString() + 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) @@ -357,11 +369,10 @@ ext { jvlChannelName = jvlChannelName.replaceAll("[^\\w\\-]+", "_") // install4j application and folder names if (install4jSuffix == "") { - install4jApplicationName = "${jalview_name}" install4jBundleId = "${install4j_bundle_id}" install4jWinApplicationId = install4j_release_win_application_id } else { - install4jApplicationName = "${jalview_name} ${install4jSuffix}" + 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 @@ -371,15 +382,15 @@ ext { } // sanitise folder and id names // install4jApplicationFolder = e.g. "Jalview Build" - install4jApplicationFolder = install4jApplicationName + install4jApplicationFolder = applicationName .replaceAll("[\"'~:/\\\\\\s]", "_") // replace all awkward filename chars " ' ~ : / \ .replaceAll("_+", "_") // collapse __ - install4jInternalId = install4jApplicationName + install4jInternalId = applicationName .replaceAll(" ","_") .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.] .replaceAll("_+", "") // collapse __ //.replaceAll("_*-_*", "-") // collapse _-_ - install4jUnixApplicationFolder = install4jApplicationName + install4jUnixApplicationFolder = applicationName .replaceAll(" ","_") .replaceAll("[^\\w\\-\\.]", "_") // replace other non [alphanumeric,_,-,.] .replaceAll("_+", "_") // collapse __ @@ -387,10 +398,10 @@ ext { .toLowerCase() getdownWrapperLink = install4jUnixApplicationFolder // e.g. "jalview_local" - getdownAppDir = string("${getdownWebsiteDir}/${getdownAppDistDir}") - //getdownJ11libDir = "${getdownWebsiteDir}/${getdown_j11lib_dir}" - getdownResourceDir = string("${getdownWebsiteDir}/${getdown_resource_dir}") - getdownInstallDir = string("${getdownWebsiteDir}/${getdown_install_dir}") + 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 @@ -1054,7 +1065,6 @@ cleanTest { // format is a string like date.format("dd MMMM yyyy") def getDate(format) { - def date = new Date() return date.format(format) } @@ -1429,7 +1439,7 @@ jar { manifest { attributes "Main-Class": main_class, "Permissions": "all-permissions", - "Application-Name": install4jApplicationName, + "Application-Name": applicationName, "Codebase": application_codebase, "Implementation-Version": JALVIEW_VERSION } @@ -1502,7 +1512,7 @@ shadowJar { } manifest { attributes "Implementation-Version": JALVIEW_VERSION, - "Application-Name": install4jApplicationName + "Application-Name": applicationName } duplicatesStrategy "INCLUDE" @@ -1527,7 +1537,7 @@ task getdownWebsite() { doFirst { // clean the getdown website and files dir before creating getdown folders - delete getdownWebsiteDir + delete getdownAppBaseDir delete getdownFilesDir copy { @@ -1539,7 +1549,7 @@ task getdownWebsite() { copy { from channelPropsFile - into getdownWebsiteDir + into getdownAppBaseDir } getdownWebsiteResourceFilenames += file(channelPropsFile).getName() @@ -1564,7 +1574,7 @@ task getdownWebsite() { } props.put("getdown_txt_title", jalview_name) - props.put("getdown_txt_ui.name", install4jApplicationName) + props.put("getdown_txt_ui.name", applicationName) // start with appbase getdownTextLines += "appbase = ${getdownAppBase}" @@ -1617,7 +1627,7 @@ task getdownWebsite() { if (s.exists()) { copy { from s - into "${getdownWebsiteDir}/${getdown_wrapper_script_dir}" + into "${getdownAppBaseDir}/${getdown_wrapper_script_dir}" } getdownTextLines += "resource = ${getdown_wrapper_script_dir}/${script}" } @@ -1670,18 +1680,18 @@ task getdownWebsite() { getdownTextLines += "jvmarg = -Dgetdownappbase=${getdownAppBase}" } - def getdownTxt = file("${getdownWebsiteDir}/getdown.txt") + 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("${getdownWebsiteDir}/${getdownLaunchJvl}") + 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 getdownWebsiteDir + into getdownAppBaseDir } // files going into the getdown website dir: getdown-launcher(-local).jar @@ -1690,7 +1700,7 @@ task getdownWebsite() { if (file(getdownLauncher).getName() != getdown_launcher) { rename(file(getdownLauncher).getName(), getdown_launcher) } - into getdownWebsiteDir + into getdownAppBaseDir } // files going into the getdown website dir: ./install dir and files @@ -1717,8 +1727,8 @@ task getdownWebsite() { from getdownTxt from launchJvl from getdownLauncher - from "${getdownWebsiteDir}/${getdown_build_properties}" - from "${getdownWebsiteDir}/${channel_props}" + from "${getdownAppBaseDir}/${getdown_build_properties}" + from "${getdownAppBaseDir}/${channel_props}" if (file(getdownLauncher).getName() != getdown_launcher) { rename(file(getdownLauncher).getName(), getdown_launcher) } @@ -1735,7 +1745,7 @@ task getdownWebsite() { if (buildDist) { inputs.dir("${jalviewDir}/${package_dir}") } - outputs.dir(getdownWebsiteDir) + outputs.dir(getdownAppBaseDir) outputs.dir(getdownFilesDir) } @@ -1766,9 +1776,9 @@ task getdownDigest(type: JavaExec) { classpath = files(getdownLauncher) } main = "com.threerings.getdown.tools.Digester" - args getdownWebsiteDir - inputs.dir(getdownWebsiteDir) - outputs.file("${getdownWebsiteDir}/digest2.txt") + args getdownAppBaseDir + inputs.dir(getdownAppBaseDir) + outputs.file("${getdownAppBaseDir}/digest2.txt") } @@ -1778,7 +1788,7 @@ task getdown() { dependsOn getdownDigest doLast { if (reportRsyncCommand) { - def fromDir = getdownWebsiteDir + (getdownWebsiteDir.endsWith('/')?'':'/') + 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'" @@ -1804,15 +1814,12 @@ task getdownArchiveBuild() { def v = "v${JALVIEW_VERSION_UNDERSCORES}" def vDir = "${getdownArchiveDir}/${v}" getdownFullArchiveDir = "${vDir}/getdown" - def vLaunchVersionJvl = "${vDir}/jalview-${v}.jvl" + getdownVersionLaunchJvl = "${vDir}/jalview-${v}.jvl" + def vAltDir = "alt_${v}" def archiveImagesDir = "${jalviewDir}/${channel_properties_dir}/old/images" doFirst { - if (getdownArchiveAppBase == null) { - throw new StopExecutionException("Cannot create getdownArchive for CHANNEL=${CHANNEL}") - } - // cleanup old "old" dir delete getdownArchiveDir @@ -1823,7 +1830,7 @@ task getdownArchiveBuild() { // the libdir copy { - from "${getdownWebsiteDir}/${getdownAppDistDir}" + from "${getdownAppBaseDir}/${getdownAppDistDir}" into "${getdownFullArchiveDir}/${vAltDir}" } @@ -1851,7 +1858,7 @@ task getdownArchiveBuild() { getdownArchiveTxt.write(getdownArchiveTextLines.join("\n")) - def vLaunchJvl = file(vLaunchVersionJvl) + def vLaunchJvl = file(getdownVersionLaunchJvl) vLaunchJvl.getParentFile().mkdirs() vLaunchJvl.write("appbase=${getdownFullArchiveAppBase}\n") def vLaunchJvlPath = vLaunchJvl.toPath().toAbsolutePath() @@ -1863,9 +1870,9 @@ task getdownArchiveBuild() { // files going into the getdown files dir: getdown.txt, getdown-launcher.jar, channel-launch.jvl, build_properties copy { from getdownLauncher - from "${getdownWebsiteDir}/${getdownLaunchJvl}" - from "${getdownWebsiteDir}/${getdown_launcher_new}" - from "${getdownWebsiteDir}/${channel_props}" + from "${getdownAppBaseDir}/${getdownLaunchJvl}" + from "${getdownAppBaseDir}/${getdown_launcher_new}" + from "${getdownAppBaseDir}/${channel_props}" if (file(getdownLauncher).getName() != getdown_launcher) { rename(file(getdownLauncher).getName(), getdown_launcher) } @@ -1905,7 +1912,7 @@ tasks.withType(JavaCompile) { clean { doFirst { - delete getdownWebsiteDir + delete getdownAppBaseDir delete getdownFilesDir delete getdownArchiveDir } @@ -2011,12 +2018,11 @@ clean { task cleanInstallersDataFiles { def installersOutputTxt = file("${jalviewDir}/${install4jBuildDir}/output.txt") def installersSha256 = file("${jalviewDir}/${install4jBuildDir}/sha256sums") - def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_") - def installersJsonFile = file("${jalviewDir}/${install4jBuildDir}/installers-${VERSION_UNDERSCORES}.json") + def hugoDataJsonFile = file("${jalviewDir}/${install4jBuildDir}/installers-${JALVIEW_VERSION_UNDERSCORES}.json") doFirst { delete installersOutputTxt delete installersSha256 - delete installersJsonFile + delete hugoDataJsonFile } } @@ -2043,7 +2049,7 @@ task installerFiles(type: com.install4j.gradle.Install4jTask) { variables = [ 'JALVIEW_NAME': jalview_name, - 'JALVIEW_APPLICATION_NAME': install4jApplicationName, + 'JALVIEW_APPLICATION_NAME': applicationName, 'JALVIEW_DIR': "../..", 'OSX_KEYSTORE': OSX_KEYSTORE, 'OSX_APPLEID': OSX_APPLEID, @@ -2075,7 +2081,7 @@ task installerFiles(type: com.install4j.gradle.Install4jTask) { 'WRAPPER_SCRIPT_BIN_DIR': getdown_wrapper_script_dir, 'INSTALLER_NAME': install4jInstallerName, 'INSTALL4J_UTILS_DIR': install4j_utils_dir, - 'GETDOWN_WEBSITE_DIR': getdown_website_dir, + 'GETDOWN_CHANNEL_DIR': getdownChannelDir, 'GETDOWN_FILES_DIR': getdown_files_dir, 'GETDOWN_RESOURCE_DIR': getdown_resource_dir, 'GETDOWN_DIST_DIR': getdownAppDistDir, @@ -2124,7 +2130,7 @@ task installerFiles(type: com.install4j.gradle.Install4jTask) { } //verbose=true - inputs.dir(getdownWebsiteDir) + inputs.dir(getdownAppBaseDir) inputs.file(install4jConfFile) inputs.file("${install4jDir}/${install4j_info_plist_file_associations}") inputs.dir(macosJavaVMDir) @@ -2132,60 +2138,66 @@ task installerFiles(type: com.install4j.gradle.Install4jTask) { outputs.dir("${jalviewDir}/${install4j_build_dir}/${JAVA_VERSION}") } -def writeInstallersJsonFile(File installersOutputTxt, File installersSha256, File installersJsonFile) { - if (!installersOutputTxt.exists()) { - throw new GradleException("Required input file '${installersOutputTxt.getPath()}' doesn't exist.") - return null; - } - if (install4jCheckSums && (!installersSha256)) { - throw new GradleException("Required input file '${installersSha256.getPath()}' doesn't exist.") - return null; - } - def hash = [:] - 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.readLines().each { def line -> +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(/\s+\*?/) - def filename = vals[1] - def innerHash = (hash.(idHash."${filename}"))."sha256" = vals[0] + 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] + } } } - return installersJsonFile.write(new JsonBuilder(hash).toPrettyString()) -} - -task makeInstallersJsonFile { - dependsOn installerFiles - - def installersOutputTxt = file("${jalviewDir}/${install4jBuildDir}/output.txt") - def installersSha256 = file("${jalviewDir}/${install4jBuildDir}/sha256sums") - def VERSION_UNDERSCORES = JALVIEW_VERSION.replaceAll("\\.", "_") - def installersJsonFile = file("${jalviewDir}/${install4jBuildDir}/installers-${VERSION_UNDERSCORES}.json") - - inputs.file(installersOutputTxt) - if (install4jCheckSums) { - inputs.file(installersSha256) - } - outputs.file(installersJsonFile) - doFirst { - writeInstallersJsonFile(installersOutputTxt, installersSha256, installersJsonFile) + [ + "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 { @@ -2196,13 +2208,12 @@ task staticMakeInstallersJsonFile { 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=...") } - writeInstallersJsonFile(file(output), file(sha256), file(json)) + writeDataJsonFile(file(output), file(sha256), file(json)) } } task installers { dependsOn installerFiles - dependsOn makeInstallersJsonFile } @@ -2311,7 +2322,9 @@ task sourceDist(type: Tar) { exclude ("utils/InstallAnywhere") exclude (getdown_files_dir) - exclude (getdown_website_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") @@ -2340,6 +2353,274 @@ task sourceDist(type: Tar) { } } +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) + } +} + +def hugoTemplateSubstitutions(String input) { + def output = input + output = output.replaceAll("__DATE__", getDate("yyyy-MM-dd")) + output = output.replaceAll("__CHANNEL__", propertiesChannelName) + output = output.replaceAll("__APPLICATION_NAME__", applicationName) + output = output.replaceAll("__GIT_HASH__", gitHash) + output = output.replaceAll("__GIT_BRANCH__", gitBranch) + output = output.replaceAll("__VERSION__", JALVIEW_VERSION) + output = output.replaceAll("__JAVA_VERSION__", JAVA_VERSION) + output = output.replaceAll("__VERSION_UNDERSCORES__", JALVIEW_VERSION_UNDERSCORES) + return output +} + +def ulToList(Element ul, int indent) { + def list = "" + ul.children().each { e -> + if (e.tagName().toLowerCase() == "ul") { + list = list.stripTrailing() + "\n" + list += ulToList(e, indent+1) + } else if (e.tagName().toLowerCase() == "li") { + def issues = [] + def issuesText = "" + def mdItem = " " * indent + "- " + e.childNodes().any {n -> + if (n.nodeName().equals("#comment")) { + mdItem += "{{}}${n.getData()}{{}} " + issuesText = n.getData().trim() + issues = n.getData().trim().split(/[,\s]+/).findAll { it.startsWith("JAL-") } + return true + } + } + def safeText = issuesText.replaceAll('"', '\"') + def joinedIssues = issues.join(",") + def issuesLink = (issues.size() > 0) ? + " {{< jal issue=\"${joinedIssues}\" alt=\"${safeText}\" >}}" + : "" + def addedIssues = false + e.childNodes().each { node -> + if (node.nodeName().toLowerCase() == "ul") { + // add issues link before sub list if it's last + if (node.nextSibling() == null) { + mdItem += "${issuesLink}" + addedIssues = true + } + mdItem = mdItem.stripTrailing() + "\n" + mdItem += ulToList(node, indent+1) + } else if (node.nodeName() == "#text") { + mdItem += node.text() + } else if (node.nodeName().toLowerCase() == "strong") { + mdItem += "**${node.text()}**" + } else if (node.nodeName().toLowerCase() == "em") { + // if (true || (node.text().length() > 50 && node.text().count(" ") > 10) || (!node.nextSibling().text().startsWith("\\s*\\n"))) { + mdItem += "*${node.text()}*" + // } else { + // mdItem += "### "+node.text() + // } + } else if (node.nodeName().toLowerCase() == "br") { + mdItem += "
\n" + } else if (node.nodeName().toLowerCase() == "a") { + mdItem += "[${node.text()}](${node.attr('href')})" + } + } + if (!addedIssues) { + mdItem += issuesLink + } + list += mdItem.stripTrailing()+"\n" + } else if (e.tagName().toLowerCase() == "div") { + e.children().each { eee -> + list += ulToList(eee, indent) + } + } else if (e.tagName().toLowerCase() == "strong") { + list += "**${e.text()}**" + } else if (e.tagName().toLowerCase() == "em") { + if (e.text().length() > 50 && e.text().count(" ") > 20) { + list += "*${e.text()}*" + } else { + list += "\n\n### ${e.text()}\n\n" + } + } + } + return list +} + +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) + + doFirst { + // specific release template for version archive + def summary = "${applicationName} ${JALVIEW_VERSION}" + def changes = "" + def oldDate = null + if (CHANNEL == "RELEASE") { + def releasesHtmlFile = file("${helpSourceDir}/${releases_html}") + //HTMLPARSE + def html = releasesHtmlFile.text + def doc = Jsoup.parse(html) + def table = doc.select("table").first() + def headings = table.select("tr").first().select("th").collect { it.text() } + def releaseRow = null + def trs = table.select("tr") + trs.any { tr -> + def tds = tr.select("td") + if (tds.size() == 0) + return false + def releaseTd = tds.first() + if (releaseTd.text().startsWith("${JALVIEW_VERSION} ")) { + releaseRow = tr + return true + } + } + + if (releaseRow != null && headings != null && headings.size() == 3) { + def releaseTd = releaseRow.select("td").first() + def spaceIndex = releaseTd.text().indexOf(" ") + if (spaceIndex >= 0) { + oldDate = new Date().parse("dd/MM/yyyy", releaseTd.text().substring(spaceIndex+1)) + } + def releaseCells = releaseRow.select("td") + if (releaseCells.size() == 3) { + def title1 = headings[1] + def title2 = headings[2] + + def lastDotIndex = JALVIEW_VERSION.lastIndexOf(".") + if (lastDotIndex > 0) { + try { + def patchRelease = JALVIEW_VERSION.substring(lastDotIndex+1) as Integer + def patchReleaseString = null + if (patchRelease == 0) { + patchReleaseString = "first minor" + } else if (patchRelease == 1) { + patchReleaseString = "first patch" + } else if (patchRelease == 2) { + patchReleaseString = "second patch" + } else if (patchRelease == 3) { + patchReleaseString = "third patch" + } else if (patchRelease == 4) { + patchReleaseString = "fourth patch" + } else if (patchRelease == 5) { + patchReleaseString = "fifth patch" + } else if (patchRelease == 6) { + patchReleaseString = "sixth patch" + } else if (patchRelease == 7) { + patchReleaseString = "seventh patch" + } else if (patchRelease > 13 && (patchRelease % 10 == 1)) { + patchReleaseString += "st" + } else if (patchRelease > 13 && (patchRelease % 10 == 2)) { + patchReleaseString += "nd" + } else if (patchRelease > 13 && (patchRelease % 10 == 3)) { + patchReleaseString += "rd" + } else if (patchRelease != null) { + patchReleaseString += "th" + } + summary += (patchReleaseString != null) ? " is the ${patchReleaseString} release in the ${JALVIEW_VERSION.substring(0,lastDotIndex)} series." : "" + } catch(Exception e) { + summary = "" + } + } + + [1,2].each { col -> + def colChanges = "" + if (headings[col] != null && headings[col].size() > 0) { + releaseCells[col].children().each { e -> + if (e.tagName().toLowerCase() == "ul" || e.tagName().toLowerCase() == "div") { + if (colChanges != "") { + colChanges = colChanges.stripTrailing() + "\n" + } + colChanges += ulToList(e, 0) + } else if (e.tagName().toLowerCase() == "em") { + colChanges += "\n\n### ${e.text()}\n\n" + } + } + } + if (colChanges != "") { + def className = headings[col].replaceAll(" ","_").toLowerCase().replaceAll("[^_a-z]","") + changes += "
\n\n## ${headings[col]}\n\n${colChanges}\n
\n\n" + } + } + + if (changes != "") { + changes = "
\n\n${changes}\n\n
" + } + } + } + } + + 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 + // summary in version archive release pages only appears from 2.10.2b2 onwards + if (oldDate.format("yyyy") as Integer >= 2019 || JALVIEW_VERSION.startsWith("2.10")) { + def summaryFile = file("${jalviewDir}/${whatsnew_dir}/whatsnew-${JALVIEW_VERSION_UNDERSCORES}.md") + if (summaryFile.exists()) { + summary = summaryFile.text + } else { + summary = "" + } + content = content.replaceAll("__SUMMARY__", summary) + } else { + content = content.replaceAll("__SUMMARY__", "") + } + content = content.replaceAll("__CHANGES__", changes) + if (oldDate != null) { + if (oldDate[java.util.Calendar.YEAR] < 90) { + oldDate[java.util.Calendar.YEAR] += 2000 + } + content = content.replaceAll("__DATE__", oldDate.format("yyyy-MM-dd")) + } + newFile.text = hugoTemplateSubstitutions(content) + } + } + + inputs.dir(hugoTemplatesDir) + inputs.property("JALVIEW_VERSION", { JALVIEW_VERSION }) + inputs.property("CHANNEL", { CHANNEL }) +} + task helppages { dependsOn copyHelp