| <?xml version="1.0"?> |
| |
| <!-- |
| 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. |
| --> |
| |
| <project name="lucene-solr" default="-projecthelp" basedir="."> |
| <import file="lucene/common-build.xml"/> |
| |
| <property name="jgit-version" value="4.6.0.201612231935-r"/> |
| |
| <property name="tests.heap-dump-dir" location="heapdumps"/> |
| |
| <property name="maven-build-dir" value="maven-build"/> |
| <property name="maven-version" value="2.2.1"/> |
| <property name="maven.dependencies.filters.file" location="lucene/build/maven.dependencies.filters.properties"/> |
| |
| <property name="smokeTestRelease.dir" location="lucene/build/smokeTestRelease/dist"/> |
| <property name="smokeTestRelease.tmp" location="lucene/build/smokeTestRelease/tmp"/> |
| <property name="smokeTestRelease.testArgs" value=""/> |
| |
| <target name="-projecthelp"> |
| <java fork="false" classname="org.apache.tools.ant.Main" taskname="-"> |
| <arg value="-projecthelp"/> |
| <arg value="-f"/> |
| <arg value="${ant.file}"/> |
| </java> |
| </target> |
| |
| <target name="test-help" description="Test runner help"> |
| <subant buildpath="lucene" target="test-help" inheritall="false" failonerror="true"/> |
| </target> |
| |
| <target name="precommit" description="Run basic checks before committing" |
| depends="check-working-copy,validate,documentation-lint"/> |
| |
| <target name="test" description="Test both Lucene and Solr" depends="resolve-groovy"> |
| <mkdir dir="lucene/build" /> |
| <tempfile property="tests.totals.tmpfile" |
| destdir="lucene/build" |
| prefix=".test-totals-" |
| suffix=".tmp" |
| deleteonexit="true" |
| createfile="true" /> |
| |
| <subant target="test" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <propertyset> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| <propertyref name="tests.totals.tmpfile" /> |
| </propertyset> |
| </subant> |
| |
| <property name="tests.totals.toplevel" value="true" /> |
| <antcall target="-check-totals" /> |
| </target> |
| |
| <target name="jacoco" depends="resolve-groovy" description="Generates JaCoCo code coverage reports"> |
| <subant target="jacoco" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="pitest" depends="resolve-groovy" description="Run PITest on both Lucene and Solr"> |
| <subant target="pitest" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="beast"> |
| <fail message="The Beast only works inside of individual modules"/> |
| </target> |
| |
| <target name="documentation" depends="resolve-markdown" description="Generate Lucene and Solr Documentation"> |
| <subant target="documentation" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="documentation-lint" depends="resolve-markdown,-ecj-javadoc-lint-unsupported,-ecj-resolve" description="Validates the generated documentation (HTML errors, broken links,...)"> |
| <subant target="documentation-lint" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="check-forbidden-apis" depends="-install-forbidden-apis" description="Check forbidden API calls in compiled class files."> |
| <subant target="check-forbidden-apis" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="validate" description="Validate dependencies, licenses, etc." depends="-validate-source-patterns,resolve-groovy,rat-sources-typedef,-install-forbidden-apis"> |
| <subant target="validate" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| <subant buildpath="lucene" target="check-lib-versions" inheritall="false" failonerror="true"> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="-validate-source-patterns" unless="disable.source-patterns" depends="resolve-groovy,rat-sources-typedef"> |
| <!-- check that there are no @author javadoc tags, tabs, svn keywords, javadoc-style licenses, or nocommits: --> |
| <property name="validate.baseDir" location="."/> |
| <groovy taskname="source-patterns" classpathref="rat.classpath"><![CDATA[ |
| import org.apache.tools.ant.BuildException; |
| import org.apache.tools.ant.Project; |
| import org.apache.rat.Defaults; |
| import org.apache.rat.document.impl.FileDocument; |
| import org.apache.rat.api.MetaData; |
| |
| def extensions = [ |
| 'java', 'jflex', 'py', 'pl', 'g4', 'jj', 'html', 'js', |
| 'css', 'xml', 'xsl', 'vm', 'sh', 'cmd', 'bat', 'policy', |
| 'properties', 'mdtext', |
| 'template', 'adoc', 'json', |
| ]; |
| def invalidPatterns = [ |
| (~$/@author\b/$) : '@author javadoc tag', |
| (~$/(?i)\bno(n|)commit\b/$) : 'nocommit', |
| (~$/\bTOOD:/$) : 'TOOD instead TODO', |
| (~$/\t/$) : 'tabs instead spaces', |
| (~$/\$$(?:LastChanged)?Date\b/$) : 'svn keyword', |
| (~$/\$$(?:(?:LastChanged)?Revision|Rev)\b/$) : 'svn keyword', |
| (~$/\$$(?:LastChangedBy|Author)\b/$) : 'svn keyword', |
| (~$/\$$(?:Head)?URL\b/$) : 'svn keyword', |
| (~$/\$$Id\b/$) : 'svn keyword', |
| (~$/\$$Header\b/$) : 'svn keyword', |
| (~$/\$$Source\b/$) : 'svn keyword', |
| (~$/^\uFEFF/$) : 'UTF-8 byte order mark' |
| ]; |
| |
| def baseDir = properties['validate.baseDir']; |
| def baseDirLen = baseDir.length() + 1; |
| |
| def found = 0; |
| def violations = new TreeSet(); |
| def reportViolation = { f, name -> |
| task.log(name + ': ' + f.toString().substring(baseDirLen).replace(File.separatorChar, (char)'/'), Project.MSG_ERR); |
| violations.add(name); |
| found++; |
| } |
| |
| def javadocsPattern = ~$/(?sm)^\Q/**\E(.*?)\Q*/\E/$; |
| def javaCommentPattern = ~$/(?sm)^\Q/*\E(.*?)\Q*/\E/$; |
| def xmlCommentPattern = ~$/(?sm)\Q<!--\E(.*?)\Q-->\E/$; |
| def lineSplitter = ~$/[\r\n]+/$; |
| def singleLineSplitter = ~$/\n\r?/$; |
| def licenseMatcher = Defaults.createDefaultMatcher(); |
| def validLoggerPattern = ~$/(?s)\b(private\s|static\s|final\s){3}+\s*Logger\s+\p{javaJavaIdentifierStart}+\s+=\s+\QLoggerFactory.getLogger(MethodHandles.lookup().lookupClass());\E/$; |
| def packagePattern = ~$/(?m)^\s*package\s+org\.apache.*;/$; |
| def xmlTagPattern = ~$/(?m)\s*<[a-zA-Z].*/$; |
| def sourceHeaderPattern = ~$/\[source\b.*/$; |
| def blockBoundaryPattern = ~$/----\s*/$; |
| def blockTitlePattern = ~$/\..*/$; |
| def unescapedSymbolPattern = ~$/(?<=[^\\]|^)([-=]>|<[-=])/$; // SOLR-10883 |
| |
| def isLicense = { matcher, ratDocument -> |
| licenseMatcher.reset(); |
| return lineSplitter.split(matcher.group(1)).any{ licenseMatcher.match(ratDocument, it) }; |
| } |
| |
| def checkLicenseHeaderPrecedes = { f, description, contentPattern, commentPattern, text, ratDocument -> |
| def contentMatcher = contentPattern.matcher(text); |
| if (contentMatcher.find()) { |
| def contentStartPos = contentMatcher.start(); |
| def commentMatcher = commentPattern.matcher(text); |
| while (commentMatcher.find()) { |
| if (isLicense(commentMatcher, ratDocument)) { |
| if (commentMatcher.start() < contentStartPos) { |
| break; // This file is all good, so break loop: license header precedes 'description' definition |
| } else { |
| reportViolation(f, description+' declaration precedes license header'); |
| } |
| } |
| } |
| } |
| } |
| |
| def checkMockitoAssume = { f, text -> |
| if (text.contains("mockito") && !text.contains("assumeWorkingMockito()")) { |
| reportViolation(f, 'File uses Mockito but has no assumeWorkingMockito() call'); |
| } |
| } |
| |
| def checkForUnescapedSymbolSubstitutions = { f, text -> |
| def inCodeBlock = false; |
| def underSourceHeader = false; |
| def lineNumber = 0; |
| singleLineSplitter.split(text).each { |
| ++lineNumber; |
| if (underSourceHeader) { // This line is either a single source line, or the boundary of a code block |
| inCodeBlock = blockBoundaryPattern.matcher(it).matches(); |
| if ( ! blockTitlePattern.matcher(it).matches()) { |
| underSourceHeader = false; |
| } |
| } else { |
| if (inCodeBlock) { |
| inCodeBlock = ! blockBoundaryPattern.matcher(it).matches(); |
| } else { |
| underSourceHeader = sourceHeaderPattern.matcher(it).lookingAt(); |
| if ( ! underSourceHeader) { |
| def unescapedSymbolMatcher = unescapedSymbolPattern.matcher(it); |
| if (unescapedSymbolMatcher.find()) { |
| reportViolation(f, 'Unescaped symbol "' + unescapedSymbolMatcher.group(1) + '" on line #' + lineNumber); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| ant.fileScanner{ |
| fileset(dir: baseDir){ |
| extensions.each{ |
| include(name: 'lucene/**/*.' + it) |
| include(name: 'solr/**/*.' + it) |
| include(name: 'dev-tools/**/*.' + it) |
| include(name: '*.' + it) |
| } |
| // TODO: For now we don't scan txt files, so we |
| // check licenses in top-level folders separately: |
| include(name: '*.txt') |
| include(name: '*/*.txt') |
| // excludes: |
| exclude(name: '**/build/**') |
| exclude(name: '**/dist/**') |
| exclude(name: 'lucene/benchmark/work/**') |
| exclude(name: 'lucene/benchmark/temp/**') |
| exclude(name: '**/CheckLoggingConfiguration.java') |
| exclude(name: 'build.xml') // ourselves :-) |
| } |
| }.each{ f -> |
| task.log('Scanning file: ' + f, Project.MSG_VERBOSE); |
| def text = f.getText('UTF-8'); |
| invalidPatterns.each{ pattern,name -> |
| if (pattern.matcher(text).find()) { |
| reportViolation(f, name); |
| } |
| } |
| def javadocsMatcher = javadocsPattern.matcher(text); |
| def ratDocument = new FileDocument(f); |
| while (javadocsMatcher.find()) { |
| if (isLicense(javadocsMatcher, ratDocument)) { |
| reportViolation(f, String.format(Locale.ENGLISH, 'javadoc-style license header [%s]', |
| ratDocument.getMetaData().value(MetaData.RAT_URL_LICENSE_FAMILY_NAME))); |
| } |
| } |
| if (f.name.endsWith('.java')) { |
| if (text.contains('org.slf4j.LoggerFactory')) { |
| if (!validLoggerPattern.matcher(text).find()) { |
| reportViolation(f, 'invalid logging pattern [not private static final, uses static class name]'); |
| } |
| } |
| checkLicenseHeaderPrecedes(f, 'package', packagePattern, javaCommentPattern, text, ratDocument); |
| if (f.name.contains("Test")) { |
| checkMockitoAssume(f, text); |
| } |
| } |
| if (f.name.endsWith('.xml') || f.name.endsWith('.xml.template')) { |
| checkLicenseHeaderPrecedes(f, '<tag>', xmlTagPattern, xmlCommentPattern, text, ratDocument); |
| } |
| if (f.name.endsWith('.adoc')) { |
| checkForUnescapedSymbolSubstitutions(f, text); |
| } |
| }; |
| |
| if (found) { |
| throw new BuildException(String.format(Locale.ENGLISH, 'Found %d violations in source files (%s).', |
| found, violations.join(', '))); |
| } |
| ]]></groovy> |
| </target> |
| |
| <target name="rat-sources" description="Runs rat across all sources and tests" depends="common.rat-sources"> |
| <subant target="rat-sources" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="resolve" description="Resolves all dependencies"> |
| <subant target="resolve" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <!-- lucene/test-framework and solr/test-framework are excluded from compilation --> |
| <target name="compile" description="Compile Lucene and Solr"> |
| <subant target="compile" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="compile-core" description="Compile Lucene Core"> |
| <subant target="compile-core" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="compile-test" description="Compile Lucene and Solr tests and test-frameworks"> |
| <subant target="compile-test" inheritAll="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="jar" description="Build Lucene and Solr Jar files"> |
| <subant target="jar" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml"/> |
| <fileset dir="solr" includes="build.xml"/> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="jar-src" description="Build Lucene and Solr Source Jar files"> |
| <subant target="jar-src" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml"/> |
| <fileset dir="solr" includes="build.xml"/> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="get-maven-poms" depends="resolve" |
| description="Copy Maven POMs from dev-tools/maven/ to maven-build/"> |
| <ant dir="lucene" target="-get-maven-poms" inheritall="false"/> |
| </target> |
| |
| <target name="clean-maven-build" |
| description="Clean up Maven POMs in working copy"> |
| <delete failonerror="true" dir="${maven-build-dir}/"/> |
| </target> |
| |
| <target name="generate-maven-artifacts" depends="resolve,resolve-groovy,resolve-markdown,install-maven-tasks" |
| description="Generate Maven Artifacts for Lucene and Solr"> |
| <property name="maven.dist.dir" location="dist/maven" /> |
| <mkdir dir="${maven.dist.dir}" /> |
| <ant dir="lucene" inheritall="false"> |
| <target name="-unpack-lucene-tgz"/> |
| <target name="-filter-pom-templates"/> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </ant> |
| <ant dir="solr" target="-unpack-solr-tgz" inheritall="false"> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </ant> |
| <subant target="-dist-maven" inheritall="false" failonerror="true"> |
| <property name="maven.dist.dir" location="${maven.dist.dir}" /> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="-install-maven-artifacts" depends="resolve,resolve-groovy,resolve-markdown,install-maven-tasks"> |
| <ant dir="lucene" inheritall="false"> |
| <target name="-unpack-lucene-tgz"/> |
| <target name="-filter-pom-templates"/> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </ant> |
| <ant dir="solr" target="-unpack-solr-tgz" inheritall="false"> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </ant> |
| <subant target="-install-to-maven-local-repo" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="validate-maven-dependencies" depends="-install-maven-artifacts" |
| description="Validates maven dependencies, licenses, etc."> |
| <subant target="-validate-maven-dependencies" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml"/> |
| <fileset dir="solr" includes="build.xml"/> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="run-maven-build" depends="get-maven-poms,install-maven-tasks,resolve-groovy" description="Runs the Maven build using automatically generated POMs"> |
| <groovy><![CDATA[ |
| import groovy.xml.NamespaceBuilder; |
| import org.apache.tools.ant.Project; |
| def userHome = properties['user.home'], commonDir = properties['common.dir']; |
| def propPrefix = '-mvn.inject.'; int propPrefixLen = propPrefix.length(); |
| def subProject = project.createSubProject(); |
| project.copyUserProperties(subProject); |
| subProject.initProperties(); |
| new AntBuilder(subProject).sequential{ |
| property(file: userHome+'/lucene.build.properties', prefix: propPrefix); |
| property(file: userHome+'/build.properties', prefix: propPrefix); |
| property(file: commonDir+'/build.properties', prefix: propPrefix); |
| }; |
| def cmdlineProps = subProject.properties |
| .findAll{ k, v -> k.startsWith(propPrefix) } |
| .collectEntries{ k, v -> [k.substring(propPrefixLen), v] }; |
| cmdlineProps << project.userProperties.findAll{ k, v -> !k.startsWith('ant.') }; |
| def artifact = NamespaceBuilder.newInstance(ant, 'antlib:org.apache.maven.artifact.ant'); |
| task.log('Running Maven with props: ' + cmdlineProps.toString(), Project.MSG_INFO); |
| artifact.mvn(pom: properties['maven-build-dir']+'/pom.xml', mavenVersion: properties['maven-version'], failonerror: true, fork: true) { |
| cmdlineProps.each{ k, v -> arg(value: '-D' + k + '=' + v) }; |
| arg(value: '-fae'); |
| arg(value: 'install'); |
| }; |
| ]]></groovy> |
| </target> |
| |
| <target name="remove-maven-artifacts" description="Removes all Lucene/Solr Maven artifacts from the local repository"> |
| <echo message="Removing all Lucene/Solr Maven artifacts from '${user.home}/.m2/repository'..."/> |
| <delete includeemptydirs="true"> |
| <fileset dir="${user.home}/.m2/repository" erroronmissingdir="false"> |
| <include name="org/apache/lucene/**"/> |
| <include name="org/apache/solr/**"/> |
| </fileset> |
| </delete> |
| </target> |
| |
| <target name="netbeans" depends="resolve" description="Setup Netbeans configuration"> |
| <pathconvert property="netbeans.fileset.sourcefolders" pathsep="|" dirsep="/"> |
| <dirset dir="${basedir}/lucene" includes="**/src/java, **/src/examples, **/src/test, **/src/resources" |
| excludes="tools/**, build/**" /> |
| <dirset dir="${basedir}/solr" includes="**/src/java, **/src/examples, **/src/test, **/src/resources" |
| excludes="build/**" /> |
| <map from="${basedir}/" to=""/> |
| </pathconvert> |
| <!-- TODO: find a better way to exclude duplicate JAR files & fix the servlet-api mess! --> |
| <pathconvert property="netbeans.path.libs" pathsep=":" dirsep="/"> |
| <fileset dir="${basedir}/lucene" includes="**/lib/*.jar" |
| excludes="**/*servlet-api*.jar, analysis/uima/**, tools/**, build/**"/> |
| <fileset dir="${basedir}/solr" includes="**/test-lib/*.jar,**/lib/*.jar" |
| excludes="core/test-lib/*servlet-api*.jar, contrib/analysis-extras/**, test-framework/lib/junit*, test-framework/lib/ant*, test-framework/lib/randomizedtesting*, build/**, dist/**, package/**, server/solr-webapp/**" /> |
| <map from="${basedir}/" to=""/> |
| </pathconvert> |
| <mkdir dir="nbproject"/> |
| <copy todir="nbproject" overwrite="true"> |
| <fileset dir="dev-tools/netbeans/nbproject"/> |
| </copy> |
| <xslt in="${ant.file}" out="nbproject/project.xml" style="dev-tools/netbeans/nb-project.xsl" force="true"> |
| <outputproperty name="indent" value="yes"/> |
| <param name="netbeans.fileset.sourcefolders" expression="${netbeans.fileset.sourcefolders}"/> |
| <param name="netbeans.path.libs" expression="${netbeans.path.libs}"/> |
| <param name="netbeans.source-level" expression="1.7"/> |
| </xslt> |
| </target> |
| |
| <target name="clean-netbeans" description="Removes all Netbeans configuration files"> |
| <delete dir="nbproject" failonerror="true"/> |
| <delete dir="nb-build" failonerror="true"/> |
| </target> |
| |
| <target name="eclipse" depends="resolve" description="Setup Eclipse configuration"> |
| <basename file="${basedir}" property="eclipseprojectname"/> |
| <copy file="dev-tools/eclipse/dot.project" tofile=".project" overwrite="false" encoding="UTF-8"> |
| <filterset> |
| <filter token="ECLIPSEPROJECTNAME" value="${eclipseprojectname}"/> |
| </filterset> |
| </copy> |
| <mkdir dir=".settings"/> |
| <copy todir=".settings/" overwrite="true"> |
| <fileset dir="dev-tools/eclipse/dot.settings" includes="*.prefs" /> |
| </copy> |
| |
| <pathconvert property="eclipse.fileset.sourcefolders" pathsep="|" dirsep="/"> |
| <dirset dir="${basedir}/lucene" includes="**/src/java, **/src/resources, **/src/test, **/src/test-files, **/src/examples" excludes="tools/**, build/**" /> |
| <dirset dir="${basedir}/solr" includes="**/src/java, **/src/resources, **/src/test, **/src/test-files, **/src/examples" excludes="build/**" /> |
| <map from="${basedir}/" to=""/> |
| </pathconvert> |
| <!-- TODO: find a better way to exclude duplicate JAR files & fix the servlet-api mess! --> |
| <pathconvert property="eclipse.fileset.libs" pathsep="|" dirsep="/"> |
| <fileset dir="${basedir}/lucene" includes="**/lib/*.jar" excludes="**/*servlet-api*.jar, analysis/uima/**, tools/**, build/**"/> |
| <fileset dir="${basedir}/solr" includes="**/test-lib/*.jar,**/lib/*.jar" excludes="core/test-lib/*servlet-api*.jar, contrib/analysis-extras/**, test-framework/lib/junit*, test-framework/lib/ant*, test-framework/lib/randomizedtesting*, build/**, dist/**, package/**" /> |
| <map from="${basedir}/" to=""/> |
| </pathconvert> |
| <xslt in="${ant.file}" out=".classpath" style="dev-tools/eclipse/dot.classpath.xsl" force="true"> |
| <outputproperty name="indent" value="yes"/> |
| <param name="eclipse.fileset.libs" expression="${eclipse.fileset.libs}"/> |
| <param name="eclipse.fileset.sourcefolders" expression="${eclipse.fileset.sourcefolders}"/> |
| </xslt> |
| |
| <echo> |
| SUCCESS: You must right-click your project and choose Refresh. |
| Your project must use a Java 8 JRE. |
| </echo> |
| </target> |
| |
| <target name="clean-eclipse" description="Removes all Eclipse configuration files"> |
| <delete dir=".settings" failonerror="true"/> |
| <delete failonerror="true"> |
| <fileset dir="." includes=".classpath,.project"/> |
| </delete> |
| <delete dir="eclipse-build" failonerror="true"/> |
| </target> |
| |
| <target name="idea" depends="resolve" description="Setup IntelliJ IDEA configuration"> |
| <condition property="idea.jdk.is.set"> |
| <isset property="idea.jdk"/> |
| </condition> |
| <!-- Define ${idea.jdk} if it's not yet defined - otherwise literal "${idea.jdk}" is substituted --> |
| <property name="idea.jdk" value=""/> |
| <!-- delete those files first, so they are regenerated by the filtering below |
| (add more files with dynamic properties like versions here): --> |
| <delete dir=".idea" includes="misc.xml workspace.xml"/> |
| <!-- Copy files with filtering: --> |
| <copy todir="." overwrite="false" encoding="UTF-8"> |
| <fileset dir="dev-tools/idea"/> |
| <filterset begintoken="subst.="" endtoken="""> |
| <filter token="idea.jdk" value="${idea.jdk}"/> |
| </filterset> |
| <filterset> |
| <filter token="version" value="${version}"/> |
| <filter token="version.base" value="${version.base}"/> |
| </filterset> |
| </copy> |
| <antcall target="-post-idea-instructions"/> |
| </target> |
| |
| <target name="-post-idea-instructions" unless="idea.jdk.is.set"> |
| <echo> |
| To complete IntelliJ IDEA setup, you must manually configure |
| File | Project Structure | Project | Project SDK. |
| |
| You won't have to do this in the future if you define property |
| $${idea.jdk}, e.g. in ~/lucene.build.properties, ~/build.properties |
| or lucene/build.properties, with a value consisting of the |
| following two XML attributes/values (adjust values according to |
| JDKs you have defined locally - see |
| File | Project Structure | Platform Settings | SDKs): |
| |
| idea.jdk = project-jdk-name="1.8" project-jdk-type="JavaSDK" |
| </echo> |
| </target> |
| |
| <target name="clean-idea" |
| description="Removes all IntelliJ IDEA configuration files"> |
| <delete dir=".idea" failonerror="true"/> |
| <delete failonerror="true"> |
| <fileset dir="." includes="*.iml,*.ipr,*.iws"/> |
| <fileset dir="solr" includes="**/*.iml"/> |
| <fileset dir="lucene" includes="**/*.iml"/> |
| </delete> |
| <delete dir="idea-build" failonerror="true"/> |
| </target> |
| |
| <target name="clean" description="Clean Lucene and Solr build dirs"> |
| <delete dir="dist" /> |
| <delete dir="${tests.heap-dump-dir}" /> |
| <subant target="clean" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="clean-jars" description="Remove all JAR files from lib folders in the checkout"> |
| <delete failonerror="true"> |
| <fileset dir="."> |
| <include name="**/*.jar"/> |
| <exclude name="*/build/**"/> |
| <exclude name="*/dist/**"/> |
| <exclude name="*/package/**"/> |
| <exclude name="*/example/exampledocs/**"/> |
| </fileset> |
| </delete> |
| </target> |
| |
| <target name="jar-checksums" description="Recompute SHA1 checksums for all JAR files."> |
| <subant target="jar-checksums" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <target name="nightly-smoke" description="Builds an unsigned release and smoke tests it" |
| depends="clean,resolve-groovy,resolve-markdown,install-maven-tasks"> |
| <fail message="To run nightly smoke, the JDK must be exactly Java 1.8, was: ${java.specification.version}"> |
| <condition> |
| <not><equals arg1="${java.specification.version}" arg2="1.8"/></not> |
| </condition> |
| </fail> |
| <exec executable="${python32.exe}" failonerror="true" taskname="python32"> |
| <arg value="-V"/> |
| </exec> |
| <subant target="prepare-release-no-sign" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <!-- pass ${version.base} here to emulate a real release, without appendix like "-SNAPSHOT": --> |
| <property name="version" value="${version.base}" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| <mkdir dir="${smokeTestRelease.dir}"/> |
| <copy todir="${smokeTestRelease.dir}/lucene"> |
| <fileset dir="lucene/dist"/> |
| </copy> |
| <copy todir="${smokeTestRelease.dir}/solr"> |
| <fileset dir="solr/package"/> |
| </copy> |
| <local name="url"/> |
| <makeurl file="${smokeTestRelease.dir}" validate="false" property="url"/> |
| <exec executable="${python32.exe}" failonerror="true" taskname="smoker"> |
| <arg value="-u"/> |
| <!-- Tell Python not to write any bytecode cache into the filesystem: --> |
| <arg value="-B"/> |
| <arg file="dev-tools/scripts/smokeTestRelease.py"/> |
| <arg value="--revision"/> |
| <arg value="skip"/> |
| <!-- pass ${version.base} here to emulate a real release, without appendix like "-SNAPSHOT": --> |
| <arg value="--version"/> |
| <arg value="${version.base}"/> |
| <arg value="--tmp-dir"/> |
| <arg file="${smokeTestRelease.tmp}"/> |
| <arg value="--not-signed"/> |
| <arg value="${url}"/> |
| <arg value="${smokeTestRelease.testArgs}"/> |
| </exec> |
| <delete dir="${smokeTestRelease.dir}"/> |
| <delete dir="${smokeTestRelease.tmp}"/> |
| </target> |
| |
| <macrodef xmlns:ivy="antlib:org.apache.ivy.ant" name="wc-checker"> |
| <attribute name="failonmodifications"/><!-- fail if modifications were found, otherwise it only fails on unversioned files --> |
| <sequential> |
| <local name="wc.unversioned.files"/> |
| <local name="wc.modified.files"/> |
| <ivy:cachepath xmlns:ivy="antlib:org.apache.ivy.ant" |
| organisation="org.eclipse.jgit" module="org.eclipse.jgit" revision="${jgit-version}" |
| inline="true" conf="default" transitive="true" pathid="jgit.classpath"/> |
| <groovy taskname="wc-checker" classpathref="jgit.classpath"><![CDATA[ |
| import org.apache.tools.ant.BuildException; |
| import org.apache.tools.ant.Project; |
| import org.eclipse.jgit.api.Git; |
| import org.eclipse.jgit.api.Status; |
| import org.eclipse.jgit.lib.Repository; |
| import org.eclipse.jgit.storage.file.FileRepositoryBuilder; |
| import org.eclipse.jgit.errors.*; |
| |
| def setProjectPropertyFromSet(prop, set) { |
| if (set) { |
| properties[prop] = '* ' + set.join(properties['line.separator'] + '* '); |
| } |
| }; |
| |
| try { |
| task.log('Initializing working copy...', Project.MSG_INFO); |
| final Repository repository = new FileRepositoryBuilder() |
| .setWorkTree(project.getBaseDir()) |
| .setMustExist(true) |
| .build(); |
| |
| task.log('Checking working copy status...', Project.MSG_INFO); |
| final Status status = new Git(repository).status().call(); |
| if (!status.isClean()) { |
| final SortedSet unversioned = new TreeSet(), modified = new TreeSet(); |
| status.properties.each{ prop, val -> |
| if (val instanceof Set) { |
| if (prop in ['untracked', 'untrackedFolders', 'missing']) { |
| unversioned.addAll(val); |
| } else if (prop != 'ignoredNotInIndex') { |
| modified.addAll(val); |
| } |
| } |
| }; |
| setProjectPropertyFromSet('wc.unversioned.files', unversioned); |
| setProjectPropertyFromSet('wc.modified.files', modified); |
| } |
| } catch (RepositoryNotFoundException | NoWorkTreeException | NotSupportedException e) { |
| task.log('WARNING: Development directory is not a valid GIT checkout! Disabling checks...', Project.MSG_WARN); |
| } |
| ]]></groovy> |
| <fail if="wc.unversioned.files" |
| message="Source checkout is dirty (unversioned/missing files) after running tests!!! Offending files:${line.separator}${wc.unversioned.files}"/> |
| <fail message="Source checkout is modified!!! Offending files:${line.separator}${wc.modified.files}"> |
| <condition> |
| <and> |
| <istrue value="@{failonmodifications}"/> |
| <isset property="wc.modified.files"/> |
| </and> |
| </condition> |
| </fail> |
| </sequential> |
| </macrodef> |
| |
| <target name="check-working-copy" description="Checks working copy for unversioned changes" depends="resolve-groovy"> |
| <wc-checker failonmodifications="${is.jenkins.build}"/> |
| </target> |
| |
| <target name="run-clover" description="Runs all tests to measure coverage and generates report (pass "ANT_OPTS=-Xmx1536M" as environment)" depends="clean"> |
| <antcall inheritAll="false"> |
| <param name="run.clover" value="true"/> |
| <!-- must be 1, as clover does not like parallel test runs: --> |
| <param name="tests.jvms.override" value="1"/> |
| <!-- Also override some other props to be fast: --> |
| <param name="tests.multiplier" value="1"/> |
| <param name="tests.nightly" value="false"/> |
| <param name="tests.weekly" value="false"/> |
| <param name="tests.badapples" value="true"/> |
| <!-- The idea behind Clover is to determine test coverage, so be immune to failing tests: --> |
| <param name="tests.haltonfailure" value="false"/> |
| |
| <target name="clover"/> |
| <target name="test"/> |
| <target name="-generate-clover-reports"/> |
| |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </antcall> |
| </target> |
| |
| <!-- |
| Run after Junit tests. |
| |
| This target is in a separate file, as it needs to include common-build.xml, |
| but must run from top-level! |
| --> |
| <target name="-generate-clover-reports" depends="clover"> |
| <fail unless="run.clover">Clover not enabled!</fail> |
| <mkdir dir="${clover.report.dir}"/> |
| <fileset dir="." id="clover.test.result.files"> |
| <include name="*/build/**/test/TEST-*.xml"/> |
| </fileset> |
| <clover-report projectName="Apache Lucene/Solr"> |
| <current outfile="${clover.report.dir}" title="Apache Lucene/Solr ${version}" numThreads="0"> |
| <format type="html" filter="assert"/> |
| <testresults refid="clover.test.result.files"/> |
| </current> |
| <current outfile="${clover.report.dir}/clover.xml" title="Apache Lucene/Solr ${version}"> |
| <format type="xml" filter="assert"/> |
| <testresults refid="clover.test.result.files"/> |
| </current> |
| </clover-report> |
| <echo>You can find the merged Lucene/Solr Clover report in '${clover.report.dir}'.</echo> |
| </target> |
| |
| <target name="test-with-heapdumps" depends="resolve-groovy,-test-with-heapdumps-enabled,-test-with-heapdumps-disabled" description="Runs tests with heap dumps on OOM enabled (if VM supports this)"/> |
| |
| <condition property="vm.supports.heapdumps"> |
| <or> |
| <contains string="${java.vm.name}" substring="hotspot" casesensitive="false"/> |
| <contains string="${java.vm.name}" substring="openjdk" casesensitive="false"/> |
| </or> |
| </condition> |
| |
| <target name="-test-with-heapdumps-enabled" if="vm.supports.heapdumps"> |
| <echo level="info" message="${java.vm.name}: Enabling heap dumps on OutOfMemoryError to dir '${tests.heap-dump-dir}'."/> |
| <mkdir dir="${tests.heap-dump-dir}"/> |
| <delete includeEmptyDirs="true"> |
| <fileset dir="${tests.heap-dump-dir}" includes="**/*"/> |
| </delete> |
| <antcall inheritAll="false" target="test"> |
| <param name="tests.heapdump.args" value="-XX:+HeapDumpOnOutOfMemoryError "-XX:HeapDumpPath=${tests.heap-dump-dir}""/> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </antcall> |
| <pathconvert property="heapdumps.list" setonempty="false" pathsep="${line.separator}"> |
| <fileset dir="${tests.heap-dump-dir}"/> |
| <map from="${tests.heap-dump-dir}${file.separator}" to="* "/> |
| </pathconvert> |
| <fail if="heapdumps.list" message="Some of the tests produced a heap dump, but did not fail. Maybe a suppressed OutOfMemoryError? Dumps created:${line.separator}${heapdumps.list}"/> |
| <delete dir="${tests.heap-dump-dir}"/> |
| </target> |
| |
| <target name="-test-with-heapdumps-disabled" unless="vm.supports.heapdumps"> |
| <echo level="warning" message="WARN: The used JVM (${java.vm.name}) does not support HPROF heap dumps on OutOfMemoryError."/> |
| <antcall target="test"> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </antcall> |
| </target> |
| |
| <target name="regenerate" description="Runs all code regenerators"> |
| <subant target="regenerate" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <!-- todo: |
| <fileset dir="solr" includes="build.xml" />--> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <!-- should only be called by jenkins, not precommit! --> |
| <target name="-check-after-regeneration" depends="resolve-groovy"> |
| <wc-checker failonmodifications="true"/> |
| </target> |
| |
| <!-- TODO: remove me when jenkins works --> |
| <target name="regenerateAndCheck" depends="regenerate,-check-after-regeneration"/> |
| |
| <target name="-append-all-modules-dependencies-properties"> |
| <delete file="lucene/build/module.dependencies.properties"/> |
| <subant target="-append-module-dependencies-properties" inheritall="false" failonerror="true"> |
| <fileset dir="lucene" includes="build.xml" /> |
| <fileset dir="solr" includes="build.xml" /> |
| <propertyset refid="uptodate.and.compiled.properties"/> |
| </subant> |
| </target> |
| |
| <!-- Jenkins tasks --> |
| <target name="-jenkins-base" depends="-print-java-info,clean,test-with-heapdumps,validate,documentation-lint,jar-checksums,check-working-copy"/> |
| |
| <target name="-print-java-info"> |
| <echo level="info" taskname="java-info">java version "${java.version}" |
| ${java.runtime.name} (${java.runtime.version}, ${java.vendor}) |
| ${java.vm.name} (${java.vm.version}, ${java.vm.vendor}) |
| Test args: [${args}]</echo> |
| </target> |
| |
| <target name="jenkins-hourly"> |
| <antcall> |
| <param name="is.jenkins.build" value="true"/> |
| <param name="tests.haltonfailure" value="false"/> |
| <target name="-jenkins-base"/> |
| </antcall> |
| </target> |
| |
| <target name="jenkins-nightly"> |
| <antcall> |
| <param name="is.jenkins.build" value="true"/> |
| <param name="tests.haltonfailure" value="false"/> |
| <param name="tests.nightly" value="true"/> |
| <target name="-jenkins-base"/> |
| </antcall> |
| </target> |
| |
| <target name="jenkins-maven-nightly" depends="-print-java-info,clean,clean-maven-build,resolve-groovy,resolve-markdown,install-maven-tasks"> |
| <!-- step 1: build, install, deploy, and validate ANT-generated maven artifacts: --> |
| <antcall> |
| <param name="is.jenkins.build" value="true"/> |
| <target name="remove-maven-artifacts"/> |
| <!-- this implicitely publishes the maven artifacts: --> |
| <target name="validate-maven-dependencies"/> |
| </antcall> |
| <!-- step 2: run the maven build to check that the pom templates also work to drive "mvn": --> |
| <antcall> |
| <param name="is.jenkins.build" value="true"/> |
| <target name="remove-maven-artifacts"/> |
| <target name="run-maven-build"/> |
| </antcall> |
| </target> |
| |
| <target name="jenkins-clover" depends="-print-java-info"> |
| <antcall> |
| <param name="is.jenkins.build" value="true"/> |
| <target name="run-clover"/> |
| </antcall> |
| </target> |
| |
| <!-- useless targets (override common-build.xml): --> |
| <target name="generate-test-reports"/> |
| </project> |