LUCENE-9896: Add 'quiet exec' utility suppressing exec output unless a failure occurs

This commit is contained in:
Dawid Weiss 2021-03-30 14:38:13 +02:00
parent c7455ff561
commit 39b8e97613
8 changed files with 80 additions and 80 deletions

View File

@ -45,23 +45,14 @@ class CheckBrokenLinksTask extends DefaultTask {
@TaskAction @TaskAction
def check() { def check() {
def result project.quietExec {
output.withOutputStream { output -> executable project.externalTool("python3")
result = project.exec { ignoreExitValue = false
executable project.externalTool("python3") args = [
ignoreExitValue = true "-B",
standardOutput = output validationScript.absolutePath,
errorOutput = output docsDir.get().getAsFile()
args = [ ]
"-B",
validationScript.absolutePath,
docsDir.get().getAsFile()
]
}
}
if (result.getExitValue() != 0) {
throw new GradleException("Broken links check failed. Command output at: ${output}")
} }
} }
} }

View File

@ -451,46 +451,11 @@ class RenderJavadocTask extends DefaultTask {
logger.info("Javadoc executable used: ${javadocCmd}") logger.info("Javadoc executable used: ${javadocCmd}")
def outputFile = project.file("${getTemporaryDir()}/javadoc-output.txt") project.quietExec {
def result
outputFile.withOutputStream { output ->
result = project.exec {
executable javadocCmd executable javadocCmd
// we want to capture both stdout and stderr to the same
// stream but gradle attempts to close these separately
// (it has two independent pumping threads) and it can happen
// that one still tries to write something when the other closed
// the underlying output stream.
def wrapped = new java.io.FilterOutputStream(output) {
public void close() {
// no-op. we close this stream manually.
}
}
standardOutput = wrapped
errorOutput = wrapped
args += [ "@${optionsFile}" ] args += [ "@${optionsFile}" ]
args += jOpts args += jOpts
ignoreExitValue true
}
}
if (result.getExitValue() != 0) {
// Pipe the output to console. Intentionally skips any encoding conversion
// and pumps raw bytes.
System.out.write(outputFile.bytes)
System.out.flush()
def cause
try {
result.rethrowFailure()
} catch (ex) {
cause = ex
}
throw new GradleException("Javadoc generation failed for ${project.path},\n Options file at: ${optionsFile}\n Command output at: ${outputFile}", cause)
} }
// append some special table css, prettify css // append some special table css, prettify css

View File

@ -63,9 +63,8 @@ configure(project(":lucene:analysis:icu")) {
] ]
} }
project.exec { project.quietExec {
executable gennorm executable gennorm
ignoreExitValue = false
args = [ args = [
"-v", "-v",
"-s", "-s",
@ -77,9 +76,9 @@ configure(project(":lucene:analysis:icu")) {
"NativeDigitFolding.txt" "NativeDigitFolding.txt"
] ]
} }
project.exec {
project.quietExec {
executable icupkg executable icupkg
ignoreExitValue = false
args = [ args = [
"-tb", "-tb",
"${buildDir}/utr30.tmp", "${buildDir}/utr30.tmp",
@ -157,10 +156,8 @@ configure(project(":lucene:analysis:icu")) {
project.delete icuSrcDir project.delete icuSrcDir
// Extract the tgz // Extract the tgz
project.exec { project.quietExec {
executable "tar" executable "tar"
ignoreExitValue false
workingDir icuBuildDir workingDir icuBuildDir
args = [ args = [
"-zxvf", "-zxvf",
@ -169,9 +166,8 @@ configure(project(":lucene:analysis:icu")) {
} }
// Compile: (cd icu/source && ./configure --prefix=$(pwd) --enable-rpath && make -j4) // Compile: (cd icu/source && ./configure --prefix=$(pwd) --enable-rpath && make -j4)
project.exec { project.quietExec {
executable "sh" executable "sh"
ignoreExitValue false
workingDir icuSrcDir workingDir icuSrcDir
args = [ args = [
@ -181,9 +177,8 @@ configure(project(":lucene:analysis:icu")) {
] ]
} }
project.exec { project.quietExec {
executable "make" executable "make"
ignoreExitValue false
workingDir icuSrcDir workingDir icuSrcDir
args = [ args = [
"-j4" "-j4"
@ -192,9 +187,8 @@ configure(project(":lucene:analysis:icu")) {
// Test that the binaries work: derb -V // Test that the binaries work: derb -V
logger.lifecycle("Compiled ICU, checking...") logger.lifecycle("Compiled ICU, checking...")
project.exec { project.quietExec {
executable "./derb" executable "./derb"
ignoreExitValue false
workingDir icuBinDir workingDir icuBinDir
args = [ args = [
"-V" "-V"

View File

@ -157,16 +157,13 @@ configure(project(":lucene:analysis:common")) {
doFirst { doFirst {
// Regenerate HTMLCharacterEntities.jflex first. // Regenerate HTMLCharacterEntities.jflex first.
def target = file('src/java/org/apache/lucene/analysis/charfilter/HTMLCharacterEntities.jflex') def target = file('src/java/org/apache/lucene/analysis/charfilter/HTMLCharacterEntities.jflex')
target.withOutputStream { output -> quietExec {
project.exec { executable = project.externalTool("python3")
executable = project.externalTool("python3") workingDir = target.parentFile
workingDir = target.parentFile args += [
standardOutput = output "-B", // don't write any bytecode cache
args += [ "htmlentity.py"
"-B", // don't write any bytecode cache ]
"htmlentity.py"
]
}
} }
project.ant.fixcrlf( project.ant.fixcrlf(

View File

@ -71,7 +71,7 @@ configure(project(":lucene:analysis:kuromoji")) {
} }
// Apply patch via local git. // Apply patch via local git.
project.exec { project.quietExec {
workingDir = unpackedDir workingDir = unpackedDir
executable "git" // TODO: better use jgit to apply patch, this is not portable!!! executable "git" // TODO: better use jgit to apply patch, this is not portable!!!
args += [ args += [

View File

@ -106,7 +106,7 @@ configure(project(":lucene:analysis:common")) {
dependsOn downloadSnowballData dependsOn downloadSnowballData
doFirst { doFirst {
project.exec { project.quietExec {
executable "bash" executable "bash"
args = [snowballScript, snowballStemmerDir, snowballWebsiteDir, snowballDataDir, projectDir] args = [snowballScript, snowballStemmerDir, snowballWebsiteDir, snowballDataDir, projectDir]
} }

View File

@ -44,7 +44,7 @@ configure(project(":lucene:core")) {
['gen_BulkOperation.py', 'gen_Packed64SingleBlock.py'].each { prog -> ['gen_BulkOperation.py', 'gen_Packed64SingleBlock.py'].each { prog ->
logger.lifecycle("Executing: ${prog} in ${targetDir}") logger.lifecycle("Executing: ${prog} in ${targetDir}")
project.exec { quietExec {
workingDir targetDir workingDir targetDir
executable project.externalTool("python3") executable project.externalTool("python3")
args = ['-B', "${prog}"] args = ['-B', "${prog}"]
@ -69,7 +69,7 @@ configure(project(":lucene:core")) {
['1', '2'].each { num -> ['1', '2'].each { num ->
['True', 'False'].each { transpose -> ['True', 'False'].each { transpose ->
project.exec { quietExec {
workingDir targetDir workingDir targetDir
executable project.externalTool("python3") executable project.externalTool("python3")
args = ['-B', 'createLevAutomata.py', num, transpose, "${momanDir}/finenight/python"] args = ['-B', 'createLevAutomata.py', num, transpose, "${momanDir}/finenight/python"]

View File

@ -72,5 +72,58 @@ allprojects {
} }
} }
} }
// Utility function similar to project.exec but not emitting
// any output unless an error code is returned from the executed command.
quietExec = { closure ->
// Resolve any properties against the provided closure.
resolveStrategy = Closure.DELEGATE_ONLY
delegate = closure.delegate
File outputFile = File.createTempFile("exec-output-", ".txt", getTemporaryDir())
ExecResult result
boolean saveIgnoreExitValue
ExecSpec saveExecSpec
outputFile.withOutputStream { output ->
// we want to capture both stdout and stderr to the same
// stream but gradle attempts to close these separately
// (it has two independent pumping threads) and it can happen
// that one still tries to write something when the other closed
// the underlying output stream.
def wrapped = new java.io.FilterOutputStream(output) {
public void close() {
// no-op. we close this stream manually.
}
}
result = project.exec { ExecSpec execSpec ->
project.configure(execSpec, closure)
saveIgnoreExitValue = execSpec.ignoreExitValue
saveExecSpec = execSpec
standardOutput = wrapped
errorOutput = wrapped
ignoreExitValue true
}
}
if (result.getExitValue() != 0) {
// Pipe the output to console. Intentionally skips any encoding conversion
// and pumps raw bytes.
logger.error(new String(outputFile.bytes))
if (!saveIgnoreExitValue) {
result.rethrowFailure()
throw new GradleException("The executed process ${saveExecSpec.executable} " +
"returned an odd status " +
"code: ${result.exitValue}, " +
"output at: ${outputFile} (and logged above).")
}
}
return result
}
} }
} }