Skip to content

Commit 6465ce7

Browse files
Support for coverage groups (#7)
1 parent 3b6f8da commit 6465ce7

File tree

5 files changed

+109
-19
lines changed

5 files changed

+109
-19
lines changed

covcheck/_cli/config.py

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from pathlib import Path
44
from typing import Any, Optional, Union
55

6+
from covcheck._cli.utilities import fail_with_error
7+
68
try:
79
import toml
810
TOML_INSTALLED = True
@@ -37,34 +39,53 @@ def __init__(
3739
@classmethod
3840
def create(
3941
cls,
40-
coverage_file: Union[str, Path],
41-
config_file: Optional[Union[str, Path]] = None,
42+
coverage_filepath: Union[str, Path],
43+
config_filepath: Optional[Union[str, Path]] = None,
44+
group: Optional[str] = None,
4245
**kwargs: Optional[Any],
4346
) -> 'Config':
4447
"""Get a config based on both CLI arguments and config file settings.
4548
4649
If the same argument is specified in both CLI arguments and config file,
4750
then the CLI argument will take precedence.
4851
49-
:param coverage_file: XML coverage file from Coverage.py.
50-
:param config_file: Path to pyproject.toml config file.
52+
:param coverage_filepath: Path to XML coverage file from Coverage.py.
53+
:param config_filepath: Path to pyproject.toml config file.
54+
:param group: Name of coverage group to check.
5155
:param kwargs: Kwargs containing additional config settings.
5256
"""
53-
config = cls(coverage_file)
57+
config = cls(coverage_filepath)
5458

55-
if config_file is not None:
59+
if config_filepath is not None:
5660
if not TOML_INSTALLED:
5761
raise ImportError("--config was passed, but the toml package was not installed. "
5862
"Please 'pip install toml' before running with --config.")
5963

60-
with open(config_file, 'r', encoding='utf-8') as f:
64+
with open(config_filepath, 'r', encoding='utf-8') as f:
6165
toml_config = toml.load(f)
6266

63-
toml_tools = toml_config['tool']
64-
if 'covcheck' in toml_tools:
65-
toml_covcheck = toml_tools['covcheck']
66-
for key, value in toml_covcheck.items():
67-
setattr(config, key, value)
67+
if 'tool' in toml_config:
68+
toml_tools = toml_config['tool']
69+
if 'covcheck' in toml_tools:
70+
toml_covcheck = toml_tools['covcheck']
71+
72+
# Check for missing group configuration
73+
if group is not None:
74+
# Group name selected but no matching group in config file
75+
if 'group' in toml_covcheck and group not in toml_covcheck['group']:
76+
fail_with_error(f"Group {group} not found in config")
77+
# Group name selected but no groups at all in config file
78+
if 'group' not in toml_covcheck:
79+
fail_with_error(f"Group {group} not found in config")
80+
81+
if 'group' in toml_covcheck and group is not None:
82+
group_dict = toml_covcheck['group'][group]
83+
if 'coverage' in group_dict:
84+
for key, value in group_dict['coverage'].items():
85+
setattr(config, key, value)
86+
else:
87+
for key, value in toml_covcheck.items():
88+
setattr(config, key, value)
6889

6990
for key, value in kwargs.items():
7091
if value is not None:

covcheck/_cli/main.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def parse_args() -> argparse.Namespace:
2020
parser.add_argument('--silent', default=False, action='store_true', help="Do not print coverage results.")
2121

2222
parser.add_argument('--config', default=None, type=str, help="Path to pyproject.toml config file.")
23+
parser.add_argument('--group', default=None, type=str, help="Name of coverage group to check.")
2324

2425
return parser.parse_args()
2526

@@ -30,11 +31,12 @@ def run() -> None:
3031

3132
config = Config.create(
3233
args.coverage_file,
33-
config_file=args.config,
34+
config_filepath=args.config,
3435
line=args.line,
3536
branch=args.branch,
3637
output=args.output,
3738
silent=args.silent,
39+
group=args.group,
3840
)
3941

4042
validate_coverage(config)

pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ types-toml = "^0.10.1"
3535
covcheck = "covcheck._cli.main:run"
3636

3737
[tool.covcheck]
38-
line = 97.0
39-
branch = 97.0
38+
line = 98.0
39+
branch = 96.0
4040

4141
[tool.flake8]
4242
ignore = "" # Required to disable default ignores
@@ -52,6 +52,7 @@ ignore_missing_imports = true
5252
good-names = ["e", "f", "h", "i", "j", "k", "m", "n", "w", "x", "y"]
5353
max-locals = 25
5454
max-args = 8
55+
max-branches = 14
5556
notes = ["FIXME"]
5657

5758
[tool.pylint.format]

tests/pytest.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[pytest]
2+
log_cli = 1
3+
log_cli_level = INFO

tests/test_cli/test_config.py

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,22 @@ def fixture_example_config_filepath(tmp_path_factory: TempPathFactory) -> Path:
2222
return config_filepath
2323

2424

25+
@pytest.fixture(name='example_group_config_filepath', scope='module')
26+
def fixture_example_group_config_filepath(tmp_path_factory: TempPathFactory) -> Path:
27+
temp_dirpath = tmp_path_factory.mktemp('configs')
28+
config_filepath = temp_dirpath / 'pyproject.toml'
29+
lines = [
30+
'[tool.covcheck.group.unit]\n',
31+
'\n',
32+
'[tool.covcheck.group.unit.coverage]\n',
33+
'line = 6.0\n',
34+
'branch = 7.0\n',
35+
]
36+
with open(config_filepath, 'w', encoding='utf-8') as f:
37+
f.writelines(lines)
38+
return config_filepath
39+
40+
2541
@pytest.fixture(name='example_config_kwargs', scope='module')
2642
def fixture_example_config_kwargs() -> Dict[str, Any]:
2743
return {
@@ -39,7 +55,7 @@ def test_create_cli(
3955
) -> None:
4056
config = config_module.Config.create(
4157
coverage_filepath,
42-
config_file=None,
58+
config_filepath=None,
4359
**example_config_kwargs,
4460
)
4561
assert config.line == 4.0
@@ -53,7 +69,7 @@ def test_create_file(
5369
) -> None:
5470
config = config_module.Config.create(
5571
coverage_filepath,
56-
config_file=example_config_filepath,
72+
config_filepath=example_config_filepath,
5773
)
5874
assert config.line == 2.0
5975
assert config.branch == 3.0
@@ -67,7 +83,7 @@ def test_create_both(
6783
) -> None:
6884
config = config_module.Config.create(
6985
coverage_filepath,
70-
config_file=example_config_filepath,
86+
config_filepath=example_config_filepath,
7187
**example_config_kwargs,
7288
)
7389
assert config.line == 4.0
@@ -87,5 +103,52 @@ def test_create_no_toml(
87103
with pytest.raises(ImportError, match=message):
88104
config_module.Config.create(
89105
coverage_filepath,
90-
config_file=example_config_filepath,
106+
config_filepath=example_config_filepath,
91107
)
108+
109+
def test_create_group(
110+
self,
111+
example_group_config_filepath: Path,
112+
coverage_filepath: Path,
113+
) -> None:
114+
config = config_module.Config.create(
115+
coverage_filepath,
116+
config_filepath=example_group_config_filepath,
117+
group='unit',
118+
)
119+
assert config.line == 6.0
120+
assert config.branch == 7.0
121+
122+
def test_create_missing_all_groups(
123+
self,
124+
example_config_filepath: Path,
125+
coverage_filepath: Path,
126+
capsys: pytest.CaptureFixture,
127+
) -> None:
128+
with pytest.raises(SystemExit):
129+
config_module.Config.create(
130+
coverage_filepath,
131+
config_filepath=example_config_filepath,
132+
group='fake-group',
133+
)
134+
135+
captured = capsys.readouterr()
136+
expected = "Group fake-group not found in config"
137+
assert expected in captured.err
138+
139+
def test_create_missing_one_group(
140+
self,
141+
example_group_config_filepath: Path,
142+
coverage_filepath: Path,
143+
capsys: pytest.CaptureFixture,
144+
) -> None:
145+
with pytest.raises(SystemExit):
146+
config_module.Config.create(
147+
coverage_filepath,
148+
config_filepath=example_group_config_filepath,
149+
group='fake-group',
150+
)
151+
152+
captured = capsys.readouterr()
153+
expected = "Group fake-group not found in config"
154+
assert expected in captured.err

0 commit comments

Comments
 (0)