Skip to content

Commit

Permalink
Merge pull request #110 from ymyzk/problem-matchers
Browse files Browse the repository at this point in the history
Add problem matchers
  • Loading branch information
ymyzk authored Dec 31, 2021
2 parents 0c40ee1 + 2a9fdfc commit c03018e
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ please check [the tox4 branch](https://github.com/ymyzk/tox-gh-actions/tree/tox4
## Features
When running tox on GitHub Actions, tox-gh-actions
* detects which environment to run based on configurations and
* provides utilities such as [grouping log lines](https://github.com/actions/toolkit/blob/main/docs/commands.md#group-and-ungroup-log-lines).
* provides utilities such as [grouping log lines](https://github.com/actions/toolkit/blob/main/docs/commands.md#group-and-ungroup-log-lines)
and [annotating error messages](https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md).

## Usage
1. Add configurations under `[gh-actions]` section along with tox's configuration.
Expand Down
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ package_dir =
zip_safe = True
python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
install_requires =
importlib_resources
tox >=3.12, <4
typing; python_version<"3.5"
setup_requires =
Expand Down Expand Up @@ -71,6 +72,7 @@ testing =

[options.package_data]
tox_gh_actions =
matcher.json
py.typed

[bdist_wheel]
Expand Down
24 changes: 24 additions & 0 deletions src/tox_gh_actions/matcher.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"problemMatcher": [
{
"owner": "tox-gh-actions-warning-error",
"pattern": [
{
"regexp": "^(WARNING|ERROR): (.+)$",
"message": 2,
"severity": 1
}
]
},
{
"owner": "tox-gh-actions-deprecation-warning",
"pattern": [
{
"regexp": "^(DEPRECATION (WARNING): .+)$",
"message": 1,
"severity": 2
}
]
}
]
}
24 changes: 24 additions & 0 deletions src/tox_gh_actions/plugin.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from itertools import product
import json
import os
import sys
import threading
from typing import Any, Dict, Iterable, List

import importlib_resources
import pluggy
from tox.action import Action
from tox.config import Config, TestenvConfig, _split_env as split_env
Expand Down Expand Up @@ -53,6 +55,9 @@ def tox_configure(config):
config.envlist_default = config.envlist = envlist
verbosity1("overriding envlist with: {}".format(envlist))

verbosity2("enabling problem matcher")
print("::add-matcher::" + get_problem_matcher_file_path())

if not is_log_grouping_enabled(config):
verbosity2(
"disabling log line grouping on GitHub Actions based on the configuration"
Expand Down Expand Up @@ -87,6 +92,13 @@ def tox_runtest_post(venv):
print("::endgroup::")


@hookimpl
def tox_cleanup(session):
# This hook can be called multiple times especially when using parallel mode
for owner in get_problem_matcher_owners():
print("::remove-matcher owner={}::".format(owner))


def start_grouping_if_necessary(venv):
# type: (VirtualEnv) -> None
"""Start log line grouping when necessary.
Expand Down Expand Up @@ -250,6 +262,18 @@ def is_env_specified(config):
return False


def get_problem_matcher_file_path():
# type: () -> str
return str(importlib_resources.files("tox_gh_actions") / "matcher.json")


def get_problem_matcher_owners():
# type: () -> List[str]
with open(get_problem_matcher_file_path()) as f:
matcher = json.load(f)
return [m["owner"] for m in matcher["problemMatcher"]]


# The following function was copied from
# https://github.com/tox-dev/tox-travis/blob/0.12/src/tox_travis/utils.py#L11-L32
# which is licensed under MIT LICENSE
Expand Down
89 changes: 89 additions & 0 deletions tests/test_matcher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import json
import re

from tox_gh_actions.plugin import get_problem_matcher_file_path


def match_problem(log):
"""Simulate GitHub Actions' problem matcher for ease of testing
This is not the same as the actual implementation by GitHub Actions.
https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md
"""
with open(get_problem_matcher_file_path()) as f:
matchers = json.load(f)
results = []
for line in log.split("\n"):
for matcher in matchers["problemMatcher"]:
# TODO Add multi-lines matcher support if necessary
pattern = matcher["pattern"][0]
match = re.search(pattern["regexp"], line)
if not match:
continue
groups = match.groups()
result = {}
for key, value in pattern.items():
if key == "regexp":
continue
result[key] = groups[value - 1]
results.append(result)
return results


def test_could_not_install_deps_error():
log = (
"ERROR: could not install deps [flake7]; "
"v = InvocationError('/tmp/.tox/py310/bin/python -m pip install flake7', 1)"
)
assert match_problem(log) == [
{
"message": (
"could not install deps [flake7]; v = "
"InvocationError('/tmp/.tox/py310/bin/python -m pip install flake7', 1)"
),
"severity": "ERROR",
}
]


def test_invocation_error_not_found():
log = "ERROR: InvocationError for command could not find executable flake9"
assert match_problem(log) == [
{
"message": "InvocationError for command could not find executable flake9",
"severity": "ERROR",
}
]


def test_invocation_error_non_zero_exit_code():
log = "ERROR: InvocationError for command /usr/bin/false (exited with code 1)"
assert match_problem(log) == [
{
"message": (
"InvocationError for command /usr/bin/false " "(exited with code 1)"
),
"severity": "ERROR",
}
]


def test_warnings_on_allowlist_externals():
log = """WARNING: test command found but not installed in testenv
cmd: /bin/echo
env: /tmp/.tox/py310
Maybe you forgot to specify a dependency?
See also the allowlist_externals envconfig setting.
DEPRECATION WARNING: this will be an error in tox 4 and above!
"""
assert match_problem(log) == [
{
"message": "test command found but not installed in testenv",
"severity": "WARNING",
},
{
"message": "DEPRECATION WARNING: this will be an error in tox 4 and above!",
"severity": "WARNING",
},
]

0 comments on commit c03018e

Please sign in to comment.