diff-cover 9.4.1__tar.gz → 9.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-9.4.1 → diff_cover-9.6.0}/PKG-INFO +2 -2
- {diff_cover-9.4.1 → diff_cover-9.6.0}/README.rst +1 -1
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/diff_cover_tool.py +11 -1
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/diff_quality_tool.py +2 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/report_generator.py +21 -0
- diff_cover-9.6.0/diff_cover/templates/github_coverage_annotations.txt +10 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/violationsreporters/violations_reporter.py +64 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/pyproject.toml +1 -1
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/test_integration.py +91 -11
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/test_report_generator.py +59 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/test_violations_reporter.py +21 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/LICENSE +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/NOTICE +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/__init__.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/command_runner.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/config_parser.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/diff_reporter.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/git_diff.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/git_path.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/hook.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/hookspecs.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/snippets.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/templates/console_coverage_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/templates/console_quality_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/templates/external_style.css +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/templates/html_coverage_report.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/templates/html_quality_report.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/templates/markdown_coverage_report.md +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/templates/markdown_quality_report.md +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/templates/snippet_content.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/templates/snippet_content.md +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/templates/snippet_content.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/templates/snippet_style.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/util.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/violationsreporters/__init__.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/violationsreporters/base.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/violationsreporters/java_violations_reporter.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/__init__.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/add_console_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/add_html_report.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/add_json_report.json +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/add_markdown_report.md +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/changed_console_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/changed_html_report.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/coverage.xml +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/coverage1.xml +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/coverage2.xml +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/coverage_missing_lines.xml +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/cpp_functions_console_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/cpp_functions_coverage.lcov +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/delete_console_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/delete_html_report.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/dotnet_coverage.xml +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/dotnet_coverage_console_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/empty.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/empty_pycodestyle_violations.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/expand_console_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/external_css_html_report.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/external_style.css +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_add.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_changed.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_code_dupe.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_cpp.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_cpp_functions.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_delete.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_dotnet.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_external_css.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_lua.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_moved.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_mult.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_python.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_subdir.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_typescript.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_typescript_branches.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_unicode.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_violations.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/git_diff_violations_two_files.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/hello.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/hi.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/html_report.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/html_report_empty.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/html_report_one_snippet.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/html_report_two_snippets.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/lcov.info +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/lua_console_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/luacoverage.xml +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/markdown_report_one_snippet.md +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/markdown_report_two_snippets.md +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/moved_console_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/moved_coverage.xml +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/moved_html_report.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/mult_inputs_console_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/mult_inputs_html_report.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pycodestyle_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pycodestyle_violations_report.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pycodestyle_violations_report.json +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pycodestyle_violations_report.md +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pycodestyle_violations_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pycodestyle_violations_report_external_css.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pyflakes_two_files.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pyflakes_violations_report.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pyflakes_violations_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pylint_dupe.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pylint_dupe_violations_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pylint_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pylint_violations_console_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pylint_violations_report.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pylint_violations_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pylintrc +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/real_cpp_console_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/real_cpp_coverage.lcov +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/real_python_console_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/real_python_coverage.lcov +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/real_typescript_console_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/real_typescript_coverage.lcov +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/show_uncovered_lines_console.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/snippet.css +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/snippet_8859.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/snippet_arabic_output.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/snippet_default.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/snippet_invalid_violations.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/snippet_list.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/snippet_list.md +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/snippet_list2.md +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/snippet_list3.md +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/snippet_no_filename_ext.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/snippet_src.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/snippet_src2.cpp +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/snippet_src3.cpp +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/snippet_unicode.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/snippet_unicode.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/snippet_unicode_html_output.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/subdir_coverage_console_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/subdir_coverage_html_report.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/test_src.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/typescript_branches_console_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/typescript_branches_coverage.lcov +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/unicode_console_report.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/unicode_coverage.xml +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/unicode_html_report.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/unicode_test_src.txt +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/violations_test_file.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/helpers.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/snippet_list_unicode.html +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/test_clover_violations_reporter/test.xml +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/test_clover_violations_reporter.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/test_config_parser.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/test_diff_cover_main.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/test_diff_cover_tool.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/test_diff_quality_main.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/test_diff_reporter.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/test_git_diff.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/test_git_diff_file.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/test_git_path.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/test_java_violations_reporter.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/test_snippets.py +0 -0
- {diff_cover-9.4.1 → diff_cover-9.6.0}/tests/test_util.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: diff_cover
|
|
3
|
-
Version: 9.
|
|
3
|
+
Version: 9.6.0
|
|
4
4
|
Summary: Run coverage and linting reports on diffs
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Author: See Contributors
|
|
@@ -161,7 +161,7 @@ You can use diff-cover to see quality reports on the diff as well by running
|
|
|
161
161
|
diff-quality --violations=<tool>
|
|
162
162
|
|
|
163
163
|
Where ``tool`` is the quality checker to use. Currently ``pycodestyle``, ``pyflakes``,
|
|
164
|
-
``flake8``, ``pylint``, ``checkstyle``, ``checkstylexml``, ``ruff
|
|
164
|
+
``flake8``, ``pylint``, ``checkstyle``, ``checkstylexml``, ``ruff.check``, ``clang`` are supported, but more
|
|
165
165
|
checkers can (and should!) be supported. See the section "Adding `diff-quality``
|
|
166
166
|
Support for a New Quality Checker".
|
|
167
167
|
|
|
@@ -129,7 +129,7 @@ You can use diff-cover to see quality reports on the diff as well by running
|
|
|
129
129
|
diff-quality --violations=<tool>
|
|
130
130
|
|
|
131
131
|
Where ``tool`` is the quality checker to use. Currently ``pycodestyle``, ``pyflakes``,
|
|
132
|
-
``flake8``, ``pylint``, ``checkstyle``, ``checkstylexml``, ``ruff
|
|
132
|
+
``flake8``, ``pylint``, ``checkstyle``, ``checkstylexml``, ``ruff.check``, ``clang`` are supported, but more
|
|
133
133
|
checkers can (and should!) be supported. See the section "Adding `diff-quality``
|
|
134
134
|
Support for a New Quality Checker".
|
|
135
135
|
|
|
@@ -12,6 +12,7 @@ from diff_cover.diff_reporter import GitDiffReporter
|
|
|
12
12
|
from diff_cover.git_diff import GitDiffFileTool, GitDiffTool
|
|
13
13
|
from diff_cover.git_path import GitPathTool
|
|
14
14
|
from diff_cover.report_generator import (
|
|
15
|
+
GitHubAnnotationsReportGenerator,
|
|
15
16
|
HtmlReportGenerator,
|
|
16
17
|
JsonReportGenerator,
|
|
17
18
|
MarkdownReportGenerator,
|
|
@@ -266,9 +267,18 @@ def generate_coverage_report(
|
|
|
266
267
|
if "markdown" in report_formats:
|
|
267
268
|
markdown_report = report_formats["markdown"] or MARKDOWN_REPORT_DEFAULT_PATH
|
|
268
269
|
reporter = MarkdownReportGenerator(coverage, diff)
|
|
269
|
-
with
|
|
270
|
+
with open_file(markdown_report, "wb") as output_file:
|
|
270
271
|
reporter.generate_report(output_file)
|
|
271
272
|
|
|
273
|
+
if "github-annotations" in report_formats:
|
|
274
|
+
# Github annotations are always written to stdout, but we can use different types
|
|
275
|
+
reporter = GitHubAnnotationsReportGenerator(
|
|
276
|
+
coverage,
|
|
277
|
+
diff,
|
|
278
|
+
report_formats["github-annotations"],
|
|
279
|
+
)
|
|
280
|
+
reporter.generate_report(sys.stdout.buffer)
|
|
281
|
+
|
|
272
282
|
# Generate the report for stdout
|
|
273
283
|
reporter = StringReportGenerator(coverage, diff, show_uncovered)
|
|
274
284
|
output_file = io.BytesIO() if quiet else sys.stdout.buffer
|
|
@@ -50,6 +50,7 @@ from diff_cover.violationsreporters.java_violations_reporter import (
|
|
|
50
50
|
checkstyle_driver,
|
|
51
51
|
)
|
|
52
52
|
from diff_cover.violationsreporters.violations_reporter import (
|
|
53
|
+
ClangFormatDriver,
|
|
53
54
|
CppcheckDriver,
|
|
54
55
|
EslintDriver,
|
|
55
56
|
PylintDriver,
|
|
@@ -63,6 +64,7 @@ from diff_cover.violationsreporters.violations_reporter import (
|
|
|
63
64
|
)
|
|
64
65
|
|
|
65
66
|
QUALITY_DRIVERS = {
|
|
67
|
+
"clang": ClangFormatDriver(),
|
|
66
68
|
"cppcheck": CppcheckDriver(),
|
|
67
69
|
"pycodestyle": pycodestyle_driver,
|
|
68
70
|
"pyflakes": pyflakes_driver,
|
|
@@ -420,6 +420,27 @@ class StringReportGenerator(TemplateReportGenerator):
|
|
|
420
420
|
self.include_snippets = show_uncovered
|
|
421
421
|
|
|
422
422
|
|
|
423
|
+
class GitHubAnnotationsReportGenerator(TemplateReportGenerator):
|
|
424
|
+
"""
|
|
425
|
+
Generate a diff coverage report for GitHub annotations.
|
|
426
|
+
https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-debug-message
|
|
427
|
+
https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-notice-message
|
|
428
|
+
https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message
|
|
429
|
+
https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
|
|
430
|
+
"""
|
|
431
|
+
|
|
432
|
+
template_path = "github_coverage_annotations.txt"
|
|
433
|
+
|
|
434
|
+
def __init__(self, violations_reporter, diff_reporter, annotations_type):
|
|
435
|
+
super().__init__(violations_reporter, diff_reporter)
|
|
436
|
+
self.annotations_type = annotations_type
|
|
437
|
+
|
|
438
|
+
def _context(self):
|
|
439
|
+
context = super().report_dict()
|
|
440
|
+
context.update({"annotations_type": self.annotations_type})
|
|
441
|
+
return context
|
|
442
|
+
|
|
443
|
+
|
|
423
444
|
class HtmlReportGenerator(TemplateReportGenerator):
|
|
424
445
|
"""
|
|
425
446
|
Generate an HTML formatted diff coverage report.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{% if src_stats %}
|
|
2
|
+
{% for src_path, stats in src_stats|dictsort %}
|
|
3
|
+
{% if stats.percent_covered < 100 %}
|
|
4
|
+
{% for line in stats.violation_lines %}
|
|
5
|
+
{% set splitLines = line.split("-") %}
|
|
6
|
+
::{{ annotations_type }} file={{ src_path }},line={{ splitLines[0] }}{% if splitLines[1] %},endLine={{ splitLines[1] }}{% endif %},title=Missing Coverage::Line {{ line }} missing coverage
|
|
7
|
+
{% endfor %}
|
|
8
|
+
{% endif %}
|
|
9
|
+
{% endfor %}
|
|
10
|
+
{% endif %}
|
|
@@ -831,3 +831,67 @@ class CppcheckDriver(QualityDriver):
|
|
|
831
831
|
Returns: boolean True if installed
|
|
832
832
|
"""
|
|
833
833
|
return run_command_for_code(self.command_to_check_install) == 0
|
|
834
|
+
|
|
835
|
+
|
|
836
|
+
class ClangFormatDriver(QualityDriver):
|
|
837
|
+
"""
|
|
838
|
+
Driver for clang-format
|
|
839
|
+
"""
|
|
840
|
+
|
|
841
|
+
def __init__(self):
|
|
842
|
+
"""
|
|
843
|
+
args:
|
|
844
|
+
expression: regex used to parse report
|
|
845
|
+
See super for other args
|
|
846
|
+
"""
|
|
847
|
+
super().__init__(
|
|
848
|
+
"clang",
|
|
849
|
+
["c", "cpp", "h", "hpp"],
|
|
850
|
+
["clang-format", "--dry-run"], # Use dry-run option to not modify files
|
|
851
|
+
output_stderr=True,
|
|
852
|
+
)
|
|
853
|
+
|
|
854
|
+
# Errors look like:
|
|
855
|
+
# src/foo.c:8:1: warning: code should be clang-formatted [-Wclang-format-violations]
|
|
856
|
+
# int foo;
|
|
857
|
+
# ^
|
|
858
|
+
# Match for everything, including ":" in the file name (first capturing
|
|
859
|
+
# group), in case there are pathological path names with ":"
|
|
860
|
+
self.clang_expression = re.compile(
|
|
861
|
+
r"^(.*?):(\d+):\d+: ([^[]* \[[^]]*\])\n(.+)\n(.+)$",
|
|
862
|
+
re.MULTILINE,
|
|
863
|
+
)
|
|
864
|
+
self.command_to_check_install = ["clang-format", "--version"]
|
|
865
|
+
|
|
866
|
+
def parse_reports(self, reports):
|
|
867
|
+
"""
|
|
868
|
+
Args:
|
|
869
|
+
reports: list[str] - output from the report
|
|
870
|
+
Return:
|
|
871
|
+
A dict[Str:Violation]
|
|
872
|
+
Violation is a simple named tuple Defined above
|
|
873
|
+
"""
|
|
874
|
+
violations_dict = defaultdict(list)
|
|
875
|
+
for report in reports:
|
|
876
|
+
|
|
877
|
+
matches = list(re.finditer(self.clang_expression, report))
|
|
878
|
+
for match in matches:
|
|
879
|
+
if match is not None:
|
|
880
|
+
(
|
|
881
|
+
clang_src_path,
|
|
882
|
+
line_number,
|
|
883
|
+
message,
|
|
884
|
+
code_extract,
|
|
885
|
+
cursor_error,
|
|
886
|
+
) = match.groups()
|
|
887
|
+
full_message = f"{message}\n{code_extract}\n{cursor_error}"
|
|
888
|
+
violation = Violation(int(line_number), full_message)
|
|
889
|
+
violations_dict[clang_src_path].append(violation)
|
|
890
|
+
return violations_dict
|
|
891
|
+
|
|
892
|
+
def installed(self):
|
|
893
|
+
"""
|
|
894
|
+
Method checks if the provided tool is installed.
|
|
895
|
+
Returns: boolean True if installed
|
|
896
|
+
"""
|
|
897
|
+
return run_command_for_code(self.command_to_check_install) == 0
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
# pylint: disable=use-implicit-booleaness-not-comparison
|
|
3
3
|
|
|
4
4
|
"""High-level integration tests of diff-cover tool."""
|
|
5
|
-
|
|
6
5
|
import json
|
|
7
6
|
import os
|
|
8
7
|
import os.path
|
|
9
8
|
import re
|
|
10
9
|
import shutil
|
|
10
|
+
import textwrap
|
|
11
11
|
from collections import defaultdict
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
from subprocess import Popen
|
|
@@ -96,21 +96,23 @@ def patch_git_command(patch_popen, mocker):
|
|
|
96
96
|
return helper
|
|
97
97
|
|
|
98
98
|
|
|
99
|
+
def clean_html(html, clear_inline_css):
|
|
100
|
+
if clear_inline_css:
|
|
101
|
+
html = re.sub("<style>.*</style>", "", html, flags=re.DOTALL)
|
|
102
|
+
return html.strip()
|
|
103
|
+
|
|
104
|
+
|
|
99
105
|
def compare_html(expected_html_path, html_report_path, clear_inline_css=True):
|
|
100
|
-
clean_content = re.compile("<style>.*</style>", flags=re.DOTALL)
|
|
101
106
|
expected_file = open(expected_html_path, encoding="utf-8")
|
|
102
107
|
html_report = open(html_report_path, encoding="utf-8")
|
|
103
108
|
|
|
104
109
|
with expected_file, html_report:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
html = clean_content.sub("", html)
|
|
112
|
-
expected = clean_content.sub("", expected)
|
|
113
|
-
assert expected.strip() == html.strip()
|
|
110
|
+
# The CSS is provided by pygments and changes fairly often.
|
|
111
|
+
# Im ok with simply saying "There was css"
|
|
112
|
+
# Perhaps I will eat these words
|
|
113
|
+
html = clean_html(html_report.read(), clear_inline_css)
|
|
114
|
+
expected = clean_html(expected_file.read(), clear_inline_css)
|
|
115
|
+
assert expected == html
|
|
114
116
|
|
|
115
117
|
|
|
116
118
|
def compare_markdown(expected_file_path, actual_file_path):
|
|
@@ -179,6 +181,36 @@ class TestDiffCoverIntegration:
|
|
|
179
181
|
compare_json("add_json_report.json", "dummy/diff_coverage.json")
|
|
180
182
|
compare_markdown("add_markdown_report.md", "dummy/diff_coverage.md")
|
|
181
183
|
|
|
184
|
+
def test_all_reports_with_stdout(self, runbin, patch_git_command, capsys):
|
|
185
|
+
patch_git_command.set_stdout("git_diff_add.txt")
|
|
186
|
+
assert (
|
|
187
|
+
runbin(
|
|
188
|
+
[
|
|
189
|
+
"coverage.xml",
|
|
190
|
+
"--format",
|
|
191
|
+
"html:-,json:-,markdown:-",
|
|
192
|
+
]
|
|
193
|
+
)
|
|
194
|
+
== 0
|
|
195
|
+
)
|
|
196
|
+
output = capsys.readouterr().out
|
|
197
|
+
with open("add_console_report.txt", "r", encoding="utf-8") as f:
|
|
198
|
+
actual = f.read()
|
|
199
|
+
assert actual in output
|
|
200
|
+
with open("add_html_report.html", "r", encoding="utf-8") as f:
|
|
201
|
+
actual = clean_html(f.read(), clear_inline_css=True)
|
|
202
|
+
# can't compare the output inside <head> since it changes
|
|
203
|
+
# a lot so we just compare the body
|
|
204
|
+
actual = actual[actual.find("</head>") :]
|
|
205
|
+
assert len(actual) > 20
|
|
206
|
+
assert actual in output
|
|
207
|
+
with open("add_json_report.json", "r", encoding="utf-8") as f:
|
|
208
|
+
actual = json.dumps(json.loads(f.read()))
|
|
209
|
+
assert actual in output
|
|
210
|
+
with open("add_markdown_report.md", "r", encoding="utf-8") as f:
|
|
211
|
+
actual = f.read()
|
|
212
|
+
assert actual in output
|
|
213
|
+
|
|
182
214
|
def test_added_file_console_lcov(self, runbin, patch_git_command, capsys):
|
|
183
215
|
patch_git_command.set_stdout("git_diff_add.txt")
|
|
184
216
|
assert runbin(["lcov.info"]) == 0
|
|
@@ -397,6 +429,54 @@ class TestDiffCoverIntegration:
|
|
|
397
429
|
assert runbin(["coverage_missing_lines.xml", "--expand-coverage-report"]) == 0
|
|
398
430
|
compare_console("expand_console_report.txt", capsys.readouterr().out)
|
|
399
431
|
|
|
432
|
+
def test_github_silent(self, runbin, patch_git_command, capsys):
|
|
433
|
+
patch_git_command.set_stdout("git_diff_add.txt")
|
|
434
|
+
assert (
|
|
435
|
+
runbin(["coverage.xml", "--format", "github-annotations:notice", "-q"]) == 0
|
|
436
|
+
)
|
|
437
|
+
expected = textwrap.dedent(
|
|
438
|
+
"""\
|
|
439
|
+
::notice file=test_src.txt,line=2,title=Missing Coverage::Line 2 missing coverage
|
|
440
|
+
::notice file=test_src.txt,line=4,title=Missing Coverage::Line 4 missing coverage
|
|
441
|
+
::notice file=test_src.txt,line=6,title=Missing Coverage::Line 6 missing coverage
|
|
442
|
+
::notice file=test_src.txt,line=8,title=Missing Coverage::Line 8 missing coverage
|
|
443
|
+
::notice file=test_src.txt,line=10,title=Missing Coverage::Line 10 missing coverage
|
|
444
|
+
"""
|
|
445
|
+
)
|
|
446
|
+
assert capsys.readouterr().out == expected
|
|
447
|
+
|
|
448
|
+
@pytest.mark.usefixtures("patch_git_command")
|
|
449
|
+
def test_github_fully_covered(self, runbin, capsys):
|
|
450
|
+
assert runbin(["coverage2.xml", "--format", "github-annotations:notice"]) == 0
|
|
451
|
+
expected = textwrap.dedent(
|
|
452
|
+
"""\
|
|
453
|
+
-------------
|
|
454
|
+
Diff Coverage
|
|
455
|
+
Diff: origin/main...HEAD, staged and unstaged changes
|
|
456
|
+
-------------
|
|
457
|
+
No lines with coverage information in this diff.
|
|
458
|
+
-------------
|
|
459
|
+
|
|
460
|
+
"""
|
|
461
|
+
)
|
|
462
|
+
assert capsys.readouterr().out == expected
|
|
463
|
+
|
|
464
|
+
def test_github_empty_diff(self, runbin, patch_git_command, capsys):
|
|
465
|
+
patch_git_command.set_stdout("")
|
|
466
|
+
assert runbin(["coverage.xml", "--format", "github-annotations:notice"]) == 0
|
|
467
|
+
expected = textwrap.dedent(
|
|
468
|
+
"""\
|
|
469
|
+
-------------
|
|
470
|
+
Diff Coverage
|
|
471
|
+
Diff: origin/main...HEAD, staged and unstaged changes
|
|
472
|
+
-------------
|
|
473
|
+
No lines with coverage information in this diff.
|
|
474
|
+
-------------
|
|
475
|
+
|
|
476
|
+
"""
|
|
477
|
+
)
|
|
478
|
+
assert capsys.readouterr().out == expected
|
|
479
|
+
|
|
400
480
|
def test_real_world_cpp_lcov_coverage(self, runbin, patch_git_command, capsys):
|
|
401
481
|
"""Test with real C++ LCOV coverage data"""
|
|
402
482
|
# Create git diff for C++ files
|
|
@@ -10,6 +10,7 @@ import pytest
|
|
|
10
10
|
from diff_cover.diff_reporter import BaseDiffReporter
|
|
11
11
|
from diff_cover.report_generator import (
|
|
12
12
|
BaseReportGenerator,
|
|
13
|
+
GitHubAnnotationsReportGenerator,
|
|
13
14
|
HtmlReportGenerator,
|
|
14
15
|
JsonReportGenerator,
|
|
15
16
|
MarkdownReportGenerator,
|
|
@@ -407,6 +408,64 @@ class TestStringReportGenerator(BaseReportGeneratorTest):
|
|
|
407
408
|
self.assert_report(expected)
|
|
408
409
|
|
|
409
410
|
|
|
411
|
+
class TestGitHubAnnotationsReportGenerator(BaseReportGeneratorTest):
|
|
412
|
+
|
|
413
|
+
@pytest.fixture
|
|
414
|
+
def report(self, coverage, diff):
|
|
415
|
+
# Create a concrete instance of a report generator
|
|
416
|
+
return GitHubAnnotationsReportGenerator(coverage, diff, "warning")
|
|
417
|
+
|
|
418
|
+
@pytest.mark.usefixtures("use_default_values")
|
|
419
|
+
def test_generate_report(self):
|
|
420
|
+
# Verify that we got the expected string
|
|
421
|
+
expected = dedent(
|
|
422
|
+
"""
|
|
423
|
+
::warning file=file1.py,line=10,endLine=11,title=Missing Coverage::Line 10-11 missing coverage
|
|
424
|
+
::warning file=subdir/file2.py,line=10,endLine=11,title=Missing Coverage::Line 10-11 missing coverage
|
|
425
|
+
"""
|
|
426
|
+
).strip()
|
|
427
|
+
|
|
428
|
+
self.assert_report(expected)
|
|
429
|
+
|
|
430
|
+
def test_single_line(
|
|
431
|
+
self, diff, diff_lines_changed, coverage_violations, coverage_measured_lines
|
|
432
|
+
):
|
|
433
|
+
diff.src_paths_changed.return_value = ["file.py"]
|
|
434
|
+
diff_lines_changed.update({"file.py": list(range(100))})
|
|
435
|
+
coverage_violations.update({"file.py": [Violation(10, None)]})
|
|
436
|
+
coverage_measured_lines.update({"file.py": [2]})
|
|
437
|
+
|
|
438
|
+
# Verify that we got the expected string
|
|
439
|
+
expected = dedent(
|
|
440
|
+
"""
|
|
441
|
+
::warning file=file.py,line=10,title=Missing Coverage::Line 10 missing coverage
|
|
442
|
+
"""
|
|
443
|
+
).strip()
|
|
444
|
+
|
|
445
|
+
self.assert_report(expected)
|
|
446
|
+
|
|
447
|
+
def test_hundred_percent(
|
|
448
|
+
self, diff, diff_lines_changed, coverage_violations, coverage_measured_lines
|
|
449
|
+
):
|
|
450
|
+
# Have the dependencies return an empty report
|
|
451
|
+
diff.src_paths_changed.return_value = ["file.py"]
|
|
452
|
+
diff_lines_changed.update({"file.py": list(range(100))})
|
|
453
|
+
coverage_violations.update({"file.py": []})
|
|
454
|
+
coverage_measured_lines.update({"file.py": [2]})
|
|
455
|
+
|
|
456
|
+
expected = ""
|
|
457
|
+
|
|
458
|
+
self.assert_report(expected)
|
|
459
|
+
|
|
460
|
+
def test_empty_report(self):
|
|
461
|
+
# Have the dependencies return an empty report
|
|
462
|
+
# (this is the default)
|
|
463
|
+
|
|
464
|
+
expected = ""
|
|
465
|
+
|
|
466
|
+
self.assert_report(expected)
|
|
467
|
+
|
|
468
|
+
|
|
410
469
|
class TestHtmlReportGenerator(BaseReportGeneratorTest):
|
|
411
470
|
|
|
412
471
|
@pytest.fixture
|
|
@@ -17,6 +17,7 @@ from diff_cover.command_runner import CommandError, run_command_for_code
|
|
|
17
17
|
from diff_cover.violationsreporters import base
|
|
18
18
|
from diff_cover.violationsreporters.base import QualityReporter
|
|
19
19
|
from diff_cover.violationsreporters.violations_reporter import (
|
|
20
|
+
ClangFormatDriver,
|
|
20
21
|
CppcheckDriver,
|
|
21
22
|
EslintDriver,
|
|
22
23
|
LcovCoverageReporter,
|
|
@@ -2238,3 +2239,23 @@ class TestRuffCheckQualityDriverTest:
|
|
|
2238
2239
|
|
|
2239
2240
|
assert quality.name() == "ruff.check"
|
|
2240
2241
|
assert actual_violations == expected_violations
|
|
2242
|
+
|
|
2243
|
+
|
|
2244
|
+
class TestClangFormatcheckQualityDriverTest:
|
|
2245
|
+
"""Tests for clang-format quality driver."""
|
|
2246
|
+
|
|
2247
|
+
def test_parse_report(self):
|
|
2248
|
+
"""Basic report test parse"""
|
|
2249
|
+
expected_violations = {
|
|
2250
|
+
"src/foo.c": [
|
|
2251
|
+
Violation(
|
|
2252
|
+
12,
|
|
2253
|
+
"warning: code should be clang-formatted [-Wclang-format-violations]\n int bar;\n ^",
|
|
2254
|
+
),
|
|
2255
|
+
]
|
|
2256
|
+
}
|
|
2257
|
+
report = "src/foo.c:12:1: warning: code should be clang-formatted [-Wclang-format-violations]\n int bar;\n ^"
|
|
2258
|
+
|
|
2259
|
+
driver = ClangFormatDriver()
|
|
2260
|
+
actual_violations = driver.parse_reports([report])
|
|
2261
|
+
assert actual_violations == expected_violations
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{diff_cover-9.4.1 → diff_cover-9.6.0}/diff_cover/violationsreporters/java_violations_reporter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{diff_cover-9.4.1 → diff_cover-9.6.0}/tests/fixtures/pycodestyle_violations_report_external_css.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|