| Defined | src/lint/linter/ArcanistScriptAndRegexLinter.php:158 |
|---|---|
| Group | Linters |
| Extends | ArcanistLinter |
Simple glue linter which runs some script on each path, and then uses a regex to parse lint messages from the script's output. (This linter uses a script and a regex to interpret the results of some real linter, it does not itself lint both scripts and regexes).
Configure this linter by setting these keys in your configuration:
The script will be invoked from the project root, so you can specify a relative path like scripts/lint.sh or an absolute path like /opt/lint/lint.sh.
This linter is necessarily more limited in its capabilities than a normal linter which can perform custom processing, but may be somewhat simpler to configure.
The script will be invoked once for each file that is to be linted, with the file passed as the first argument. The file may begin with a "-"; ensure your script will not interpret such files as flags (perhaps by ending your script configuration with "--", if its argument parser supports that).
Note that when run via arc diff, the list of files to be linted includes deleted files and files that were moved away by the change. The linter should not assume the path it is given exists, and it is not an error for the linter to be invoked with paths which are no longer there. (Every affected path is subject to lint because some linters may raise errors in other files when a file is removed, or raise an error about its removal.)
The script should emit lint messages to stdout, which will be parsed with the provided regex.
For example, you might use a configuration like this:
/opt/lint/lint.sh --flag value --other-flag --
stderr is ignored. If you have a script which writes messages to stderr, you can redirect stderr to stdout by using a configuration like this:
sh -c '/opt/lint/lint.sh "$0" 2>&1'
The return code of the script must be 0, or an exception will be raised reporting that the linter failed. If you have a script which exits nonzero under normal circumstances, you can force it to always exit 0 by using a configuration like this:
sh -c '/opt/lint/lint.sh "$0" || true'
Multiple instances of the script will be run in parallel if there are multiple files to be linted, so they should not use any unique resources. For instance, this configuration would not work properly, because several processes may attempt to write to the file at the same time:
sh -c '/opt/lint/lint.sh --output /tmp/lint.out "$0" && cat /tmp/lint.out'
There are necessary limits to how gracefully this linter can deal with edge cases, because it is just a script and a regex. If you need to do things that this linter can't handle, you can write a phutil linter and move the logic to handle those cases into PHP. PHP is a better general-purpose programming language than regular expressions are, if only by a small margin.
The regex must be a valid PHP PCRE regex, including delimiters and flags.
The regex will be matched against the entire output of the script, so it should generally be in this form if messages are one-per-line:
/^...$/m
The regex should capture these named patterns with (?P<name>...):
Numbered capturing groups are ignored.
For example, if your lint script's output looks like this:
error:13 Too many goats! warning:22 Not enough boats.
...you could use this regex to parse it:
/^(?P<severity>warning|error):(?P<line>\d+) (?P<message>.*)$/m
The simplest valid regex for line-oriented output is something like this:
/^(?P<message>.*)$/m
| return | string | A valid PHP PCRE regular expression. |
Load, validate, and return the "regex" configuration.
| return | string | The shell command fragment to use to run the linter. |
Load, validate, and return the "script" configuration.
| return | string | Short linter identifier. |
Return the short name of the linter.
| parameters | dict | $match | Captured groups from regex. |
| wild | $path | ||
| return | pair<int,int> | Line and character of the message. |
Get the line and character of the message from the regex match.
| parameters | dict | $match | Captured groups from regex. |
| return | const | ArcanistLintSeverity constant. |
Map the regex matching groups to a message severity. We look for either a nonempty severity name group like 'error', or a group called 'severity' with a valid name.
| parameters | wild | $path | |
| return | wild |
Run the regex on the output of the script.
| parameters | array | $paths | |
| return | wild |
Run the script on each file to be linted.