diff-cover 9.0.0__tar.gz → 9.1.1__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.0.0 → diff_cover-9.1.1}/PKG-INFO +28 -1
- {diff_cover-9.0.0 → diff_cover-9.1.1}/README.rst +27 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/diff_cover_tool.py +16 -6
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/diff_reporter.py +48 -19
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/git_diff.py +35 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/pyproject.toml +4 -4
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/test_diff_reporter.py +51 -4
- diff_cover-9.1.1/tests/test_git_diff_file.py +72 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/LICENSE +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/__init__.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/command_runner.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/config_parser.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/diff_quality_tool.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/git_path.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/hook.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/hookspecs.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/report_generator.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/snippets.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/templates/console_coverage_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/templates/console_quality_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/templates/external_style.css +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/templates/html_coverage_report.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/templates/html_quality_report.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/templates/markdown_coverage_report.md +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/templates/markdown_quality_report.md +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/templates/snippet_content.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/templates/snippet_content.md +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/templates/snippet_content.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/templates/snippet_style.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/util.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/violationsreporters/__init__.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/violationsreporters/base.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/violationsreporters/java_violations_reporter.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/diff_cover/violationsreporters/violations_reporter.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/__init__.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/add_console_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/add_html_report.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/changed_console_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/changed_html_report.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/coverage.xml +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/coverage1.xml +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/coverage2.xml +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/delete_console_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/delete_html_report.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/dotnet_coverage.xml +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/dotnet_coverage_console_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/empty.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/empty_pycodestyle_violations.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/external_css_html_report.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/external_style.css +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/git_diff_add.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/git_diff_changed.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/git_diff_code_dupe.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/git_diff_delete.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/git_diff_dotnet.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/git_diff_external_css.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/git_diff_lua.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/git_diff_moved.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/git_diff_mult.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/git_diff_subdir.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/git_diff_unicode.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/git_diff_violations.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/git_diff_violations_two_files.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/hello.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/hi.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/html_report.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/html_report_empty.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/html_report_one_snippet.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/html_report_two_snippets.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/lcov.info +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/lua_console_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/luacoverage.xml +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/markdown_report_one_snippet.md +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/markdown_report_two_snippets.md +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/moved_console_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/moved_coverage.xml +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/moved_html_report.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/mult_inputs_console_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/mult_inputs_html_report.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/pycodestyle_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/pycodestyle_violations_report.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/pycodestyle_violations_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/pycodestyle_violations_report_external_css.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/pyflakes_two_files.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/pyflakes_violations_report.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/pyflakes_violations_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/pylint_dupe.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/pylint_dupe_violations_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/pylint_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/pylint_violations_console_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/pylint_violations_report.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/pylint_violations_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/pylintrc +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/show_uncovered_lines_console.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/snippet.css +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/snippet_8859.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/snippet_arabic_output.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/snippet_default.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/snippet_invalid_violations.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/snippet_list.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/snippet_list.md +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/snippet_list2.md +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/snippet_list3.md +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/snippet_no_filename_ext.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/snippet_src.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/snippet_src2.cpp +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/snippet_src3.cpp +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/snippet_unicode.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/snippet_unicode.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/snippet_unicode_html_output.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/subdir_coverage_console_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/subdir_coverage_html_report.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/test_src.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/unicode_console_report.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/unicode_coverage.xml +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/unicode_html_report.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/unicode_test_src.txt +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/fixtures/violations_test_file.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/helpers.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/snippet_list_unicode.html +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/test_clover_violations_reporter/test.xml +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/test_clover_violations_reporter.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/test_config_parser.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/test_diff_cover_main.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/test_diff_cover_tool.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/test_diff_quality_main.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/test_git_diff.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/test_git_path.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/test_integration.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/test_java_violations_reporter.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/test_report_generator.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/test_snippets.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/test_util.py +0 -0
- {diff_cover-9.0.0 → diff_cover-9.1.1}/tests/test_violations_reporter.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: diff_cover
|
|
3
|
-
Version: 9.
|
|
3
|
+
Version: 9.1.1
|
|
4
4
|
Summary: Run coverage and linting reports on diffs
|
|
5
5
|
Home-page: https://github.com/Bachmann1234/diff-cover
|
|
6
6
|
License: Apache-2.0
|
|
@@ -223,6 +223,33 @@ By default, ``diff-cover`` compares the current branch to ``origin/main``. To s
|
|
|
223
223
|
|
|
224
224
|
diff-cover coverage.xml --compare-branch=origin/release
|
|
225
225
|
|
|
226
|
+
Diff File
|
|
227
|
+
--------------
|
|
228
|
+
|
|
229
|
+
You may provide a file containing the output of ``git diff`` to ``diff-cover`` instead of using a branch name.
|
|
230
|
+
|
|
231
|
+
For example, Say you have 2 branches ``main`` and ``feature``. Lets say after creating and checking out the feature branch,
|
|
232
|
+
you make commits ``A``, ``B``, and ``C`` in that order.
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
If you want to see all changes between the ``feature`` and ``main`` branch, you can generate a diff file like this:
|
|
236
|
+
|
|
237
|
+
.. code:: bash
|
|
238
|
+
|
|
239
|
+
git diff main..feature > diff.txt
|
|
240
|
+
|
|
241
|
+
If you want to see the changes between the ``feature`` branch and the commit ``A``, you can generate a diff file using the following command:
|
|
242
|
+
|
|
243
|
+
.. code:: bash
|
|
244
|
+
|
|
245
|
+
git diff A..feature > diff.txt
|
|
246
|
+
|
|
247
|
+
You can then run ``diff-cover`` with the diff file as an argument:
|
|
248
|
+
|
|
249
|
+
.. code:: bash
|
|
250
|
+
|
|
251
|
+
diff-cover coverage.xml --diff-file=diff.txt
|
|
252
|
+
|
|
226
253
|
Fail Under
|
|
227
254
|
----------
|
|
228
255
|
|
|
@@ -190,6 +190,33 @@ By default, ``diff-cover`` compares the current branch to ``origin/main``. To s
|
|
|
190
190
|
|
|
191
191
|
diff-cover coverage.xml --compare-branch=origin/release
|
|
192
192
|
|
|
193
|
+
Diff File
|
|
194
|
+
--------------
|
|
195
|
+
|
|
196
|
+
You may provide a file containing the output of ``git diff`` to ``diff-cover`` instead of using a branch name.
|
|
197
|
+
|
|
198
|
+
For example, Say you have 2 branches ``main`` and ``feature``. Lets say after creating and checking out the feature branch,
|
|
199
|
+
you make commits ``A``, ``B``, and ``C`` in that order.
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
If you want to see all changes between the ``feature`` and ``main`` branch, you can generate a diff file like this:
|
|
203
|
+
|
|
204
|
+
.. code:: bash
|
|
205
|
+
|
|
206
|
+
git diff main..feature > diff.txt
|
|
207
|
+
|
|
208
|
+
If you want to see the changes between the ``feature`` branch and the commit ``A``, you can generate a diff file using the following command:
|
|
209
|
+
|
|
210
|
+
.. code:: bash
|
|
211
|
+
|
|
212
|
+
git diff A..feature > diff.txt
|
|
213
|
+
|
|
214
|
+
You can then run ``diff-cover`` with the diff file as an argument:
|
|
215
|
+
|
|
216
|
+
.. code:: bash
|
|
217
|
+
|
|
218
|
+
diff-cover coverage.xml --diff-file=diff.txt
|
|
219
|
+
|
|
193
220
|
Fail Under
|
|
194
221
|
----------
|
|
195
222
|
|
|
@@ -8,7 +8,7 @@ import xml.etree.ElementTree as etree
|
|
|
8
8
|
from diff_cover import DESCRIPTION, VERSION
|
|
9
9
|
from diff_cover.config_parser import Tool, get_config
|
|
10
10
|
from diff_cover.diff_reporter import GitDiffReporter
|
|
11
|
-
from diff_cover.git_diff import GitDiffTool
|
|
11
|
+
from diff_cover.git_diff import GitDiffFileTool, GitDiffTool
|
|
12
12
|
from diff_cover.git_path import GitPathTool
|
|
13
13
|
from diff_cover.report_generator import (
|
|
14
14
|
HtmlReportGenerator,
|
|
@@ -43,6 +43,7 @@ QUIET_HELP = "Only print errors and failures"
|
|
|
43
43
|
SHOW_UNCOVERED = "Show uncovered lines on the console"
|
|
44
44
|
INCLUDE_UNTRACKED_HELP = "Include untracked files"
|
|
45
45
|
CONFIG_FILE_HELP = "The configuration file to use"
|
|
46
|
+
DIFF_FILE_HELP = "The diff file to use"
|
|
46
47
|
|
|
47
48
|
LOGGER = logging.getLogger(__name__)
|
|
48
49
|
|
|
@@ -169,6 +170,8 @@ def parse_coverage_args(argv):
|
|
|
169
170
|
"-c", "--config-file", help=CONFIG_FILE_HELP, metavar="CONFIG_FILE"
|
|
170
171
|
)
|
|
171
172
|
|
|
173
|
+
parser.add_argument("--diff-file", type=str, default=None, help=DIFF_FILE_HELP)
|
|
174
|
+
|
|
172
175
|
defaults = {
|
|
173
176
|
"show_uncovered": False,
|
|
174
177
|
"compare_branch": "origin/main",
|
|
@@ -188,6 +191,7 @@ def parse_coverage_args(argv):
|
|
|
188
191
|
def generate_coverage_report(
|
|
189
192
|
coverage_files,
|
|
190
193
|
compare_branch,
|
|
194
|
+
diff_tool,
|
|
191
195
|
html_report=None,
|
|
192
196
|
css_file=None,
|
|
193
197
|
json_report=None,
|
|
@@ -198,8 +202,6 @@ def generate_coverage_report(
|
|
|
198
202
|
exclude=None,
|
|
199
203
|
include=None,
|
|
200
204
|
src_roots=None,
|
|
201
|
-
diff_range_notation=None,
|
|
202
|
-
ignore_whitespace=False,
|
|
203
205
|
quiet=False,
|
|
204
206
|
show_uncovered=False,
|
|
205
207
|
):
|
|
@@ -208,7 +210,7 @@ def generate_coverage_report(
|
|
|
208
210
|
"""
|
|
209
211
|
diff = GitDiffReporter(
|
|
210
212
|
compare_branch,
|
|
211
|
-
git_diff=
|
|
213
|
+
git_diff=diff_tool,
|
|
212
214
|
ignore_staged=ignore_staged,
|
|
213
215
|
ignore_unstaged=ignore_unstaged,
|
|
214
216
|
include_untracked=include_untracked,
|
|
@@ -281,9 +283,19 @@ def main(argv=None, directory=None):
|
|
|
281
283
|
|
|
282
284
|
GitPathTool.set_cwd(directory)
|
|
283
285
|
fail_under = arg_dict.get("fail_under")
|
|
286
|
+
diff_tool = None
|
|
287
|
+
|
|
288
|
+
if not arg_dict["diff_file"]:
|
|
289
|
+
diff_tool = GitDiffTool(
|
|
290
|
+
arg_dict["diff_range_notation"], arg_dict["ignore_whitespace"]
|
|
291
|
+
)
|
|
292
|
+
else:
|
|
293
|
+
diff_tool = GitDiffFileTool(arg_dict["diff_file"])
|
|
294
|
+
|
|
284
295
|
percent_covered = generate_coverage_report(
|
|
285
296
|
arg_dict["coverage_file"],
|
|
286
297
|
arg_dict["compare_branch"],
|
|
298
|
+
diff_tool,
|
|
287
299
|
html_report=arg_dict["html_report"],
|
|
288
300
|
json_report=arg_dict["json_report"],
|
|
289
301
|
markdown_report=arg_dict["markdown_report"],
|
|
@@ -294,8 +306,6 @@ def main(argv=None, directory=None):
|
|
|
294
306
|
exclude=arg_dict["exclude"],
|
|
295
307
|
include=arg_dict["include"],
|
|
296
308
|
src_roots=arg_dict["src_roots"],
|
|
297
|
-
diff_range_notation=arg_dict["diff_range_notation"],
|
|
298
|
-
ignore_whitespace=arg_dict["ignore_whitespace"],
|
|
299
309
|
quiet=quiet,
|
|
300
310
|
show_uncovered=arg_dict["show_uncovered"],
|
|
301
311
|
)
|
|
@@ -165,18 +165,31 @@ class GitDiffReporter(BaseDiffReporter):
|
|
|
165
165
|
|
|
166
166
|
# Get the diff dictionary
|
|
167
167
|
diff_dict = self._git_diff()
|
|
168
|
-
|
|
169
168
|
# include untracked files
|
|
170
169
|
if self._include_untracked:
|
|
171
170
|
for path in self._git_diff_tool.untracked():
|
|
172
|
-
|
|
173
|
-
|
|
171
|
+
if not self._validate_path_to_diff(path):
|
|
172
|
+
continue
|
|
173
|
+
|
|
174
|
+
num_lines = self._get_file_lines(path)
|
|
174
175
|
diff_dict[path] = list(range(1, num_lines + 1))
|
|
175
176
|
|
|
176
177
|
# Return the changed file paths (dict keys)
|
|
177
178
|
# in alphabetical order
|
|
178
179
|
return sorted(diff_dict.keys(), key=lambda x: x.lower())
|
|
179
180
|
|
|
181
|
+
@staticmethod
|
|
182
|
+
def _get_file_lines(path):
|
|
183
|
+
"""
|
|
184
|
+
Return the number of lines in a file.
|
|
185
|
+
"""
|
|
186
|
+
|
|
187
|
+
try:
|
|
188
|
+
with open(path, encoding="utf-8") as file_handle:
|
|
189
|
+
return len(file_handle.readlines())
|
|
190
|
+
except UnicodeDecodeError:
|
|
191
|
+
return 0
|
|
192
|
+
|
|
180
193
|
def lines_changed(self, src_path):
|
|
181
194
|
"""
|
|
182
195
|
See base class docstring.
|
|
@@ -224,23 +237,16 @@ class GitDiffReporter(BaseDiffReporter):
|
|
|
224
237
|
diff_dict = self._parse_diff_str(diff_str)
|
|
225
238
|
|
|
226
239
|
for src_path, (added_lines, deleted_lines) in diff_dict.items():
|
|
227
|
-
if self.
|
|
240
|
+
if not self._validate_path_to_diff(src_path):
|
|
228
241
|
continue
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
# Remove any lines from the dict that have been deleted
|
|
238
|
-
# Include any lines that have been added
|
|
239
|
-
result_dict[src_path] = [
|
|
240
|
-
line
|
|
241
|
-
for line in result_dict.get(src_path, [])
|
|
242
|
-
if line not in deleted_lines
|
|
243
|
-
] + added_lines
|
|
242
|
+
|
|
243
|
+
# Remove any lines from the dict that have been deleted
|
|
244
|
+
# Include any lines that have been added
|
|
245
|
+
result_dict[src_path] = [
|
|
246
|
+
line
|
|
247
|
+
for line in result_dict.get(src_path, [])
|
|
248
|
+
if line not in deleted_lines
|
|
249
|
+
] + added_lines
|
|
244
250
|
|
|
245
251
|
# Eliminate repeats and order line numbers
|
|
246
252
|
for src_path, lines in result_dict.items():
|
|
@@ -252,6 +258,29 @@ class GitDiffReporter(BaseDiffReporter):
|
|
|
252
258
|
# Return the diff cache
|
|
253
259
|
return self._diff_dict
|
|
254
260
|
|
|
261
|
+
def _validate_path_to_diff(self, src_path: str) -> bool:
|
|
262
|
+
"""
|
|
263
|
+
Validate if a path should be included in the diff.
|
|
264
|
+
|
|
265
|
+
Returns True if the path should be included, otherwise False.
|
|
266
|
+
|
|
267
|
+
A path should be excluded if:
|
|
268
|
+
- If the path is excluded
|
|
269
|
+
- If the path has an extension that is not supported
|
|
270
|
+
"""
|
|
271
|
+
|
|
272
|
+
if self._is_path_excluded(src_path):
|
|
273
|
+
return False
|
|
274
|
+
|
|
275
|
+
# If no _supported_extensions provided, or extension present: process
|
|
276
|
+
_, extension = os.path.splitext(src_path)
|
|
277
|
+
extension = extension[1:].lower()
|
|
278
|
+
|
|
279
|
+
if self._supported_extensions and extension not in self._supported_extensions:
|
|
280
|
+
return False
|
|
281
|
+
|
|
282
|
+
return True
|
|
283
|
+
|
|
255
284
|
# Regular expressions used to parse the diff output
|
|
256
285
|
SRC_FILE_RE = re.compile(r'^diff --git "?a/.*"? "?b/([^\n"]*)"?')
|
|
257
286
|
MERGE_CONFLICT_RE = re.compile(r"^diff --cc ([^\n]*)")
|
|
@@ -110,3 +110,38 @@ class GitDiffTool:
|
|
|
110
110
|
if not output:
|
|
111
111
|
return []
|
|
112
112
|
return [line for line in output.splitlines() if line]
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class GitDiffFileTool(GitDiffTool):
|
|
116
|
+
|
|
117
|
+
def __init__(self, diff_file_path):
|
|
118
|
+
|
|
119
|
+
self.diff_file_path = diff_file_path
|
|
120
|
+
super().__init__("...", False)
|
|
121
|
+
|
|
122
|
+
def diff_committed(self, compare_branch="origin/main"):
|
|
123
|
+
"""
|
|
124
|
+
Returns the contents of a diff file.
|
|
125
|
+
|
|
126
|
+
Raises a `GitDiffError` if the file cannot be read.
|
|
127
|
+
"""
|
|
128
|
+
try:
|
|
129
|
+
with open(self.diff_file_path, "r") as file:
|
|
130
|
+
return file.read()
|
|
131
|
+
except IOError as e:
|
|
132
|
+
raise ValueError(
|
|
133
|
+
dedent(
|
|
134
|
+
f"""
|
|
135
|
+
Could not read the diff file. Make sure '{self.diff_file_path}' exists?
|
|
136
|
+
"""
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
def diff_unstaged(self):
|
|
141
|
+
return ""
|
|
142
|
+
|
|
143
|
+
def diff_staged(self):
|
|
144
|
+
return ""
|
|
145
|
+
|
|
146
|
+
def untracked(self):
|
|
147
|
+
return ""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "diff_cover"
|
|
3
|
-
version = "9.
|
|
3
|
+
version = "9.1.1"
|
|
4
4
|
description = "Run coverage and linting reports on diffs"
|
|
5
5
|
authors = ["See Contributors"]
|
|
6
6
|
homepage = "https://github.com/Bachmann1234/diff-cover"
|
|
@@ -55,10 +55,10 @@ pytest-mock = "^3.14.0"
|
|
|
55
55
|
pycodestyle = ">=2.9.1"
|
|
56
56
|
flake8 = "^5.0.4"
|
|
57
57
|
pyflakes = "^2.5.0"
|
|
58
|
-
pylint = "^3.
|
|
59
|
-
pylint-pytest = "^1.1.
|
|
58
|
+
pylint = "^3.2.5"
|
|
59
|
+
pylint-pytest = "^1.1.8"
|
|
60
60
|
pydocstyle = "^6.1.1"
|
|
61
|
-
black = "^24.
|
|
61
|
+
black = "^24.4.2"
|
|
62
62
|
isort = "^5.13.2"
|
|
63
63
|
doc8 = "1.1.1"
|
|
64
64
|
|
|
@@ -618,16 +618,63 @@ def test_include_untracked(mocker, git_diff):
|
|
|
618
618
|
{"subdir/file1.py": line_numbers(3, 10) + line_numbers(34, 47)}
|
|
619
619
|
)
|
|
620
620
|
_set_git_diff_output(
|
|
621
|
-
reporter,
|
|
621
|
+
reporter,
|
|
622
|
+
git_diff,
|
|
623
|
+
staged_diff=diff_output,
|
|
624
|
+
untracked=["u1.py", " u2.py", "binary1.bin"],
|
|
622
625
|
)
|
|
623
626
|
|
|
624
|
-
|
|
625
|
-
|
|
627
|
+
base_open_mock = mocker.mock_open(read_data="1\n2\n3\n")
|
|
628
|
+
raise_count = 0
|
|
629
|
+
|
|
630
|
+
def open_side_effect(*args, **kwargs):
|
|
631
|
+
if args[0] == "binary1.bin":
|
|
632
|
+
nonlocal raise_count
|
|
633
|
+
raise_count += 1
|
|
634
|
+
|
|
635
|
+
raise UnicodeDecodeError("utf-8", b"", 0, 1, "invalid start byte")
|
|
636
|
+
return base_open_mock(*args, **kwargs)
|
|
637
|
+
|
|
638
|
+
mocker.patch("diff_cover.diff_reporter.open", open_side_effect)
|
|
626
639
|
changed = reporter.src_paths_changed()
|
|
627
640
|
|
|
628
|
-
assert sorted(changed) == [" u2.py", "subdir/file1.py", "u1.py"]
|
|
641
|
+
assert sorted(changed) == [" u2.py", "binary1.bin", "subdir/file1.py", "u1.py"]
|
|
629
642
|
assert reporter.lines_changed("u1.py") == [1, 2, 3]
|
|
630
643
|
assert reporter.lines_changed(" u2.py") == [1, 2, 3]
|
|
644
|
+
assert reporter.lines_changed("binary1.bin") == []
|
|
645
|
+
|
|
646
|
+
assert raise_count == 1
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
@pytest.mark.parametrize(
|
|
650
|
+
"excluded, supported_extensions, path",
|
|
651
|
+
[
|
|
652
|
+
(["file.bin"], ["py"], "file.bin"),
|
|
653
|
+
([], ["py"], "file.bin"),
|
|
654
|
+
],
|
|
655
|
+
)
|
|
656
|
+
def test_include_untracked__not_valid_path__not_include_it(
|
|
657
|
+
git_diff, excluded, supported_extensions, path
|
|
658
|
+
):
|
|
659
|
+
reporter = GitDiffReporter(
|
|
660
|
+
git_diff=git_diff,
|
|
661
|
+
include_untracked=True,
|
|
662
|
+
supported_extensions=supported_extensions,
|
|
663
|
+
exclude=excluded,
|
|
664
|
+
)
|
|
665
|
+
diff_output = git_diff_output(
|
|
666
|
+
{"subdir/file1.py": line_numbers(3, 10) + line_numbers(34, 47)}
|
|
667
|
+
)
|
|
668
|
+
_set_git_diff_output(
|
|
669
|
+
reporter,
|
|
670
|
+
git_diff,
|
|
671
|
+
staged_diff=diff_output,
|
|
672
|
+
untracked=[path],
|
|
673
|
+
)
|
|
674
|
+
|
|
675
|
+
changed = reporter.src_paths_changed()
|
|
676
|
+
|
|
677
|
+
assert sorted(changed) == ["subdir/file1.py"]
|
|
631
678
|
|
|
632
679
|
|
|
633
680
|
def _set_git_diff_output(
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# pylint: disable=missing-function-docstring
|
|
2
|
+
|
|
3
|
+
"""Test for diff_cover.git_diff.GitDiffFileTool"""
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from diff_cover.git_diff import GitDiffFileTool
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture
|
|
11
|
+
def mock_file(mocker):
|
|
12
|
+
def _inner(file_content):
|
|
13
|
+
mock_open = mocker.mock_open(read_data=file_content)
|
|
14
|
+
mocker.patch("builtins.open", mock_open)
|
|
15
|
+
|
|
16
|
+
return _inner
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@pytest.fixture
|
|
20
|
+
def diff_tool():
|
|
21
|
+
def _inner(file):
|
|
22
|
+
return GitDiffFileTool(file)
|
|
23
|
+
|
|
24
|
+
return _inner
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_diff_file_not_found(mocker, diff_tool):
|
|
28
|
+
mocker.patch("builtins.open", side_effect=IOError)
|
|
29
|
+
|
|
30
|
+
_diff_tool = diff_tool("non_existent_diff_file.txt")
|
|
31
|
+
|
|
32
|
+
with pytest.raises(ValueError) as excinfo:
|
|
33
|
+
_diff_tool.diff_committed()
|
|
34
|
+
|
|
35
|
+
assert (
|
|
36
|
+
f"Could not read the diff file. Make sure '{_diff_tool.diff_file_path}' exists?"
|
|
37
|
+
in str(excinfo.value)
|
|
38
|
+
)
|
|
39
|
+
assert _diff_tool.diff_file_path == "non_existent_diff_file.txt"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_large_diff_file(mock_file, diff_tool):
|
|
43
|
+
large_diff = "diff --git a/file1 b/file2\n" * 1000000
|
|
44
|
+
|
|
45
|
+
mock_file(large_diff)
|
|
46
|
+
|
|
47
|
+
_diff_tool = diff_tool("large_diff_file.txt")
|
|
48
|
+
|
|
49
|
+
assert _diff_tool.diff_committed() == large_diff
|
|
50
|
+
assert _diff_tool.diff_file_path == "large_diff_file.txt"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def test_diff_committed(mock_file, diff_tool):
|
|
54
|
+
diff = "diff --git a/file1 b/file2\n"
|
|
55
|
+
|
|
56
|
+
mock_file(diff)
|
|
57
|
+
|
|
58
|
+
_diff_tool = diff_tool("diff_file.txt")
|
|
59
|
+
|
|
60
|
+
assert _diff_tool.diff_committed() == diff
|
|
61
|
+
assert _diff_tool.diff_file_path == "diff_file.txt"
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def test_empty_diff_file(mock_file, diff_tool):
|
|
65
|
+
empty_diff = ""
|
|
66
|
+
|
|
67
|
+
mock_file(empty_diff)
|
|
68
|
+
|
|
69
|
+
_diff_tool = diff_tool("empty_diff.txt")
|
|
70
|
+
|
|
71
|
+
assert _diff_tool.diff_committed() == empty_diff
|
|
72
|
+
assert _diff_tool.diff_file_path == "empty_diff.txt"
|
|
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.0.0 → diff_cover-9.1.1}/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
|
{diff_cover-9.0.0 → diff_cover-9.1.1}/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
|