{"id":13501876,"url":"https://github.com/Bachmann1234/diff_cover","last_synced_at":"2025-03-29T10:32:20.555Z","repository":{"id":25505625,"uuid":"28937065","full_name":"Bachmann1234/diff_cover","owner":"Bachmann1234","description":"Automatically find diff lines that need test coverage.","archived":false,"fork":false,"pushed_at":"2024-05-16T09:37:47.000Z","size":1523,"stargazers_count":679,"open_issues_count":47,"forks_count":184,"subscribers_count":18,"default_branch":"main","last_synced_at":"2024-05-23T08:32:34.474Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Bachmann1234.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-01-07T22:22:21.000Z","updated_at":"2024-06-01T20:47:37.496Z","dependencies_parsed_at":"2024-06-01T20:47:32.166Z","dependency_job_id":"f5313091-8111-481d-8247-b5b17f4bcb6c","html_url":"https://github.com/Bachmann1234/diff_cover","commit_stats":{"total_commits":699,"total_committers":64,"mean_commits":10.921875,"dds":0.6208869814020028,"last_synced_commit":"21239938edbc6ed6fc26530731aca2fd2f461b7e"},"previous_names":["bachmann1234/diff-cover"],"tags_count":139,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bachmann1234%2Fdiff_cover","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bachmann1234%2Fdiff_cover/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bachmann1234%2Fdiff_cover/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bachmann1234%2Fdiff_cover/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Bachmann1234","download_url":"https://codeload.github.com/Bachmann1234/diff_cover/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246173880,"owners_count":20735405,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T22:01:53.972Z","updated_at":"2025-03-29T10:32:20.176Z","avatar_url":"https://github.com/Bachmann1234.png","language":"Python","readme":"diff-cover |pypi-version| |conda-version| |build-status|\n========================================================================================\n\nAutomatically find diff lines that need test coverage.\nAlso finds diff lines that have violations (according to tools such\nas pycodestyle, pyflakes, flake8, or pylint).\nThis is used as a code quality metric during code reviews.\n\nOverview\n--------\n\nDiff coverage is the percentage of new or modified\nlines that are covered by tests.  This provides a clear\nand achievable standard for code review: If you touch a line\nof code, that line should be covered.  Code coverage\nis *every* developer's responsibility!\n\nThe ``diff-cover`` command line tool compares an XML coverage report\nwith the output of ``git diff``.  It then reports coverage information\nfor lines in the diff.\n\nCurrently, ``diff-cover`` requires that:\n\n- You are using ``git`` for version control.\n- Your test runner generates coverage reports in Cobertura, Clover\n  or JaCoCo XML format, or LCov format.\n\nSupported XML or LCov coverage reports can be generated with many coverage tools,\nincluding:\n\n- Cobertura__ (Java)\n- Clover__ (Java)\n- JaCoCo__ (Java)\n- coverage.py__ (Python)\n- JSCover__ (JavaScript)\n- lcov__ (C/C++)\n\n__ http://cobertura.sourceforge.net/\n__ http://openclover.org/\n__ https://www.jacoco.org/\n__ http://nedbatchelder.com/code/coverage/\n__ http://tntim96.github.io/JSCover/\n__ https://ltp.sourceforge.net/coverage/lcov.php\n\n\n``diff-cover`` is designed to be extended.  If you are interested\nin adding support for other version control systems or coverage\nreport formats, see below for information on how to contribute!\n\n\nInstallation\n------------\n\nTo install the latest release:\n\n.. code:: bash\n\n    pip install diff_cover\n\n\nTo install the development version:\n\n.. code:: bash\n\n    git clone https://github.com/Bachmann1234/diff-cover.git\n    cd diff-cover\n    poetry install\n    poetry shell\n\n\nGetting Started\n---------------\n\n1. Set the current working directory to a ``git`` repository.\n\n2. Run your test suite under coverage and generate a [Cobertura, Clover or JaCoCo] XML report.\n   For example, using `pytest-cov`__:\n\n.. code:: bash\n\n    pytest --cov --cov-report=xml\n\n__ https://pypi.org/project/pytest-cov\n\nThis will create a ``coverage.xml`` file in the current working directory.\n\n**NOTE**: If you are using a different coverage generator, you will\nneed to use different commands to generate the coverage XML report.\n\n\n3. Run ``diff-cover``:\n\n.. code:: bash\n\n    diff-cover coverage.xml\n\nThis will compare the current ``git`` branch to ``origin/main`` and print\nthe diff coverage report to the console.\n\nYou can also generate an HTML, JSON or Markdown version of the report:\n\n.. code:: bash\n\n    diff-cover coverage.xml --html-report report.html\n    diff-cover coverage.xml --json-report report.json\n    diff-cover coverage.xml --markdown-report report.md\n\nMultiple XML Coverage Reports\n-------------------------------\n\nIn the case that one has multiple xml reports form multiple test suites, you\ncan get a combined coverage report (a line is counted  as covered if it is\ncovered in ANY of the xml reports) by running ``diff-cover`` with multiple\ncoverage reports as arguments. You may specify any arbitrary number of coverage\nreports:\n\n.. code:: bash\n\n    diff-cover coverage1.xml coverage2.xml\n\nQuality Coverage\n-----------------\nYou can use diff-cover to see quality reports on the diff as well by running\n``diff-quality``.\n\n.. code :: bash\n\n    diff-quality --violations=\u003ctool\u003e\n\nWhere ``tool`` is the quality checker to use. Currently ``pycodestyle``, ``pyflakes``,\n``flake8``, ``pylint``, ``checkstyle``, ``checkstylexml`` are supported, but more\ncheckers can (and should!) be supported. See the section \"Adding `diff-quality``\nSupport for a New Quality Checker\".\n\nNOTE: There's no way to run ``findbugs`` from ``diff-quality`` as it operating\nover the generated java bytecode and should be integrated into the build\nframework.\n\nLike ``diff-cover``, HTML, JSON or Markdown reports can be generated with\n\n.. code:: bash\n\n    diff-quality --violations=\u003ctool\u003e --html-report report.html\n    diff-quality --violations=\u003ctool\u003e --json-report report.json\n    diff-quality --violations=\u003ctool\u003e --markdown-report report.md\n\nIf you have already generated a report using ``pycodestyle``, ``pyflakes``, ``flake8``,\n``pylint``, ``checkstyle``, ``checkstylexml``, or ``findbugs`` you can pass the report\nto ``diff-quality``.  This is more efficient than letting ``diff-quality`` re-run\n``pycodestyle``, ``pyflakes``, ``flake8``, ``pylint``, ``checkstyle``, or ``checkstylexml``.\n\n.. code:: bash\n\n    # For pylint \u003c 1.0\n    pylint -f parseable \u003e pylint_report.txt\n\n    # For pylint \u003e= 1.0\n    pylint --msg-template=\"{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}\" \u003e pylint_report.txt\n\n    # Use the generated pylint report when running diff-quality\n    diff-quality --violations=pylint pylint_report.txt\n\n    # Use a generated pycodestyle report when running diff-quality.\n    pycodestyle \u003e pycodestyle_report.txt\n    diff-quality --violations=pycodestyle pycodestyle_report.txt\n\nNote that you must use the ``-f parseable`` option to generate\nthe ``pylint`` report for pylint versions less than 1.0 and the\n``--msg-template`` option for versions \u003e= 1.0.\n\n``diff-quality`` will also accept multiple ``pycodestyle``, ``pyflakes``, ``flake8``,\nor ``pylint`` reports:\n\n.. code:: bash\n\n    diff-quality --violations=pylint report_1.txt report_2.txt\n\nIf you need to pass in additional options you can with the ``options`` flag\n\n.. code:: bash\n\n    diff-quality --violations=pycodestyle --options=\"--exclude='*/migrations*' --statistics\" pycodestyle_report.txt\n\nCompare Branch\n--------------\n\nBy default, ``diff-cover`` compares the current branch to ``origin/main``.  To specify a different compare branch:\n\n.. code:: bash\n\n    diff-cover coverage.xml --compare-branch=origin/release\n\nDiff File\n--------------\n\nYou may provide a file containing the output of ``git diff`` to ``diff-cover`` instead of using a branch name.\n\nFor example, Say you have 2 branches ``main`` and ``feature``. Lets say after creating and checking out the feature branch,\nyou make commits ``A``, ``B``, and ``C`` in that order.\n\n\nIf you want to see all changes between the ``feature`` and ``main`` branch, you can generate a diff file like this:\n\n.. code:: bash\n\n    git diff main..feature \u003e diff.txt\n\nIf you want to see the changes between the ``feature`` branch and the commit ``A``, you can generate a diff file using the following command:\n\n.. code:: bash\n\n    git diff A..feature \u003e diff.txt\n\nYou can then run ``diff-cover`` with the diff file as an argument:\n\n.. code:: bash\n\n    diff-cover coverage.xml --diff-file=diff.txt\n\nFail Under\n----------\n\nTo have ``diff-cover`` and ``diff-quality`` return a non zero status code if the report quality/coverage percentage is\nbelow a certain threshold specify the fail-under parameter\n\n.. code:: bash\n\n    diff-cover coverage.xml --fail-under=80\n    diff-quality --violations=pycodestyle --fail-under=80\n\nThe above will return a non zero status if the coverage or quality score was below 80%.\n\nExclude/Include paths\n---------------------\n\nExplicit exclusion of paths is possible for both ``diff-cover`` and ``diff-quality``, while inclusion is\nonly supported for ``diff-quality`` (since 5.1.0).\n\nThe exclude option works with ``fnmatch``, include with ``glob``. Both options can consume multiple values.\nInclude options should be wrapped in double quotes to prevent shell globbing. Also they should be relative to\nthe current git directory.\n\n.. code:: bash\n\n    diff-cover coverage.xml --exclude setup.py\n    diff-quality --violations=pycodestyle --exclude setup.py\n\n    diff-quality --violations=pycodestyle --include project/foo/**\n\nThe following is executed for every changed file:\n\n#. check if any include pattern was specified\n#. if yes, check if the changed file is part of at least one include pattern\n#. check if the file is part of any exclude pattern\n\nIgnore/Include based on file status in git\n------------------------------------------\nBoth ``diff-cover`` and ``diff-quality`` allow users to ignore and include files based on the git\nstatus: staged, unstaged, untracked:\n\n* ``--ignore-staged``: ignore all staged files (by default include them)\n* ``--ignore-unstaged``: ignore all unstaged files (by default include them)\n* ``--include-untracked``: include all untracked files (by default ignore them)\n\nQuiet mode\n----------\nBoth ``diff-cover`` and ``diff-quality`` support a quiet mode which is disable by default.\nIt can be enabled by using the ``-q``/``--quiet`` flag:\n\n.. code:: bash\n\n    diff-cover coverage.xml -q\n    diff-quality --violations=pycodestyle -q\n\nIf enabled, the tool will only print errors and failures but no information or warning messages.\n\nCompatibility with multi-line statements\n----------------------------------------\n``diff-cover`` relies on the comparison of diff reports and coverage reports, and does not report\nlines that appear in one and not in the other. While diff reports list all lines that changed,\ncoverage reports usually list code statements. As a result, a change in a multi-line statement may not be analyzed by ``diff-cover``.\n\nAs a workaround, you can use the argument ``--expand-coverage-report``: lines not appearing in the coverage reports will be added to them with the same number of hits as the previously reported line. ``diff-cover`` will then perform diff coverage analysis on all changed lines.\n\nNotes:\n- This argument is only available for XML coverage reports.\n- This workaround is designed under the assumption that the coverage tool reports untested statements with hits set to 0, and it reports statements based on the opening line.\n\nConfiguration files\n-------------------\nBoth tools allow users to specify the options in a configuration file with `--config-file`/`-c`:\n\n.. code:: bash\n\n    diff-cover coverage.xml --config-file myconfig.toml\n    diff-quality --violations=pycodestyle --config-file myconfig.toml\n\nCurrently, only TOML files are supported.\nPlease note, that only non-mandatory options are supported.\nIf an option is specified in the configuration file and over the command line, the value of the\ncommand line is used.\n\nTOML configuration\n~~~~~~~~~~~~~~~~~~\n\nThe parser will only react to configuration files ending with `.toml`.\nTo use it, install `diff-cover` with the extra requirement `toml`.\n\nThe option names are the same as on the command line, but all dashes should be underscores.\nIf an option can be specified multiple times, the configuration value should be specified as a list.\n\n.. code:: toml\n\n    [tool.diff_cover]\n    compare_branch = \"origin/feature\"\n    quiet = true\n\n    [tool.diff_quality]\n    compare_branch = \"origin/feature\"\n    ignore_staged = true\n\n\nTroubleshooting\n----------------------\n\n**Issue**: ``diff-cover`` always reports: \"No lines with coverage information in this diff.\"\n\n**Solution**: ``diff-cover`` matches source files in the coverage XML report with\nsource files in the ``git diff``.  For this reason, it's important\nthat the relative paths to the files match.  If you are using `coverage.py`__\nto generate the coverage XML report, then make sure you run\n``diff-cover`` from the same working directory.\n\n__ http://nedbatchelder.com/code/coverage/\n\n**Issue**: ``GitDiffTool._execute()`` raises the error:\n\n.. code:: bash\n\n    fatal: ambiguous argument 'origin/main...HEAD': unknown revision or path not in the working tree.\n\nThis is known to occur when running ``diff-cover`` in `Travis CI`__\n\n__ http://travis-ci.org\n\n**Solution**: Fetch the remote main branch before running ``diff-cover``:\n\n.. code:: bash\n\n    git fetch origin master:refs/remotes/origin/main\n\n**Issue**: ``diff-quality`` reports \"diff_cover.violations_reporter.QualityReporterError:\nNo config file found, using default configuration\"\n\n**Solution**: Your project needs a `pylintrc` file.\nProvide this file (it can be empty) and ``diff-quality`` should run without issue.\n\n**Issue**: ``diff-quality`` reports \"Quality tool not installed\"\n\n**Solution**: ``diff-quality`` assumes you have the tool you wish to run against your diff installed.\nIf you do not have it then install it with your favorite package manager.\n\n**Issue**: ``diff-quality`` reports no quality issues\n\n**Solution**: You might use a pattern like ``diff-quality --violations foo *.py``. The last argument\nis not used to specify the files but for the quality tool report. Remove it to resolve the issue\n\nLicense\n-------\n\nThe code in this repository is licensed under the Apache 2.0 license.\nPlease see ``LICENSE.txt`` for details.\n\n\nHow to Contribute\n-----------------\n\nContributions are very welcome. The easiest way is to fork this repo, and then\nmake a pull request from your fork.\n\nNOTE: ``diff-quality`` supports a plugin model, so new tools can be integrated\nwithout requiring changes to this repo. See the section \"Adding `diff-quality``\nSupport for a New Quality Checker\".\n\nSetting Up For Development\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThis project is managed with `poetry` this can be installed with `pip`\npoetry manages a python virtual environment and organizes dependencies. It also\npackages this project.\n\n.. code:: bash\n\n    pip install poetry\n\n.. code:: bash\n\n    poetry install\n\nI would also suggest running this command after. This will make it so git blame ignores the commit\nthat formatted the entire codebase.\n\n.. code:: bash\n\n    git config blame.ignoreRevsFile .git-blame-ignore-revs\n\n\nAdding `diff-quality`` Support for a New Quality Checker\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nAdding support for a new quality checker is simple. ``diff-quality`` supports\nplugins using the popular Python\n`pluggy package \u003chttps://pluggy.readthedocs.io/en/latest/\u003e`_.\n\nIf the quality checker is already implemented as a Python package, great! If not,\n`create a Python package \u003chttps://packaging.python.org/tutorials/packaging-projects/\u003e`_\nto host the plugin implementation.\n\nIn the Python package's ``setup.py`` file, define an entry point for the plugin,\ne.g.\n\n.. code:: python\n\n    setup(\n        ...\n        entry_points={\n            'diff_cover': [\n                'sqlfluff = sqlfluff.diff_quality_plugin'\n            ],\n        },\n        ...\n    )\n\nNotes:\n\n* The dictionary key for the entry point must be named ``diff_cover``\n* The value must be in the format ``TOOL_NAME = YOUR_PACKAGE.PLUGIN_MODULE``\n\nWhen your package is installed, ``diff-quality`` uses this information to\nlook up the tool package and module based on the tool name provided to the\n``--violations`` option of the ``diff-quality`` command, e.g.:\n\n.. code:: bash\n\n    $ diff-quality --violations sqlfluff\n\nThe plugin implementation will look something like the example below. This is\na simplified example based on a working plugin implementation.\n\n.. code:: python\n\n    from diff_cover.hook import hookimpl as diff_cover_hookimpl\n    from diff_cover.violationsreporters.base import BaseViolationReporter, Violation\n\n    class SQLFluffViolationReporter(BaseViolationReporter):\n        supported_extensions = ['sql']\n\n        def __init__(self):\n            super(SQLFluffViolationReporter, self).__init__('sqlfluff')\n\n        def violations(self, src_path):\n            return [\n                Violation(violation.line_number, violation.description)\n                for violation in get_linter().get_violations(src_path)\n            ]\n\n        def measured_lines(self, src_path):\n            return None\n\n        @staticmethod\n        def installed():\n            return True\n\n\n    @diff_cover_hookimpl\n    def diff_cover_report_quality():\n        return SQLFluffViolationReporter()\n\nImportant notes:\n\n* ``diff-quality`` is looking for a plugin function:\n\n  * Located in your package's module that was listed in the ``setup.py`` entry point.\n  * Marked with the ``@diff_cover_hookimpl`` decorator\n  * Named ``diff_cover_report_quality``. (This distinguishes it from any other\n    plugin types ``diff_cover`` may support.)\n* The function should return an object with the following properties and methods:\n\n  * ``supported_extensions`` property with a list of supported file extensions\n  * ``violations()`` function that returns a list of ``Violation`` objects for\n    the specified ``src_path``. For more details on this function and other\n    possible reporting-related methods, see the ``BaseViolationReporter`` class\n    `here \u003chttps://github.com/Bachmann1234/diff_cover/blob/main/diff_cover/violationsreporters/base.py\u003e`_.\n\nSpecial Thanks\n-------------------------\n\nShout out to the original author of diff-cover `Will Daly\n\u003chttps://github.com/wedaly\u003e`_ and the original author of diff-quality `Sarina Canelake\n\u003chttps://github.com/sarina\u003e`_.\n\nOriginally created with the support of `edX\n\u003chttps://github.com/edx\u003e`_.\n\n\n.. |pypi-version| image:: https://img.shields.io/pypi/v/diff-cover.svg\n    :target: https://pypi.org/project/diff-cover\n    :alt: PyPI version\n.. |conda-version| image:: https://img.shields.io/conda/vn/conda-forge/diff-cover.svg\n    :target: https://anaconda.org/conda-forge/diff-cover\n    :alt: Conda version\n.. |build-status| image:: https://github.com/bachmann1234/diff_cover/actions/workflows/verify.yaml/badge.svg?branch=main\n    :target: https://github.com/Bachmann1234/diff_cover/actions/workflows/verify.yaml\n    :alt: Build Status\n","funding_links":[],"categories":["Python","Code Coverage"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FBachmann1234%2Fdiff_cover","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FBachmann1234%2Fdiff_cover","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FBachmann1234%2Fdiff_cover/lists"}