diff-cover 8.0.3__tar.gz → 9.1.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.
Files changed (137) hide show
  1. {diff_cover-8.0.3 → diff_cover-9.1.0}/PKG-INFO +28 -1
  2. {diff_cover-8.0.3 → diff_cover-9.1.0}/README.rst +27 -0
  3. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/command_runner.py +5 -3
  4. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/diff_cover_tool.py +16 -6
  5. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/diff_reporter.py +1 -0
  6. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/git_diff.py +36 -0
  7. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/git_path.py +1 -0
  8. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/report_generator.py +1 -0
  9. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/snippets.py +18 -2
  10. {diff_cover-8.0.3 → diff_cover-9.1.0}/pyproject.toml +6 -6
  11. diff_cover-9.1.0/tests/fixtures/snippet_list.md +38 -0
  12. diff_cover-9.1.0/tests/fixtures/snippet_list2.md +10 -0
  13. diff_cover-9.1.0/tests/fixtures/snippet_list3.md +13 -0
  14. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/helpers.py +1 -0
  15. diff_cover-9.1.0/tests/test_git_diff_file.py +72 -0
  16. diff_cover-8.0.3/tests/fixtures/snippet_list.md +0 -38
  17. diff_cover-8.0.3/tests/fixtures/snippet_list2.md +0 -11
  18. diff_cover-8.0.3/tests/fixtures/snippet_list3.md +0 -13
  19. {diff_cover-8.0.3 → diff_cover-9.1.0}/LICENSE +0 -0
  20. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/__init__.py +0 -0
  21. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/config_parser.py +0 -0
  22. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/diff_quality_tool.py +0 -0
  23. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/hook.py +0 -0
  24. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/hookspecs.py +0 -0
  25. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/templates/console_coverage_report.txt +0 -0
  26. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/templates/console_quality_report.txt +0 -0
  27. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/templates/external_style.css +0 -0
  28. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/templates/html_coverage_report.html +0 -0
  29. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/templates/html_quality_report.html +0 -0
  30. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/templates/markdown_coverage_report.md +0 -0
  31. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/templates/markdown_quality_report.md +0 -0
  32. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/templates/snippet_content.html +0 -0
  33. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/templates/snippet_content.md +0 -0
  34. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/templates/snippet_content.txt +0 -0
  35. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/templates/snippet_style.html +0 -0
  36. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/util.py +0 -0
  37. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/violationsreporters/__init__.py +0 -0
  38. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/violationsreporters/base.py +0 -0
  39. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/violationsreporters/java_violations_reporter.py +0 -0
  40. {diff_cover-8.0.3 → diff_cover-9.1.0}/diff_cover/violationsreporters/violations_reporter.py +0 -0
  41. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/__init__.py +0 -0
  42. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/add_console_report.txt +0 -0
  43. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/add_html_report.html +0 -0
  44. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/changed_console_report.txt +0 -0
  45. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/changed_html_report.html +0 -0
  46. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/coverage.xml +0 -0
  47. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/coverage1.xml +0 -0
  48. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/coverage2.xml +0 -0
  49. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/delete_console_report.txt +0 -0
  50. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/delete_html_report.html +0 -0
  51. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/dotnet_coverage.xml +0 -0
  52. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/dotnet_coverage_console_report.txt +0 -0
  53. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/empty.txt +0 -0
  54. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/empty_pycodestyle_violations.txt +0 -0
  55. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/external_css_html_report.html +0 -0
  56. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/external_style.css +0 -0
  57. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/git_diff_add.txt +0 -0
  58. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/git_diff_changed.txt +0 -0
  59. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/git_diff_code_dupe.txt +0 -0
  60. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/git_diff_delete.txt +0 -0
  61. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/git_diff_dotnet.txt +0 -0
  62. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/git_diff_external_css.txt +0 -0
  63. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/git_diff_lua.txt +0 -0
  64. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/git_diff_moved.txt +0 -0
  65. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/git_diff_mult.txt +0 -0
  66. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/git_diff_subdir.txt +0 -0
  67. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/git_diff_unicode.txt +0 -0
  68. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/git_diff_violations.txt +0 -0
  69. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/git_diff_violations_two_files.txt +0 -0
  70. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/hello.py +0 -0
  71. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/hi.py +0 -0
  72. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/html_report.html +0 -0
  73. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/html_report_empty.html +0 -0
  74. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/html_report_one_snippet.html +0 -0
  75. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/html_report_two_snippets.html +0 -0
  76. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/lcov.info +0 -0
  77. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/lua_console_report.txt +0 -0
  78. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/luacoverage.xml +0 -0
  79. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/markdown_report_one_snippet.md +0 -0
  80. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/markdown_report_two_snippets.md +0 -0
  81. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/moved_console_report.txt +0 -0
  82. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/moved_coverage.xml +0 -0
  83. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/moved_html_report.html +0 -0
  84. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/mult_inputs_console_report.txt +0 -0
  85. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/mult_inputs_html_report.html +0 -0
  86. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/pycodestyle_report.txt +0 -0
  87. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/pycodestyle_violations_report.html +0 -0
  88. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/pycodestyle_violations_report.txt +0 -0
  89. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/pycodestyle_violations_report_external_css.html +0 -0
  90. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/pyflakes_two_files.txt +0 -0
  91. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/pyflakes_violations_report.html +0 -0
  92. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/pyflakes_violations_report.txt +0 -0
  93. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/pylint_dupe.txt +0 -0
  94. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/pylint_dupe_violations_report.txt +0 -0
  95. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/pylint_report.txt +0 -0
  96. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/pylint_violations_console_report.txt +0 -0
  97. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/pylint_violations_report.html +0 -0
  98. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/pylint_violations_report.txt +0 -0
  99. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/pylintrc +0 -0
  100. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/show_uncovered_lines_console.txt +0 -0
  101. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/snippet.css +0 -0
  102. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/snippet_8859.py +0 -0
  103. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/snippet_arabic_output.html +0 -0
  104. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/snippet_default.html +0 -0
  105. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/snippet_invalid_violations.html +0 -0
  106. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/snippet_list.html +0 -0
  107. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/snippet_no_filename_ext.html +0 -0
  108. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/snippet_src.py +0 -0
  109. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/snippet_src2.cpp +0 -0
  110. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/snippet_src3.cpp +0 -0
  111. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/snippet_unicode.html +0 -0
  112. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/snippet_unicode.py +0 -0
  113. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/snippet_unicode_html_output.html +0 -0
  114. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/subdir_coverage_console_report.txt +0 -0
  115. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/subdir_coverage_html_report.html +0 -0
  116. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/test_src.txt +0 -0
  117. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/unicode_console_report.txt +0 -0
  118. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/unicode_coverage.xml +0 -0
  119. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/unicode_html_report.html +0 -0
  120. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/unicode_test_src.txt +0 -0
  121. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/fixtures/violations_test_file.py +0 -0
  122. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/snippet_list_unicode.html +0 -0
  123. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/test_clover_violations_reporter/test.xml +0 -0
  124. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/test_clover_violations_reporter.py +0 -0
  125. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/test_config_parser.py +0 -0
  126. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/test_diff_cover_main.py +0 -0
  127. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/test_diff_cover_tool.py +0 -0
  128. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/test_diff_quality_main.py +0 -0
  129. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/test_diff_reporter.py +0 -0
  130. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/test_git_diff.py +0 -0
  131. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/test_git_path.py +0 -0
  132. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/test_integration.py +0 -0
  133. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/test_java_violations_reporter.py +0 -0
  134. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/test_report_generator.py +0 -0
  135. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/test_snippets.py +0 -0
  136. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/test_util.py +0 -0
  137. {diff_cover-8.0.3 → diff_cover-9.1.0}/tests/test_violations_reporter.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: diff_cover
3
- Version: 8.0.3
3
+ Version: 9.1.0
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
 
@@ -31,9 +31,11 @@ def execute(command, exit_codes=None):
31
31
  sys.stderr.write(
32
32
  " ".join(
33
33
  [
34
- cmd.decode(sys.getfilesystemencoding())
35
- if isinstance(cmd, bytes)
36
- else cmd
34
+ (
35
+ cmd.decode(sys.getfilesystemencoding())
36
+ if isinstance(cmd, bytes)
37
+ else cmd
38
+ )
37
39
  for cmd in command
38
40
  ]
39
41
  )
@@ -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=GitDiffTool(diff_range_notation, ignore_whitespace),
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
  )
@@ -1,6 +1,7 @@
1
1
  """
2
2
  Classes for querying which lines have changed based on a diff.
3
3
  """
4
+
4
5
  import fnmatch
5
6
  import glob
6
7
  import os
@@ -1,6 +1,7 @@
1
1
  """
2
2
  Wrapper for `git diff` command.
3
3
  """
4
+
4
5
  from textwrap import dedent
5
6
 
6
7
  from diff_cover.command_runner import CommandError, execute
@@ -109,3 +110,38 @@ class GitDiffTool:
109
110
  if not output:
110
111
  return []
111
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,7 @@
1
1
  """
2
2
  Converter for `git diff` paths
3
3
  """
4
+
4
5
  import os
5
6
  import sys
6
7
 
@@ -1,6 +1,7 @@
1
1
  """
2
2
  Classes for generating diff coverage reports.
3
3
  """
4
+
4
5
  import contextlib
5
6
  import json
6
7
  import os
@@ -2,6 +2,7 @@
2
2
  Load snippets from source files to show violation lines
3
3
  in HTML reports.
4
4
  """
5
+
5
6
  import contextlib
6
7
  from tokenize import open as openpy
7
8
 
@@ -115,18 +116,33 @@ class Snippet:
115
116
  Return a Markdown representation of the snippet using Markdown fenced code blocks.
116
117
  See https://github.github.com/gfm/#fenced-code-blocks.
117
118
  """
119
+
120
+ line_number_length = len(str(self._last_line))
121
+
122
+ text = ""
123
+ for i, line in enumerate(self.text().splitlines(), start=self._start_line):
124
+ if i > self._start_line:
125
+ text += "\n"
126
+
127
+ notice = " "
128
+ if i in self._violation_lines:
129
+ notice = "!"
130
+
131
+ format_string = "{} {:>" + str(line_number_length) + "} {}"
132
+ text += format_string.format(notice, i, line)
133
+
118
134
  header = "Lines %d-%d\n\n" % (self._start_line, self._last_line)
119
135
  if self._lexer_name in self.LEXER_TO_MARKDOWN_CODE_HINT:
120
136
  return header + (
121
137
  "```"
122
138
  + self.LEXER_TO_MARKDOWN_CODE_HINT[self._lexer_name]
123
139
  + "\n"
124
- + self.text()
140
+ + text
125
141
  + "\n```\n"
126
142
  )
127
143
 
128
144
  # unknown programming language, return a non-decorated fenced code block:
129
- return "```\n" + self.text() + "\n```\n"
145
+ return "```\n" + text + "\n```\n"
130
146
 
131
147
  def terminal(self):
132
148
  """
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "diff_cover"
3
- version = "8.0.3"
3
+ version = "9.1.0"
4
4
  description = "Run coverage and linting reports on diffs"
5
5
  authors = ["See Contributors"]
6
6
  homepage = "https://github.com/Bachmann1234/diff-cover"
@@ -49,16 +49,16 @@ tomli = {version = ">=1.2.1", optional = true}
49
49
  setuptools = { version = ">=17.0.0", python = "<3.8" }
50
50
 
51
51
  [tool.poetry.dev-dependencies]
52
- pytest-cov = "^4.1.0"
52
+ pytest-cov = "^5.0.0"
53
53
  pytest-datadir = "^1.5.0"
54
- pytest-mock = "^3.12.0"
54
+ 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.0.3"
59
- pylint-pytest = "^1.1.7"
58
+ pylint = "^3.2.2"
59
+ pylint-pytest = "^1.1.8"
60
60
  pydocstyle = "^6.1.1"
61
- black = "^23.12.1"
61
+ black = "^24.4.2"
62
62
  isort = "^5.13.2"
63
63
  doc8 = "1.1.1"
64
64
 
@@ -0,0 +1,38 @@
1
+ Lines 6-17
2
+
3
+ ```python
4
+ 6 Line 6
5
+ 7 Line 7
6
+ 8 Line 8
7
+ 9 Line 9
8
+ ! 10 Line 10
9
+ 11 Line 11
10
+ ! 12 Line 12
11
+ ! 13 Line 13
12
+ 14 Line 14
13
+ 15 Line 15
14
+ 16 Line 16
15
+ 17 Line 17
16
+ ```
17
+
18
+
19
+ Lines 46-61
20
+
21
+ ```python
22
+ 46 Line 46
23
+ 47 Line 47
24
+ 48 Line 48
25
+ 49 Line 49
26
+ ! 50 Line 50
27
+ ! 51 Line 51
28
+ 52 Line 52
29
+ 53 Line 53
30
+ ! 54 Line 54
31
+ ! 55 Line 55
32
+ 56 Line 56
33
+ ! 57 Line 57
34
+ 58 Line 58
35
+ 59 Line 59
36
+ 60 Line 60
37
+ 61 Line 61
38
+ ```
@@ -0,0 +1,10 @@
1
+ Lines 1-7
2
+
3
+ ```cpp
4
+ 1 #include <iostream>
5
+ 2
6
+ 3 int main() {
7
+ ! 4 std::cout << "Hello World!";
8
+ ! 5 return 0;
9
+ 6 }
10
+ ```
@@ -0,0 +1,13 @@
1
+ Lines 8-16
2
+
3
+ ```cpp
4
+ 8 // this is line 8
5
+ 9 printf("Test2");
6
+ 10
7
+ 11 // this is line 11
8
+ ! 12 printf("Test");
9
+ 13 }
10
+ 14
11
+ 15 int main()
12
+ 16 {
13
+ ```
@@ -1,6 +1,7 @@
1
1
  """
2
2
  Test helper functions.
3
3
  """
4
+
4
5
  import os.path
5
6
  import random
6
7
 
@@ -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"
@@ -1,38 +0,0 @@
1
- Lines 6-17
2
-
3
- ```python
4
- Line 6
5
- Line 7
6
- Line 8
7
- Line 9
8
- Line 10
9
- Line 11
10
- Line 12
11
- Line 13
12
- Line 14
13
- Line 15
14
- Line 16
15
- Line 17
16
- ```
17
-
18
-
19
- Lines 46-61
20
-
21
- ```python
22
- Line 46
23
- Line 47
24
- Line 48
25
- Line 49
26
- Line 50
27
- Line 51
28
- Line 52
29
- Line 53
30
- Line 54
31
- Line 55
32
- Line 56
33
- Line 57
34
- Line 58
35
- Line 59
36
- Line 60
37
- Line 61
38
- ```
@@ -1,11 +0,0 @@
1
- Lines 1-7
2
-
3
- ```cpp
4
- #include <iostream>
5
-
6
- int main() {
7
- std::cout << "Hello World!";
8
- return 0;
9
- }
10
-
11
- ```
@@ -1,13 +0,0 @@
1
- Lines 8-16
2
-
3
- ```cpp
4
- // this is line 8
5
- printf("Test2");
6
-
7
- // this is line 11
8
- printf("Test");
9
- }
10
-
11
- int main()
12
- {
13
- ```
File without changes
File without changes