blob: 857164635d65bdb234128e83615dedca2fb739a4 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// TODO 1: the separation of sources between tools and refGuide is awkward; it'd be
// better to separate the refGuideTools as a plain Java module and then depend on
// it as a project dependency. This would enable this module to *not* be a java module at all
// and inherit from base, adding just refGuide-related tasks.
// OR (better) one could rewrite those tools in Groovy (or Kotlin) and use them directly, without
// an additional compilation phase.
// TODO 2: property expansion via ant properties is awkward in gradle. We can do cleaner than going
// through ant -- we could use gradle's expand when copying or at least use some more humane
// property names.
// TODO 3: currently buildscript dependencies are hardcoded (asciidoctor) because they can't be resolved
// using Palantir's plugin. This is another reason to switch to gradle-based tools -- then
// only the build script dependencies would be needed and asciidoctorj would be removed from version
// properties entirely (it is only used locally in this build file).
import java.time.*
import java.time.format.*
import java.nio.file.*
import org.asciidoctor.*
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath "org.asciidoctor:asciidoctorj:1.6.2"
}
}
plugins {
id 'java'
id 'com.github.jruby-gradle.base' version '2.0.0-alpha.7'
}
// This project does not contribute anything to main dependencies.
versionsLock {
testProject()
}
description = 'Solr reference guide'
// Use an internal proxy to ruby gems.
repositories {
ruby.gems()
}
configurations {
depVer
refGuide
}
dependencies {
// Dependencies to compile internal tools.
implementation('org.asciidoctor:asciidoctorj')
implementation('com.vaadin.external.google:android-json')
implementation('org.jsoup:jsoup')
implementation('org.slf4j:jcl-over-slf4j')
implementation('org.slf4j:slf4j-simple')
implementation('org.apache.logging.log4j:log4j-core')
implementation('com.google.guava:guava')
implementation('commons-codec:commons-codec')
// Dependencies referenced in the guide.
depVer('commons-codec:commons-codec')
depVer('io.dropwizard.metrics:metrics-core')
depVer('org.apache.logging.log4j:log4j-core')
depVer('org.apache.opennlp:opennlp-tools')
depVer('org.apache.tika:tika-core')
depVer('org.apache.velocity.tools:velocity-tools-generic')
depVer('org.apache.zookeeper:zookeeper')
// jekyll dependencies
gems 'rubygems:jekyll:3.5.2'
gems 'rubygems:jekyll-asciidoc:3.0.0'
// don't know why we have to explicitly add these deps but it doesn't resolve them
// automatically.
gems 'rubygems:tilt:2.0.10'
gems 'rubygems:slim:4.0.1'
gems 'rubygems:concurrent-ruby:1.0.5'
}
sourceSets {
refGuide {
java {
srcDirs = []
}
resources {
srcDirs = ['src']
}
}
main {
java {
srcDirs = ['tools']
}
}
test {
java {
srcDirs = []
}
}
}
ext {
buildContentDir = file("${buildDir}/content")
mainPage = "index"
solrDocsVersion = "${version}".replaceAll(/^(\d+\.\d+)(|\..*)$/, "\$1")
solrDocsVersionPath = "${solrDocsVersion}".replaceAll(/^(\d+)\.(\d+)$/, "\$1_\$2_0")
solrGuideVersion = propertyOrDefault("solrGuideVersion", "${solrDocsVersion}-DRAFT")
solrRootPath = '../../../../solr/'
solrGuideDraftStatus = solrGuideVersion.matches(/^\d+\.\d+(|\.\d+)$/) ? "" : "DRAFT"
solrGuideVersionPath = solrGuideVersion.replaceAll(/^(\d+)\.(\d+)(-DRAFT)?.*/, "\$1_\$2\$3")
javadocLink = "https://docs.oracle.com/en/java/javase/11/docs/api/"
if (project.hasProperty("local.javadocs")) {
htmlSolrJavadocs = "link:../../docs/"
htmlLuceneJavadocs = "link:../../../../lucene/build/docs/"
} else {
htmlSolrJavadocs = "https://lucene.apache.org/solr/${solrDocsVersionPath}/"
htmlLuceneJavadocs = "https://lucene.apache.org/core/${solrDocsVersionPath}/"
}
bareBonesDir = file("${buildDir}/bare-bones-html")
// Some additional version properties are lazily computed
// in setupLazyProps (because they need to be computed after evaluation is complete).
props = [
"solr-root-path" : solrRootPath,
"solr-guide-draft-status": solrGuideDraftStatus,
"solr-guide-version" : solrGuideVersion,
"solr-guide-version-path": solrGuideVersionPath,
"solr-docs-version" : solrDocsVersion,
"javadoc.link" : javadocLink,
"java-javadocs" : javadocLink,
"solr-javadocs" : htmlSolrJavadocs,
"html-solr-javadocs" : htmlSolrJavadocs,
"lucene-javadocs" : htmlLuceneJavadocs,
"html-lucene-javadocs" : htmlLuceneJavadocs,
"build-date" : buildDate,
"DSTAMP" : buildDate,
"build-year" : buildYear,
"current.year" : buildYear
]
asciiDocAttrs = [
'common': [
'attribute-missing' : 'warn',
'icons' : 'font',
'icon-set' : 'fa',
'figure-caption!' : '',
'idprefix' : '',
'idseparator' : '-',
'source-highlighter': 'coderay',
'solr-root-path' : solrRootPath,
],
'html' : [
'imagesdir': buildContentDir.toString()
]
]
}
task setupLazyProps {
doFirst {
// These properties have to be resolved after the configuration phase is complete (palantir's constraint)
// so we can't use them as input for caches.
[
["ivyversions./commons-codec/commons-codec", "commons-codec", "commons-codec"],
["ivyversions.io.dropwizard.metrics.version", "io.dropwizard.metrics", "metrics-core"],
["ivyversions.org.apache.logging.log4j.version", "org.apache.logging.log4j", "log4j-core"],
["ivyversions./org.apache.opennlp/opennlp-tools", "org.apache.opennlp", "opennlp-tools"],
["ivyversions.org.apache.tika.version", "org.apache.tika", "tika-core"],
["ivyversions.org.apache.velocity.tools.version", "org.apache.velocity.tools", "velocity-tools-generic"],
["ivyversions.org.apache.zookeeper.version", "org.apache.zookeeper", "zookeeper"],
["ivy-zookeeper-version", "org.apache.zookeeper", "zookeeper"],
["ivy-log4j-version", "org.apache.logging.log4j", "log4j-core"],
["ivy-tika-version", "org.apache.tika", "tika-core"],
["ivy-opennlp-version", "org.apache.opennlp", "opennlp-tools"],
["ivy-commons-codec-version", "commons-codec", "commons-codec"],
["ivy-velocity-tools-version", "org.apache.velocity.tools", "velocity-tools-generic"],
["ivy-dropwizard-version", "io.dropwizard.metrics", "metrics-core"]
].each { antProp, depGroup, depId ->
props[antProp] = getVersion(depGroup, depId, configurations.depVer)
}
// Emit info about properties for clarity.
logger.warn("Building ref guide with:\n" + props.collect({ k, v -> " ${k} -> ${v}" }).join('\n'))
}
}
task prepareSources(type: Sync) {
dependsOn setupLazyProps
// If replaceable properties change, we have to rerun the task.
inputs.properties props
def dummyAntProject = new org.apache.tools.ant.Project()
from(file("src"), {
exclude '**/*.template'
})
from(file("src"), {
include '**/*.template'
rename '(.+)\\.template', '$1'
filteringCharset = 'UTF-8'
filter(org.apache.tools.ant.filters.ExpandProperties, project: dummyAntProject)
})
doFirst {
props.each { k, v ->
dummyAntProject.setProperty(k, v)
}
}
into buildContentDir
}
task buildNavDataFiles(type: JavaExec) {
dependsOn prepareSources, classes
classpath = sourceSets.main.runtimeClasspath
main = 'BuildNavDataFiles'
workingDir = buildContentDir
args([
"${buildContentDir}",
"${mainPage}"
])
doFirst {
// Remove previously generated files first.
[
"scrollnav.json",
"sidebar.json"
].each { name ->
project.delete(file("${buildContentDir}/_data/${name}"))
}
}
}
task bareBonesAsciiDoctor {
dependsOn buildNavDataFiles
doLast {
// Regenerate fully.
project.delete(bareBonesDir)
bareBonesDir.mkdirs()
// Convert each file separately so that folders are preserved.
Path source = buildContentDir.toPath().toAbsolutePath().normalize()
Path target = bareBonesDir.toPath().toAbsolutePath().normalize()
Asciidoctor adoc = Asciidoctor.Factory.create()
fileTree(source, {
include "**/*.adoc"
exclude "**/_*"
}).each { file ->
Path relative = source.relativize(file.toPath())
Path targetDir = target.resolve(relative).getParent()
def opts = OptionsBuilder.options()
.backend('html5')
.docType("book")
.headerFooter(false)
.safe(SafeMode.UNSAFE)
.baseDir(source.toFile())
.toDir(targetDir.toFile())
.destinationDir(targetDir.toFile())
.mkDirs(true)
.attributes(asciiDocAttrs.common + asciiDocAttrs.html + props)
adoc.convertFile(file, opts)
}
}
}
task bareBonesHtmlValidation(type: JavaExec) {
dependsOn bareBonesAsciiDoctor
description("Builds (w/o Jekyll) a very simple html version of the guide and runs link/anchor validation on it")
classpath = sourceSets.main.runtimeClasspath
main = 'CheckLinksAndAnchors'
workingDir = buildContentDir
args([
"${bareBonesDir}",
"-bare-bones"
])
if (project.hasProperty("local.javadocs")) {
args += "-check-all-relative-links"
}
}
task buildSiteJekyll(type: com.github.jrubygradle.JRubyExec) {
dependsOn buildNavDataFiles
inputs.dir buildContentDir
outputs.dir file("${buildDir}/html-site")
script 'jekyll'
scriptArgs 'build' //, '--verbose'
workingDir buildContentDir
}
task buildSite(type: JavaExec) {
group "Documentation"
description "Builds an HTML Site w/Jekyll and verifies the anchors+links are valid"
dependsOn buildSiteJekyll
classpath = sourceSets.main.runtimeClasspath
main = 'CheckLinksAndAnchors'
workingDir = buildContentDir
args([
file("${buildDir}/html-site"),
])
if (project.hasProperty("local.javadocs")) {
args += "-check-all-relative-links"
}
}
// Hook up custom tasks with standard tasks.
check.dependsOn bareBonesHtmlValidation
// Do not hook site building to assemble, at least for now.
// assemble.dependsOn buildSite