diff-cover 9.4.0__tar.gz → 9.5.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 (157) hide show
  1. {diff_cover-9.4.0 → diff_cover-9.5.0}/PKG-INFO +2 -2
  2. {diff_cover-9.4.0 → diff_cover-9.5.0}/README.rst +1 -1
  3. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/diff_quality_tool.py +2 -0
  4. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/violationsreporters/violations_reporter.py +71 -4
  5. {diff_cover-9.4.0 → diff_cover-9.5.0}/pyproject.toml +1 -1
  6. diff_cover-9.5.0/tests/fixtures/real_python_coverage.lcov +75 -0
  7. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/test_violations_reporter.py +43 -6
  8. diff_cover-9.4.0/tests/fixtures/real_python_coverage.lcov +0 -55
  9. {diff_cover-9.4.0 → diff_cover-9.5.0}/LICENSE +0 -0
  10. {diff_cover-9.4.0 → diff_cover-9.5.0}/NOTICE +0 -0
  11. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/__init__.py +0 -0
  12. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/command_runner.py +0 -0
  13. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/config_parser.py +0 -0
  14. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/diff_cover_tool.py +0 -0
  15. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/diff_reporter.py +0 -0
  16. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/git_diff.py +0 -0
  17. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/git_path.py +0 -0
  18. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/hook.py +0 -0
  19. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/hookspecs.py +0 -0
  20. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/report_generator.py +0 -0
  21. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/snippets.py +0 -0
  22. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/templates/console_coverage_report.txt +0 -0
  23. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/templates/console_quality_report.txt +0 -0
  24. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/templates/external_style.css +0 -0
  25. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/templates/html_coverage_report.html +0 -0
  26. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/templates/html_quality_report.html +0 -0
  27. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/templates/markdown_coverage_report.md +0 -0
  28. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/templates/markdown_quality_report.md +0 -0
  29. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/templates/snippet_content.html +0 -0
  30. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/templates/snippet_content.md +0 -0
  31. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/templates/snippet_content.txt +0 -0
  32. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/templates/snippet_style.html +0 -0
  33. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/util.py +0 -0
  34. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/violationsreporters/__init__.py +0 -0
  35. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/violationsreporters/base.py +0 -0
  36. {diff_cover-9.4.0 → diff_cover-9.5.0}/diff_cover/violationsreporters/java_violations_reporter.py +0 -0
  37. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/__init__.py +0 -0
  38. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/add_console_report.txt +0 -0
  39. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/add_html_report.html +0 -0
  40. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/add_json_report.json +0 -0
  41. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/add_markdown_report.md +0 -0
  42. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/changed_console_report.txt +0 -0
  43. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/changed_html_report.html +0 -0
  44. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/coverage.xml +0 -0
  45. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/coverage1.xml +0 -0
  46. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/coverage2.xml +0 -0
  47. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/coverage_missing_lines.xml +0 -0
  48. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/cpp_functions_console_report.txt +0 -0
  49. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/cpp_functions_coverage.lcov +0 -0
  50. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/delete_console_report.txt +0 -0
  51. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/delete_html_report.html +0 -0
  52. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/dotnet_coverage.xml +0 -0
  53. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/dotnet_coverage_console_report.txt +0 -0
  54. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/empty.txt +0 -0
  55. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/empty_pycodestyle_violations.txt +0 -0
  56. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/expand_console_report.txt +0 -0
  57. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/external_css_html_report.html +0 -0
  58. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/external_style.css +0 -0
  59. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_add.txt +0 -0
  60. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_changed.txt +0 -0
  61. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_code_dupe.txt +0 -0
  62. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_cpp.txt +0 -0
  63. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_cpp_functions.txt +0 -0
  64. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_delete.txt +0 -0
  65. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_dotnet.txt +0 -0
  66. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_external_css.txt +0 -0
  67. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_lua.txt +0 -0
  68. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_moved.txt +0 -0
  69. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_mult.txt +0 -0
  70. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_python.txt +0 -0
  71. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_subdir.txt +0 -0
  72. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_typescript.txt +0 -0
  73. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_typescript_branches.txt +0 -0
  74. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_unicode.txt +0 -0
  75. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_violations.txt +0 -0
  76. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/git_diff_violations_two_files.txt +0 -0
  77. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/hello.py +0 -0
  78. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/hi.py +0 -0
  79. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/html_report.html +0 -0
  80. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/html_report_empty.html +0 -0
  81. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/html_report_one_snippet.html +0 -0
  82. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/html_report_two_snippets.html +0 -0
  83. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/lcov.info +0 -0
  84. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/lua_console_report.txt +0 -0
  85. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/luacoverage.xml +0 -0
  86. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/markdown_report_one_snippet.md +0 -0
  87. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/markdown_report_two_snippets.md +0 -0
  88. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/moved_console_report.txt +0 -0
  89. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/moved_coverage.xml +0 -0
  90. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/moved_html_report.html +0 -0
  91. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/mult_inputs_console_report.txt +0 -0
  92. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/mult_inputs_html_report.html +0 -0
  93. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/pycodestyle_report.txt +0 -0
  94. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/pycodestyle_violations_report.html +0 -0
  95. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/pycodestyle_violations_report.json +0 -0
  96. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/pycodestyle_violations_report.md +0 -0
  97. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/pycodestyle_violations_report.txt +0 -0
  98. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/pycodestyle_violations_report_external_css.html +0 -0
  99. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/pyflakes_two_files.txt +0 -0
  100. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/pyflakes_violations_report.html +0 -0
  101. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/pyflakes_violations_report.txt +0 -0
  102. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/pylint_dupe.txt +0 -0
  103. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/pylint_dupe_violations_report.txt +0 -0
  104. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/pylint_report.txt +0 -0
  105. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/pylint_violations_console_report.txt +0 -0
  106. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/pylint_violations_report.html +0 -0
  107. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/pylint_violations_report.txt +0 -0
  108. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/pylintrc +0 -0
  109. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/real_cpp_console_report.txt +0 -0
  110. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/real_cpp_coverage.lcov +0 -0
  111. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/real_python_console_report.txt +0 -0
  112. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/real_typescript_console_report.txt +0 -0
  113. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/real_typescript_coverage.lcov +0 -0
  114. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/show_uncovered_lines_console.txt +0 -0
  115. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/snippet.css +0 -0
  116. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/snippet_8859.py +0 -0
  117. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/snippet_arabic_output.html +0 -0
  118. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/snippet_default.html +0 -0
  119. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/snippet_invalid_violations.html +0 -0
  120. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/snippet_list.html +0 -0
  121. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/snippet_list.md +0 -0
  122. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/snippet_list2.md +0 -0
  123. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/snippet_list3.md +0 -0
  124. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/snippet_no_filename_ext.html +0 -0
  125. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/snippet_src.py +0 -0
  126. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/snippet_src2.cpp +0 -0
  127. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/snippet_src3.cpp +0 -0
  128. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/snippet_unicode.html +0 -0
  129. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/snippet_unicode.py +0 -0
  130. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/snippet_unicode_html_output.html +0 -0
  131. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/subdir_coverage_console_report.txt +0 -0
  132. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/subdir_coverage_html_report.html +0 -0
  133. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/test_src.txt +0 -0
  134. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/typescript_branches_console_report.txt +0 -0
  135. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/typescript_branches_coverage.lcov +0 -0
  136. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/unicode_console_report.txt +0 -0
  137. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/unicode_coverage.xml +0 -0
  138. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/unicode_html_report.html +0 -0
  139. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/unicode_test_src.txt +0 -0
  140. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/fixtures/violations_test_file.py +0 -0
  141. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/helpers.py +0 -0
  142. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/snippet_list_unicode.html +0 -0
  143. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/test_clover_violations_reporter/test.xml +0 -0
  144. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/test_clover_violations_reporter.py +0 -0
  145. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/test_config_parser.py +0 -0
  146. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/test_diff_cover_main.py +0 -0
  147. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/test_diff_cover_tool.py +0 -0
  148. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/test_diff_quality_main.py +0 -0
  149. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/test_diff_reporter.py +0 -0
  150. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/test_git_diff.py +0 -0
  151. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/test_git_diff_file.py +0 -0
  152. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/test_git_path.py +0 -0
  153. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/test_integration.py +0 -0
  154. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/test_java_violations_reporter.py +0 -0
  155. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/test_report_generator.py +0 -0
  156. {diff_cover-9.4.0 → diff_cover-9.5.0}/tests/test_snippets.py +0 -0
  157. {diff_cover-9.4.0 → diff_cover-9.5.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.4.0
3
+ Version: 9.5.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 check`` are supported, but more
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 check`` are supported, but more
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
 
@@ -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,
@@ -308,8 +308,7 @@ class LcovCoverageReporter(BaseViolationReporter):
308
308
  def parse(lcov_file):
309
309
  """
310
310
  Parse a single LCov coverage report
311
- File format: https://linux.die.net/man/1/geninfo
312
- More info: https://github.com/linux-test-project/lcov/issues/113#issuecomment-762335134
311
+ File format: https://github.com/linux-test-project/lcov/blob/master/man/geninfo.1
313
312
  """
314
313
  branch_coverage = defaultdict(
315
314
  lambda: defaultdict(lambda: {"total": 0, "hit": 0, "executions": 0})
@@ -361,14 +360,18 @@ class LcovCoverageReporter(BaseViolationReporter):
361
360
  branch_coverage[source_file][line_no]["hit"] += 1
362
361
  elif directive == "FN":
363
362
  args = content.split(",")
364
- if len(args) != 2:
363
+ # FN:<line number of function start>,[<line number of function end>,]<function name>
364
+ if len(args) != 2 and len(args) != 3:
365
365
  raise ValueError(f"Unknown syntax in lcov report: {line}")
366
366
  if source_file is None:
367
367
  raise ValueError(
368
368
  f"No source file specified for line coverage: {line}"
369
369
  )
370
370
  line_no = int(args[0])
371
- func_name = args[1]
371
+ if len(args) == 3:
372
+ func_name = args[2]
373
+ else:
374
+ func_name = args[1]
372
375
  function_lines[source_file][func_name] = (line_no, 0)
373
376
  elif directive == "FNDA":
374
377
  args = content.split(",")
@@ -828,3 +831,67 @@ class CppcheckDriver(QualityDriver):
828
831
  Returns: boolean True if installed
829
832
  """
830
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
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "diff_cover"
3
- version = "9.4.0"
3
+ version = "9.5.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"
@@ -0,0 +1,75 @@
1
+ SF:calculator.py
2
+ DA:1,1
3
+ DA:3,1
4
+ DA:4,1
5
+ DA:6,1
6
+ DA:8,1
7
+ DA:10,1
8
+ DA:11,1
9
+ DA:12,1
10
+ DA:14,1
11
+ DA:16,1
12
+ DA:17,1
13
+ DA:18,1
14
+ DA:20,1
15
+ DA:22,1
16
+ DA:23,1
17
+ DA:25,1
18
+ DA:26,1
19
+ DA:27,1
20
+ DA:28,1
21
+ DA:29,1
22
+ DA:30,1
23
+ DA:32,1
24
+ LF:22
25
+ LH:22
26
+ FN:4,6,Calculator.add
27
+ FNDA:1,Calculator.add
28
+ FN:8,12,Calculator.divide
29
+ FNDA:1,Calculator.divide
30
+ FN:14,18,Calculator.process_numbers
31
+ FNDA:1,Calculator.process_numbers
32
+ FN:20,32,Calculator.get_grade
33
+ FNDA:1,Calculator.get_grade
34
+ FNF:4
35
+ FNH:4
36
+ end_of_record
37
+ SF:test_calculator.py
38
+ DA:1,1
39
+ DA:2,1
40
+ DA:4,1
41
+ DA:5,1
42
+ DA:6,1
43
+ DA:8,1
44
+ DA:10,1
45
+ DA:12,1
46
+ DA:14,1
47
+ DA:15,1
48
+ DA:16,1
49
+ DA:18,1
50
+ DA:21,1
51
+ DA:24,1
52
+ DA:26,1
53
+ DA:28,1
54
+ DA:29,1
55
+ DA:30,1
56
+ DA:31,1
57
+ DA:33,1
58
+ DA:34,1
59
+ DA:35,1
60
+ DA:36,1
61
+ LF:23
62
+ LH:23
63
+ FN:5,6,calculator
64
+ FNDA:1,calculator
65
+ FN:8,10,test_add
66
+ FNDA:1,test_add
67
+ FN:12,16,test_divide
68
+ FNDA:1,test_divide
69
+ FN:18,24,test_process_numbers
70
+ FNDA:1,test_process_numbers
71
+ FN:26,36,test_get_grade
72
+ FNDA:1,test_get_grade
73
+ FNF:5
74
+ FNH:5
75
+ end_of_record
@@ -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,
@@ -999,8 +1000,8 @@ class TestLcovCoverageReporterTest:
999
1000
  # line 50: function not hit (should NOT be covered)
1000
1001
  function_data = {
1001
1002
  "file1.cpp": {
1002
- "func_hit": (40, 3),
1003
- "func_not_hit": (50, 0),
1003
+ "func_hit": (40, 40, 3),
1004
+ "func_not_hit": (50, 50, 0),
1004
1005
  }
1005
1006
  }
1006
1007
 
@@ -1012,6 +1013,15 @@ class TestLcovCoverageReporterTest:
1012
1013
  function_data=function_data,
1013
1014
  )
1014
1015
 
1016
+ lcov_report_obsolete_format = self._coverage_lcov(
1017
+ file_paths,
1018
+ violations,
1019
+ measured,
1020
+ branch_data=branch_data,
1021
+ function_data=function_data,
1022
+ use_obsolete_format=True,
1023
+ )
1024
+
1015
1025
  assert lcov_report == {
1016
1026
  "file1.cpp": {
1017
1027
  10: 1, # covered (no branch/function)
@@ -1027,6 +1037,7 @@ class TestLcovCoverageReporterTest:
1027
1037
  60: 0, # DA=0 and branch executions=0 (no override)
1028
1038
  }
1029
1039
  }
1040
+ assert lcov_report_obsolete_format == lcov_report
1030
1041
 
1031
1042
  def _coverage_lcov(
1032
1043
  self,
@@ -1035,12 +1046,13 @@ class TestLcovCoverageReporterTest:
1035
1046
  measured,
1036
1047
  branch_data=None,
1037
1048
  function_data=None,
1049
+ use_obsolete_format=False,
1038
1050
  ):
1039
1051
  """
1040
1052
  Build an LCOV document based on the provided arguments.
1041
1053
  Optionally include branch and function coverage data.
1042
1054
  - branch_data: dict {file: {line: [(block, branch, taken), ...]}}
1043
- - function_data: dict {file: {func_name: (line, hit_count)}}
1055
+ - function_data: dict {file: {func_name: (line, end_line, hit_count)}}
1044
1056
  """
1045
1057
  violation_lines = {violation.line for violation in violations}
1046
1058
  branch_data = branch_data or {}
@@ -1050,9 +1062,14 @@ class TestLcovCoverageReporterTest:
1050
1062
  for path in file_paths:
1051
1063
  f.write(f"SF:{path}\n")
1052
1064
  # Write function data
1053
- for func_name, (line, _) in function_data.get(path, {}).items():
1054
- f.write(f"FN:{line},{func_name}\n")
1055
- for func_name, (_, hit_count) in function_data.get(path, {}).items():
1065
+ for func_name, (line, end_line, _) in function_data.get(
1066
+ path, {}
1067
+ ).items():
1068
+ if use_obsolete_format:
1069
+ f.write(f"FN:{line},{end_line},{func_name}\n")
1070
+ else:
1071
+ f.write(f"FN:{line},{func_name}\n")
1072
+ for func_name, (_, _, hit_count) in function_data.get(path, {}).items():
1056
1073
  f.write(f"FNDA:{hit_count},{func_name}\n")
1057
1074
  # Write line data
1058
1075
  for line in measured:
@@ -2222,3 +2239,23 @@ class TestRuffCheckQualityDriverTest:
2222
2239
 
2223
2240
  assert quality.name() == "ruff.check"
2224
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
@@ -1,55 +0,0 @@
1
- TN:
2
- SF:calculator.py
3
- DA:1,1,IHjYfPUnPG8XenhaH5YO/A
4
- DA:3,1,R5ld61rEtMw8k5QnLG/J2Q
5
- DA:4,1,824CHOF+HuLf/TU8YUFs3A
6
- DA:6,1,7sXP/iICKUB6zWn67Juhgw
7
- DA:8,1,VsQ+B+HRaHmq81Fqbx2QvA
8
- DA:10,1,BhU+8GTrCvRmgSqWExCDtw
9
- DA:11,1,iaVNZHjse2AAQEIo1DuElQ
10
- DA:12,1,DrJU7aquMDtN+H52evA2kQ
11
- DA:14,1,vz2ZrwkD72YsQlDFhatNTw
12
- DA:16,1,ej3lkHPyE9SPnHBQWhY2QA
13
- DA:17,1,dfjHCoNB/lnYATH1PKxTig
14
- DA:18,1,QDzepsBi0Nd5VGR1pIoG7g
15
- DA:20,1,dSPjq3qexO3trH1KNMOIrQ
16
- DA:22,1,KYYfniyp2UPWWb+toC9jEg
17
- DA:23,1,ysgtnA7MU8LBfvqFnGW6vg
18
- DA:25,1,VoeqHedB53YTCJlr69LfAA
19
- DA:26,1,GbubG/XPO1WUDJqws3/Mhw
20
- DA:27,1,zbu7HynDC8IUMxz1TO8jAQ
21
- DA:28,1,6u/GbyzwJH3M/dAabCl9xQ
22
- DA:29,1,G75rLj1DYjeHhEjySNy/jQ
23
- DA:30,1,8Lrh8yJ/HPW1l96Gijc30g
24
- DA:32,1,l51yLGGGnM963UYCPo5N+A
25
- LF:22
26
- LH:22
27
- end_of_record
28
- TN:
29
- SF:test_calculator.py
30
- DA:1,1,6EqVyswJtxIE+9LVqyxOlA
31
- DA:2,1,O+96DUKqth1yjtUSIiMjXg
32
- DA:4,1,94X4nhA7Pe/OFJ+DxO73Mg
33
- DA:5,1,AKQyaclVFU9MNkdGMkzs1g
34
- DA:6,1,QK9KC7UVGwqStuMy+v3pYg
35
- DA:8,1,bTRe83kvssxoIveAKlMtfw
36
- DA:10,1,Vp4R4VgS/waq+RKmbztn/w
37
- DA:12,1,CFpmjrG5+jyhBoDLp/j5SQ
38
- DA:14,1,fWVWF2PjNTR1w2tnzAHuPA
39
- DA:15,1,lBb4Sb8TwZ/RIs6NdopHxA
40
- DA:16,1,L6hOpXMze2kVzf4at7QkPA
41
- DA:18,1,IzGG+ih8CeOLfQ7c+2tpCw
42
- DA:21,1,Fa2YbvHqjM0BMTarkRYeZQ
43
- DA:24,1,RKMlQwK1jpAcAaOjSB1sxQ
44
- DA:26,1,hwE0rNvci2CH1ZL7MP5D8A
45
- DA:28,1,xljWfj7mIHapHiNDY9x5vw
46
- DA:29,1,3Hd39iqUHWrP0w5fTsT+BA
47
- DA:30,1,CKdSOYRMADcYxuWGZZR5tA
48
- DA:31,1,Yt+uqA6V839ujVOYeX4Zfg
49
- DA:33,1,L4rVXtVP7DKlM4zvi6GP9w
50
- DA:34,1,1rUMQgfQLoAH5Bwk7IVFnA
51
- DA:35,1,L4rVXtVP7DKlM4zvi6GP9w
52
- DA:36,1,XF0EF2+Yi+Rg8tvFiw13qg
53
- LF:23
54
- LH:23
55
- end_of_record
File without changes
File without changes
File without changes
File without changes