Skip to content

Commit

Permalink
Merge pull request #120 from melexis/yaml
Browse files Browse the repository at this point in the history
Support YAML syntax for the configuration file
  • Loading branch information
JasperCraeghs authored Jan 6, 2023
2 parents 4a871b3 + b7cc6ec commit 190e638
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10']
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
Expand Down
4 changes: 3 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ Configuration File to Pass Options
----------------------------------

Beside command line, you can pass options through the configuration file.
Configuration file is in JSON format with a simple structure.
Configuration file is in JSON or YAML_ format with a simple structure.

.. code-block:: json
Expand Down Expand Up @@ -429,3 +429,5 @@ Contribute

There is a Contribution guide available if you would like to get involved in
development of the plugin. We encourage anyone to contribute to our repository.

.. _YAML: https://yaml.org/spec/1.2.2/
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
sphinx>=1.3
sphinx>=1.3,<6.0
sphinx-py3doc-enhanced-theme
sphinxcontrib-plantuml
setuptools_scm
Expand Down
6 changes: 5 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@

PROJECT_URL = 'https://github.com/melexis/warnings-plugin'

requires = ['junitparser>=1.0.0,<2.0']
requires = [
'junitparser>=1.0.0,<2.0',
'ruamel.yaml>=0.17.21',
]

setup(
name='mlx.warnings',
Expand Down Expand Up @@ -44,6 +47,7 @@
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
# 'Programming Language :: Python :: Implementation :: CPython',
# 'Programming Language :: Python :: Implementation :: PyPy',
# uncomment if you test on these interpreters:
Expand Down
19 changes: 12 additions & 7 deletions src/mlx/warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import json
import subprocess
import sys
from pathlib import Path

from pkg_resources import require
from ruamel.yaml import YAML

from mlx.junit_checker import JUnitChecker
from mlx.regex_checker import CoverityChecker, DoxyChecker, SphinxChecker, XMLRunnerChecker
Expand All @@ -25,7 +27,7 @@ def __init__(self, verbose=False, config_file=None):
Args:
verbose (bool): optional - enable verbose logging
config_file (str): optional - configuration file with setup
config_file (Path): optional - configuration file with setup
'''
self.activated_checkers = {}
self.verbose = verbose
Expand All @@ -34,9 +36,12 @@ def __init__(self, verbose=False, config_file=None):
RobotChecker(self.verbose)]

if config_file:
with open(config_file, 'r') as open_file:
config = json.load(open_file)
self.config_parser_json(config)
with open(config_file, 'r', encoding='utf-8') as open_file:
if config_file.suffix.lower().startswith('.y'):
config = YAML().load(open_file)
else:
config = json.load(open_file)
self.config_parser(config)

self.warn_min = 0
self.warn_max = 0
Expand Down Expand Up @@ -169,11 +174,11 @@ def toggle_printout(self, printout):
'''
self.printout = printout

def config_parser_json(self, config):
def config_parser(self, config):
''' Parsing configuration dict extracted by previously opened JSON file
Args:
config (dict): JSON dump of the configuration
config (dict): Content of configuration file
'''
# activate checker
for checker in self.public_checkers:
Expand Down Expand Up @@ -215,7 +220,7 @@ def warnings_wrapper(args):
group1.add_argument('--exact-warnings', type=int, default=0,
help='Exact amount of warnings expected')
group2 = parser.add_argument_group('Configuration file with options')
group2.add_argument('--config', dest='configfile', action='store', required=False,
group2.add_argument('--config', dest='configfile', action='store', required=False, type=Path,
help='Config file in JSON format provides toggle of checkers and their limits')
group2.add_argument('--include-sphinx-deprecation', dest='include_sphinx_deprecation', action='store_true',
help="Sphinx checker will include warnings matching (RemovedInSphinx\\d+Warning) regex")
Expand Down
61 changes: 35 additions & 26 deletions tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from io import StringIO
from pathlib import Path
from unittest import TestCase

from unittest.mock import patch

from mlx.junit_checker import JUnitChecker
Expand All @@ -9,10 +9,12 @@

from mlx.warnings import WarningsPlugin

TEST_IN_DIR = Path(__file__).parent / 'test_in'


class TestConfig(TestCase):
def test_configfile_parsing(self):
warnings = WarningsPlugin(config_file="tests/test_in/config_example.json")
warnings = WarningsPlugin(config_file=(TEST_IN_DIR / "config_example.json"))
warnings.check('testfile.c:6: warning: group test: ignoring title "Some test functions" that does not match old title "Some freaky test functions"')
self.assertEqual(warnings.return_count(), 0)
warnings.check('<testcase classname="dummy_class" name="dummy_name"><failure message="some random message from test case" /></testcase>')
Expand All @@ -24,8 +26,7 @@ def test_configfile_parsing(self):
warnings.check('ERROR [0.000s]: test_some_error_test (something.anything.somewhere)')
self.assertEqual(warnings.return_count(), 1)

def test_configfile_parsing_exclude(self):
warnings = WarningsPlugin(verbose=True, config_file="tests/test_in/config_example_exclude.json")
def _helper_exclude(self, warnings):
with patch('sys.stdout', new=StringIO()) as verbose_output:
warnings.check('testfile.c:6: warning: group test: ignoring title "Some test functions" that does not match old title "Some freaky test functions"')
self.assertEqual(warnings.return_count(), 0)
Expand All @@ -48,8 +49,16 @@ def test_configfile_parsing_exclude(self):
warning_echo = "home/bljah/test/index.rst:5: WARNING: this warning should not get excluded"
self.assertIn(warning_echo, verbose_output.getvalue())

def test_configfile_parsing_exclude_json(self):
warnings = WarningsPlugin(verbose=True, config_file=(TEST_IN_DIR / "config_example_exclude.json"))
self._helper_exclude(warnings)

def test_configfile_parsing_exclude_yml(self):
warnings = WarningsPlugin(verbose=True, config_file=(TEST_IN_DIR / "config_example_exclude.yml"))
self._helper_exclude(warnings)

def test_configfile_parsing_include_priority(self):
warnings = WarningsPlugin(verbose=True, config_file="tests/test_in/config_example_exclude.json")
warnings = WarningsPlugin(verbose=True, config_file=(TEST_IN_DIR / "config_example_exclude.json"))
warnings.get_checker('sphinx').include_sphinx_deprecation()
deprecation_warning = 'sphinx/application.py:402: RemovedInSphinx20Warning: app.info() is now deprecated. Use sphinx.util.logging instead.'
warnings.check(deprecation_warning)
Expand All @@ -65,7 +74,7 @@ def test_partial_sphinx_config_parsing(self):
}
}

warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
warnings.check('testfile.c:6: warning: group test: ignoring title "Some test functions" that does not match old title "Some freaky test functions"')
self.assertEqual(warnings.return_count(), 0)
with open('tests/test_in/junit_single_fail.xml', 'r') as xmlfile:
Expand All @@ -86,7 +95,7 @@ def test_partial_doxygen_config_parsing(self):
}
}

warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
with open('tests/test_in/junit_single_fail.xml', 'r') as xmlfile:
warnings.check(xmlfile.read())
self.assertEqual(warnings.return_count(), 0)
Expand All @@ -107,7 +116,7 @@ def test_partial_junit_config_parsing(self):
}
}

warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
warnings.check("/home/bljah/test/index.rst:5: WARNING: toctree contains reference to nonexisting document u'installation'")
self.assertEqual(warnings.return_count(), 0)
warnings.check('testfile.c:6: warning: group test: ignoring title "Some test functions" that does not match old title "Some freaky test functions"')
Expand All @@ -129,7 +138,7 @@ def test_exclude_feature_type_error(self):
}
}
with self.assertRaises(TypeError) as c_m:
warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
self.assertEqual(str(c_m.exception), "Expected a list value for exclude key in configuration file; got str")

def test_partial_junit_config_parsing_exclude_regex(self):
Expand All @@ -142,7 +151,7 @@ def test_partial_junit_config_parsing_exclude_regex(self):
"exclude": ["able to trace this random failure msg"]
}
}
warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
with open('tests/test_in/junit_single_fail.xml', 'r') as xmlfile:
warnings.check(xmlfile.read())
self.assertEqual(warnings.return_count(), 0)
Expand All @@ -168,7 +177,7 @@ def test_partial_robot_config_parsing_exclude_regex(self):
]
}
}
warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
with open('tests/test_in/robot_double_fail.xml', 'r') as xmlfile:
with patch('sys.stdout', new=StringIO()) as verbose_output:
warnings.check(xmlfile.read())
Expand Down Expand Up @@ -200,7 +209,7 @@ def test_partial_robot_config_empty_name(self):
]
}
}
warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
with open('tests/test_in/robot_double_fail.xml', 'r') as xmlfile:
with patch('sys.stdout', new=StringIO()) as verbose_output:
warnings.check(xmlfile.read())
Expand All @@ -226,7 +235,7 @@ def test_partial_xmlrunner_config_parsing(self):
}
}

warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
with open('tests/test_in/junit_single_fail.xml', 'r') as xmlfile:
warnings.check(xmlfile.read())
self.assertEqual(warnings.return_count(), 0)
Expand All @@ -252,7 +261,7 @@ def test_doxy_junit_options_config_parsing(self):
}

}
warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
warnings.check("/home/bljah/test/index.rst:5: WARNING: toctree contains reference to nonexisting document u'installation'")
self.assertEqual(warnings.return_count(), 0)
warnings.check('testfile.c:6: warning: group test: ignoring title "Some test functions" that does not match old title "Some freaky test functions"')
Expand All @@ -276,7 +285,7 @@ def test_sphinx_doxy_config_parsing(self):
}
}

warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
with open('tests/test_in/junit_single_fail.xml', 'r') as xmlfile:
warnings.check(xmlfile.read())
self.assertEqual(warnings.return_count(), 0)
Expand All @@ -302,7 +311,7 @@ def test_sphinx_config_max(self):
}
}

warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
self.assertEqual(warnings.get_checker(SphinxChecker().name).get_maximum(), 5)

def test_doxygen_config_max(self):
Expand All @@ -315,7 +324,7 @@ def test_doxygen_config_max(self):
}
}

warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
self.assertEqual(warnings.get_checker(DoxyChecker().name).get_maximum(), 5)

def test_junit_config_max(self):
Expand All @@ -328,7 +337,7 @@ def test_junit_config_max(self):
}
}

warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
self.assertEqual(warnings.get_checker(JUnitChecker().name).get_maximum(), 5)

def test_xmlrunner_config_max(self):
Expand All @@ -341,7 +350,7 @@ def test_xmlrunner_config_max(self):
}
}

warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
self.assertEqual(warnings.get_checker(XMLRunnerChecker().name).get_maximum(), 5)

def test_all_config_max(self):
Expand Down Expand Up @@ -389,7 +398,7 @@ def test_all_config_max(self):
}
}

warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
self.assertEqual(warnings.get_checker(SphinxChecker().name).get_maximum(), 4)
self.assertEqual(warnings.get_checker(DoxyChecker().name).get_maximum(), 5)
self.assertEqual(warnings.get_checker(JUnitChecker().name).get_maximum(), 6)
Expand All @@ -406,7 +415,7 @@ def test_sphinx_config_min(self):
}
}

warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
self.assertEqual(warnings.get_checker(SphinxChecker().name).get_minimum(), 5)

def test_doxygen_config_min(self):
Expand All @@ -419,7 +428,7 @@ def test_doxygen_config_min(self):
}
}

warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
self.assertEqual(warnings.get_checker(DoxyChecker().name).get_minimum(), 5)

def test_junit_config_min(self):
Expand All @@ -432,7 +441,7 @@ def test_junit_config_min(self):
}
}

warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
self.assertEqual(warnings.get_checker(JUnitChecker().name).get_minimum(), 5)

def test_xmlrunner_config_min(self):
Expand All @@ -445,7 +454,7 @@ def test_xmlrunner_config_min(self):
}
}

warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
self.assertEqual(warnings.get_checker(XMLRunnerChecker().name).get_minimum(), 5)

def test_all_config_min(self):
Expand Down Expand Up @@ -493,7 +502,7 @@ def test_all_config_min(self):
}
}

warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
self.assertEqual(warnings.get_checker(SphinxChecker().name).get_minimum(), 4)
self.assertEqual(warnings.get_checker(DoxyChecker().name).get_minimum(), 3)
self.assertEqual(warnings.get_checker(JUnitChecker().name).get_minimum(), 5)
Expand Down Expand Up @@ -525,6 +534,6 @@ def test_invalid_config(self):
}
}
with self.assertRaises(ValueError) as c_m:
warnings.config_parser_json(tmpjson)
warnings.config_parser(tmpjson)
self.assertEqual(str(c_m.exception),
'Invalid argument: minimum limit must be lower than maximum limit (9); cannot set 10.')
32 changes: 32 additions & 0 deletions tests/test_in/config_example_exclude.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
sphinx:
enabled: true
min: 0
max: 0
exclude:
- RemovedInSphinx\d+Warning
- 'WARNING: toctree'
doxygen:
enabled: false
min: 0
max: 0
junit:
enabled: false
min: 0
max: 0
xmlrunner:
enabled: false
min: 0
max: 0
coverity:
enabled: false
min: 0
max: 0
robot:
enabled: false
suites:
- name: Suite name 1
min: 10
max: 10
- name: Suite name 2
min: 0
max: 0
Loading

0 comments on commit 190e638

Please sign in to comment.