You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by dw...@apache.org on 2021/03/30 12:38:27 UTC

[lucene] branch main updated: LUCENE-9896: Add 'quiet exec' utility suppressing exec output unless a failure occurs

This is an automated email from the ASF dual-hosted git repository.

dweiss pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/lucene.git


The following commit(s) were added to refs/heads/main by this push:
     new 39b8e97  LUCENE-9896: Add 'quiet exec' utility suppressing exec output unless a failure occurs
39b8e97 is described below

commit 39b8e976138045883bda600f2ee3a1724c2ddbf6
Author: Dawid Weiss <da...@carrotsearch.com>
AuthorDate: Tue Mar 30 14:38:13 2021 +0200

    LUCENE-9896: Add 'quiet exec' utility suppressing exec output unless a failure occurs
---
 gradle/documentation/check-broken-links.gradle | 25 ++++--------
 gradle/documentation/render-javadoc.gradle     | 37 +-----------------
 gradle/generation/icu.gradle                   | 20 ++++------
 gradle/generation/jflex.gradle                 | 17 ++++-----
 gradle/generation/kuromoji.gradle              |  2 +-
 gradle/generation/snowball.gradle              |  2 +-
 gradle/generation/util.gradle                  |  4 +-
 gradle/globals.gradle                          | 53 ++++++++++++++++++++++++++
 8 files changed, 80 insertions(+), 80 deletions(-)

diff --git a/gradle/documentation/check-broken-links.gradle b/gradle/documentation/check-broken-links.gradle
index 79a0818..235bca0 100644
--- a/gradle/documentation/check-broken-links.gradle
+++ b/gradle/documentation/check-broken-links.gradle
@@ -45,23 +45,14 @@ class CheckBrokenLinksTask extends DefaultTask {
 
   @TaskAction
   def check() {
-    def result
-    output.withOutputStream { output ->
-      result = project.exec {
-        executable project.externalTool("python3")
-        ignoreExitValue = true
-        standardOutput = output
-        errorOutput = output
-        args = [
-          "-B",
-          validationScript.absolutePath,
-          docsDir.get().getAsFile()
-        ]
-      }
-    }
-
-    if (result.getExitValue() != 0) {
-      throw new GradleException("Broken links check failed. Command output at: ${output}")
+    project.quietExec {
+      executable project.externalTool("python3")
+      ignoreExitValue = false
+      args = [
+        "-B",
+        validationScript.absolutePath,
+        docsDir.get().getAsFile()
+      ]
     }
   }
 }
diff --git a/gradle/documentation/render-javadoc.gradle b/gradle/documentation/render-javadoc.gradle
index 4503f8e..e852794 100644
--- a/gradle/documentation/render-javadoc.gradle
+++ b/gradle/documentation/render-javadoc.gradle
@@ -451,46 +451,11 @@ class RenderJavadocTask extends DefaultTask {
 
     logger.info("Javadoc executable used: ${javadocCmd}")
 
-    def outputFile = project.file("${getTemporaryDir()}/javadoc-output.txt")
-    def result
-
-    outputFile.withOutputStream { output ->
-      result = project.exec {
+    project.quietExec {
         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 += 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
diff --git a/gradle/generation/icu.gradle b/gradle/generation/icu.gradle
index fca3d8a..d450d48 100644
--- a/gradle/generation/icu.gradle
+++ b/gradle/generation/icu.gradle
@@ -63,9 +63,8 @@ configure(project(":lucene:analysis:icu")) {
         ]
       }
 
-      project.exec {
+      project.quietExec {
         executable gennorm
-        ignoreExitValue = false
         args = [
             "-v",
             "-s",
@@ -77,9 +76,9 @@ configure(project(":lucene:analysis:icu")) {
             "NativeDigitFolding.txt"
         ]
       }
-      project.exec {
+
+      project.quietExec {
         executable icupkg
-        ignoreExitValue = false
         args = [
             "-tb",
             "${buildDir}/utr30.tmp",
@@ -157,10 +156,8 @@ configure(project(":lucene:analysis:icu")) {
       project.delete icuSrcDir
 
       // Extract the tgz
-      project.exec {
+      project.quietExec {
         executable "tar"
-        ignoreExitValue false
-
         workingDir icuBuildDir
         args = [
             "-zxvf",
@@ -169,9 +166,8 @@ configure(project(":lucene:analysis:icu")) {
       }
 
       // Compile: (cd icu/source && ./configure --prefix=$(pwd) --enable-rpath && make -j4)
-      project.exec {
+      project.quietExec {
         executable "sh"
-        ignoreExitValue false
 
         workingDir icuSrcDir
         args = [
@@ -181,9 +177,8 @@ configure(project(":lucene:analysis:icu")) {
         ]
       }
 
-      project.exec {
+      project.quietExec {
         executable "make"
-        ignoreExitValue false
         workingDir icuSrcDir
         args = [
             "-j4"
@@ -192,9 +187,8 @@ configure(project(":lucene:analysis:icu")) {
 
       // Test that the binaries work:  derb -V
       logger.lifecycle("Compiled ICU, checking...")
-      project.exec {
+      project.quietExec {
         executable "./derb"
-        ignoreExitValue false
         workingDir icuBinDir
         args = [
             "-V"
diff --git a/gradle/generation/jflex.gradle b/gradle/generation/jflex.gradle
index 8f6f5ca..3e9a949 100644
--- a/gradle/generation/jflex.gradle
+++ b/gradle/generation/jflex.gradle
@@ -157,16 +157,13 @@ configure(project(":lucene:analysis:common")) {
     doFirst {
       // Regenerate HTMLCharacterEntities.jflex first.
       def target = file('src/java/org/apache/lucene/analysis/charfilter/HTMLCharacterEntities.jflex')
-      target.withOutputStream { output ->
-        project.exec {
-          executable = project.externalTool("python3")
-          workingDir = target.parentFile
-          standardOutput = output
-          args += [
-              "-B", // don't write any bytecode cache
-              "htmlentity.py"
-          ]
-        }
+      quietExec {
+        executable = project.externalTool("python3")
+        workingDir = target.parentFile
+        args += [
+            "-B", // don't write any bytecode cache
+            "htmlentity.py"
+        ]
       }
 
       project.ant.fixcrlf(
diff --git a/gradle/generation/kuromoji.gradle b/gradle/generation/kuromoji.gradle
index 49e32ae..566eaec 100644
--- a/gradle/generation/kuromoji.gradle
+++ b/gradle/generation/kuromoji.gradle
@@ -71,7 +71,7 @@ configure(project(":lucene:analysis:kuromoji")) {
         }
 
         // Apply patch via local git.
-        project.exec {
+        project.quietExec {
           workingDir = unpackedDir
           executable "git" // TODO: better use jgit to apply patch, this is not portable!!!
           args += [
diff --git a/gradle/generation/snowball.gradle b/gradle/generation/snowball.gradle
index 5f2ff71..7ea4556 100644
--- a/gradle/generation/snowball.gradle
+++ b/gradle/generation/snowball.gradle
@@ -106,7 +106,7 @@ configure(project(":lucene:analysis:common")) {
       dependsOn downloadSnowballData
 
       doFirst {
-        project.exec {
+        project.quietExec {
           executable "bash"
           args = [snowballScript, snowballStemmerDir, snowballWebsiteDir, snowballDataDir, projectDir]
         }
diff --git a/gradle/generation/util.gradle b/gradle/generation/util.gradle
index 2484f44..e672ecc 100644
--- a/gradle/generation/util.gradle
+++ b/gradle/generation/util.gradle
@@ -44,7 +44,7 @@ configure(project(":lucene:core")) {
 
       ['gen_BulkOperation.py', 'gen_Packed64SingleBlock.py'].each { prog ->
         logger.lifecycle("Executing: ${prog} in ${targetDir}")
-        project.exec {
+        quietExec {
           workingDir targetDir
           executable project.externalTool("python3")
           args = ['-B', "${prog}"]
@@ -69,7 +69,7 @@ configure(project(":lucene:core")) {
 
       ['1', '2'].each { num ->
         ['True', 'False'].each { transpose ->
-          project.exec {
+          quietExec {
             workingDir targetDir
             executable project.externalTool("python3")
             args = ['-B', 'createLevAutomata.py', num, transpose, "${momanDir}/finenight/python"]
diff --git a/gradle/globals.gradle b/gradle/globals.gradle
index 0ca1af1..fbcbb2d 100644
--- a/gradle/globals.gradle
+++ b/gradle/globals.gradle
@@ -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
+    }
   }
 }