Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package maven-script-interpreter for
openSUSE:Factory checked in at 2026-09-28 10:38:49
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/maven-script-interpreter (Old)
and /work/SRC/openSUSE:Factory/.maven-script-interpreter.new.383539 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "maven-script-interpreter"
Mon Sep 28 10:38:49 2026 rev:8 rq:1380999 version:1.9
Changes:
--------
---
/work/SRC/openSUSE:Factory/maven-script-interpreter/maven-script-interpreter.changes
2026-09-11 18:07:31.401382950 +0200
+++
/work/SRC/openSUSE:Factory/.maven-script-interpreter.new.383539/maven-script-interpreter.changes
2026-09-28 10:39:58.708676810 +0200
@@ -1,0 +2,27 @@
+Sun Sep 27 20:16:44 UTC 2026 - Fridrich Strba <[email protected]>
+
+- Upgrade to version 1.9
+ * Maven Script Interpreter 1.9 fixes how scripts run under the
+ Maven Invoker Plugin: the basedir variable, Groovy class
+ loading, and script encoding.
+ * Behaviour changes:
+ + The basedir script variable is now the project directory, as
+ the invoker plugin documentation describes. Before, it was the
+ directory holding the script, so the two differed for scripts
+ in a subdirectory. Scripts that need their own directory can
+ use the new scriptdir variable.
+ + Without an explicit encoding, scripts are read as UTF-8
+ instead of the platform default charset.
+ * Bug fixes
+ + Bind the basedir script variable to the project directory and
+ add scriptdir
+ + Load Groovy's own classes parent-first, so a different Groovy
+ version on the caller's class path no longer breaks compiled
+ scripts
+ + Read scripts as UTF-8 when no encoding is set
+ + FileLogger: fix the NullPointerException for a log file with
+ no parent directory
+ * Maintenance
+ + Test that a failing script throws an exception
+
+-------------------------------------------------------------------
Old:
----
maven-script-interpreter-1.8-source-release.zip
New:
----
maven-script-interpreter-1.9-source-release.zip
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ maven-script-interpreter.spec ++++++
--- /var/tmp/diff_new_pack.Xab6Sm/_old 2026-09-28 10:40:03.424874574 +0200
+++ /var/tmp/diff_new_pack.Xab6Sm/_new 2026-09-28 10:40:03.425874616 +0200
@@ -17,7 +17,7 @@
Name: maven-script-interpreter
-Version: 1.8
+Version: 1.9
Release: 0
Summary: Maven Script Interpreter
License: Apache-2.0
@@ -68,8 +68,7 @@
slf4j/api \
slf4j/simple
-%{ant} \
- jar javadoc
+ant jar javadoc
%install
# jar
++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.Xab6Sm/_old 2026-09-28 10:40:03.458876000 +0200
+++ /var/tmp/diff_new_pack.Xab6Sm/_new 2026-09-28 10:40:03.461876125 +0200
@@ -1,6 +1,6 @@
-mtime: 1788616025
-commit: f970277aa145567fd6ff760715b2196da327cd2ee04d2c34b1490d492ac229df
+mtime: 1790540624
+commit: 3a2fe120a66000db30a86d430d8c631814030e2835adf4b0105732c7cea08887
url: https://src.opensuse.org/java-packages/maven-script-interpreter
-revision: f970277aa145567fd6ff760715b2196da327cd2ee04d2c34b1490d492ac229df
+revision: 3a2fe120a66000db30a86d430d8c631814030e2835adf4b0105732c7cea08887
projectscmsync: https://src.opensuse.org/java-packages/_ObsPrj
++++++ build.specials.obscpio ++++++
++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore 1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore 2026-09-27 22:23:44.000000000 +0200
@@ -0,0 +1 @@
+.osc
++++++ maven-script-interpreter-1.8-source-release.zip ->
maven-script-interpreter-1.9-source-release.zip ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/maven-script-interpreter-1.8/pom.xml
new/maven-script-interpreter-1.9/pom.xml
--- old/maven-script-interpreter-1.8/pom.xml 2026-09-01 06:09:38.000000000
+0200
+++ new/maven-script-interpreter-1.9/pom.xml 2026-09-19 14:17:02.000000000
+0200
@@ -27,7 +27,7 @@
</parent>
<artifactId>maven-script-interpreter</artifactId>
- <version>1.8</version>
+ <version>1.9</version>
<name>Apache Maven Script Interpreter</name>
<description>This component provides some utilities to interpret/execute
some scripts for various implementations:
@@ -36,7 +36,7 @@
<scm>
<connection>scm:git:https://gitbox.apache.org/repos/asf/maven-script-interpreter.git</connection>
<developerConnection>scm:git:https://gitbox.apache.org/repos/asf/maven-script-interpreter.git</developerConnection>
- <tag>maven-script-interpreter-1.8</tag>
+ <tag>maven-script-interpreter-1.9</tag>
<url>https://github.com/apache/maven-script-interpreter/tree/${project.scm.tag}</url>
</scm>
<issueManagement>
@@ -56,7 +56,7 @@
<properties>
<slf4j.version>1.7.36</slf4j.version>
-
<project.build.outputTimestamp>2026-09-01T06:09:37Z</project.build.outputTimestamp>
+
<project.build.outputTimestamp>2026-09-19T14:17:01Z</project.build.outputTimestamp>
</properties>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/maven-script-interpreter-1.8/src/main/java/org/apache/maven/shared/scriptinterpreter/FileLogger.java
new/maven-script-interpreter-1.9/src/main/java/org/apache/maven/shared/scriptinterpreter/FileLogger.java
---
old/maven-script-interpreter-1.8/src/main/java/org/apache/maven/shared/scriptinterpreter/FileLogger.java
2026-09-01 06:09:38.000000000 +0200
+++
new/maven-script-interpreter-1.9/src/main/java/org/apache/maven/shared/scriptinterpreter/FileLogger.java
2026-09-19 14:17:02.000000000 +0200
@@ -65,7 +65,10 @@
if (outputFile != null) {
Path outputPath = outputFile.toPath();
- Files.createDirectories(outputPath.getParent());
+ Path parent = outputPath.getParent();
+ if (parent != null) {
+ Files.createDirectories(parent);
+ }
outputStream = createOutputStream(outputPath);
} else {
outputStream = new NullOutputStream();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/maven-script-interpreter-1.8/src/main/java/org/apache/maven/shared/scriptinterpreter/GroovyScriptInterpreter.java
new/maven-script-interpreter-1.9/src/main/java/org/apache/maven/shared/scriptinterpreter/GroovyScriptInterpreter.java
---
old/maven-script-interpreter-1.8/src/main/java/org/apache/maven/shared/scriptinterpreter/GroovyScriptInterpreter.java
2026-09-01 06:09:38.000000000 +0200
+++
new/maven-script-interpreter-1.9/src/main/java/org/apache/maven/shared/scriptinterpreter/GroovyScriptInterpreter.java
2026-09-19 14:17:02.000000000 +0200
@@ -39,8 +39,55 @@
*/
class GroovyScriptInterpreter implements ScriptInterpreter {
- private final RootLoader childFirstLoader =
- new RootLoader(new URL[] {},
Thread.currentThread().getContextClassLoader());
+ /**
+ * A child-first class loader that makes one exception: Groovy's own
classes always come from the parent. The
+ * scripts are compiled by the Groovy runtime on the parent class path, so
a Groovy of a different version on the
+ * caller-supplied class path would otherwise shadow it and the compiled
script could not be cast to
+ * {@link groovy.lang.GroovyObject}.
+ */
+ static class GroovyParentFirstRootLoader extends RootLoader {
+
+ GroovyParentFirstRootLoader(ClassLoader parent) {
+ super(new URL[] {}, parent);
+ }
+
+ /**
+ * Indicates whether the given class belongs to the Groovy runtime and
must therefore be loaded from the
+ * parent class loader.
+ *
+ * @param name The binary name of the class, must not be
<code>null</code>.
+ * @return <code>true</code> if the class must be loaded parent-first.
+ */
+ static boolean isGroovyRuntimeClass(String name) {
+ return name.startsWith("groovy.")
+ || name.startsWith("org.codehaus.groovy.")
+ || name.startsWith("org.apache.groovy.");
+ }
+
+ @Override
+ protected synchronized Class<?> loadClass(String name, boolean
resolve) throws ClassNotFoundException {
+ if (isGroovyRuntimeClass(name)) {
+ Class<?> c = findLoadedClass(name);
+ if (c == null && getParent() != null) {
+ try {
+ c = getParent().loadClass(name);
+ } catch (ClassNotFoundException e) {
+ // not provided by the parent, fall back to the
regular child-first lookup
+ }
+ }
+ if (c != null) {
+ if (resolve) {
+ resolveClass(c);
+ }
+ return c;
+ }
+ }
+ return super.loadClass(name, resolve);
+ }
+ }
+
+ private final GroovyParentFirstRootLoader childFirstLoader =
+ new
GroovyParentFirstRootLoader(Thread.currentThread().getContextClassLoader());
private String targetBytecode;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/maven-script-interpreter-1.8/src/main/java/org/apache/maven/shared/scriptinterpreter/ScriptRunner.java
new/maven-script-interpreter-1.9/src/main/java/org/apache/maven/shared/scriptinterpreter/ScriptRunner.java
---
old/maven-script-interpreter-1.8/src/main/java/org/apache/maven/shared/scriptinterpreter/ScriptRunner.java
2026-09-01 06:09:38.000000000 +0200
+++
new/maven-script-interpreter-1.9/src/main/java/org/apache/maven/shared/scriptinterpreter/ScriptRunner.java
2026-09-19 14:17:02.000000000 +0200
@@ -22,6 +22,7 @@
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
+import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -56,7 +57,7 @@
private final Map<String, Object> globalVariables;
/**
- * The file encoding of the hook scripts or <code>null</code> to use
platform encoding.
+ * The file encoding of the hook scripts or <code>null</code> to use UTF-8.
*/
private String encoding;
@@ -119,8 +120,7 @@
/**
* Sets the file encoding of the hook scripts.
*
- * @param encoding The file encoding of the hook scripts, may be
<code>null</code> or empty to use the platform's
- * default encoding.
+ * @param encoding The file encoding of the hook scripts, may be
<code>null</code> or empty to use UTF-8.
*/
public void setScriptEncoding(String encoding) {
this.encoding = encoding != null && !encoding.isEmpty() ? encoding :
null;
@@ -128,6 +128,10 @@
/**
* Runs the specified hook script (after resolution).
+ * <p>
+ * The script is given the global variables <code>basedir</code>, holding
the project base directory passed in
+ * here, and <code>scriptdir</code>, holding the directory the script file
itself lives in. The two differ when
+ * <code>relativeScriptPath</code> points into a subdirectory of the
project.
*
* @param scriptDescription The description of the script to use for
logging, must not be <code>null</code>.
* @param basedir The base directory of the project, must not be
<code>null</code>.
@@ -161,11 +165,14 @@
return;
}
- executeRun(scriptDescription, scriptFile, context, logger);
+ executeRun(scriptDescription, basedir, scriptFile, context, logger);
}
/**
* Runs the specified hook script.
+ * <p>
+ * As no project base directory is passed in, both the
<code>basedir</code> and the <code>scriptdir</code> global
+ * variables are set to the directory the script file lives in.
*
* @param scriptDescription The description of the script to use for
logging, must not be <code>null</code>.
* @param scriptFile The path to the script, may be <code>null</code> to
skip the script execution.
@@ -183,11 +190,15 @@
return;
}
- executeRun(scriptDescription, scriptFile, context, logger);
+ executeRun(scriptDescription, scriptFile.getParentFile(), scriptFile,
context, logger);
}
private void executeRun(
- final String scriptDescription, File scriptFile, final Map<String,
?> context, final ExecutionLogger logger)
+ final String scriptDescription,
+ final File basedir,
+ File scriptFile,
+ final Map<String, ?> context,
+ final ExecutionLogger logger)
throws IOException, ScriptException {
ScriptInterpreter interpreter = getInterpreter(scriptFile);
if (LOG.isDebugEnabled()) {
@@ -202,7 +213,7 @@
if (encoding != null) {
script = new String(bytes, encoding);
} else {
- script = new String(bytes);
+ script = new String(bytes, StandardCharsets.UTF_8);
}
} catch (IOException e) {
String errorMessage =
@@ -219,7 +230,8 @@
PrintStream out = (logger != null) ? logger.getPrintStream() :
null;
Map<String, Object> scriptVariables = new
HashMap<>(this.globalVariables);
- scriptVariables.put("basedir", scriptFile.getParentFile());
+ scriptVariables.put("basedir", basedir);
+ scriptVariables.put("scriptdir", scriptFile.getParentFile());
scriptVariables.put("context", context);
synchronized (LOCK) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/maven-script-interpreter-1.8/src/site/markdown/index.md.vm
new/maven-script-interpreter-1.9/src/site/markdown/index.md.vm
--- old/maven-script-interpreter-1.8/src/site/markdown/index.md.vm
2026-09-01 06:09:38.000000000 +0200
+++ new/maven-script-interpreter-1.9/src/site/markdown/index.md.vm
2026-09-19 14:17:02.000000000 +0200
@@ -84,9 +84,12 @@
#[[### Global variables]]#
-Your scripts will have by default two global variables:
+Your scripts will have by default three global variables:
-- `basedir`: the base directory of your script
+- `basedir`: the base directory passed to `run(...)`, which is the project
directory. For the `run(...)` overload that
+ takes a script file and no base directory, it is the directory containing
the script.
+- `scriptdir`: the directory containing the script, which differs from
`basedir` when the script lives in a
+ subdirectory of the project
- `context`: the build context (see below)
You can add more global variables as it.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/maven-script-interpreter-1.8/src/test/java/org/apache/maven/shared/scriptinterpreter/FileLoggerTest.java
new/maven-script-interpreter-1.9/src/test/java/org/apache/maven/shared/scriptinterpreter/FileLoggerTest.java
---
old/maven-script-interpreter-1.8/src/test/java/org/apache/maven/shared/scriptinterpreter/FileLoggerTest.java
2026-09-01 06:09:38.000000000 +0200
+++
new/maven-script-interpreter-1.9/src/test/java/org/apache/maven/shared/scriptinterpreter/FileLoggerTest.java
2026-09-19 14:17:02.000000000 +0200
@@ -109,4 +109,24 @@
assertTrue(outputFile.exists());
assertEquals(EXPECTED_LOG, new
String(Files.readAllBytes(outputFile.toPath())));
}
+
+ @Test
+ void bareFilenameNoParent() throws Exception {
+ File outputFile = new File("filelogger-204-bare.log");
+ assertNull(outputFile.getParent());
+ try {
+ 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, new
String(Files.readAllBytes(outputFile.toPath())));
+ } finally {
+ Files.deleteIfExists(outputFile.toPath());
+ }
+ }
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/maven-script-interpreter-1.8/src/test/java/org/apache/maven/shared/scriptinterpreter/GroovyScriptInterpreterTest.java
new/maven-script-interpreter-1.9/src/test/java/org/apache/maven/shared/scriptinterpreter/GroovyScriptInterpreterTest.java
---
old/maven-script-interpreter-1.8/src/test/java/org/apache/maven/shared/scriptinterpreter/GroovyScriptInterpreterTest.java
2026-09-01 06:09:38.000000000 +0200
+++
new/maven-script-interpreter-1.9/src/test/java/org/apache/maven/shared/scriptinterpreter/GroovyScriptInterpreterTest.java
2026-09-19 14:17:02.000000000 +0200
@@ -18,17 +18,28 @@
*/
package org.apache.maven.shared.scriptinterpreter;
+import javax.tools.JavaCompiler;
+import javax.tools.ToolProvider;
+
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.apache.commons.io.FilenameUtils;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
/**
* Tests the Groovy interpreter facade.
@@ -36,6 +47,10 @@
* @author Benjamin Bentmann
*/
class GroovyScriptInterpreterTest {
+
+ @TempDir
+ private File tempDir;
+
@Test
void evaluateScript() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -109,6 +124,93 @@
assertEquals("Test", out.toString());
}
+ /**
+ * A Groovy of a different version on the caller-supplied class path must
not shadow the Groovy the scripts are
+ * compiled with, while every other class stays child-first.
+ *
+ * @see <a
href="https://github.com/apache/maven-invoker-plugin/issues/642">maven-invoker-plugin#642</a>
+ */
+ @Test
+ void groovyClassesAreLoadedParentFirstOtherClassesChildFirst() throws
Exception {
+ File classesDir = compileShadowClasses();
+
+ try (GroovyScriptInterpreter.GroovyParentFirstRootLoader loader =
+ new GroovyScriptInterpreter.GroovyParentFirstRootLoader(
+ getClass().getClassLoader())) {
+ loader.addURL(classesDir.toURI().toURL());
+
+ assertSame(groovy.lang.Binding.class,
loader.loadClass("groovy.lang.Binding"));
+
+ Class<?> shadowed =
loader.loadClass(FilenameUtils.class.getName());
+ assertNotSame(FilenameUtils.class, shadowed);
+ assertSame(loader, shadowed.getClassLoader());
+ }
+ }
+
+ /**
+ * A script must still compile and run when a stale Groovy sits on the
supplied class path.
+ */
+ @Test
+ void evaluateScriptWithShadowedGroovyOnClassPath() throws Exception {
+ File classesDir = compileShadowClasses();
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try (ScriptInterpreter interpreter = new GroovyScriptInterpreter()) {
+
interpreter.setClassPath(Collections.singletonList(classesDir.getAbsolutePath()));
+ assertEquals(
+ Boolean.TRUE,
+ interpreter.evaluateScript("print \"Test\"\nreturn true",
null, new PrintStream(out)));
+ }
+ assertEquals("Test", out.toString());
+ }
+
+ /**
+ * Compiles stripped-down copies of <code>groovy.lang.Binding</code>,
<code>groovy.lang.Script</code> and
+ * <code>org.apache.commons.io.FilenameUtils</code>, all of which also
exist on the parent class path, into a
+ * directory usable as an additional class path entry. This stands in for
the incompatible Groovy version that
+ * <code>addTestClassPath</code> puts in front of the interpreter's own.
+ */
+ private File compileShadowClasses() throws Exception {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ assumeTrue(compiler != null, "JDK compiler is not available");
+
+ File sourceDir = new File(tempDir, "src");
+ File classesDir = new File(tempDir, "classes");
+ assertTrue(classesDir.mkdirs() || classesDir.isDirectory());
+
+ File binding = writeSource(
+ sourceDir, "groovy/lang/Binding.java", "package
groovy.lang;\n\npublic class Binding {\n}\n");
+ File script =
+ writeSource(sourceDir, "groovy/lang/Script.java", "package
groovy.lang;\n\npublic class Script {\n}\n");
+ File filenameUtils = writeSource(
+ sourceDir,
+ "org/apache/commons/io/FilenameUtils.java",
+ "package org.apache.commons.io;\n\npublic class FilenameUtils
{\n}\n");
+
+ assertTrue(
+ compiler.run(
+ null,
+ null,
+ null,
+ "-d",
+ classesDir.getAbsolutePath(),
+ binding.getAbsolutePath(),
+ script.getAbsolutePath(),
+ filenameUtils.getAbsolutePath())
+ == 0,
+ "compilation of the shadowing classes failed");
+
+ return classesDir;
+ }
+
+ private File writeSource(File sourceDir, String relativePath, String
content) throws Exception {
+ File sourceFile = new File(sourceDir, relativePath);
+ assertTrue(sourceFile.getParentFile().mkdirs()
+ || sourceFile.getParentFile().isDirectory());
+ Files.write(sourceFile.toPath(),
content.getBytes(StandardCharsets.UTF_8));
+ return sourceFile;
+ }
+
@Test
void normalizeTargetBytecodeMapsOldJdksToDotForm() {
assertEquals("1.4",
GroovyScriptInterpreter.normalizeTargetBytecode("4"));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/maven-script-interpreter-1.8/src/test/java/org/apache/maven/shared/scriptinterpreter/ScriptRunnerTest.java
new/maven-script-interpreter-1.9/src/test/java/org/apache/maven/shared/scriptinterpreter/ScriptRunnerTest.java
---
old/maven-script-interpreter-1.8/src/test/java/org/apache/maven/shared/scriptinterpreter/ScriptRunnerTest.java
2026-09-01 06:09:38.000000000 +0200
+++
new/maven-script-interpreter-1.9/src/test/java/org/apache/maven/shared/scriptinterpreter/ScriptRunnerTest.java
2026-09-19 14:17:02.000000000 +0200
@@ -32,6 +32,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Olivier Lamy
@@ -81,44 +82,35 @@
@Test
void failedBeanshellShouldCreateProperLogsMessage() throws Exception {
File logFile = new File(tempDir, "build.log");
-
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);
- } catch (ScriptEvaluationException e) {
- catchedException = e;
+ fail();
+ } catch (ScriptEvaluationException expected) {
+ String logContent = new
String(Files.readAllBytes(logFile.toPath()));
+ assertTrue(logContent.contains(new
File("src/test/resources/bsh-test/failed.bsh").getPath()));
+ assertEquals(logContent, mirrorHandler.getLoggedMessage());
}
-
- assertNotNull(catchedException);
- String logContent = new String(Files.readAllBytes(logFile.toPath()));
- assertTrue(logContent.contains(new
File("src/test/resources/bsh-test/failed.bsh").getPath()));
- assertEquals(logContent, mirrorHandler.getLoggedMessage());
}
@Test
void beanshellReturnedNotTrueShouldThrowException() throws Exception {
File logFile = new File(tempDir, "build.log");
-
TestMirrorHandler mirrorHandler = new TestMirrorHandler();
- ScriptReturnException catchedException = null;
-
try (FileLogger fileLogger = new FileLogger(logFile, mirrorHandler);
ScriptRunner scriptRunner = new ScriptRunner()) {
scriptRunner.run("test", new File("src/test/resources/bsh-test"),
"return-not-true", null, fileLogger);
- } catch (ScriptReturnException e) {
- catchedException = e;
+ fail();
+ } catch (ScriptReturnException expected) {
+ assertEquals("Not true value", expected.getResult());
+ assertEquals("The test returned Not true value.",
expected.getMessage());
+ String logContent = new
String(Files.readAllBytes(logFile.toPath()));
+ assertTrue(logContent.contains(new
File("src/test/resources/bsh-test/return-not-true.bsh").getPath()));
+ assertEquals(logContent, mirrorHandler.getLoggedMessage());
}
-
- assertEquals("Not true value", catchedException.getResult());
- assertEquals("The test returned Not true value.",
catchedException.getMessage());
- String logContent = new String(Files.readAllBytes(logFile.toPath()));
- assertTrue(logContent.contains(new
File("src/test/resources/bsh-test/return-not-true.bsh").getPath()));
- assertEquals(logContent, mirrorHandler.getLoggedMessage());
}
@Test
@@ -181,45 +173,34 @@
@Test
void failedGroovyShouldCreateProperLogsMessage() throws Exception {
File logFile = new File(tempDir, "build.log");
-
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/groovy-test"), "failed", buildContext(), fileLogger);
- } catch (ScriptEvaluationException e) {
- catchedException = e;
+ } catch (ScriptEvaluationException expected) {
+ String logContent = new
String(Files.readAllBytes(logFile.toPath()));
+ assertTrue(logContent.contains(new
File("src/test/resources/groovy-test/failed.groovy").getPath()));
+ assertEquals(logContent, mirrorHandler.getLoggedMessage());
}
-
- assertNotNull(catchedException);
- String logContent = new String(Files.readAllBytes(logFile.toPath()));
- assertTrue(logContent.contains(new
File("src/test/resources/groovy-test/failed.groovy").getPath()));
- assertEquals(logContent, mirrorHandler.getLoggedMessage());
}
@Test
void groovyReturnedFalseShouldThrowException() throws Exception {
File logFile = new File(tempDir, "build.log");
-
TestMirrorHandler mirrorHandler = new TestMirrorHandler();
- ScriptReturnException catchedException = null;
-
try (FileLogger fileLogger = new FileLogger(logFile, mirrorHandler);
ScriptRunner scriptRunner = new ScriptRunner()) {
scriptRunner.run(
"test", new File("src/test/resources/groovy-test"),
"return-false", buildContext(), fileLogger);
- } catch (ScriptReturnException e) {
- catchedException = e;
+ } catch (ScriptReturnException expected) {
+ assertEquals(false, expected.getResult());
+ assertEquals("The test returned false.", expected.getMessage());
+ String logContent = new
String(Files.readAllBytes(logFile.toPath()));
+ assertTrue(logContent.contains(new
File("src/test/resources/groovy-test/return-false.groovy").getPath()));
+ assertEquals(logContent, mirrorHandler.getLoggedMessage());
}
-
- assertEquals(false, catchedException.getResult());
- assertEquals("The test returned false.",
catchedException.getMessage());
- String logContent = new String(Files.readAllBytes(logFile.toPath()));
- assertTrue(logContent.contains(new
File("src/test/resources/groovy-test/return-false.groovy").getPath()));
- assertEquals(logContent, mirrorHandler.getLoggedMessage());
}
@Test
@@ -264,6 +245,75 @@
assertTrue(logContent.contains("wireMockServer stopped"));
}
+ /**
+ * A script living in a subdirectory of the project must still see the
project directory as <code>basedir</code>,
+ * with its own directory available as <code>scriptdir</code>.
+ *
+ * @see <a
href="https://github.com/apache/maven-invoker-plugin/issues/299">maven-invoker-plugin#299</a>
+ */
+ @ValueSource(strings = {"bsh", "groovy"})
+ @ParameterizedTest
+ void scriptInSubDirectoryShouldSeeProjectBasedir(String scriptType) throws
Exception {
+ File logFile = new File(tempDir, "build.log");
+ File basedir = new File("src/test/resources/basedir-test");
+
+ Map<String, Object> context = new HashMap<>();
+
+ try (FileLogger logger = new FileLogger(logFile);
+ ScriptRunner scriptRunner = new ScriptRunner()) {
+ scriptRunner.run("test", basedir, "scripts/verify." + scriptType,
context, logger);
+ }
+
+ assertEquals(basedir, context.get("basedir"));
+ assertEquals(new File(basedir, "scripts"), context.get("scriptdir"));
+ }
+
+ /**
+ * The overload without a project directory has no better candidate, so
both variables point at the script's own
+ * directory.
+ */
+ @ValueSource(strings = {"bsh", "groovy"})
+ @ParameterizedTest
+ void scriptRunWithoutBasedirShouldUseScriptDirectory(String scriptType)
throws Exception {
+ File logFile = new File(tempDir, "build.log");
+ File scriptDir = new File("src/test/resources/basedir-test/scripts");
+
+ Map<String, Object> context = new HashMap<>();
+
+ try (FileLogger logger = new FileLogger(logFile);
+ ScriptRunner scriptRunner = new ScriptRunner()) {
+ scriptRunner.run("test", new File(scriptDir, "verify." +
scriptType), context, logger);
+ }
+
+ assertEquals(scriptDir, context.get("basedir"));
+ assertEquals(scriptDir, context.get("scriptdir"));
+ }
+
+ /**
+ * Verifies that a Groovy script containing non-ASCII characters (UTF-8
encoded)
+ * is decoded correctly when no explicit encoding is set. The script file
+ * utf8-test.groovy contains the UTF-8 string literal "café" and asserts it
+ * matches the expected value, returning true on success.
+ *
+ * @see <a
href="https://github.com/apache/maven-script-interpreter/issues/206">#206</a>
+ */
+ @Test
+ void groovyUtf8ScriptShouldDecodeCorrectly() throws Exception {
+ File logFile = new File(tempDir, "build.log");
+
+ Map<String, Object> context = new HashMap<>();
+ context.put("expected", "café");
+
+ try (FileLogger logger = new FileLogger(logFile);
+ ScriptRunner scriptRunner = new ScriptRunner()) {
+ scriptRunner.run("utf8-test", new
File("src/test/resources/groovy-test/utf8-test.groovy"), context, logger);
+ }
+
+ String logContent = new String(Files.readAllBytes(logFile.toPath()));
+ assertTrue(logContent.contains("expected=café"));
+ assertTrue(logContent.contains("actual=café"));
+ }
+
private Map<String, ?> buildContext() {
Map<String, Object> context = new HashMap<>();
context.put("foo", "bar");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/maven-script-interpreter-1.8/src/test/resources/basedir-test/scripts/verify.bsh
new/maven-script-interpreter-1.9/src/test/resources/basedir-test/scripts/verify.bsh
---
old/maven-script-interpreter-1.8/src/test/resources/basedir-test/scripts/verify.bsh
1970-01-01 01:00:00.000000000 +0100
+++
new/maven-script-interpreter-1.9/src/test/resources/basedir-test/scripts/verify.bsh
2026-09-19 14:17:02.000000000 +0200
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+context.put("basedir", basedir);
+context.put("scriptdir", scriptdir);
+
+return true;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/maven-script-interpreter-1.8/src/test/resources/basedir-test/scripts/verify.groovy
new/maven-script-interpreter-1.9/src/test/resources/basedir-test/scripts/verify.groovy
---
old/maven-script-interpreter-1.8/src/test/resources/basedir-test/scripts/verify.groovy
1970-01-01 01:00:00.000000000 +0100
+++
new/maven-script-interpreter-1.9/src/test/resources/basedir-test/scripts/verify.groovy
2026-09-19 14:17:02.000000000 +0200
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+context.put("basedir", basedir)
+context.put("scriptdir", scriptdir)
+
+return true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/maven-script-interpreter-1.8/src/test/resources/groovy-test/utf8-test.groovy
new/maven-script-interpreter-1.9/src/test/resources/groovy-test/utf8-test.groovy
---
old/maven-script-interpreter-1.8/src/test/resources/groovy-test/utf8-test.groovy
1970-01-01 01:00:00.000000000 +0100
+++
new/maven-script-interpreter-1.9/src/test/resources/groovy-test/utf8-test.groovy
2026-09-19 14:17:02.000000000 +0200
@@ -0,0 +1,27 @@
+/*
+ * 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 result = context.get("expected")
+assert result != null
+System.out.println("expected=" + result)
+
+def actual = "café"
+System.out.println("actual=" + actual)
+
+return result.equals(actual)
++++++ maven-script-interpreter-build.xml ++++++
--- /var/tmp/diff_new_pack.Xab6Sm/_old 2026-09-28 10:40:03.652884135 +0200
+++ /var/tmp/diff_new_pack.Xab6Sm/_new 2026-09-28 10:40:03.655884261 +0200
@@ -10,7 +10,7 @@
<property name="project.groupId" value="org.apache.maven.shared"/>
<property name="project.artifactId" value="maven-script-interpreter"/>
- <property name="project.version" value="1.8"/>
+ <property name="project.version" value="1.9"/>
<property name="project.name" value="Apache Maven Script Interpreter"/>
<property name="project.organization.name" value="The Apache Software
Foundation"/>