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

slachiewicz pushed a commit to branch MSHARED-907
in repository https://gitbox.apache.org/repos/asf/maven-script-interpreter.git

commit 9f62f6084299a4e3048f535356da94551725c70d
Author: Slawomir Jaranowski <slawomir.jaranow...@payu.pl>
AuthorDate: Tue Jun 2 21:05:52 2020 +0200

    [MSHARED-907] Output build log from script to application
    
    Closes #4
---
 pom.xml                                            |  20 ++-
 .../maven/shared/scriptinterpreter/FileLogger.java | 151 +++++++++++++--------
 .../scriptinterpreter/FileLoggerMirrorHandler.java |  34 +++++
 .../shared/scriptinterpreter/ScriptRunner.java     |  70 ++++------
 src/site/apt/index.apt.vm                          |  29 +++-
 .../shared/scriptinterpreter/FileLoggerTest.java   | 129 ++++++++++++++++++
 .../shared/scriptinterpreter/ScriptRunnerTest.java | 141 ++++++++++++++-----
 .../scriptinterpreter/TestMirrorHandler.java       |  48 +++++++
 src/test/resources/bsh-test/failed.bsh             |  20 +++
 src/test/resources/groovy-test/failed.groovy       |  25 ++++
 10 files changed, 524 insertions(+), 143 deletions(-)

diff --git a/pom.xml b/pom.xml
index b78ae5b..3eb16b8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -56,15 +56,11 @@
   <properties>
     <javaVersion>7</javaVersion>
     
<project.build.outputTimestamp>2020-04-04T09:03:59Z</project.build.outputTimestamp>
+    <slf4j.version>1.7.30</slf4j.version>
   </properties>
 
   <dependencies>
     <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-plugin-api</artifactId>
-      <version>2.0.6</version>
-    </dependency>
-    <dependency>
       <groupId>org.apache.maven.shared</groupId>
       <artifactId>maven-shared-utils</artifactId>
       <version>3.2.1</version>
@@ -107,6 +103,20 @@
         </exclusion>
       </exclusions>
     </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>${slf4j.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <version>${slf4j.version}</version>
+      <scope>test</scope>
+    </dependency>
+
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
diff --git 
a/src/main/java/org/apache/maven/shared/scriptinterpreter/FileLogger.java 
b/src/main/java/org/apache/maven/shared/scriptinterpreter/FileLogger.java
index 236a2bb..b915090 100644
--- a/src/main/java/org/apache/maven/shared/scriptinterpreter/FileLogger.java
+++ b/src/main/java/org/apache/maven/shared/scriptinterpreter/FileLogger.java
@@ -19,18 +19,17 @@ package org.apache.maven.shared.scriptinterpreter;
  * under the License.
  */
 
-import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.shared.utils.io.IOUtil;
 
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.io.PrintStream;
 
 /**
  */
-public class FileLogger
-    implements ExecutionLogger
+public class FileLogger implements ExecutionLogger, AutoCloseable
 {
 
     /**
@@ -44,65 +43,52 @@ public class FileLogger
     private PrintStream stream;
 
     /**
-     * A flag whether the output stream should be closed during finalization 
of this logger.
-     */
-    private boolean shouldFinalize = true;
-
-    /**
-     * The optional mojo logger to additionally write messages to, can be 
<code>null</code>.
-     */
-    private final Log log;
-
-    /**
      * Creates a new logger that writes to the specified file.
-     * 
-     * @param outputFile The path to the output file, must not be 
<code>null</code>.
+     *
+     * @param outputFile The path to the output file, if null all message will 
be discarded.
      * @throws java.io.IOException If the output file could not be created.
      */
-    public FileLogger( File outputFile )
-        throws IOException
+    public FileLogger( File outputFile ) throws IOException
     {
         this( outputFile, null );
     }
 
     /**
-     * Creates a new logger that writes to the specified file and optionally 
mirrors messages to the given mojo logger.
+     * Creates a new logger that writes to the specified file and optionally 
mirrors messages.
      *
-     * @param outputFile The path to the output file, must not be 
<code>null</code>.
-     * @param log The mojo logger to additionally output messages to, may be 
<code>null</code> if not used.
+     * @param outputFile The path to the output file, if null all message will 
be discarded.
+     * @param mirrorHandler The class which handle mirrored message, can be 
<code>null</code>.
      * @throws java.io.IOException If the output file could not be created.
      */
-    public FileLogger( File outputFile, Log log )
-        throws IOException
+    public FileLogger( File outputFile, FileLoggerMirrorHandler mirrorHandler 
) throws IOException
     {
         this.file = outputFile;
-        this.log = log;
 
-        outputFile.getParentFile().mkdirs();
-        stream = new PrintStream( new FileOutputStream( outputFile ) );
+        OutputStream outputStream;
 
-        Runnable finalizer = new Runnable()
+        if ( outputFile != null )
         {
-            @Override
-            public void run()
-            {
-                try
-                {
-                    finalize();
-                }
-                catch ( Throwable e )
-                {
-                    // ignore
-                }
-            }
-        };
+            outputFile.getParentFile().mkdirs();
+            outputStream = new FileOutputStream( outputFile );
+        }
+        else
+        {
+            outputStream = new NullOutputStream();
+        }
 
-        Runtime.getRuntime().addShutdownHook( new Thread( finalizer ) );
+        if ( mirrorHandler != null )
+        {
+            stream = new PrintStream( new MirrorStreamWrapper( outputStream, 
mirrorHandler ) );
+        }
+        else
+        {
+            stream = new PrintStream( outputStream );
+        }
     }
 
     /**
      * Gets the path to the output file.
-     * 
+     *
      * @return The path to the output file, never <code>null</code>.
      */
     public File getOutputFile()
@@ -112,7 +98,7 @@ public class FileLogger
 
     /**
      * Gets the underlying stream used to write message to the log file.
-     * 
+     *
      * @return The underlying stream used to write message to the log file, 
never <code>null</code>.
      */
     @Override
@@ -122,8 +108,9 @@ public class FileLogger
     }
 
     /**
-     * Writes the specified line to the log file and optionally to the mojo 
logger.
-     * 
+     * Writes the specified line to the log file
+     * and invoke {@link FileLoggerMirrorHandler#consumeOutput(String)} if is 
given.
+     *
      * @param line The message to log.
      */
     @Override
@@ -131,11 +118,6 @@ public class FileLogger
     {
         stream.println( line );
         stream.flush();
-
-        if ( log != null )
-        {
-            log.info( line );
-        }
     }
 
     /**
@@ -151,15 +133,72 @@ public class FileLogger
         IOUtil.close( stream );
     }
 
-    /**
-     * Closes the underlying file stream.
-     */
-    @Override
-    protected void finalize()
+    private static class MirrorStreamWrapper extends OutputStream
     {
-        if ( shouldFinalize )
+        private final OutputStream out;
+        private final FileLoggerMirrorHandler mirrorHandler;
+
+        private StringBuilder lineBuffer;
+
+        MirrorStreamWrapper( OutputStream outputStream, 
FileLoggerMirrorHandler mirrorHandler )
+        {
+            this.out = outputStream;
+            this.mirrorHandler = mirrorHandler;
+            this.lineBuffer = new StringBuilder();
+        }
+
+        @Override
+        public void write( int b ) throws IOException
+        {
+            out.write( b );
+            lineBuffer.append( (char) ( b ) );
+        }
+
+        @Override
+        public void write( byte[] b, int off, int len ) throws IOException
+        {
+            out.write( b, off, len );
+            lineBuffer.append( new String( b, off, len ) );
+        }
+
+        @Override
+        public void flush() throws IOException
+        {
+            out.flush();
+
+            int len = lineBuffer.length();
+            if ( len == 0 )
+            {
+                // nothing to log
+                return;
+            }
+
+            // remove line end for log
+            while ( len > 0 && ( lineBuffer.charAt( len - 1 ) == '\n' || 
lineBuffer.charAt( len - 1 ) == '\r' ) )
+            {
+                len--;
+            }
+            lineBuffer.setLength( len );
+
+            mirrorHandler.consumeOutput( lineBuffer.toString() );
+
+            // clear buffer
+            lineBuffer = new StringBuilder();
+        }
+    }
+
+    private static class NullOutputStream extends OutputStream
+    {
+        @Override
+        public void write( int b )
+        {
+            // do nothing
+        }
+
+        @Override
+        public void write( byte[] b, int off, int len )
         {
-            close();
+            // do nothing
         }
     }
 }
diff --git 
a/src/main/java/org/apache/maven/shared/scriptinterpreter/FileLoggerMirrorHandler.java
 
b/src/main/java/org/apache/maven/shared/scriptinterpreter/FileLoggerMirrorHandler.java
new file mode 100644
index 0000000..fcc219e
--- /dev/null
+++ 
b/src/main/java/org/apache/maven/shared/scriptinterpreter/FileLoggerMirrorHandler.java
@@ -0,0 +1,34 @@
+package org.apache.maven.shared.scriptinterpreter;
+
+/*
+ * 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.
+ */
+
+/**
+ * Handle output form interpreter.
+ */
+public interface FileLoggerMirrorHandler
+{
+    /**
+     * Handle output message generated by script interpreter.
+     * This method is invoked when flush occurs on the underlying stream.
+     *
+     * @param message last message
+     */
+    void consumeOutput( String message );
+}
diff --git 
a/src/main/java/org/apache/maven/shared/scriptinterpreter/ScriptRunner.java 
b/src/main/java/org/apache/maven/shared/scriptinterpreter/ScriptRunner.java
index f17b398..d30e8f7 100644
--- a/src/main/java/org/apache/maven/shared/scriptinterpreter/ScriptRunner.java
+++ b/src/main/java/org/apache/maven/shared/scriptinterpreter/ScriptRunner.java
@@ -19,9 +19,10 @@ package org.apache.maven.shared.scriptinterpreter;
  * under the License.
  */
 
-import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.shared.utils.io.FileUtils;
 import org.apache.maven.shared.utils.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.io.File;
 import java.io.IOException;
@@ -41,10 +42,8 @@ import java.util.Map;
 public class ScriptRunner
 {
 
-    /**
-     * The mojo logger to print diagnostic to, never <code>null</code>.
-     */
-    private Log log;
+
+    private static final Logger LOG = LoggerFactory.getLogger( 
ScriptRunner.class );
 
     /**
      * The supported script interpreters, indexed by the lower-case file 
extension of their associated script files,
@@ -69,16 +68,9 @@ public class ScriptRunner
 
     /**
      * Creates a new script runner.
-     *
-     * @param log The mojo logger to print diagnostic to, must not be 
<code>null</code>.
      */
-    public ScriptRunner( Log log )
+    public ScriptRunner()
     {
-        if ( log == null )
-        {
-            throw new IllegalArgumentException( "missing logger" );
-        }
-        this.log = log;
         scriptInterpreters = new LinkedHashMap<>();
         scriptInterpreters.put( "bsh", new BeanShellScriptInterpreter() );
         scriptInterpreters.put( "groovy", new GroovyScriptInterpreter() );
@@ -92,19 +84,9 @@ public class ScriptRunner
     }
 
     /**
-     * Gets the mojo logger.
-     *
-     * @return The mojo logger, never <code>null</code>.
-     */
-    private Log getLog()
-    {
-        return log;
-    }
-
-    /**
      * Sets a global variable for the script interpreter.
      *
-     * @param name  The name of the variable, must not be <code>null</code>.
+     * @param name The name of the variable, must not be <code>null</code>.
      * @param value The value of the variable, may be <code>null</code>.
      */
     public void setGlobalVariable( String name, Object value )
@@ -117,8 +99,8 @@ public class ScriptRunner
      * will not affect the scripts.
      *
      * @param classPath The additional class path for the script interpreter, 
may be <code>null</code> or empty if only
-     *            the plugin realm should be used for the script evaluation. 
If specified, this class path will precede
-     *            the artifacts from the plugin class path.
+     * the plugin realm should be used for the script evaluation. If 
specified, this class path will precede the
+     * artifacts from the plugin class path.
      */
     public void setClassPath( List<String> classPath )
     {
@@ -160,7 +142,7 @@ public class ScriptRunner
     {
         if ( relativeScriptPath == null )
         {
-            getLog().debug( scriptDescription + ": relativeScriptPath is null, 
not executing script" );
+            LOG.debug( "{}: relativeScriptPath is null, not executing script", 
scriptDescription );
             return;
         }
 
@@ -168,13 +150,13 @@ public class ScriptRunner
 
         if ( !scriptFile.exists() )
         {
-            getLog().debug( scriptDescription + ": no script '" + 
relativeScriptPath + "' found in directory "
-                + basedir.getAbsolutePath() );
+            LOG.debug( "{} : no script '{}' found in directory {}", 
scriptDescription, relativeScriptPath,
+                    basedir.getAbsolutePath() );
             return;
         }
 
-        getLog().info( "run " + scriptDescription + ' ' + relativeScriptPath + 
'.'
-            + FileUtils.extension( scriptFile.getAbsolutePath() ) );
+        LOG.info( "run {} {}.{}",
+                scriptDescription, relativeScriptPath, FileUtils.extension( 
scriptFile.getAbsolutePath() ) );
 
         executeRun( scriptDescription, scriptFile, context, logger, stage, 
failOnException );
     }
@@ -187,11 +169,10 @@ public class ScriptRunner
      * @param context The key-value storage used to share information between 
hook scripts, may be <code>null</code>.
      * @param logger The logger to redirect the script output to, may be 
<code>null</code> to use stdout/stderr.
      * @param stage The stage of the build job the script is invoked in, must 
not be <code>null</code>. This is for
-     *            logging purpose only.
-     * @param failOnException If <code>true</code> and the script throws an 
exception, then a
-     *            {@link RunFailureException} will be thrown, otherwise a 
{@link RunErrorException} will be thrown on
-     *            script exception.
-     * @throws IOException If an I/O error occurred while reading the script 
file.
+     * logging purpose only.
+     * @param failOnException If <code>true</code> and the script throws an 
exception, then a {@link
+     * RunFailureException} will be thrown, otherwise a {@link 
RunErrorException} will be thrown on script exception.
+     * @throws IOException         If an I/O error occurred while reading the 
script file.
      * @throws RunFailureException If the script did not return 
<code>true</code> of threw an exception.
      */
     public void run( final String scriptDescription, File scriptFile, final 
Map<String, ? extends Object> context,
@@ -201,12 +182,11 @@ public class ScriptRunner
 
         if ( !scriptFile.exists() )
         {
-            getLog().debug( scriptDescription + ": script file not found in 
directory "
-                + scriptFile.getAbsolutePath() );
+            LOG.debug( "{} : script file not found in directory {}", 
scriptDescription, scriptFile.getAbsolutePath() );
             return;
         }
 
-        getLog().info( "run " + scriptDescription + ' ' + 
scriptFile.getAbsolutePath() );
+        LOG.info( "run {} {}", scriptDescription, scriptFile.getAbsolutePath() 
);
 
         executeRun( scriptDescription, scriptFile, context, logger, stage, 
failOnException );
     }
@@ -221,11 +201,11 @@ public class ScriptRunner
         globalVariables.put( "context", context );
 
         ScriptInterpreter interpreter = getInterpreter( scriptFile );
-        if ( getLog().isDebugEnabled() )
+        if ( LOG.isDebugEnabled() )
         {
             String name = interpreter.getClass().getName();
             name = name.substring( name.lastIndexOf( '.' ) + 1 );
-            getLog().debug( "Running script with " + name + ": " + scriptFile 
);
+            LOG.debug( "Running script with {} :{}", name, scriptFile );
         }
 
         String script;
@@ -237,9 +217,7 @@ public class ScriptRunner
         {
             String errorMessage =
                 "error reading " + scriptDescription + " " + 
scriptFile.getPath() + ", " + e.getMessage();
-            IOException ioException = new IOException( errorMessage );
-            ioException.initCause( e );
-            throw ioException;
+            throw new IOException( errorMessage, e );
         }
 
         Object result;
@@ -262,10 +240,10 @@ public class ScriptRunner
         {
             Throwable t = ( e.getCause() != null ) ? e.getCause() : e;
             String msg = ( t.getMessage() != null ) ? t.getMessage() : 
t.toString();
-            if ( getLog().isDebugEnabled() )
+            if ( LOG.isDebugEnabled() )
             {
                 String errorMessage = "Error evaluating " + scriptDescription 
+ " " + scriptFile.getPath() + ", " + t;
-                getLog().debug( errorMessage, t );
+                LOG.debug( errorMessage, t );
             }
             if ( logger != null )
             {
diff --git a/src/site/apt/index.apt.vm b/src/site/apt/index.apt.vm
index f43ff0f..2dbae50 100644
--- a/src/site/apt/index.apt.vm
+++ b/src/site/apt/index.apt.vm
@@ -73,13 +73,38 @@ ${project.name}
   See 
{{{./apidocs/org/apache/maven/shared/scriptinterpreter/ScriptRunner.html}javadoc}}
 for run method.
 
 +---------
-    SystemStreamLog systemStreamLog = new SystemStreamLog();
 
-    ScriptRunner scriptRunner = new ScriptRunner( systemStreamLog );
+    ScriptRunner scriptRunner = new ScriptRunner( );
     scriptRunner.run( "test", new File( "src/test/resources/bsh-test" ), 
"verify", buildContext(),
                       new FileLogger( logFile ), "foo", true );
 +---------
 
+* Mirror output from script interpreter
+
+  In order to do something more with script output, eg. log by your 
application you must implement FileLoggerMirrorHandler
+
++---------
+
+class MyMirrorHandler implements FileLoggerMirrorHandler
+{
+    void consumeOutput( String message )
+    {
+        // this method is invoked every time when flush occurs on the 
underlying stream.
+    }
+}
+
++---------
+
+  Now use it:
+
++---------
+
+      ScriptRunner scriptRunner = new ScriptRunner( );
+      scriptRunner.run( "test", new File( "src/test/resources/bsh-test" ), 
"verify", buildContext(),
+                        new FileLogger( logFile, new MyMirrorHandler() ), 
"foo", true );
+
++---------
+
 ** Global variables
 
   Your scripts will have by default two global variables:
diff --git 
a/src/test/java/org/apache/maven/shared/scriptinterpreter/FileLoggerTest.java 
b/src/test/java/org/apache/maven/shared/scriptinterpreter/FileLoggerTest.java
new file mode 100644
index 0000000..8eee66c
--- /dev/null
+++ 
b/src/test/java/org/apache/maven/shared/scriptinterpreter/FileLoggerTest.java
@@ -0,0 +1,129 @@
+package org.apache.maven.shared.scriptinterpreter;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.shared.utils.io.FileUtils;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class FileLoggerTest
+{
+
+    public static final String EXPECTED_LOG = "Test1" + System.lineSeparator() 
+ "Test2" + System.lineSeparator();
+
+    @Test
+    public void nullOutputFileNoMirror() throws IOException
+    {
+        try ( FileLogger fileLogger = new FileLogger( null ) )
+        {
+            fileLogger.consumeLine( "Test1" );
+            fileLogger.getPrintStream().println( "Test2" );
+            fileLogger.getPrintStream().flush();
+
+            assertNull( fileLogger.getOutputFile() );
+        }
+    }
+
+    @Test
+    public void nullOutputFileWithMirror() throws IOException
+    {
+        TestMirrorHandler mirrorHandler = new TestMirrorHandler();
+
+        try ( FileLogger fileLogger = new FileLogger( null, mirrorHandler ) )
+        {
+            fileLogger.consumeLine( "Test1" );
+            fileLogger.getPrintStream().println( "Test2" );
+            fileLogger.getPrintStream().flush();
+
+            assertNull( fileLogger.getOutputFile() );
+        }
+
+        assertEquals( EXPECTED_LOG, mirrorHandler.getLoggedMessage() );
+    }
+
+    @Test
+    public void nullOutputFileWithMirrorWriteByte() throws IOException
+    {
+        TestMirrorHandler mirrorHandler = new TestMirrorHandler();
+
+        try ( FileLogger fileLogger = new FileLogger( null, mirrorHandler ) )
+        {
+            fileLogger.getPrintStream().write( 'A' );
+            fileLogger.getPrintStream().flush();
+
+            assertNull( fileLogger.getOutputFile() );
+        }
+
+        assertEquals( "A" + System.lineSeparator(), 
mirrorHandler.getLoggedMessage() );
+    }
+
+    @Test
+    public void outputFileNoMirror() throws IOException
+    {
+        File outputFile = new File( "target/test.log" );
+        if ( outputFile.exists() )
+        {
+            outputFile.delete();
+        }
+
+        try ( FileLogger fileLogger = new FileLogger( outputFile ) )
+        {
+            fileLogger.consumeLine( "Test1" );
+            fileLogger.getPrintStream().println( "Test2" );
+            fileLogger.getPrintStream().flush();
+
+            assertEquals( outputFile, fileLogger.getOutputFile() );
+        }
+
+        assertTrue( outputFile.exists() );
+        assertEquals( EXPECTED_LOG, FileUtils.fileRead( outputFile ) );
+    }
+
+    @Test
+    public void outputFileWithMirror() throws IOException
+    {
+        File outputFile = new File( "target/test.log" );
+        if ( outputFile.exists() )
+        {
+            outputFile.delete();
+        }
+        TestMirrorHandler mirrorHandler = new TestMirrorHandler();
+
+        try ( FileLogger fileLogger = new FileLogger( outputFile, 
mirrorHandler ) )
+        {
+            fileLogger.consumeLine( "Test1" );
+            fileLogger.getPrintStream().println( "Test2" );
+            fileLogger.getPrintStream().flush();
+
+            assertEquals( outputFile, fileLogger.getOutputFile() );
+        }
+
+        assertEquals( EXPECTED_LOG, mirrorHandler.getLoggedMessage() );
+
+        assertTrue( outputFile.exists() );
+        assertEquals( EXPECTED_LOG, FileUtils.fileRead( outputFile ) );
+    }
+}
diff --git 
a/src/test/java/org/apache/maven/shared/scriptinterpreter/ScriptRunnerTest.java 
b/src/test/java/org/apache/maven/shared/scriptinterpreter/ScriptRunnerTest.java
index d2c1c37..46fc885 100644
--- 
a/src/test/java/org/apache/maven/shared/scriptinterpreter/ScriptRunnerTest.java
+++ 
b/src/test/java/org/apache/maven/shared/scriptinterpreter/ScriptRunnerTest.java
@@ -1,4 +1,5 @@
 package org.apache.maven.shared.scriptinterpreter;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -18,7 +19,6 @@ package org.apache.maven.shared.scriptinterpreter;
  * under the License.
  */
 
-import org.apache.maven.plugin.logging.SystemStreamLog;
 import org.apache.maven.shared.utils.io.FileUtils;
 import org.junit.Test;
 
@@ -26,6 +26,7 @@ import java.io.File;
 import java.util.HashMap;
 import java.util.Map;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 /**
@@ -33,67 +34,108 @@ import static org.junit.Assert.assertTrue;
  */
 public class ScriptRunnerTest
 {
+
     @Test
-    public void testBeanshell()
-        throws Exception
+    public void testBeanshell() throws Exception
     {
         File logFile = new File( "target/build.log" );
         if ( logFile.exists() )
         {
             logFile.delete();
         }
-        SystemStreamLog systemStreamLog = new SystemStreamLog();
 
-        ScriptRunner scriptRunner = new ScriptRunner( systemStreamLog );
-        scriptRunner.setGlobalVariable( "globalVar", "Yeah baby it's rocks" );
-        scriptRunner.run( "test", new File( "src/test/resources/bsh-test" ), 
"verify", buildContext(),
-                          new FileLogger( logFile ), "foo", true );
+        TestMirrorHandler mirrorHandler = new TestMirrorHandler();
+
+        try ( FileLogger fileLogger = new FileLogger( logFile, mirrorHandler ) 
)
+        {
+            ScriptRunner scriptRunner = new ScriptRunner();
+            scriptRunner.setGlobalVariable( "globalVar", "Yeah baby it's 
rocks" );
+            scriptRunner.run( "test", new File( "src/test/resources/bsh-test" 
), "verify",
+                    buildContext(), fileLogger, "foo", true );
+        }
 
         String logContent = FileUtils.fileRead( logFile );
         assertTrue( logContent.contains( new File( 
"src/test/resources/bsh-test/verify.bsh" ).getPath() ) );
         assertTrue( logContent.contains( "foo=bar" ) );
         assertTrue( logContent.contains( "globalVar=Yeah baby it's rocks" ) );
 
+        assertEquals( logContent, mirrorHandler.getLoggedMessage() );
+    }
+
+    @Test
+    public void failedBeanshellShouldCreateProperLogsMessage() throws Exception
+    {
+        File logFile = new File( "target/build.log" );
+        if ( logFile.exists() )
+        {
+            logFile.delete();
+        }
+
+        TestMirrorHandler mirrorHandler = new TestMirrorHandler();
+
+        Exception catchedException = null;
+
+        try ( FileLogger fileLogger = new FileLogger( logFile, mirrorHandler ) 
)
+        {
+            ScriptRunner scriptRunner = new ScriptRunner();
+            scriptRunner.run( "test", new File( "src/test/resources/bsh-test" 
), "failed",
+                    buildContext(), fileLogger, "foo", false );
+        }
+        catch ( Exception e )
+        {
+            catchedException = e;
+        }
+
+        assertTrue( catchedException instanceof RunErrorException );
+        String logContent = FileUtils.fileRead( logFile );
+        assertTrue( logContent.contains( new File( 
"src/test/resources/bsh-test/failed.bsh" ).getPath() ) );
+        assertEquals( logContent, mirrorHandler.getLoggedMessage() );
     }
 
     @Test
-    public void testBeanshellWithFile()
-        throws Exception
+    public void testBeanshellWithFile() throws Exception
     {
         File logFile = new File( "target/build.log" );
         if ( logFile.exists() )
         {
             logFile.delete();
         }
-        SystemStreamLog systemStreamLog = new SystemStreamLog();
 
-        ScriptRunner scriptRunner = new ScriptRunner( systemStreamLog );
-        scriptRunner.setGlobalVariable( "globalVar", "Yeah baby it's rocks" );
-        scriptRunner.run( "test", new File( 
"src/test/resources/bsh-test/verify.bsh" ), buildContext(),
-                          new FileLogger( logFile ), "foo", true );
+        TestMirrorHandler mirrorHandler = new TestMirrorHandler();
+
+        try ( FileLogger fileLogger = new FileLogger( logFile, mirrorHandler ) 
)
+        {
+            ScriptRunner scriptRunner = new ScriptRunner();
+            scriptRunner.setGlobalVariable( "globalVar", "Yeah baby it's 
rocks" );
+            scriptRunner.run( "test", new File( 
"src/test/resources/bsh-test/verify.bsh" ),
+                    buildContext(), fileLogger, "foo", true );
+        }
 
         String logContent = FileUtils.fileRead( logFile );
         assertTrue( logContent.contains( new File( 
"src/test/resources/bsh-test/verify.bsh" ).getPath() ) );
         assertTrue( logContent.contains( "foo=bar" ) );
 
-
+        assertEquals( logContent, mirrorHandler.getLoggedMessage() );
     }
 
     @Test
-    public void testGroovy()
-        throws Exception
+    public void testGroovy() throws Exception
     {
         File logFile = new File( "target/build.log" );
         if ( logFile.exists() )
         {
             logFile.delete();
         }
-        SystemStreamLog systemStreamLog = new SystemStreamLog();
 
-        ScriptRunner scriptRunner = new ScriptRunner( systemStreamLog );
-        scriptRunner.setGlobalVariable( "globalVar", "Yeah baby it's rocks" );
-        scriptRunner.run( "test", new File( "src/test/resources/groovy-test" 
), "verify", buildContext(),
-                          new FileLogger( logFile ), "foo", true );
+        TestMirrorHandler mirrorHandler = new TestMirrorHandler();
+
+        try ( FileLogger fileLogger = new FileLogger( logFile, mirrorHandler ) 
)
+        {
+            ScriptRunner scriptRunner = new ScriptRunner();
+            scriptRunner.setGlobalVariable( "globalVar", "Yeah baby it's 
rocks" );
+            scriptRunner.run( "test", new File( 
"src/test/resources/groovy-test" ), "verify",
+                    buildContext(), fileLogger, "foo", true );
+        }
 
         String logContent = FileUtils.fileRead( logFile );
         assertTrue(
@@ -101,31 +143,63 @@ public class ScriptRunnerTest
         assertTrue( logContent.contains( "foo=bar" ) );
         assertTrue( logContent.contains( "globalVar=Yeah baby it's rocks" ) );
 
+        assertEquals( logContent, mirrorHandler.getLoggedMessage() );
     }
 
     @Test
-    public void testGroovyWithFile()
-        throws Exception
+    public void failedGroovyShouldCreateProperLogsMessage() throws Exception
     {
         File logFile = new File( "target/build.log" );
         if ( logFile.exists() )
         {
             logFile.delete();
         }
-        SystemStreamLog systemStreamLog = new SystemStreamLog();
 
-        ScriptRunner scriptRunner = new ScriptRunner( systemStreamLog );
-        scriptRunner.run( "test", new File( 
"src/test/resources/groovy-test/verify.groovy" ), buildContext(),
-                          new FileLogger( logFile ), "foo", true );
+        TestMirrorHandler mirrorHandler = new TestMirrorHandler();
 
-        String logContent = FileUtils.fileRead( logFile );
-        assertTrue(
-                logContent.contains( new File( 
"src/test/resources/groovy-test/verify.groovy" ).getPath() ) );
-        assertTrue( logContent.contains( "foo=bar" ) );
+        Exception catchedException = null;
 
+        try ( FileLogger fileLogger = new FileLogger( logFile, mirrorHandler ) 
)
+        {
+            ScriptRunner scriptRunner = new ScriptRunner();
+            scriptRunner.run( "test", new File( 
"src/test/resources/groovy-test" ), "failed",
+                    buildContext(), fileLogger, "foo", true );
+        }
+        catch ( Exception e )
+        {
+            catchedException = e;
+        }
 
+        assertTrue( catchedException instanceof RunFailureException );
+        String logContent = FileUtils.fileRead( logFile );
+        assertTrue( logContent.contains( new File( 
"src/test/resources/groovy-test/failed.groovy" ).getPath() ) );
+        assertEquals( logContent, mirrorHandler.getLoggedMessage() );
     }
 
+    @Test
+    public void testGroovyWithFile() throws Exception
+    {
+        File logFile = new File( "target/build.log" );
+        if ( logFile.exists() )
+        {
+            logFile.delete();
+        }
+
+        TestMirrorHandler mirrorHandler = new TestMirrorHandler();
+
+        try ( FileLogger fileLogger = new FileLogger( logFile, mirrorHandler ) 
)
+        {
+            ScriptRunner scriptRunner = new ScriptRunner();
+            scriptRunner.run( "test", new File( 
"src/test/resources/groovy-test/verify.groovy" ),
+                    buildContext(), fileLogger, "foo", true );
+        }
+
+        String logContent = FileUtils.fileRead( logFile );
+        assertTrue( logContent.contains( new File( 
"src/test/resources/groovy-test/verify.groovy" ).getPath() ) );
+        assertTrue( logContent.contains( "foo=bar" ) );
+
+        assertEquals( logContent, mirrorHandler.getLoggedMessage() );
+    }
 
     private Map<String, ? extends Object> buildContext()
     {
@@ -133,5 +207,4 @@ public class ScriptRunnerTest
         context.put( "foo", "bar" );
         return context;
     }
-
 }
diff --git 
a/src/test/java/org/apache/maven/shared/scriptinterpreter/TestMirrorHandler.java
 
b/src/test/java/org/apache/maven/shared/scriptinterpreter/TestMirrorHandler.java
new file mode 100644
index 0000000..e818d5b
--- /dev/null
+++ 
b/src/test/java/org/apache/maven/shared/scriptinterpreter/TestMirrorHandler.java
@@ -0,0 +1,48 @@
+package org.apache.maven.shared.scriptinterpreter;
+
+/*
+ * 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.
+ */
+
+import java.io.IOException;
+
+/**
+ * Implementing {@link FileLoggerMirrorHandler} for testing
+ */
+class TestMirrorHandler implements FileLoggerMirrorHandler
+{
+
+    private StringBuilder loggedMessage;
+
+    public TestMirrorHandler() throws IOException
+    {
+        loggedMessage = new StringBuilder();
+    }
+
+    public String getLoggedMessage()
+    {
+        return loggedMessage.toString();
+    }
+
+    @Override
+    public void consumeOutput( String message )
+    {
+        loggedMessage.append( message );
+        loggedMessage.append( System.lineSeparator() );
+    }
+}
diff --git a/src/test/resources/bsh-test/failed.bsh 
b/src/test/resources/bsh-test/failed.bsh
new file mode 100644
index 0000000..f8226bf
--- /dev/null
+++ b/src/test/resources/bsh-test/failed.bsh
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+throw new Exception( "test exception" )
diff --git a/src/test/resources/groovy-test/failed.groovy 
b/src/test/resources/groovy-test/failed.groovy
new file mode 100644
index 0000000..b1881f1
--- /dev/null
+++ b/src/test/resources/groovy-test/failed.groovy
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+
+def message = 'no Te Message'
+
+assert message.contains('Test Message')
+
+return true

Reply via email to