diff-cover 10.5.0__tar.gz → 10.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- diff_cover-10.6.0/.gitignore +50 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/PKG-INFO +27 -20
- {diff_cover-10.5.0 → diff_cover-10.6.0}/README.rst +14 -7
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/command_runner.py +32 -1
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/diff_cover_tool.py +21 -4
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/diff_quality_tool.py +21 -4
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/git_diff.py +4 -3
- diff_cover-10.6.0/diff_cover/violationsreporters/clover.py +84 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/violationsreporters/violations_reporter.py +12 -34
- diff_cover-10.6.0/pyproject.toml +138 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pycodestyle_violations_report.html +1 -1
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pycodestyle_violations_report_external_css.html +1 -1
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pyflakes_violations_report.html +1 -1
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pylint_violations_report.html +1 -1
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/test_clover_violations_reporter.py +2 -3
- diff_cover-10.6.0/tests/test_command_runner_missing_executable.py +92 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/test_diff_cover_tool.py +21 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/test_diff_quality_main.py +22 -1
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/test_integration.py +34 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/test_java_violations_reporter.py +44 -14
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/test_report_generator.py +3 -10
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/test_violations_reporter.py +170 -38
- diff_cover-10.5.0/pyproject.toml +0 -184
- {diff_cover-10.5.0 → diff_cover-10.6.0}/LICENSE +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/NOTICE +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/__init__.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/config_parser.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/diff_reporter.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/git_path.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/hook.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/hookspecs.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/report_generator.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/snippets.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/templates/console_coverage_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/templates/console_quality_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/templates/external_style.css +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/templates/github_coverage_annotations.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/templates/html_coverage_report.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/templates/html_quality_report.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/templates/markdown_coverage_report.md +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/templates/markdown_quality_report.md +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/templates/snippet_content.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/templates/snippet_content.md +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/templates/snippet_content.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/templates/snippet_style.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/util.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/violationsreporters/__init__.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/violationsreporters/base.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/violationsreporters/java_violations_reporter.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/__init__.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/conftest.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/add_console_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/add_html_report.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/add_json_report.json +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/add_json_report_float.json +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/add_markdown_report.md +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/changed_console_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/changed_html_report.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/coverage.xml +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/coverage1.xml +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/coverage2.xml +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/coverage_missing_lines.xml +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/cpp_functions_console_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/cpp_functions_coverage.lcov +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/delete_console_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/delete_html_report.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/dotnet_coverage.xml +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/empty.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/empty_pycodestyle_violations.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/expand_console_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/external_css_html_report.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/external_style.css +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_add.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_changed.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_code_dupe.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_cpp.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_cpp_functions.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_delete.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_dotnet.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_external_css.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_lua.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_moved.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_mult.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_python.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_subdir.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_typescript.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_typescript_branches.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_unicode.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_violations.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/git_diff_violations_two_files.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/hello.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/hi.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/html_report.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/html_report_empty.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/html_report_one_snippet.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/html_report_two_snippets.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/lcov.info +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/lua_console_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/luacoverage.xml +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/markdown_report_one_snippet.md +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/markdown_report_two_snippets.md +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/moved_console_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/moved_coverage.xml +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/moved_html_report.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/mult_inputs_console_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/mult_inputs_html_report.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pycodestyle_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pycodestyle_violations_report.json +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pycodestyle_violations_report.md +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pycodestyle_violations_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pycodestyle_violations_report_float.json +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pyflakes_two_files.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pyflakes_violations_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pylint_dupe.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pylint_dupe_violations_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pylint_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pylint_violations_console_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pylint_violations_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/pylintrc +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/real_cpp_console_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/real_cpp_coverage.lcov +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/real_python_console_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/real_python_coverage.lcov +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/real_typescript_console_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/real_typescript_coverage.lcov +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/show_uncovered_lines_console.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/snippet.css +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/snippet_8859.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/snippet_arabic_output.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/snippet_default.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/snippet_invalid_violations.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/snippet_list.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/snippet_list.md +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/snippet_list2.md +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/snippet_list3.md +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/snippet_no_filename_ext.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/snippet_src.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/snippet_src2.cpp +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/snippet_src3.cpp +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/snippet_unicode.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/snippet_unicode.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/snippet_unicode_html_output.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/subdir_coverage_console_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/subdir_coverage_html_report.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/test_src.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/typescript_branches_console_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/typescript_branches_coverage.lcov +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/unicode_console_report.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/unicode_coverage.xml +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/unicode_html_report.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/unicode_test_src.txt +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/fixtures/violations_test_file.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/helpers.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/snippet_list_unicode.html +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/test_clover_violations_reporter/test.xml +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/test_config_parser.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/test_diff_cover_main.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/test_diff_reporter.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/test_git_diff.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/test_git_diff_file.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/test_git_path.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/test_snippets.py +0 -0
- {diff_cover-10.5.0 → diff_cover-10.6.0}/tests/test_util.py +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
*.py[cod]
|
|
2
|
+
.DS_Store
|
|
3
|
+
|
|
4
|
+
.idea
|
|
5
|
+
venv
|
|
6
|
+
27venv
|
|
7
|
+
.venv
|
|
8
|
+
|
|
9
|
+
# C extensions
|
|
10
|
+
*.so
|
|
11
|
+
|
|
12
|
+
# Packages
|
|
13
|
+
*.egg
|
|
14
|
+
*.egg-info
|
|
15
|
+
dist
|
|
16
|
+
build
|
|
17
|
+
eggs
|
|
18
|
+
parts
|
|
19
|
+
bin
|
|
20
|
+
var
|
|
21
|
+
sdist
|
|
22
|
+
develop-eggs
|
|
23
|
+
.installed.cfg
|
|
24
|
+
lib
|
|
25
|
+
lib64
|
|
26
|
+
__pycache__
|
|
27
|
+
.pytest_cache
|
|
28
|
+
|
|
29
|
+
# Installer logs
|
|
30
|
+
pip-log.txt
|
|
31
|
+
|
|
32
|
+
# Unit test / coverage reports
|
|
33
|
+
.coverage*
|
|
34
|
+
.tox
|
|
35
|
+
/coverage.xml
|
|
36
|
+
/report.html
|
|
37
|
+
|
|
38
|
+
# Translations
|
|
39
|
+
*.mo
|
|
40
|
+
|
|
41
|
+
# Mr Developer
|
|
42
|
+
.mr.developer.cfg
|
|
43
|
+
.project
|
|
44
|
+
.pydevproject
|
|
45
|
+
.python-version
|
|
46
|
+
|
|
47
|
+
# VS Code
|
|
48
|
+
.vscode/*
|
|
49
|
+
*.code-workspaces
|
|
50
|
+
.history/
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: diff_cover
|
|
3
|
-
Version: 10.
|
|
3
|
+
Version: 10.6.0
|
|
4
4
|
Summary: Run coverage and linting reports on diffs
|
|
5
|
-
|
|
5
|
+
Project-URL: Homepage, https://github.com/Bachmann1234/diff-cover
|
|
6
|
+
Project-URL: Repository, https://github.com/Bachmann1234/diff-cover
|
|
6
7
|
Author: See Contributors
|
|
7
|
-
|
|
8
|
+
License-Expression: Apache-2.0
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
License-File: NOTICE
|
|
8
11
|
Classifier: Development Status :: 5 - Production/Stable
|
|
9
12
|
Classifier: Environment :: Console
|
|
10
13
|
Classifier: Intended Audience :: Developers
|
|
11
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
14
|
Classifier: Operating System :: OS Independent
|
|
13
15
|
Classifier: Programming Language :: Python
|
|
14
16
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -20,14 +22,13 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
20
22
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
21
23
|
Classifier: Topic :: Software Development :: Quality Assurance
|
|
22
24
|
Classifier: Topic :: Software Development :: Testing
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
|
+
Requires-Dist: chardet>=3.0.0
|
|
27
|
+
Requires-Dist: jinja2>=2.7.1
|
|
28
|
+
Requires-Dist: pluggy<2,>=0.13.1
|
|
29
|
+
Requires-Dist: pygments<3,>=2.19.1
|
|
23
30
|
Provides-Extra: toml
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist: Pygments (>=2.19.1,<3.0.0)
|
|
26
|
-
Requires-Dist: chardet (>=3.0.0)
|
|
27
|
-
Requires-Dist: pluggy (>=0.13.1,<2)
|
|
28
|
-
Requires-Dist: tomli (>=1.2.1) ; extra == "toml"
|
|
29
|
-
Project-URL: Homepage, https://github.com/Bachmann1234/diff-cover
|
|
30
|
-
Project-URL: Repository, https://github.com/Bachmann1234/diff-cover
|
|
31
|
+
Requires-Dist: tomli>=1.2.1; extra == 'toml'
|
|
31
32
|
Description-Content-Type: text/x-rst
|
|
32
33
|
|
|
33
34
|
diff-cover |pypi-version| |conda-version| |build-status|
|
|
@@ -96,8 +97,11 @@ To install the development version:
|
|
|
96
97
|
|
|
97
98
|
git clone https://github.com/Bachmann1234/diff-cover.git
|
|
98
99
|
cd diff-cover
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
uv sync
|
|
101
|
+
|
|
102
|
+
This creates a ``.venv`` with the project installed. Run commands through it with
|
|
103
|
+
``uv run``, for example ``uv run diff-cover --help``, or activate it the usual way
|
|
104
|
+
with ``source .venv/bin/activate``.
|
|
101
105
|
|
|
102
106
|
|
|
103
107
|
Getting Started
|
|
@@ -508,17 +512,21 @@ Support for a New Quality Checker".
|
|
|
508
512
|
Setting Up For Development
|
|
509
513
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
510
514
|
|
|
511
|
-
This project is managed with `
|
|
512
|
-
|
|
513
|
-
packages this project.
|
|
515
|
+
This project is managed with `uv <https://docs.astral.sh/uv/>`_. uv provisions the
|
|
516
|
+
Python toolchain and a project virtual environment, resolves and locks dependencies,
|
|
517
|
+
and packages this project. Install it by following the
|
|
518
|
+
`uv installation guide <https://docs.astral.sh/uv/getting-started/installation/>`_.
|
|
514
519
|
|
|
515
520
|
.. code:: bash
|
|
516
521
|
|
|
517
|
-
|
|
522
|
+
uv sync
|
|
523
|
+
|
|
524
|
+
This creates ``.venv`` with all runtime and development dependencies. Run project
|
|
525
|
+
commands through ``uv run``, for example the full verification suite:
|
|
518
526
|
|
|
519
527
|
.. code:: bash
|
|
520
528
|
|
|
521
|
-
|
|
529
|
+
uv run ./verify.sh
|
|
522
530
|
|
|
523
531
|
I would also suggest running this command after. This will make it so git blame ignores the commit
|
|
524
532
|
that formatted the entire codebase.
|
|
@@ -649,4 +657,3 @@ Originally created with the support of `edX
|
|
|
649
657
|
.. |build-status| image:: https://github.com/bachmann1234/diff_cover/actions/workflows/verify.yaml/badge.svg?branch=main
|
|
650
658
|
:target: https://github.com/Bachmann1234/diff_cover/actions/workflows/verify.yaml
|
|
651
659
|
:alt: Build Status
|
|
652
|
-
|
|
@@ -64,8 +64,11 @@ To install the development version:
|
|
|
64
64
|
|
|
65
65
|
git clone https://github.com/Bachmann1234/diff-cover.git
|
|
66
66
|
cd diff-cover
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
uv sync
|
|
68
|
+
|
|
69
|
+
This creates a ``.venv`` with the project installed. Run commands through it with
|
|
70
|
+
``uv run``, for example ``uv run diff-cover --help``, or activate it the usual way
|
|
71
|
+
with ``source .venv/bin/activate``.
|
|
69
72
|
|
|
70
73
|
|
|
71
74
|
Getting Started
|
|
@@ -476,17 +479,21 @@ Support for a New Quality Checker".
|
|
|
476
479
|
Setting Up For Development
|
|
477
480
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
478
481
|
|
|
479
|
-
This project is managed with `
|
|
480
|
-
|
|
481
|
-
packages this project.
|
|
482
|
+
This project is managed with `uv <https://docs.astral.sh/uv/>`_. uv provisions the
|
|
483
|
+
Python toolchain and a project virtual environment, resolves and locks dependencies,
|
|
484
|
+
and packages this project. Install it by following the
|
|
485
|
+
`uv installation guide <https://docs.astral.sh/uv/getting-started/installation/>`_.
|
|
482
486
|
|
|
483
487
|
.. code:: bash
|
|
484
488
|
|
|
485
|
-
|
|
489
|
+
uv sync
|
|
490
|
+
|
|
491
|
+
This creates ``.venv`` with all runtime and development dependencies. Run project
|
|
492
|
+
commands through ``uv run``, for example the full verification suite:
|
|
486
493
|
|
|
487
494
|
.. code:: bash
|
|
488
495
|
|
|
489
|
-
|
|
496
|
+
uv run ./verify.sh
|
|
490
497
|
|
|
491
498
|
I would also suggest running this command after. This will make it so git blame ignores the commit
|
|
492
499
|
that formatted the entire codebase.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import subprocess
|
|
2
2
|
import sys
|
|
3
3
|
|
|
4
|
+
GIT_INSTALL_URL = "https://git-scm.com/book/en/v2/Getting-Started-Installing-Git"
|
|
5
|
+
|
|
4
6
|
|
|
5
7
|
class CommandError(Exception):
|
|
6
8
|
"""
|
|
@@ -8,6 +10,16 @@ class CommandError(Exception):
|
|
|
8
10
|
"""
|
|
9
11
|
|
|
10
12
|
|
|
13
|
+
class ExecutableNotFoundError(CommandError):
|
|
14
|
+
"""
|
|
15
|
+
Error raised when the executable of a command cannot be found at all.
|
|
16
|
+
|
|
17
|
+
This is a `CommandError` so that existing handling keeps working, but a
|
|
18
|
+
distinct type so the command line tools can tell "your tooling is not
|
|
19
|
+
installed" apart from "the command ran and failed".
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
|
|
11
23
|
def execute(command, exit_codes=None):
|
|
12
24
|
"""Execute provided command returning the stdout
|
|
13
25
|
Args:
|
|
@@ -24,7 +36,12 @@ def execute(command, exit_codes=None):
|
|
|
24
36
|
exit_codes = [0]
|
|
25
37
|
|
|
26
38
|
stdout_pipe = subprocess.PIPE
|
|
27
|
-
|
|
39
|
+
try:
|
|
40
|
+
popen = subprocess.Popen(command, stdout=stdout_pipe, stderr=stdout_pipe)
|
|
41
|
+
except FileNotFoundError as exc:
|
|
42
|
+
raise ExecutableNotFoundError(_executable_not_found_message(command)) from exc
|
|
43
|
+
|
|
44
|
+
with popen as process:
|
|
28
45
|
try:
|
|
29
46
|
stdout, stderr = process.communicate()
|
|
30
47
|
except OSError:
|
|
@@ -52,6 +69,20 @@ def run_command_for_code(command):
|
|
|
52
69
|
return process.returncode
|
|
53
70
|
|
|
54
71
|
|
|
72
|
+
def _executable_not_found_message(command):
|
|
73
|
+
"""
|
|
74
|
+
Explain that the executable of `command` is not installed or not on PATH.
|
|
75
|
+
"""
|
|
76
|
+
executable = _ensure_unicode(command[0]) if command else ""
|
|
77
|
+
message = (
|
|
78
|
+
f"'{executable}' was not found. diff-cover needs '{executable}' to be "
|
|
79
|
+
"installed and on your PATH in order to run."
|
|
80
|
+
)
|
|
81
|
+
if executable == "git":
|
|
82
|
+
message += f" See {GIT_INSTALL_URL} for installation instructions."
|
|
83
|
+
return message
|
|
84
|
+
|
|
85
|
+
|
|
55
86
|
def _ensure_unicode(text):
|
|
56
87
|
"""
|
|
57
88
|
Ensures the text passed in becomes unicode
|
|
@@ -7,6 +7,7 @@ import warnings
|
|
|
7
7
|
import xml.etree.ElementTree as etree
|
|
8
8
|
|
|
9
9
|
from diff_cover import DESCRIPTION, VERSION
|
|
10
|
+
from diff_cover.command_runner import ExecutableNotFoundError
|
|
10
11
|
from diff_cover.config_parser import Tool, get_config
|
|
11
12
|
from diff_cover.diff_reporter import GitDiffReporter
|
|
12
13
|
from diff_cover.git_diff import GitDiffFileTool, GitDiffTool
|
|
@@ -33,6 +34,7 @@ CSS_FILE_HELP = "Write CSS into an external file"
|
|
|
33
34
|
FAIL_UNDER_HELP = (
|
|
34
35
|
"Returns an error code if coverage or quality score is below this value"
|
|
35
36
|
)
|
|
37
|
+
MINIMUM_CHANGE_HELP = "Always pass if total lines of change is below this value"
|
|
36
38
|
IGNORE_STAGED_HELP = "Ignores staged changes"
|
|
37
39
|
IGNORE_UNSTAGED_HELP = "Ignores unstaged changes"
|
|
38
40
|
IGNORE_WHITESPACE = "When getting a diff ignore any and all whitespace"
|
|
@@ -155,6 +157,13 @@ def parse_coverage_args(argv):
|
|
|
155
157
|
parser.add_argument(
|
|
156
158
|
"--fail-under", metavar="SCORE", type=float, default=None, help=FAIL_UNDER_HELP
|
|
157
159
|
)
|
|
160
|
+
parser.add_argument(
|
|
161
|
+
"--minimum-change",
|
|
162
|
+
metavar="LINES",
|
|
163
|
+
type=int,
|
|
164
|
+
default=None,
|
|
165
|
+
help=MINIMUM_CHANGE_HELP,
|
|
166
|
+
)
|
|
158
167
|
|
|
159
168
|
parser.add_argument(
|
|
160
169
|
"--ignore-staged", action="store_true", default=None, help=IGNORE_STAGED_HELP
|
|
@@ -229,6 +238,7 @@ def parse_coverage_args(argv):
|
|
|
229
238
|
"compare_branch": "origin/main",
|
|
230
239
|
"format": {},
|
|
231
240
|
"fail_under": 0,
|
|
241
|
+
"minimum_change": 0,
|
|
232
242
|
"ignore_staged": False,
|
|
233
243
|
"ignore_unstaged": False,
|
|
234
244
|
"ignore_untracked": False,
|
|
@@ -353,7 +363,7 @@ def generate_coverage_report(
|
|
|
353
363
|
|
|
354
364
|
# Generate the report
|
|
355
365
|
reporter.generate_report(output_file)
|
|
356
|
-
return reporter.total_percent_covered()
|
|
366
|
+
return reporter.total_percent_covered(), reporter.total_num_lines()
|
|
357
367
|
|
|
358
368
|
|
|
359
369
|
def handle_old_format(description, argv):
|
|
@@ -418,8 +428,13 @@ def main(argv=None, directory=None):
|
|
|
418
428
|
level = logging.ERROR if quiet else logging.WARNING
|
|
419
429
|
logging.basicConfig(format="%(message)s", level=level)
|
|
420
430
|
|
|
421
|
-
|
|
431
|
+
try:
|
|
432
|
+
GitPathTool.set_cwd(directory)
|
|
433
|
+
except ExecutableNotFoundError as exc:
|
|
434
|
+
LOGGER.error("%s", exc)
|
|
435
|
+
return 1
|
|
422
436
|
fail_under = arg_dict.get("fail_under")
|
|
437
|
+
minimum_change = arg_dict.get("minimum_change") or 0
|
|
423
438
|
diff_tool = None
|
|
424
439
|
|
|
425
440
|
if not arg_dict["diff_file"]:
|
|
@@ -429,7 +444,7 @@ def main(argv=None, directory=None):
|
|
|
429
444
|
else:
|
|
430
445
|
diff_tool = GitDiffFileTool(arg_dict["diff_file"])
|
|
431
446
|
|
|
432
|
-
percent_covered = generate_coverage_report(
|
|
447
|
+
percent_covered, num_changed_lines = generate_coverage_report(
|
|
433
448
|
arg_dict["coverage_files"],
|
|
434
449
|
arg_dict["compare_branch"],
|
|
435
450
|
diff_tool,
|
|
@@ -449,7 +464,9 @@ def main(argv=None, directory=None):
|
|
|
449
464
|
total_percent_float=arg_dict["total_percent_float"],
|
|
450
465
|
)
|
|
451
466
|
|
|
452
|
-
if percent_covered >= fail_under
|
|
467
|
+
if percent_covered >= fail_under or (
|
|
468
|
+
minimum_change and num_changed_lines < minimum_change
|
|
469
|
+
):
|
|
453
470
|
return 0
|
|
454
471
|
LOGGER.error("Failure. Coverage is below %i%%.", fail_under)
|
|
455
472
|
return 1
|
|
@@ -14,6 +14,7 @@ import pluggy
|
|
|
14
14
|
|
|
15
15
|
import diff_cover
|
|
16
16
|
from diff_cover import hookspecs
|
|
17
|
+
from diff_cover.command_runner import ExecutableNotFoundError
|
|
17
18
|
from diff_cover.config_parser import Tool, get_config
|
|
18
19
|
from diff_cover.diff_cover_tool import (
|
|
19
20
|
COMPARE_BRANCH_HELP,
|
|
@@ -30,6 +31,7 @@ from diff_cover.diff_cover_tool import (
|
|
|
30
31
|
INCLUDE_UNTRACKED_HELP,
|
|
31
32
|
JSON_REPORT_DEFAULT_PATH,
|
|
32
33
|
MARKDOWN_REPORT_DEFAULT_PATH,
|
|
34
|
+
MINIMUM_CHANGE_HELP,
|
|
33
35
|
QUIET_HELP,
|
|
34
36
|
TOTAL_PERCENT_FLOAT_HELP,
|
|
35
37
|
format_type,
|
|
@@ -146,6 +148,12 @@ def parse_quality_args(argv):
|
|
|
146
148
|
parser.add_argument(
|
|
147
149
|
"--fail-under", metavar="SCORE", type=float, help=FAIL_UNDER_HELP
|
|
148
150
|
)
|
|
151
|
+
parser.add_argument(
|
|
152
|
+
"--minimum-change",
|
|
153
|
+
metavar="LINES",
|
|
154
|
+
type=int,
|
|
155
|
+
help=MINIMUM_CHANGE_HELP,
|
|
156
|
+
)
|
|
149
157
|
|
|
150
158
|
parser.add_argument(
|
|
151
159
|
"--ignore-staged", action="store_true", default=None, help=IGNORE_STAGED_HELP
|
|
@@ -217,6 +225,7 @@ def parse_quality_args(argv):
|
|
|
217
225
|
"diff_range_notation": "...",
|
|
218
226
|
"input_reports": [],
|
|
219
227
|
"fail_under": 0,
|
|
228
|
+
"minimum_change": 0,
|
|
220
229
|
"ignore_staged": False,
|
|
221
230
|
"ignore_unstaged": False,
|
|
222
231
|
"ignore_untracked": False,
|
|
@@ -297,7 +306,7 @@ def generate_quality_report(
|
|
|
297
306
|
output_file = io.BytesIO() if quiet else sys.stdout.buffer
|
|
298
307
|
reporter.generate_report(output_file)
|
|
299
308
|
|
|
300
|
-
return reporter.total_percent_covered()
|
|
309
|
+
return reporter.total_percent_covered(), reporter.total_num_lines()
|
|
301
310
|
|
|
302
311
|
|
|
303
312
|
def _call_reporter_factory(factory_fn, reports, options):
|
|
@@ -339,8 +348,13 @@ def main(argv=None, directory=None):
|
|
|
339
348
|
level = logging.ERROR if quiet else logging.WARNING
|
|
340
349
|
logging.basicConfig(format="%(message)s", level=level)
|
|
341
350
|
|
|
342
|
-
|
|
351
|
+
try:
|
|
352
|
+
GitPathTool.set_cwd(directory)
|
|
353
|
+
except ExecutableNotFoundError as exc:
|
|
354
|
+
LOGGER.error("%s", exc)
|
|
355
|
+
return 1
|
|
343
356
|
fail_under = arg_dict.get("fail_under")
|
|
357
|
+
minimum_change = arg_dict.get("minimum_change") or 0
|
|
344
358
|
tool = arg_dict["violations"]
|
|
345
359
|
user_options = arg_dict.get("options")
|
|
346
360
|
if user_options:
|
|
@@ -394,7 +408,7 @@ def main(argv=None, directory=None):
|
|
|
394
408
|
reporter_factory_fn, input_reports, user_options
|
|
395
409
|
)
|
|
396
410
|
|
|
397
|
-
percent_passing = generate_quality_report(
|
|
411
|
+
percent_passing, num_changed_lines = generate_quality_report(
|
|
398
412
|
reporter,
|
|
399
413
|
arg_dict["compare_branch"],
|
|
400
414
|
GitDiffTool(
|
|
@@ -410,7 +424,10 @@ def main(argv=None, directory=None):
|
|
|
410
424
|
quiet=quiet,
|
|
411
425
|
total_percent_float=arg_dict["total_percent_float"],
|
|
412
426
|
)
|
|
413
|
-
|
|
427
|
+
|
|
428
|
+
if percent_passing >= fail_under or (
|
|
429
|
+
minimum_change and num_changed_lines < minimum_change
|
|
430
|
+
):
|
|
414
431
|
return 0
|
|
415
432
|
|
|
416
433
|
LOGGER.error("Failure. Quality is below %i.", fail_under)
|
|
@@ -72,10 +72,12 @@ class GitDiffTool:
|
|
|
72
72
|
)[0]
|
|
73
73
|
except CommandError as e:
|
|
74
74
|
if "unknown revision" in str(e):
|
|
75
|
-
raise ValueError(
|
|
75
|
+
raise ValueError(
|
|
76
|
+
dedent(f"""
|
|
76
77
|
Could not find the branch to compare to. Does '{compare_branch}' exist?
|
|
77
78
|
the `--compare-branch` argument allows you to set a different branch.
|
|
78
|
-
""")
|
|
79
|
+
""")
|
|
80
|
+
) from e
|
|
79
81
|
raise
|
|
80
82
|
|
|
81
83
|
def diff_unstaged(self):
|
|
@@ -115,7 +117,6 @@ class GitDiffTool:
|
|
|
115
117
|
|
|
116
118
|
|
|
117
119
|
class GitDiffFileTool(GitDiffTool):
|
|
118
|
-
|
|
119
120
|
def __init__(self, diff_file_path):
|
|
120
121
|
|
|
121
122
|
self.diff_file_path = diff_file_path
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Reading the ``<file>`` elements of a Clover XML coverage report.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import itertools
|
|
6
|
+
from collections import defaultdict
|
|
7
|
+
|
|
8
|
+
from diff_cover import util
|
|
9
|
+
from diff_cover.git_path import GitPathTool
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class CloverFileIndex:
|
|
13
|
+
"""
|
|
14
|
+
The ``<file>`` elements of one Clover report, indexed for lookup by path.
|
|
15
|
+
|
|
16
|
+
Building the index costs one walk of the document. Looking a source path up
|
|
17
|
+
by walking the document instead costs that walk once per source path, which
|
|
18
|
+
is quadratic in a report with many files.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, xml_document):
|
|
22
|
+
"""
|
|
23
|
+
Index every ``<file>`` element of `xml_document`.
|
|
24
|
+
|
|
25
|
+
A file is matched either by its path relative to the repository root
|
|
26
|
+
or, when the report carries absolute paths, by a suffix test. The
|
|
27
|
+
suffix can only match when the last path segment does, so candidates
|
|
28
|
+
for it are grouped by that segment and the test is applied to the few
|
|
29
|
+
that share it.
|
|
30
|
+
|
|
31
|
+
Both tables store the document position of each element so that
|
|
32
|
+
lookups can return matches in document order, as a direct walk would.
|
|
33
|
+
"""
|
|
34
|
+
self._by_relative_path = defaultdict(list)
|
|
35
|
+
self._by_last_segment = defaultdict(list)
|
|
36
|
+
for position, file_tree in enumerate(xml_document.findall(".//file")):
|
|
37
|
+
file_path = file_tree.get("path") or file_tree.get("name")
|
|
38
|
+
if not file_path:
|
|
39
|
+
continue
|
|
40
|
+
|
|
41
|
+
normalized_file_path = util.to_unix_path(file_path)
|
|
42
|
+
relative_file_path = util.to_unix_path(GitPathTool.relative_path(file_path))
|
|
43
|
+
self._by_relative_path[relative_file_path].append((position, file_tree))
|
|
44
|
+
self._by_last_segment[normalized_file_path.rsplit("/", 1)[-1]].append(
|
|
45
|
+
(position, normalized_file_path, file_tree)
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
def _files(self, src_path):
|
|
49
|
+
"""
|
|
50
|
+
Return the ``<file>`` elements for `src_path`, in document order.
|
|
51
|
+
"""
|
|
52
|
+
normalized_src_path = util.to_unix_path(src_path)
|
|
53
|
+
|
|
54
|
+
matches = {}
|
|
55
|
+
for position, file_tree in self._by_relative_path.get(normalized_src_path, ()):
|
|
56
|
+
matches[position] = file_tree
|
|
57
|
+
suffix = f"/{normalized_src_path}"
|
|
58
|
+
for position, normalized_file_path, file_tree in self._by_last_segment.get(
|
|
59
|
+
normalized_src_path.rsplit("/", 1)[-1], ()
|
|
60
|
+
):
|
|
61
|
+
if normalized_file_path.endswith(suffix):
|
|
62
|
+
matches[position] = file_tree
|
|
63
|
+
|
|
64
|
+
return [matches[position] for position in sorted(matches)]
|
|
65
|
+
|
|
66
|
+
def line_nodes(self, src_path):
|
|
67
|
+
"""
|
|
68
|
+
Return a list of nodes containing line information for `src_path`.
|
|
69
|
+
|
|
70
|
+
If the file is not present in the report, return None
|
|
71
|
+
"""
|
|
72
|
+
files = self._files(src_path)
|
|
73
|
+
if not files:
|
|
74
|
+
return None
|
|
75
|
+
lines = []
|
|
76
|
+
for file_tree in files:
|
|
77
|
+
# Clover marks an executable line as one of these three types. PHPUnit's
|
|
78
|
+
# writer emits `method` for the declaration line of every function it
|
|
79
|
+
# measured; leaving it out reported those lines as unmeasured.
|
|
80
|
+
# https://github.com/sebastianbergmann/php-code-coverage/blob/main/src/Report/Clover.php
|
|
81
|
+
lines.append(file_tree.findall('./line[@type="method"]'))
|
|
82
|
+
lines.append(file_tree.findall('./line[@type="stmt"]'))
|
|
83
|
+
lines.append(file_tree.findall('./line[@type="cond"]'))
|
|
84
|
+
return list(itertools.chain(*lines))
|
{diff_cover-10.5.0 → diff_cover-10.6.0}/diff_cover/violationsreporters/violations_reporter.py
RENAMED
|
@@ -17,6 +17,7 @@ from diff_cover.violationsreporters.base import (
|
|
|
17
17
|
RegexBasedDriver,
|
|
18
18
|
Violation,
|
|
19
19
|
)
|
|
20
|
+
from diff_cover.violationsreporters.clover import CloverFileIndex
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
class XmlCoverageReporter(BaseViolationReporter):
|
|
@@ -51,6 +52,9 @@ class XmlCoverageReporter(BaseViolationReporter):
|
|
|
51
52
|
# once per source file in `_cache_file`.
|
|
52
53
|
self._report_formats = [self._detect_report_format(root) for root in xml_roots]
|
|
53
54
|
|
|
55
|
+
# A `CloverFileIndex` for each Clover report, built on first use.
|
|
56
|
+
self._clover_file_index = [None] * len(xml_roots)
|
|
57
|
+
|
|
54
58
|
self._src_roots = src_roots or [""]
|
|
55
59
|
self._expand_coverage_report = expand_coverage_report
|
|
56
60
|
self._branch_coverage = branch_coverage
|
|
@@ -125,41 +129,16 @@ class XmlCoverageReporter(BaseViolationReporter):
|
|
|
125
129
|
lines = [clazz.findall("./lines/line") for clazz in classes]
|
|
126
130
|
return list(itertools.chain(*lines))
|
|
127
131
|
|
|
128
|
-
|
|
129
|
-
def get_src_path_line_nodes_clover(xml_document, src_path):
|
|
132
|
+
def get_src_path_line_nodes_clover(self, index, xml_document, src_path):
|
|
130
133
|
"""
|
|
131
134
|
Return a list of nodes containing line information for `src_path`
|
|
132
135
|
in `xml_document`.
|
|
133
136
|
|
|
134
137
|
If file is not present in `xml_document`, return None
|
|
135
138
|
"""
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
for file_tree in xml_document.findall(".//file"):
|
|
140
|
-
file_path = file_tree.get("path") or file_tree.get("name")
|
|
141
|
-
if not file_path:
|
|
142
|
-
continue
|
|
143
|
-
|
|
144
|
-
normalized_file_path = util.to_unix_path(file_path)
|
|
145
|
-
relative_file_path = util.to_unix_path(GitPathTool.relative_path(file_path))
|
|
146
|
-
if (
|
|
147
|
-
relative_file_path == normalized_src_path
|
|
148
|
-
or normalized_file_path.endswith(f"/{normalized_src_path}")
|
|
149
|
-
):
|
|
150
|
-
files.append(file_tree)
|
|
151
|
-
if not files:
|
|
152
|
-
return None
|
|
153
|
-
lines = []
|
|
154
|
-
for file_tree in files:
|
|
155
|
-
# Clover marks an executable line as one of these three types. PHPUnit's
|
|
156
|
-
# writer emits `method` for the declaration line of every function it
|
|
157
|
-
# measured; leaving it out reported those lines as unmeasured.
|
|
158
|
-
# https://github.com/sebastianbergmann/php-code-coverage/blob/main/src/Report/Clover.php
|
|
159
|
-
lines.append(file_tree.findall('./line[@type="method"]'))
|
|
160
|
-
lines.append(file_tree.findall('./line[@type="stmt"]'))
|
|
161
|
-
lines.append(file_tree.findall('./line[@type="cond"]'))
|
|
162
|
-
return list(itertools.chain(*lines))
|
|
139
|
+
if self._clover_file_index[index] is None:
|
|
140
|
+
self._clover_file_index[index] = CloverFileIndex(xml_document)
|
|
141
|
+
return self._clover_file_index[index].line_nodes(src_path)
|
|
163
142
|
|
|
164
143
|
@staticmethod
|
|
165
144
|
def _detect_report_format(xml_document):
|
|
@@ -246,7 +225,7 @@ class XmlCoverageReporter(BaseViolationReporter):
|
|
|
246
225
|
report_format = self._report_formats[i]
|
|
247
226
|
if report_format == "clover":
|
|
248
227
|
line_nodes = self.get_src_path_line_nodes_clover(
|
|
249
|
-
xml_document, src_path
|
|
228
|
+
i, xml_document, src_path
|
|
250
229
|
)
|
|
251
230
|
_number = "num"
|
|
252
231
|
_hits = "count"
|
|
@@ -475,9 +454,9 @@ class LcovCoverageReporter(BaseViolationReporter):
|
|
|
475
454
|
if not has_da_directive:
|
|
476
455
|
# No line execution data, use branch coverage
|
|
477
456
|
if info["total"] > 0 and info["hit"] < info["total"]:
|
|
478
|
-
lcov_report[source_file][
|
|
479
|
-
|
|
480
|
-
|
|
457
|
+
lcov_report[source_file][line_no] = (
|
|
458
|
+
0 # Partial branch coverage
|
|
459
|
+
)
|
|
481
460
|
else:
|
|
482
461
|
lcov_report[source_file][line_no] = info["executions"]
|
|
483
462
|
continue
|
|
@@ -955,7 +934,6 @@ class ClangFormatDriver(QualityDriver):
|
|
|
955
934
|
"""
|
|
956
935
|
violations_dict = defaultdict(list)
|
|
957
936
|
for report in reports:
|
|
958
|
-
|
|
959
937
|
matches = list(re.finditer(self.clang_expression, report))
|
|
960
938
|
for match in matches:
|
|
961
939
|
if match is not None:
|