+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"
+ 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 {
+ print ("Setting target compatibility to "+targetCompatibility+"\n")
+ }
+}
+
+
+clean {
+ doFirst {
+ delete sourceSets.main.java.outputDir
+ }
+}
+
+
+cleanTest {
+ dependsOn cleanClover
+ doFirst {
+ delete sourceSets.test.java.outputDir
+ }
+}
+
+
+// format is a string like date.format("dd MMMM yyyy")
+def getDate(format) {
+ 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, "<span class=\"octicon octicon-link\"></span>")
+
+ 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 = '''<html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Content-Style-Type" content="text/css" />
+ <meta name="generator" content="flexmark" />
+'''
+ htmlText += ((title != null) ? " <title>${title}</title>" : '' )
+ htmlText += '''
+ <style type="text/css">code{white-space: pre;}</style>
+'''
+ htmlText += ((cssFile != null) ? cssFile.text : '')
+ htmlText += '''</head>
+ <body>
+'''
+ htmlText += htmlBody
+ htmlText += '''
+ </body>
+</html>
+'''
+
+ 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}"
+ from(inputDir) {
+ include('**/*.txt')
+ include('**/*.md')
+ include('**/*.html')
+ include('**/*.xml')
+ filter(ReplaceTokens,
+ beginToken: '$$',
+ endToken: '$$',
+ tokens: [
+ 'Version-Rel': JALVIEW_VERSION,
+ 'Year-Rel': getDate("yyyy")
+ ]
+ )
+ }
+ from(inputDir) {
+ exclude('**/*.txt')
+ exclude('**/*.md')
+ exclude('**/*.html')
+ exclude('**/*.xml')
+ }
+ into outputDir
+
+ inputs.dir(inputDir)
+ outputs.dir(outputDir)
+}
+
+
+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 = '<div class="release_notes">\n\n'
+ def inSection = false
+ changes.eachLine { line ->
+ def m = null
+ if (m = line =~ /^##([^#].*)$/) {
+ if (inSection) {
+ changesHugo += "</div>\n\n"
+ }
+ def section = m[0][1].trim()
+ section = section.toLowerCase()
+ section = section.replaceAll(/ +/, "_")
+ section = section.replaceAll(/[^a-z0-9_\-]/, "")
+ changesHugo += "<div class=\"${section}\">\n\n"
+ inSection = true
+ } else if (m = line =~ /^(\s*-\s*)<!--([^>]+)-->(.*?)(<br\/?>)?\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>}}${comment}{{</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</div>\n\n"
+ }
+ changesHugo += '</div>'
+ }
+
+ 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}"
+ from(inputDir) {
+ include('**/*.txt')
+ include('**/*.md')
+ include('**/*.html')
+ include('**/*.hs')
+ include('**/*.xml')
+ include('**/*.jhm')
+ filter(ReplaceTokens,
+ beginToken: '$$',
+ endToken: '$$',
+ tokens: [
+ 'Version-Rel': JALVIEW_VERSION,
+ 'Year-Rel': getDate("yyyy")
+ ]
+ )
+ }
+ from(inputDir) {
+ exclude('**/*.txt')
+ exclude('**/*.md')
+ exclude('**/*.html')
+ exclude('**/*.hs')
+ exclude('**/*.xml')
+ exclude('**/*.jhm')
+ }
+ into outputDir
+
+ inputs.dir(inputDir)
+ outputs.files(helpFile)
+ outputs.dir(outputDir)
+}
+
+
+task releasesTemplates {
+ group "help"
+ description "Recreate whatsNew.html and releases.html from markdown files and templates in help"
+
+ dependsOn copyHelp
+
+ def releasesTemplateFile = file("${jalviewDir}/${releases_template}")
+ def whatsnewTemplateFile = file("${jalviewDir}/${whatsnew_template}")
+ def releasesHtmlFile = file("${helpBuildDir}/${help_dir}/${releases_html}")
+ def whatsnewHtmlFile = file("${helpBuildDir}/${help_dir}/${whatsnew_html}")
+ def releasesMdDir = "${jalviewDir}/${releases_dir}"
+ def whatsnewMdDir = "${jalviewDir}/${whatsnew_dir}"
+
+ doFirst {
+ def releaseMdFile = file("${releasesMdDir}/release-${JALVIEW_VERSION_UNDERSCORES}.md")
+ def whatsnewMdFile = file("${whatsnewMdDir}/whatsnew-${JALVIEW_VERSION_UNDERSCORES}.md")
+
+ if (CHANNEL == "RELEASE") {
+ if (!releaseMdFile.exists()) {
+ throw new GradleException("File ${releaseMdFile} must be created for RELEASE")
+ }
+ if (!whatsnewMdFile.exists()) {
+ throw new GradleException("File ${whatsnewMdFile} must be created for RELEASE")
+ }
+ }
+
+ def releaseFiles = fileTree(dir: releasesMdDir, include: "release-*.md")
+ def releaseFilesDates = releaseFiles.collectEntries {
+ [(it): getMdDate(it)]
+ }
+ releaseFiles = releaseFiles.sort { a,b -> releaseFilesDates[a].compareTo(releaseFilesDates[b]) }
+
+ def releasesTemplate = releasesTemplateFile.text
+ 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 += "<a id=\"Jalview.${partialVersion}\">${displayPart}</a>"
+ 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")
+ }
+
+ }
+
+ inputs.file(releasesTemplateFile)
+ inputs.file(whatsnewTemplateFile)
+ inputs.dir(releasesMdDir)
+ inputs.dir(whatsnewMdDir)
+ outputs.file(releasesHtmlFile)
+ outputs.file(whatsnewHtmlFile)
+}
+
+
+task copyResources(type: Copy) {
+ group = "build"
+ description = "Copy (and make text substitutions in) the resources dir to the build area"
+
+ def inputDir = resourceDir
+ def outputDir = resourcesBuildDir
+ from(inputDir) {
+ include('**/*.txt')
+ include('**/*.md')
+ include('**/*.html')
+ include('**/*.xml')
+ filter(ReplaceTokens,
+ beginToken: '$$',
+ endToken: '$$',
+ tokens: [
+ 'Version-Rel': JALVIEW_VERSION,
+ 'Year-Rel': getDate("yyyy")
+ ]
+ )
+ }
+ from(inputDir) {
+ exclude('**/*.txt')
+ exclude('**/*.md')
+ exclude('**/*.html')
+ exclude('**/*.xml')
+ }
+ into outputDir
+
+ inputs.dir(inputDir)
+ outputs.dir(outputDir)
+}
+
+task copyChannelResources(type: Copy) {
+ dependsOn copyResources
+ group = "build"
+ description = "Copy the channel resources dir to the build resources area"
+
+ 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)
+ }
+ 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
+ }
+ outputs.file(outputFile)
+}
+
+
+task buildIndices(type: JavaExec) {
+ dependsOn copyHelp
+ classpath = sourceSets.main.compileClasspath
+ main = "com.sun.java.help.search.Indexer"
+ workingDir = "${helpBuildDir}/${help_dir}"
+ def argDir = "html"
+ args = [ argDir ]
+ inputs.dir("${workingDir}/${argDir}")
+
+ outputs.dir("${classesDir}/doc")
+ outputs.dir("${classesDir}/help")
+ outputs.file("${workingDir}/JavaHelpSearch/DOCS")
+ outputs.file("${workingDir}/JavaHelpSearch/DOCS.TAB")
+ outputs.file("${workingDir}/JavaHelpSearch/OFFSETS")
+ outputs.file("${workingDir}/JavaHelpSearch/POSITIONS")
+ outputs.file("${workingDir}/JavaHelpSearch/SCHEMA")
+ outputs.file("${workingDir}/JavaHelpSearch/TMAP")
+}
+
+task buildResources {
+ dependsOn copyResources
+ dependsOn copyChannelResources
+ dependsOn createBuildProperties
+}
+
+task prepare {
+ dependsOn buildResources
+ dependsOn copyDocs
+ dependsOn copyHelp
+ dependsOn releasesTemplates
+ dependsOn convertMdFiles
+ dependsOn buildIndices
+}
+
+
+compileJava.dependsOn prepare
+run.dependsOn compileJava
+compileTestJava.dependsOn compileJava
+
+
+
+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
+ }
+}
+
+/* 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(",")
+ 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"