/* * 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.* import groovy.json.StringEscapeUtils 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.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" // the "MAJOR.MINOR" version of solr this guide is about (guides aren't specific to BUGFIX releases) // So on 'branch_9_9' where 'version' may be 9.9.0, 9.9.1, 9.9.9, etc..; solrDocsVersion = 9.9 solrDocsVersion = "${version}".replaceAll(/^(\d+\.\d+)(|\..*)$/, "\$1") // the "MAJOR_MINOR" version as a path for publishing the guide // So on 'branch_9_9' where solrDocsVersion = 9.9; solrGuideVersionPath => 9_9 solrGuideVersionPath = "${solrDocsVersion}".replaceAll(/^(\d+)\.(\d+)$/, "\$1_\$2") if (project.hasProperty("local.javadocs")) { htmlSolrJavadocs = "link:../../docs/" htmlLuceneJavadocs = "link:../../../../lucene/build/docs/" } else { // when linking to javadocs of code releases, which always use paths like "MAJOR_MINOR_BUGFIX" // (even when 'BUGFIX' = 0), we link to the javadocs for the "MAJOR.MINOR.0" release // So if solrGuideVersionPath = '9_9'; use '9_9_0' for javadoc links... htmlSolrJavadocs = "https://lucene.apache.org/solr/${solrGuideVersionPath}_0/" htmlLuceneJavadocs = "https://lucene.apache.org/core/${solrGuideVersionPath}_0/" } // ivy* props will be set in setupLazyProps // (because they need to be computed after evaluation is complete). templateProps = [ javadocLink: "https://docs.oracle.com/en/java/javase/11/docs/api/", solrGuideDraftStatus: propertyOrDefault("solrGuideDraft", "true").toBoolean() ? "DRAFT" : "", solrRootPath: StringEscapeUtils.escapeJava(project(':solr').projectDir.toString() + File.separator), solrDocsVersion: solrDocsVersion, solrGuideVersionPath: solrGuideVersionPath, htmlSolrJavadocs: htmlSolrJavadocs, htmlLuceneJavadocs: htmlLuceneJavadocs, buildDate: buildDate, buildYear: buildYear, ] } 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. [ ["ivyCommonsCodec", "commons-codec", "commons-codec"], ["ivyDropwizardMetrics", "io.dropwizard.metrics", "metrics-core"], ["ivyLog4j", "org.apache.logging.log4j", "log4j-core"], ["ivyOpennlpTools", "org.apache.opennlp", "opennlp-tools"], ["ivyTika", "org.apache.tika", "tika-core"], ["ivyZookeeper", "org.apache.zookeeper", "zookeeper"], ].each { p, depGroup, depId -> templateProps[p] = getVersion(depGroup, depId, configurations.depVer) } // Emit info about properties for clarity. logger.warn("Building ref guide with:\n" + templateProps.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 templateProps from(file("src"), { exclude '**/*.template' }) from(file("src"), { include '**/*.template' rename '(.+)\\.template', '$1' filteringCharset = 'UTF-8' expand(templateProps) }) 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 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 buildSite // Do not hook site building to assemble, at least for now. // assemble.dependsOn buildSite