+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
+//run.dependsOn prepare
+
+
+//testReportDirName = "test-reports" // note that test workingDir will be $jalviewDir
+test {
+ dependsOn prepare
+
+ if (useClover) {
+ dependsOn cloverClasses
+ } else { //?
+ dependsOn compileJava //?
+ }
+
+ useTestNG() {
+ includeGroups testng_groups
+ excludeGroups testng_excluded_groups
+ preserveOrder true
+ useDefaultListeners=true
+ // Uncomment to show stdout and stderr for tests in gradle build output
+ // testLogging.showStandardStreams = true
+ }
+
+ maxHeapSize = "1024m"
+
+ workingDir = jalviewDir
+ def testLaf = project.findProperty("test_laf")
+ if (testLaf != null) {
+ println("Setting Test LaF to '${testLaf}'")
+ systemProperty "laf", testLaf
+ }
+ def testHiDPIScale = project.findProperty("test_HiDPIScale")
+ if (testHiDPIScale != null) {
+ println("Setting Test HiDPI Scale to '${testHiDPIScale}'")
+ systemProperty "sun.java2d.uiScale", testHiDPIScale
+ }
+ sourceCompatibility = compile_source_compatibility
+ targetCompatibility = compile_target_compatibility
+ jvmArgs += additional_compiler_args
+
+ doFirst {
+ if (useClover) {
+ println("Running tests " + (useClover?"WITH":"WITHOUT") + " clover")
+ }
+ }
+}
+
+
+task compileLinkCheck(type: JavaCompile) {
+ options.fork = true
+ classpath = files("${jalviewDir}/${utils_dir}")
+ destinationDir = file("${jalviewDir}/${utils_dir}")
+ source = fileTree(dir: "${jalviewDir}/${utils_dir}", include: ["HelpLinksChecker.java", "BufferedLineReader.java"])
+
+ inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
+ inputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.java")
+ outputs.file("${jalviewDir}/${utils_dir}/HelpLinksChecker.class")
+ outputs.file("${jalviewDir}/${utils_dir}/BufferedLineReader.class")
+}
+
+
+task linkCheck(type: JavaExec) {
+ dependsOn prepare
+ dependsOn compileLinkCheck
+
+ def helpLinksCheckerOutFile = file("${jalviewDir}/${utils_dir}/HelpLinksChecker.out")
+ classpath = files("${jalviewDir}/${utils_dir}")
+ main = "HelpLinksChecker"
+ workingDir = "${helpBuildDir}"
+ args = [ "${helpBuildDir}/${help_dir}", "-nointernet" ]
+
+ def outFOS = new FileOutputStream(helpLinksCheckerOutFile, false) // false == don't append
+ standardOutput = new org.apache.tools.ant.util.TeeOutputStream(
+ outFOS,
+ System.out)
+ errorOutput = new org.apache.tools.ant.util.TeeOutputStream(
+ outFOS,
+ System.err)
+
+ inputs.dir(helpBuildDir)
+ outputs.file(helpLinksCheckerOutFile)
+}
+
+
+// import the pubhtmlhelp target
+ant.properties.basedir = "${jalviewDir}"
+ant.properties.helpBuildDir = "${helpBuildDir}/${help_dir}"
+ant.importBuild "${utils_dir}/publishHelp.xml"
+
+
+task cleanPackageDir(type: Delete) {
+ doFirst {
+ delete fileTree(dir: "${jalviewDir}/${package_dir}", include: "*.jar")
+ }
+}
+
+
+jar {
+ dependsOn prepare
+ dependsOn linkCheck
+
+ manifest {
+ attributes "Main-Class": main_class,
+ "Permissions": "all-permissions",
+ "Application-Name": applicationName,
+ "Codebase": application_codebase,
+ "Implementation-Version": JALVIEW_VERSION
+ }
+
+ def outputDir = "${jalviewDir}/${package_dir}"
+ destinationDirectory = file(outputDir)
+ archiveFileName = rootProject.name+".jar"
+ duplicatesStrategy "EXCLUDE"
+
+
+ exclude "cache*/**"
+ exclude "*.jar"
+ exclude "*.jar.*"
+ exclude "**/*.jar"
+ exclude "**/*.jar.*"
+
+ inputs.dir(sourceSets.main.java.outputDir)
+ sourceSets.main.resources.srcDirs.each{ dir ->
+ inputs.dir(dir)
+ }
+ outputs.file("${outputDir}/${archiveFileName}")
+}
+
+