jenkinsci/warnings-plugin — pull request #46 by Vynce (2014-10-27 23:36:43+00:00)
Title: Persist Binding across DynamicParser script execs

Don't create a new Binding for every match/execution of the
DynamicParser script. This allows the script to add new variables to the
Binding and have them persist across all matches. Variables can be added
to the Binding within a script by omitting a type [[1]]. The Binding can
be checked for the presence of global variables with something like [[2]]:
binding.variables.containsKey("bindingVar"). Also add a reference to the
falsePositive Warning object. The motivation for these changes is to
enable scripts to keep a reference to the current working directory that
can be used to resolve relative paths in warning messages.

[1]: http://groovy.codehaus.org/Scoping+and+the+Semantics+of+%22def%22
[2]: http://www.justinleegrant.com/?p=129

An example script that makes use of this feature to keep track of the
current working directory follows:

// This script is designed to operate on Windows paths in a Unix
// environment. Since java.nio.file only appears to support local
// filesystems supported by the JVM, the Windows path separators need
// to be changed manually and some of the Path methods don't function
// correctly (like isAbsolute()).

// Associated regular expression:
// ^((.+?):(\d+):(?:(\d+):)? (warning|.*error): (.*))|
// (Waf: Entering directory\s*\`(.*)\')$

import hudson.plugins.warnings.parser.Warning
import hudson.plugins.analysis.util.model.Priority
import java.nio.file.Path
import java.nio.file.Paths

// If it matched a directory
if(matcher.group(7) != null) {
// Save the directory in the Binding as a Path object
directory = Paths.get(matcher.group(8).replace("\\", "/"))
return falsePositive
}

String fileName = matcher.group(2).replace("\\", "/")
int lineNumber = Integer.parseInt(matcher.group(3))
int column = Integer.parseInt(matcher.group(4))
String message = matcher.group(6)

Priority priority
String category

if (matcher.group(5).contains("error")) {
priority = Priority.HIGH
category = "Error"
}
else {
priority = Priority.NORMAL
category = "Warning"
}

// If the fileName is not absolute and we
// have a directory variable in the Binding,
if(!fileName.contains(":") &&
binding.variables.containsKey("directory")) {
// then append the filename to the directory and normalize
// the path to remove redundant components
fileName = directory.resolve(fileName).normalize().toString()
}

Warning warning = new Warning(fileName, lineNumber,
"Relative GCC Parser", category,
message, priority)
warning.setColumnPosition(column)
return warning