Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 30 additions & 73 deletions diff_cover/config_parser.py
Original file line number Diff line number Diff line change
@@ -1,90 +1,47 @@
import abc
import enum

try:
import tomli as toml
import configargparse

_HAS_TOML = True
except ImportError: # pragma: no cover
_HAS_TOML = False

if not _HAS_TOML:
try:
import tomllib as toml

_HAS_TOML = True
except ImportError: # pragma: no cover
pass
CONFIG_FILE_HELP = "The configuration file to use"


class Tool(enum.Enum):
DIFF_COVER = enum.auto()
DIFF_QUALITY = enum.auto()


class ParserError(Exception):
pass


class ConfigParser(abc.ABC):
def __init__(self, file_name, tool):
self._file_name = file_name
self._tool = tool

@abc.abstractmethod
def parse(self):
"""Returns a dict of the parsed data or None if the file cannot be handled."""


class TOMLParser(ConfigParser):
def __init__(self, file_name, tool):
super().__init__(file_name, tool)
self._section = "diff_cover" if tool == Tool.DIFF_COVER else "diff_quality"

def parse(self):
if not self._file_name.endswith(".toml"):
return None

if not _HAS_TOML:
raise ParserError("No Toml lib installed")

with open(self._file_name, "rb") as file_handle:
config = toml.load(file_handle)

config = config.get("tool", {}).get(self._section, {})
if not config:
raise ParserError(f"No 'tool.{self._section}' configuration available")
return config


_PARSERS = [TOMLParser]


def _parse_config_file(file_name, tool):
for parser_class in _PARSERS:
parser = parser_class(file_name, tool)
config = parser.parse()
if config:
return config

raise ParserError(f"No config parser could handle {file_name}")


def get_config(parser, argv, defaults, tool):
def get_parser(description):
sections = ["tool.diff_cover", "tool:diff_cover", "diff_cover"]
parser = configargparse.ArgParser(
description=description,
default_config_files=["pyproject.toml"],
config_file_parser_class=configargparse.CompositeConfigParser(
[
configargparse.TomlConfigParser(sections),
]
),
)
parser.add_argument(
"-c",
"--config-file",
help=CONFIG_FILE_HELP,
is_config_file=True,
metavar="CONFIG_FILE",
)
return parser


def get_config(parser, argv, tool):
cli_config = vars(parser.parse_args(argv))
if cli_config["config_file"]:
file_config = _parse_config_file(cli_config["config_file"], tool)
else:
file_config = {}
# if cli_config["config_file"]:
# file_config = _parse_config_file(cli_config["config_file"], tool)
# else:
file_config = {}

config = defaults
config = {}
for config_dict in [file_config, cli_config]:
for key, value in config_dict.items():
if value is None:
# if the value is None, it's a default one; only override if not present
config.setdefault(key, value)
else:
# else just override the existing value
config[key] = value
config[key] = value

return config
43 changes: 14 additions & 29 deletions diff_cover/diff_cover_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import xml.etree.ElementTree as etree

from diff_cover import DESCRIPTION, VERSION
from diff_cover.config_parser import Tool, get_config
from diff_cover.config_parser import Tool, get_config, get_parser
from diff_cover.diff_reporter import GitDiffReporter
from diff_cover.git_diff import GitDiffFileTool, GitDiffTool
from diff_cover.git_path import GitPathTool
Expand Down Expand Up @@ -79,7 +79,7 @@ def parse_coverage_args(argv):

The path strings may or may not exist.
"""
parser = argparse.ArgumentParser(description=DESCRIPTION)
parser = get_parser(description=DESCRIPTION)

parser.add_argument("coverage_files", type=str, help=COVERAGE_FILE_HELP, nargs="+")

Expand All @@ -91,13 +91,13 @@ def parse_coverage_args(argv):
)

parser.add_argument(
"--show-uncovered", action="store_true", default=None, help=SHOW_UNCOVERED
"--show-uncovered", action="store_true", default=False, help=SHOW_UNCOVERED
)

parser.add_argument(
"--expand-coverage-report",
action="store_true",
default=None,
default=False,
help=EXPAND_COVERAGE_REPORT,
)

Expand All @@ -111,29 +111,30 @@ def parse_coverage_args(argv):
parser.add_argument(
"--compare-branch",
metavar="BRANCH",
default="origin/main",
type=str,
help=COMPARE_BRANCH_HELP,
)

parser.add_argument(
"--fail-under", metavar="SCORE", type=float, default=None, help=FAIL_UNDER_HELP
"--fail-under", metavar="SCORE", type=float, default=0, help=FAIL_UNDER_HELP
)

parser.add_argument(
"--ignore-staged", action="store_true", default=None, help=IGNORE_STAGED_HELP
"--ignore-staged", action="store_true", default=False, help=IGNORE_STAGED_HELP
)

parser.add_argument(
"--ignore-unstaged",
action="store_true",
default=None,
default=False,
help=IGNORE_UNSTAGED_HELP,
)

parser.add_argument(
"--include-untracked",
action="store_true",
default=None,
default=False,
help=INCLUDE_UNTRACKED_HELP,
)

Expand All @@ -150,6 +151,7 @@ def parse_coverage_args(argv):
metavar="DIRECTORY",
type=str,
nargs="+",
default=["src/main/java", "src/test/java"],
help=SRC_ROOTS_HELP,
)

Expand All @@ -158,6 +160,7 @@ def parse_coverage_args(argv):
metavar="RANGE_NOTATION",
type=str,
choices=["...", ".."],
default="...",
help=DIFF_RANGE_NOTATION_HELP,
)

Expand All @@ -166,35 +169,17 @@ def parse_coverage_args(argv):
parser.add_argument(
"--ignore-whitespace",
action="store_true",
default=None,
default=False,
help=IGNORE_WHITESPACE,
)

parser.add_argument(
"-q", "--quiet", action="store_true", default=None, help=QUIET_HELP
)

parser.add_argument(
"-c", "--config-file", help=CONFIG_FILE_HELP, metavar="CONFIG_FILE"
"-q", "--quiet", action="store_true", default=False, help=QUIET_HELP
)

parser.add_argument("--diff-file", type=str, default=None, help=DIFF_FILE_HELP)

defaults = {
"show_uncovered": False,
"compare_branch": "origin/main",
"fail_under": 0,
"ignore_staged": False,
"ignore_unstaged": False,
"ignore_untracked": False,
"src_roots": ["src/main/java", "src/test/java"],
"ignore_whitespace": False,
"diff_range_notation": "...",
"quiet": False,
"expand_coverage_report": False,
}

return get_config(parser=parser, argv=argv, defaults=defaults, tool=Tool.DIFF_COVER)
return get_config(parser=parser, argv=argv, tool=Tool.DIFF_COVER)


def generate_coverage_report(
Expand Down
39 changes: 11 additions & 28 deletions diff_cover/diff_quality_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@

import diff_cover
from diff_cover import hookspecs
from diff_cover.config_parser import Tool, get_config
from diff_cover.config_parser import Tool, get_config, get_parser
from diff_cover.diff_cover_tool import (
COMPARE_BRANCH_HELP,
CONFIG_FILE_HELP,
CSS_FILE_HELP,
DIFF_RANGE_NOTATION_HELP,
EXCLUDE_HELP,
Expand Down Expand Up @@ -103,7 +102,7 @@ def parse_quality_args(argv):

where `HTML_REPORT` and `CSS_FILE` are paths.
"""
parser = argparse.ArgumentParser(description=diff_cover.QUALITY_DESCRIPTION)
parser = get_parser(diff_cover.QUALITY_DESCRIPTION)

parser.add_argument(
"--violations", metavar="TOOL", type=str, help=VIOLATION_CMD_HELP, required=True
Expand All @@ -127,6 +126,7 @@ def parse_quality_args(argv):
"--compare-branch",
metavar="BRANCH",
type=str,
default="origin/main",
help=COMPARE_BRANCH_HELP,
)

Expand All @@ -135,24 +135,24 @@ def parse_quality_args(argv):
parser.add_argument("--options", type=str, nargs="?", help=OPTIONS_HELP)

parser.add_argument(
"--fail-under", metavar="SCORE", type=float, help=FAIL_UNDER_HELP
"--fail-under", metavar="SCORE", type=float, default=0, help=FAIL_UNDER_HELP
)

parser.add_argument(
"--ignore-staged", action="store_true", default=None, help=IGNORE_STAGED_HELP
"--ignore-staged", action="store_true", default=False, help=IGNORE_STAGED_HELP
)

parser.add_argument(
"--ignore-unstaged",
action="store_true",
default=None,
default=False,
help=IGNORE_UNSTAGED_HELP,
)

parser.add_argument(
"--include-untracked",
action="store_true",
default=None,
default=False,
help=INCLUDE_UNTRACKED_HELP,
)

Expand All @@ -168,6 +168,7 @@ def parse_quality_args(argv):
"--diff-range-notation",
metavar="RANGE_NOTATION",
type=str,
default="...",
help=DIFF_RANGE_NOTATION_HELP,
)

Expand All @@ -179,37 +180,19 @@ def parse_quality_args(argv):
parser.add_argument(
"--ignore-whitespace",
action="store_true",
default=None,
default=False,
help=IGNORE_WHITESPACE,
)

parser.add_argument(
"-q", "--quiet", action="store_true", default=None, help=QUIET_HELP
)

parser.add_argument(
"-c", "--config-file", help=CONFIG_FILE_HELP, metavar="CONFIG_FILE"
"-q", "--quiet", action="store_true", default=False, help=QUIET_HELP
)

parser.add_argument(
"--report-root-path", help=REPORT_ROOT_PATH_HELP, metavar="ROOT_PATH"
)

defaults = {
"ignore_whitespace": False,
"compare_branch": "origin/main",
"diff_range_notation": "...",
"input_reports": [],
"fail_under": 0,
"ignore_staged": False,
"ignore_unstaged": False,
"ignore_untracked": False,
"quiet": False,
}

return get_config(
parser=parser, argv=argv, defaults=defaults, tool=Tool.DIFF_QUALITY
)
return get_config(parser=parser, argv=argv, tool=Tool.DIFF_QUALITY)


def generate_quality_report(
Expand Down
Loading
Loading