diff --git a/.github/workflows/mkdocs-deploy.yml b/.github/workflows/mkdocs-deploy.yml index 7ca30a6f..801a6945 100644 --- a/.github/workflows/mkdocs-deploy.yml +++ b/.github/workflows/mkdocs-deploy.yml @@ -13,13 +13,13 @@ jobs: with: python-version: 3.x - name: Install python action for doc extraction - run: pip install . -r docs/requirements.txt + run: pip install -r docs/requirements.txt - name: check mkdocs build - if: github.ref != 'refs/heads/master' + # if: github.ref != 'refs/heads/master' run: mkdocs build - - name: Build docs and deploy to gh-pages - if: github.ref == 'refs/heads/master' - run: | - git config user.name 'github-actions' - git config user.email '41898282+github-actions[bot]@users.noreply.github.com' - mkdocs gh-deploy --force + # - name: Build docs and deploy to gh-pages + # if: github.ref == 'refs/heads/master' + # run: | + # git config user.name 'github-actions' + # git config user.email '41898282+github-actions[bot]@users.noreply.github.com' + # mkdocs gh-deploy --force diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml deleted file mode 100644 index 00ad109a..00000000 --- a/.github/workflows/publish-pypi.yml +++ /dev/null @@ -1,51 +0,0 @@ -# This workflow will upload a Python Package using Twine when a release is created -# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries - -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -name: Upload Python Package - -on: - release: - branches: [master] - types: [published] - workflow_dispatch: - -permissions: - contents: read - -jobs: - deploy: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - # use fetch --all for setuptools_scm to work - with: - fetch-depth: 0 - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.x' - - name: Install dependencies - run: python -m pip install --upgrade pip twine - - name: Build wheel - run: python -m pip wheel -w dist --no-deps . - - name: Check distribution - run: twine check dist/* - - name: Publish package (to TestPyPI) - if: github.event_name == 'workflow_dispatch' && github.repository == 'cpp-linter/cpp-linter-action' - env: - TWINE_USERNAME: __token__ - TWINE_PASSWORD: ${{ secrets.TEST_PYPI_TOKEN }} - run: twine upload --repository testpypi dist/* - - name: Publish package (to PyPI) - if: github.event_name != 'workflow_dispatch' && github.repository == 'cpp-linter/cpp-linter-action' - env: - TWINE_USERNAME: __token__ - TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} - run: twine upload dist/* diff --git a/.github/workflows/run-dev-tests.yml b/.github/workflows/run-dev-tests.yml deleted file mode 100644 index ae17ce5d..00000000 --- a/.github/workflows/run-dev-tests.yml +++ /dev/null @@ -1,113 +0,0 @@ -name: "Check python code" - -on: - push: - paths: - - "**.py" - - pyproject.toml - - pre-commit-config.yaml - - ".github/workflows/run-dev-tests.yml" - pull_request: - types: opened - paths: - - "**.py" - - "**requirements*.txt" - - pyproject.toml - - pre-commit-config.yaml - - ".github/workflows/run-dev-tests.yml" - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - with: - python-version: '3.x' - - name: Build wheel - run: python3 -m pip wheel --no-deps -w dist . - - name: Upload wheel as artifact - uses: actions/upload-artifact@v3 - with: - name: cpp-linter-action_wheel - path: ${{ github.workspace }}/dist/*.whl - - test: - needs: [build] - strategy: - fail-fast: false - matrix: - py: ['3.7', '3.8', '3.9', '3.10'] - os: ['windows-latest', ubuntu-latest] - version: ['13', '12', '11', '10', '9', '8', '7'] - include: - - tools_dir: 'N/A' - - os: 'windows-latest' - version: '10' - tools_dir: temp - - os: 'windows-latest' - version: '10' - tools_dir: temp - - os: 'windows-latest' - version: '11' - tools_dir: temp - - os: 'windows-latest' - version: '12' - tools_dir: temp - - os: 'ubuntu-latest' - version: '13' - tools_dir: temp - # - version: '14' - # tools_dir: temp - - version: '7' - tools_dir: temp - - version: '8' - tools_dir: temp - - version: '9' - tools_dir: temp - - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v3 - - - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.py }} - - - name: download wheel artifact - uses: actions/download-artifact@v3 - with: - name: cpp-linter-action_wheel - path: dist - - - name: Install workflow deps - # using a wildcard as filename on Windows requires a bash shell - shell: bash - run: python3 -m pip install pytest coverage[toml] dist/*.whl - - - name: Install clang-tools - if: matrix.tools_dir == 'temp' - run: | - python -m pip install clang-tools - clang-tools --install ${{ matrix.version }} --directory ${{ runner.temp }}/clang-tools - - - name: Collect Coverage (native clang install) - if: matrix.tools_dir == 'N/A' - env: - CLANG_VERSION: ${{ matrix.version }} - run: coverage run -m pytest - - - name: Collect Coverage (non-native clang install) - if: matrix.tools_dir == 'temp' - env: - CLANG_VERSION: ${{ runner.temp }}/clang-tools - run: coverage run -m pytest - - - run: coverage report && coverage xml - - - uses: codecov/codecov-action@v3 - if: matrix.os == 'ubuntu-latest' && matrix.version == '12' && matrix.py == '3.10' - with: - files: ./coverage.xml - fail_ci_if_error: true # optional (default = false) - verbose: true # optional (default = false) diff --git a/.gitpod.yml b/.gitpod.yml deleted file mode 100644 index c21ea2f0..00000000 --- a/.gitpod.yml +++ /dev/null @@ -1,2 +0,0 @@ -tasks: - - init: pip install -r requirements.txt diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e5ea8a37..cc14a830 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,33 +4,5 @@ repos: hooks: - id: trailing-whitespace - id: end-of-file-fixer - - id: check-docstring-first - id: check-added-large-files - id: check-yaml - - id: check-toml - - id: requirements-txt-fixer - - repo: https://github.com/python/black - rev: '22.6.0' - hooks: - - id: black - args: ["--diff"] - - repo: https://github.com/pycqa/pylint - rev: v2.14.5 - hooks: - - id: pylint - name: pylint (action code) - types: [python] - exclude: "^(docs/|tests/|setup.py$)" - additional_dependencies: [pyyaml, requests] - - repo: local - # this is a "local" hook to run mypy (see https://pre-commit.com/#repository-local-hooks) - # because the mypy project doesn't seem to be compatible with pre-commit hooks - hooks: - - id: mypy - name: mypy - description: type checking with mypy tool - language: python - types: [python] - entry: mypy - exclude: "^(docs/|setup.py$)" - additional_dependencies: [mypy, types-pyyaml, types-requests, rich, requests, pytest, pyyaml, '.'] diff --git a/Dockerfile b/Dockerfile index fbb6128b..427dfabe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,9 +14,7 @@ LABEL maintainer="shenxianpeng <20297606+shenxianpeng@users.noreply.github.com>" RUN apt-get update && apt-get -y install python3-pip -COPY cpp_linter/ pkg/cpp_linter/ -COPY pyproject.toml pkg/pyproject.toml -RUN python3 -m pip install pkg/ +RUN python3 -m pip install cpp-linter # github action args use the CMD option # See https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runsargs diff --git a/README.md b/README.md index b854411e..33d9fa09 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/cpp-linter/cpp-linter-action/cpp-linter?label=cpp-linter&logo=Github&style=flat-square)](https://github.com/cpp-linter/cpp-linter-action/actions/workflows/cpp-linter.yml) [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/cpp-linter/cpp-linter-action/MkDocs%20Deploy?label=docs&logo=Github&style=flat-square)](https://github.com/cpp-linter/cpp-linter-action/actions/workflows/mkdocs-deploy.yml) ![GitHub](https://img.shields.io/github/license/cpp-linter/cpp-linter-action?label=license&logo=github&style=flat-square) -[![codecov](https://codecov.io/gh/cpp-linter/cpp-linter-action/branch/master/graph/badge.svg?token=4SF7UEDEZ2)](https://codecov.io/gh/cpp-linter/cpp-linter-action) A Github Action for linting C/C++ code integrating clang-tidy and clang-format to collect feedback provided in the form of thread comments and/or annotations. @@ -187,7 +186,7 @@ jobs: directory: ${{ runner.temp }}/llvm - name: Install linter python package - run: python3 -m pip install git+https://github.com/cpp-linter/cpp-linter-action@v1 + run: python3 -m pip install cpp-linter - name: run linter as a python package id: linter @@ -219,7 +218,7 @@ is equivalent to ```yaml - name: Install linter python package - run: python3 -m pip install git+https://github.com/cpp-linter/cpp-linter-action@v1 + run: python3 -m pip install cpp-linter - name: run linter as a python package run: | diff --git a/cpp_linter/__init__.py b/cpp_linter/__init__.py deleted file mode 100644 index 84394cdf..00000000 --- a/cpp_linter/__init__.py +++ /dev/null @@ -1,160 +0,0 @@ -"""The Base module of the `cpp_linter` package. This holds the objects shared by -multiple modules.""" -import os -from pathlib import Path -import platform -import logging -from typing import TYPE_CHECKING, List, Dict, Union, Any -from requests import Response - -if TYPE_CHECKING: # Used to avoid circular imports - from cpp_linter.clang_format_xml import XMLFixit - from cpp_linter.clang_tidy_yml import YMLFixit - from cpp_linter.clang_tidy import TidyNotification - -FOUND_RICH_LIB = False -try: - from rich.logging import RichHandler - - FOUND_RICH_LIB = True - - logging.basicConfig( - format="%(name)s: %(message)s", - handlers=[RichHandler(show_time=False)], - ) - -except ImportError: # pragma: no cover - logging.basicConfig() - -#: The logging.Logger object used for outputting data. -logger = logging.getLogger("CPP Linter") -if not FOUND_RICH_LIB: - logger.debug("rich module not found") - -# global constant variables -IS_ON_RUNNER = bool(os.getenv("CI")) -GITHUB_SHA = os.getenv("GITHUB_SHA", "") -GITHUB_TOKEN = os.getenv("GITHUB_TOKEN", os.getenv("GIT_REST_API", "")) -API_HEADERS = { - "Accept": "application/vnd.github.v3.text+json", -} -if GITHUB_TOKEN: - API_HEADERS["Authorization"] = f"token {GITHUB_TOKEN}" -IS_ON_WINDOWS = platform.system().lower() == "windows" - - -class Globals: - """Global variables for re-use (non-constant).""" - - PAYLOAD_TIDY: str = "" - """The accumulated output of clang-tidy (gets appended to OUTPUT)""" - OUTPUT: str = "" - """The accumulated body of the resulting comment that gets posted.""" - FILES: List[Dict[str, Any]] = [] - """The responding payload containing info about changed files.""" - EVENT_PAYLOAD: Dict[str, Any] = {} - """The parsed JSON of the event payload.""" - response_buffer = Response() - """A shared response object for `requests` module.""" - - -class GlobalParser: - """Global variables specific to output parsers. Each element in each of the - following attributes represents a clang-tool's output for 1 source file. - """ - - tidy_notes = [] # type: List[TidyNotification] - """This can only be a `list` of type - [`TidyNotification`][cpp_linter.clang_tidy.TidyNotification]""" - tidy_advice = [] # type: List[YMLFixit] - """This can only be a `list` of type - [`YMLFixit`][cpp_linter.clang_tidy_yml.YMLFixit]""" - format_advice = [] # type: List[XMLFixit] - """This can only be a `list` of type - [`XMLFixit`][cpp_linter.clang_format_xml.XMLFixit]""" - - -def get_line_cnt_from_cols(file_path: str, offset: int) -> tuple: - """Gets a line count and columns offset from a file's absolute offset. - - Args: - file_path: Path to file. - offset: The byte offset to translate - - Returns: - A `tuple` of 2 `int` numbers: - - - Index 0 is the line number for the given offset. - - Index 1 is the column number for the given offset on the line. - """ - # logger.debug("Getting line count from %s at offset %d", file_path, offset) - contents = Path(file_path).read_bytes()[:offset] - return (contents.count(b"\n") + 1, offset - contents.rfind(b"\n")) - - -def range_of_changed_lines( - file_obj: Dict[str, Any], lines_changed_only: int -) -> List[int]: - """Assemble a list of lines changed. - - Args: - file_obj: The file's JSON object. - lines_changed_only: A flag to indicate the focus of certain lines. - - - 0: focuses on all lines in file. - - 1: focuses on any lines shown in the event's diff - (may include unchanged lines). - - 2: focuses strictly on lines in the diff that contain additions. - Returns: - A list of line numbers for which to give attention. - """ - if lines_changed_only: - ranges = file_obj["line_filter"][ - "diff_chunks" if lines_changed_only == 1 else "lines_added" - ] - return [l for r in ranges for l in range(r[0], r[1])] - return [] - - -def log_response_msg() -> bool: - """Output the response buffer's message on a failed request. - - Returns: - A bool describing if response's status code was less than 400. - """ - if Globals.response_buffer.status_code >= 400: - logger.error( - "response returned %d message: %s", - Globals.response_buffer.status_code, - Globals.response_buffer.text, - ) - return False - return True - - -def assemble_version_exec(tool_name: str, specified_version: str) -> str: - """Assembles the command to the executable of the given clang tool based on given - version information. - - Args: - tool_name: The name of the clang tool to be executed. - specified_version: The version number or the installed path to a version of - the tool's executable. - """ - suffix = ".exe" if IS_ON_WINDOWS else "" - if specified_version.isdigit(): # version info is not a path - # let's assume the exe is in the PATH env var - if IS_ON_WINDOWS: - # installs don't usually append version number to exe name on Windows - return f"{tool_name}{suffix}" # omit version number - return f"{tool_name}-{specified_version}{suffix}" - version_path = Path(specified_version).resolve() # make absolute - for path in [ - # if installed via KyleMayes/install-llvm-action using the `directory` option - version_path / "bin" / (tool_name + suffix), - # if installed via clang-tools-pip pkg using the `-d` option - version_path / (tool_name + suffix), - ]: - if path.exists(): - return str(path) - return tool_name + suffix diff --git a/cpp_linter/clang_format_xml.py b/cpp_linter/clang_format_xml.py deleted file mode 100644 index 7ba4c18b..00000000 --- a/cpp_linter/clang_format_xml.py +++ /dev/null @@ -1,150 +0,0 @@ -"""Parse output from clang-format's XML suggestions.""" -from pathlib import PurePath -from typing import List, Optional -import xml.etree.ElementTree as ET -from . import GlobalParser, get_line_cnt_from_cols - - -class FormatReplacement: - """An object representing a single replacement. - - Attributes: - cols (int): The columns number of where the suggestion starts on the line - null_len (int): The number of bytes removed by suggestion - text (str): The `bytearray` of the suggestion - """ - - def __init__(self, cols: int, null_len: int, text: str) -> None: - """ - Args: - cols: The columns number of where the suggestion starts on the line - null_len: The number of bytes removed by suggestion - text: The `bytearray` of the suggestion - """ - self.cols = cols - self.null_len = null_len - self.text = text - - def __repr__(self) -> str: - return ( - f"" - ) - - -class FormatReplacementLine: - """An object that represents a replacement(s) for a single line. - - Attributes: - line (int): The line number of where the suggestion starts - replacements (list): A list of - [`FormatReplacement`][cpp_linter.clang_format_xml.FormatReplacement] - object(s) representing suggestions. - """ - - def __init__(self, line_numb: int): - """ - Args: - line_numb: The line number of about the replacements - """ - self.line = line_numb - self.replacements: List[FormatReplacement] = [] - - def __repr__(self): - return ( - f"" - ) - - -class XMLFixit: - """A single object to represent each suggestion. - - Attributes: - filename (str): The source file that the suggestion concerns. - replaced_lines (list): A list of - [`FormatReplacementLine`][ - cpp_linter.clang_format_xml.FormatReplacementLine] - representing replacement(s) on a single line. - """ - - def __init__(self, filename: str): - """ - Args: - filename: The source file's name for which the contents of the xml - file exported by clang-tidy. - """ - self.filename = PurePath(filename).as_posix() - self.replaced_lines: List[FormatReplacementLine] = [] - - def __repr__(self) -> str: - return ( - f"" - ) - - def log_command(self, style: str, line_filter: List[int]) -> Optional[str]: - """Output a notification as a github log command. - - !!! info See Also - - [An error message](https://docs.github.com/en/actions/learn-github- - actions/workflow-commands-for-github-actions#setting-an-error-message) - - [A warning message](https://docs.github.com/en/actions/learn-github- - actions/workflow-commands-for-github-actions#setting-a-warning-message) - - [A notice message](https://docs.github.com/en/actions/learn-github- - actions/workflow-commands-for-github-actions#setting-a-notice-message) - - Args: - style: The chosen code style guidelines. - """ - if style not in ("llvm", "google", "webkit", "mozilla", "gnu"): - # potentially the style parameter could be a str of JSON/YML syntax - style = "Custom" - else: - if style.startswith("llvm") or style.startswith("gnu"): - style = style.upper() - else: - style = style.title() - line_list = [] - for fix in self.replaced_lines: - if not line_filter or (line_filter and fix.line in line_filter): - line_list.append(str(fix.line)) - if not line_list: - return None - return ( - "::notice file={name},title=Run clang-format on {name}::" - "File {name} (lines {lines}): Code does not conform to {style_guide} " - "style guidelines.".format( - name=self.filename, - lines=", ".join(line_list), - style_guide=style, - ) - ) - - -def parse_format_replacements_xml(src_filename: str): - """Parse XML output of replacements from clang-format. Output is saved to - [`format_advice`][cpp_linter.GlobalParser.format_advice]. - - Args: - src_filename: The source file's name for which the contents of the xml - file exported by clang-tidy. - """ - tree = ET.parse("clang_format_output.xml") - fixit = XMLFixit(src_filename) - for child in tree.getroot(): - if child.tag == "replacement": - offset = int(child.attrib["offset"]) - line, cols = get_line_cnt_from_cols(src_filename, offset) - null_len = int(child.attrib["length"]) - text = "" if child.text is None else child.text - fix = FormatReplacement(cols, null_len, text) - if not fixit.replaced_lines or ( - fixit.replaced_lines and line != fixit.replaced_lines[-1].line - ): - line_fix = FormatReplacementLine(line) - line_fix.replacements.append(fix) - fixit.replaced_lines.append(line_fix) - elif fixit.replaced_lines and line == fixit.replaced_lines[-1].line: - fixit.replaced_lines[-1].replacements.append(fix) - GlobalParser.format_advice.append(fixit) diff --git a/cpp_linter/clang_tidy.py b/cpp_linter/clang_tidy.py deleted file mode 100644 index 3eb0167c..00000000 --- a/cpp_linter/clang_tidy.py +++ /dev/null @@ -1,119 +0,0 @@ -"""Parse output from clang-tidy's stdout""" -from pathlib import Path, PurePath -import re -from typing import Tuple, Union, List, cast -from . import GlobalParser - -NOTE_HEADER = re.compile(r"^(.*):(\d+):(\d+):\s(\w+):(.*)\[(.*)\]$") - - -class TidyNotification: - """Create a object that decodes info from the clang-tidy output's initial line that - details a specific notification. - - Attributes: - diagnostic (str): The clang-tidy check that enabled the notification. - filename (str): The source filename concerning the notification. - line (int): The line number of the source file. - cols (int): The columns of the line that triggered the notification. - note_type (str): The priority level of notification (warning/error). - note_info (str): The rationale of the notification. - fixit_lines (list): A `list` of lines (`str`) for the code-block in the - notification. - """ - - def __init__( - self, - notification_line: Tuple[str, Union[int, str], Union[int, str], str, str, str], - ): - """ - Args: - notification_line: The first line in the notification parsed into a tuple of - string that represent the different components of the notification's - details. - """ - # logger.debug("Creating tidy note from line %s", notification_line) - ( - self.filename, - self.line, - self.cols, - self.note_type, - self.note_info, - self.diagnostic, - ) = notification_line - - self.note_info = self.note_info.strip() - self.note_type = self.note_type.strip() - self.line = int(self.line) - self.cols = int(self.cols) - self.filename = ( - PurePath(self.filename).as_posix().replace(Path.cwd().as_posix(), "") - ) - self.fixit_lines: List[str] = [] - - def __repr__(self) -> str: - concerned_code = "" - if self.fixit_lines: - if not self.fixit_lines[-1].endswith("\n"): - # some notifications' code-blocks don't end in a LF - self.fixit_lines[-1] += "\n" # and they should for us - concerned_code = "```{}\n{}```\n".format( - PurePath(self.filename).suffix.lstrip("."), - "\n".join(self.fixit_lines), - ) - return ( - "
\n{}:{}:{}: {}: [{}]" - "\n\n> {}\n

\n\n{}

\n
\n\n".format( - self.filename, - self.line, - self.cols, - self.note_type, - self.diagnostic, - self.note_info, - concerned_code, - ) - ) - - def log_command(self) -> str: - """Output the notification as a github log command. - - !!! info See Also - - [An error message](https://docs.github.com/en/actions/learn-github- - actions/workflow-commands-for-github-actions#setting-an-error-message) - - [A warning message](https://docs.github.com/en/actions/learn-github- - actions/workflow-commands-for-github-actions#setting-a-warning-message) - - [A notice message](https://docs.github.com/en/actions/learn-github- - actions/workflow-commands-for-github-actions#setting-a-notice-message) - """ - filename = self.filename.replace("\\", "/") - return ( - "::{} file={file},line={line},title={file}:{line}:{cols} [{diag}]::" - "{info}".format( - "notice" if self.note_type.startswith("note") else self.note_type, - file=filename, - line=self.line, - cols=self.cols, - diag=self.diagnostic, - info=self.note_info, - ) - ) - - -def parse_tidy_output() -> None: - """Parse clang-tidy output in a file created from stdout.""" - notification = None - tidy_out = Path("clang_tidy_report.txt").read_text(encoding="utf-8") - for line in tidy_out.splitlines(): - match = re.match(NOTE_HEADER, line) - if match is not None: - notification = TidyNotification( - cast( - Tuple[str, Union[int, str], Union[int, str], str, str, str], - match.groups(), - ) - ) - GlobalParser.tidy_notes.append(notification) - elif notification is not None: - # append lines of code that are part of - # the previous line's notification - notification.fixit_lines.append(line) diff --git a/cpp_linter/clang_tidy_yml.py b/cpp_linter/clang_tidy_yml.py deleted file mode 100644 index 26de4e7c..00000000 --- a/cpp_linter/clang_tidy_yml.py +++ /dev/null @@ -1,135 +0,0 @@ -"""Parse output from clang-tidy's YML format""" -from pathlib import Path, PurePath -from typing import List, cast, Dict, Any -import yaml -from . import GlobalParser, get_line_cnt_from_cols, logger - - -CWD_HEADER_GUARD = bytes( - "_".join([p.upper().replace("-", "_") for p in Path.cwd().parts]), encoding="utf-8" -) #: The constant used to trim absolute paths from header guard suggestions. - - -class TidyDiagnostic: - """Create an object that represents a diagnostic output found in the - YAML exported from clang-tidy. - - Attributes: - name (str): The diagnostic name - message (str): The diagnostic message - line (int): The line number that triggered the diagnostic - cols (int): The columns of the `line` that triggered the diagnostic - null_len (int): The number of bytes replaced by suggestions - replacements (list): The `list` of - [`TidyReplacement`][cpp_linter.clang_tidy_yml.TidyReplacement] objects. - - """ - - def __init__(self, diagnostic_name: str): - """ - Args: - diagnostic_name: The name of the check that got triggered. - """ - self.name = diagnostic_name - self.message = "" - self.line = 0 - self.cols = 0 - self.null_len = 0 - self.replacements: List["TidyReplacement"] = [] - - def __repr__(self): - """a str representation of all attributes.""" - return ( - f"" - ) - - -class TidyReplacement: - """Create an object representing a clang-tidy suggested replacement. - - Attributes: - line (int): The replacement content's starting line - cols (int): The replacement content's starting columns - null_len (int): The number of bytes discarded from `cols` - text (bytes): The replacement content's text. - """ - - def __init__(self, line_cnt: int, cols: int, length: int): - """ - Args: - line_cnt: The replacement content's starting line - cols: The replacement content's starting columns - length: The number of bytes discarded from `cols` - """ - self.line = line_cnt - self.cols = cols - self.null_len = length - self.text: bytes = b"" - - def __repr__(self) -> str: - return ( - f"" - ) - - -class YMLFixit: - """A single object to represent each suggestion. - - Attributes: - filename (str): The source file's name concerning the suggestion. - diagnostics (list): The `list` of - [`TidyDiagnostic`][cpp_linter.clang_tidy_yml.TidyDiagnostic] objects. - """ - - def __init__(self, filename: str) -> None: - """ - Args: - filename: The source file's name (with path) concerning the suggestion. - """ - self.filename = PurePath(filename).relative_to(Path.cwd()).as_posix() - self.diagnostics: List[TidyDiagnostic] = [] - - def __repr__(self) -> str: - return ( - f"" - ) - - -def parse_tidy_suggestions_yml(): - """Read a YAML file from clang-tidy and create a list of suggestions from it. - Output is saved to [`tidy_advice`][cpp_linter.GlobalParser.tidy_advice]. - """ - yml_file = Path("clang_tidy_output.yml").read_text(encoding="utf-8") - yml = yaml.safe_load(yml_file) - fixit = YMLFixit(yml["MainSourceFile"]) - - for diag_results in yml["Diagnostics"]: - diag = TidyDiagnostic(diag_results["DiagnosticName"]) - if "DiagnosticMessage" in cast(Dict[str, Any], diag_results).keys(): - msg = diag_results["DiagnosticMessage"]["Message"] - offset = diag_results["DiagnosticMessage"]["FileOffset"] - replacements = diag_results["DiagnosticMessage"]["Replacements"] - else: # prior to clang-tidy v9, the YML output was structured differently - msg = diag_results["Message"] - offset = diag_results["FileOffset"] - replacements = diag_results["Replacements"] - diag.message = msg - diag.line, diag.cols = get_line_cnt_from_cols(yml["MainSourceFile"], offset) - for replacement in [] if replacements is None else replacements: - line_cnt, cols = get_line_cnt_from_cols( - yml["MainSourceFile"], replacement["Offset"] - ) - fix = TidyReplacement(line_cnt, cols, replacement["Length"]) - fix.text = bytes(replacement["ReplacementText"], encoding="utf-8") - if fix.text.startswith(b"header is missing header guard"): - logger.debug( - "filtering header guard suggestion (making relative to repo root)" - ) - fix.text = fix.text.replace(CWD_HEADER_GUARD, b"") - diag.replacements.append(fix) - fixit.diagnostics.append(diag) - # filter out absolute header guards - GlobalParser.tidy_advice.append(fixit) diff --git a/cpp_linter/run.py b/cpp_linter/run.py deleted file mode 100644 index 082fdfe7..00000000 --- a/cpp_linter/run.py +++ /dev/null @@ -1,898 +0,0 @@ -"""Run clang-tidy and clang-format on a list of changed files provided by GitHub's -REST API. If executed from command-line, then [`main()`][cpp_linter.run.main] is -the entrypoint. - -!!! info "See Also" - - [github rest API reference for pulls]( - https://docs.github.com/en/rest/reference/pulls) - - [github rest API reference for repos]( - https://docs.github.com/en/rest/reference/repos) - - [github rest API reference for issues]( - https://docs.github.com/en/rest/reference/issues) -""" -import subprocess -from pathlib import Path, PurePath -import os -import sys -import argparse -import configparser -import json -from typing import cast, List, Dict, Any, Tuple -import requests -from . import ( - Globals, - GlobalParser, - logging, - logger, - GITHUB_TOKEN, - GITHUB_SHA, - API_HEADERS, - IS_ON_RUNNER, - log_response_msg, - range_of_changed_lines, - assemble_version_exec, -) -from .clang_tidy_yml import parse_tidy_suggestions_yml -from .clang_format_xml import parse_format_replacements_xml -from .clang_tidy import parse_tidy_output, TidyNotification -from .thread_comments import remove_bot_comments, list_diff_comments # , get_review_id - - -# global constant variables -GITHUB_EVENT_PATH = os.getenv("GITHUB_EVENT_PATH", "") -GITHUB_API_URL = os.getenv("GITHUB_API_URL", "https://api.github.com") -GITHUB_REPOSITORY = os.getenv("GITHUB_REPOSITORY", "") -GITHUB_EVENT_NAME = os.getenv("GITHUB_EVENT_NAME", "unknown") -GITHUB_WORKSPACE = os.getenv("GITHUB_WORKSPACE", "") -IS_USING_DOCKER = os.getenv("USING_CLANG_TOOLS_DOCKER", os.getenv("CLANG_VERSIONS")) -RUNNER_WORKSPACE = "/github/workspace" if IS_USING_DOCKER else GITHUB_WORKSPACE - -# setup CLI args -cli_arg_parser = argparse.ArgumentParser( - description=__doc__[: __doc__.find("If executed from")] -) -cli_arg_parser.add_argument( - "-v", - "--verbosity", - type=int, - default=10, - help="The logging level. Defaults to level 20 (aka 'logging.INFO').", -) -cli_arg_parser.add_argument( - "-p", - "--database", - default="", - help="-p is used to read a compile command database." - "For example, it can be a CMake build directory in which a file named" - "compile_commands.json exists (use -DCMAKE_EXPORT_COMPILE_COMMANDS=ON" - "CMake option to get this output). When no build path is specified," - "a search for compile_commands.json will be attempted through all" - "parent paths of the first input file . See:" - "https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an" - "example of setting up Clang Tooling on a source tree.", -) -cli_arg_parser.add_argument( - "-s", - "--style", - default="llvm", - help="The style rules to use (defaults to 'llvm'). Set this to 'file' to have " - "clang-format use the closest relative .clang-format file.", -) -cli_arg_parser.add_argument( - "-c", - "--tidy-checks", - default="boost-*,bugprone-*,performance-*,readability-*,portability-*,modernize-*," - "clang-analyzer-*,cppcoreguidelines-*", - help="A string of regex-like patterns specifying what checks clang-tidy will use. " - "This defaults to %(default)s. See also clang-tidy docs for more info.", -) -cli_arg_parser.add_argument( - "-V", - "--version", - default="", - help="The desired version of the clang tools to use. Accepted options are strings " - "which can be 8, 9, 10, 11, 12, 13, 14. Defaults to '%(default)s'. On Windows, " - "this can also be a path to the install location of LLVM", -) -cli_arg_parser.add_argument( - "-e", - "--extensions", - default=["c", "h", "C", "H", "cpp", "hpp", "cc", "hh", "c++", "h++", "cxx", "hxx"], - type=lambda i: [ext.strip().lstrip(".") for ext in i.split(",")], - help="The file extensions to run the action against. This comma-separated string " - "defaults to %(default)s.", -) -cli_arg_parser.add_argument( - "-r", - "--repo-root", - default=".", - help="The relative path to the repository root directory. The default value " - "'%(default)s' is relative to the runner's GITHUB_WORKSPACE environment variable.", -) -cli_arg_parser.add_argument( - "-i", - "--ignore", - default=".github", - help="Set this option with paths to ignore. In the case of multiple " - "paths, you can set this option (multiple times) for each path. This can " - "also have files, but the file's relative path has to be specified as well " - "with the filename. Prefix a path with '!' to explicitly not ignore it.", -) -cli_arg_parser.add_argument( - "-l", - "--lines-changed-only", - default=0, - type=lambda a: 2 if a.lower() == "true" else (1 if a.lower() == "diff" else 0), - help="Set this option to 'true' to only analyze changes in the event's diff. " - "Set this to 'strict' to only analyze additions in the event's diff. " - "Defaults to %(default)s.", -) -cli_arg_parser.add_argument( - "-f", - "--files-changed-only", - default="false", - type=lambda input: input.lower() == "true", - help="Set this option to 'false' to analyze any source files in the repo. " - "Defaults to %(default)s.", -) -cli_arg_parser.add_argument( - "-t", - "--thread-comments", - default="false", - type=lambda input: input.lower() == "true", - help="Set this option to false to disable the use of thread comments as feedback." - "Defaults to %(default)s.", -) -cli_arg_parser.add_argument( - "-a", - "--file-annotations", - default="true", - type=lambda input: input.lower() == "true", - help="Set this option to false to disable the use of file annotations as feedback." - "Defaults to %(default)s.", -) - - -def set_exit_code(override: int = None) -> int: - """Set the action's exit code. - - Args: - override: The number to use when overriding the action's logic. - - Returns: - The exit code that was used. If the `override` parameter was not passed, - then this value will describe (like a bool value) if any checks failed. - """ - exit_code = override if override is not None else bool(Globals.OUTPUT) - print(f"::set-output name=checks-failed::{exit_code}") - return exit_code - - -# setup a separate logger for using github log commands -log_commander = logging.getLogger("LOG COMMANDER") # create a child of our logger obj -log_commander.setLevel(logging.DEBUG) # be sure that log commands are output -console_handler = logging.StreamHandler() # Create special stdout stream handler -console_handler.setFormatter(logging.Formatter("%(message)s")) # no formatted log cmds -log_commander.addHandler(console_handler) # Use special handler for log_commander -log_commander.propagate = False - - -def start_log_group(name: str) -> None: - """Begin a collapsable group of log statements. - - Args: - name: The name of the collapsable group - """ - log_commander.fatal("::group::%s", name) - - -def end_log_group() -> None: - """End a collapsable group of log statements.""" - log_commander.fatal("::endgroup::") - - -def is_file_in_list(paths: List[str], file_name: str, prompt: str) -> bool: - """Determine if a file is specified in a list of paths and/or filenames. - - Args: - paths: A list of specified paths to compare with. This list can contain a - specified file, but the file's path must be included as part of the - filename. - file_name: The file's path & name being sought in the `paths` list. - prompt: A debugging prompt to use when the path is found in the list. - Returns: - - True if `file_name` is in the `paths` list. - - False if `file_name` is not in the `paths` list. - """ - for path in paths: - result = os.path.commonpath( - [PurePath(path).as_posix(), PurePath(file_name).as_posix()] - ) - if result == path: - logger.debug( - '"./%s" is %s as specified in the domain "./%s"', - file_name, - prompt, - path, - ) - return True - return False - - -def get_list_of_changed_files() -> None: - """Fetch the JSON payload of the event's changed files. Sets the - [`FILES`][cpp_linter.Globals.FILES] attribute.""" - start_log_group("Get list of specified source files") - files_link = f"{GITHUB_API_URL}/repos/{GITHUB_REPOSITORY}/" - if GITHUB_EVENT_NAME == "pull_request": - files_link += f"pulls/{Globals.EVENT_PAYLOAD['number']}/files" - else: - if GITHUB_EVENT_NAME != "push": - logger.warning( - "Triggered on unsupported event '%s'. Behaving like a push event.", - GITHUB_EVENT_NAME, - ) - files_link += f"commits/{GITHUB_SHA}" - logger.info("Fetching files list from url: %s", files_link) - Globals.response_buffer = requests.get(files_link, headers=API_HEADERS) - log_response_msg() - if GITHUB_EVENT_NAME == "pull_request": - Globals.FILES = Globals.response_buffer.json() - else: - Globals.FILES = Globals.response_buffer.json()["files"] - - -def consolidate_list_to_ranges(just_numbers: List[int]) -> List[List[int]]: - """A helper function to [`filter_out_non_source_files()`] that is only used when - extracting the lines from a diff that contain additions.""" - result: List[List[int]] = [] - for i, n in enumerate(just_numbers): - if not i: - result.append([n]) - elif n - 1 != just_numbers[i - 1]: - result[-1].append(just_numbers[i - 1] + 1) - result.append([n]) - if i == len(just_numbers) - 1: - result[-1].append(n + 1) - return result - - -def filter_out_non_source_files( - ext_list: List[str], - ignored: List[str], - not_ignored: List[str], -) -> bool: - """Exclude undesired files (specified by user input 'extensions'). This filter - applies to the event's [`FILES`][cpp_linter.Globals.FILES] attribute. - - Args: - ext_list: A list of file extensions that are to be examined. - ignored: A list of paths to explicitly ignore. - not_ignored: A list of paths to explicitly not ignore. - - Returns: - True if there are files to check. False will invoke a early exit (in - [`main()`][cpp_linter.run.main]) when no files to be checked. - """ - files = [] - for file in Globals.FILES: - if ( - PurePath(file["filename"]).suffix.lstrip(".") in ext_list - and not file["status"].endswith("removed") - and ( - not is_file_in_list(ignored, file["filename"], "ignored") - or is_file_in_list(not_ignored, file["filename"], "not ignored") - ) - ): - if "patch" in file.keys(): - # get diff details for the file's changes - # ranges is a list of start/end line numbers shown in the diff - ranges: List[List[int]] = [] - # additions is a list line numbers in the diff containing additions - additions: List[int] = [] - line_numb_in_diff: int = 0 - for line in cast(str, file["patch"]).splitlines(): - if line.startswith("+"): - additions.append(line_numb_in_diff) - if line.startswith("@@ -"): - hunk = line[line.find(" +") + 2 : line.find(" @@")].split(",") - start_line, hunk_length = [int(x) for x in hunk] - ranges.append([start_line, hunk_length + start_line]) - line_numb_in_diff = start_line - elif not line.startswith("-"): - line_numb_in_diff += 1 - file["line_filter"] = dict( - diff_chunks=ranges, - lines_added=consolidate_list_to_ranges(additions), - ) - files.append(file) - - if files: - logger.info( - "Giving attention to the following files:\n\t%s", - "\n\t".join([f["filename"] for f in files]), - ) - Globals.FILES = files - if not IS_ON_RUNNER: # if not executed on a github runner - # dump altered json of changed files - Path(".changed_files.json").write_text( - json.dumps(Globals.FILES, indent=2), - encoding="utf-8", - ) - else: - logger.info("No source files need checking!") - return False - return True - - -def verify_files_are_present() -> None: - """Download the files if not present. - - !!! hint - This function assumes the working directory is the root of the invoking - repository. If files are not found, then they are downloaded to the working - directory. This is bad for files with the same name from different folders. - """ - for file in Globals.FILES: - file_name = Path(file["filename"]) - if not file_name.exists(): - logger.warning("Could not find %s! Did you checkout the repo?", file_name) - logger.info("Downloading file from url: %s", file["raw_url"]) - Globals.response_buffer = requests.get(file["raw_url"]) - # retain the repo's original structure - Path.mkdir(file_name.parent, parents=True, exist_ok=True) - file_name.write_text(Globals.response_buffer.text, encoding="utf-8") - - -def list_source_files( - ext_list: List[str], ignored_paths: List[str], not_ignored: List[str] -) -> bool: - """Make a list of source files to be checked. The resulting list is stored in - [`FILES`][cpp_linter.Globals.FILES]. - - Args: - ext_list: A list of file extensions that should by attended. - ignored_paths: A list of paths to explicitly ignore. - not_ignored: A list of paths to explicitly not ignore. - - Returns: - True if there are files to check. False will invoke a early exit (in - [`main()`][cpp_linter.run.main]) when no files to be checked. - """ - start_log_group("Get list of specified source files") - - root_path = Path(".") - for ext in ext_list: - for rel_path in root_path.rglob(f"*.{ext}"): - for parent in rel_path.parts[:-1]: - if parent.startswith("."): - break - else: - file_path = rel_path.as_posix() - logger.debug('"./%s" is a source code file', file_path) - if not is_file_in_list( - ignored_paths, file_path, "ignored" - ) or is_file_in_list(not_ignored, file_path, "not ignored"): - Globals.FILES.append(dict(filename=file_path)) - - if Globals.FILES: - logger.info( - "Giving attention to the following files:\n\t%s", - "\n\t".join([f["filename"] for f in Globals.FILES]), - ) - else: - logger.info("No source files found.") # this might need to be warning - return False - return True - - -def run_clang_tidy( - filename: str, - file_obj: Dict[str, Any], - version: str, - checks: str, - lines_changed_only: int, - database: str, - repo_root: str, -) -> None: - """Run clang-tidy on a certain file. - - Args: - filename: The name of the local file to run clang-tidy on. - file_obj: JSON info about the file. - version: The version of clang-tidy to run. - checks: The `str` of comma-separated regulate expressions that describe - the desired clang-tidy checks to be enabled/configured. - lines_changed_only: A flag that forces focus on only changes in the event's - diff info. - """ - if checks == "-*": # if all checks are disabled, then clang-tidy is skipped - # clear the clang-tidy output file and exit function - Path("clang_tidy_report.txt").write_bytes(b"") - return - filename = PurePath(filename).as_posix() - cmds = [ - assemble_version_exec("clang-tidy", version), - "--export-fixes=clang_tidy_output.yml", - ] - if checks: - cmds.append(f"-checks={checks}") - if database: - cmds.append("-p") - if not PurePath(database).is_absolute(): - database = str(Path(RUNNER_WORKSPACE, repo_root, database).resolve()) - cmds.append(database) - if lines_changed_only: - ranges = "diff_chunks" if lines_changed_only == 1 else "lines_added" - line_ranges = dict(name=filename, lines=file_obj["line_filter"][ranges]) - logger.info("line_filter = %s", json.dumps([line_ranges])) - cmds.append(f"--line-filter={json.dumps([line_ranges])}") - cmds.append(filename) - # clear yml file's content before running clang-tidy - Path("clang_tidy_output.yml").write_bytes(b"") - logger.info('Running "%s"', " ".join(cmds)) - results = subprocess.run(cmds, capture_output=True) - Path("clang_tidy_report.txt").write_bytes(results.stdout) - logger.debug("Output from clang-tidy:\n%s", results.stdout.decode()) - if Path("clang_tidy_output.yml").stat().st_size: - parse_tidy_suggestions_yml() # get clang-tidy fixes from yml - if results.stderr: - logger.debug( - "clang-tidy made the following summary:\n%s", results.stderr.decode() - ) - - -def run_clang_format( - filename: str, - file_obj: Dict[str, Any], - version: str, - style: str, - lines_changed_only: int, -) -> None: - """Run clang-format on a certain file - - Args: - filename: The name of the local file to run clang-format on. - file_obj: JSON info about the file. - version: The version of clang-format to run. - style: The clang-format style rules to adhere. Set this to 'file' to - use the relative-most .clang-format configuration file. - lines_changed_only: A flag that forces focus on only changes in the event's - diff info. - """ - if not style: # if `style` == "" - Path("clang_format_output.xml").write_bytes(b"") - return # clear any previous output and exit - cmds = [ - assemble_version_exec("clang-format", version), - f"-style={style}", - "--output-replacements-xml", - ] - if lines_changed_only: - ranges = "diff_chunks" if lines_changed_only == 1 else "lines_added" - for line_range in file_obj["line_filter"][ranges]: - cmds.append(f"--lines={line_range[0]}:{line_range[1]}") - cmds.append(PurePath(filename).as_posix()) - logger.info('Running "%s"', " ".join(cmds)) - results = subprocess.run(cmds, capture_output=True) - Path("clang_format_output.xml").write_bytes(results.stdout) - if results.returncode: - logger.debug( - "%s raised the following error(s):\n%s", cmds[0], results.stderr.decode() - ) - - -def create_comment_body( - filename: str, - file_obj: Dict[str, Any], - lines_changed_only: int, - tidy_notes: List[TidyNotification], -): - """Create the content for a thread comment about a certain file. - This is a helper function to [`capture_clang_tools_output()`]. - - Args: - filename: The file's name (& path). - file_obj: The file's JSON `dict`. - lines_changed_only: A flag used to filter the comment based on line changes. - tidy_notes: A list of cached notifications from clang-tidy. This is used to - avoid duplicated content in comment, and it is later used again by - [`make_annotations()`] after [`capture_clang_tools_output()`] us finished. - """ - ranges = range_of_changed_lines(file_obj, lines_changed_only) - if Path("clang_tidy_report.txt").stat().st_size: - parse_tidy_output() # get clang-tidy fixes from stdout - comment_output = "" - if Globals.PAYLOAD_TIDY: - Globals.PAYLOAD_TIDY += "
" - for fix in GlobalParser.tidy_notes: - if lines_changed_only and fix.line not in ranges: - continue - comment_output += repr(fix) - tidy_notes.append(fix) - if comment_output: - Globals.PAYLOAD_TIDY += f"
{filename}
\n" - Globals.PAYLOAD_TIDY += comment_output - GlobalParser.tidy_notes.clear() # empty list to avoid duplicated output - - if Path("clang_format_output.xml").stat().st_size: - parse_format_replacements_xml(PurePath(filename).as_posix()) - if GlobalParser.format_advice and GlobalParser.format_advice[-1].replaced_lines: - should_comment = lines_changed_only == 0 - if not should_comment: - for line in [ - replacement.line - for replacement in GlobalParser.format_advice[-1].replaced_lines - ]: - if line in ranges: - should_comment = True - break - if should_comment: - if not Globals.OUTPUT: - Globals.OUTPUT = "\n## :scroll: " - Globals.OUTPUT += "Run `clang-format` on the following files\n" - Globals.OUTPUT += f"- [ ] {file_obj['filename']}\n" - - -def capture_clang_tools_output( - version: str, - checks: str, - style: str, - lines_changed_only: int, - database: str, - repo_root: str, -): - """Execute and capture all output from clang-tidy and clang-format. This aggregates - results in the [`OUTPUT`][cpp_linter.Globals.OUTPUT]. - - Args: - version: The version of clang-tidy to run. - checks: The `str` of comma-separated regulate expressions that describe - the desired clang-tidy checks to be enabled/configured. - style: The clang-format style rules to adhere. Set this to 'file' to - use the relative-most .clang-format configuration file. - lines_changed_only: A flag that forces focus on only changes in the event's - diff info. - """ - # temporary cache of parsed notifications for use in log commands - tidy_notes: List[TidyNotification] = [] - for file in Globals.FILES: - filename = cast(str, file["filename"]) - start_log_group(f"Performing checkup on {filename}") - run_clang_tidy( - filename, file, version, checks, lines_changed_only, database, repo_root - ) - run_clang_format(filename, file, version, style, lines_changed_only) - end_log_group() - - create_comment_body(filename, file, lines_changed_only, tidy_notes) - - if Globals.PAYLOAD_TIDY: - if not Globals.OUTPUT: - Globals.OUTPUT = "\n" - else: - Globals.OUTPUT += "\n---\n" - Globals.OUTPUT += "## :speech_balloon: Output from `clang-tidy`\n" - Globals.OUTPUT += Globals.PAYLOAD_TIDY - GlobalParser.tidy_notes = tidy_notes[:] # restore cache of notifications - - -def post_push_comment(base_url: str, user_id: int) -> bool: - """POST action's results for a push event. - - Args: - base_url: The root of the url used to interact with the REST API via `requests`. - user_id: The user's account ID number. - - Returns: - A bool describing if the linter checks passed. This is used as the action's - output value (a soft exit code). - """ - comments_url = base_url + f"commits/{GITHUB_SHA}/comments" - remove_bot_comments(comments_url, user_id) - - if Globals.OUTPUT: # diff comments are not supported for push events (yet) - payload = json.dumps({"body": Globals.OUTPUT}) - logger.debug("payload body:\n%s", json.dumps({"body": Globals.OUTPUT})) - Globals.response_buffer = requests.post( - comments_url, headers=API_HEADERS, data=payload - ) - logger.info( - "Got %d response from POSTing comment", Globals.response_buffer.status_code - ) - log_response_msg() - return bool(Globals.OUTPUT) - - -def post_diff_comments(base_url: str, user_id: int) -> bool: - """Post comments inside a unified diff (only PRs are supported). - - Args: - base_url: The root of the url used to interact with the REST API via `requests`. - user_id: The user's account ID number. - - Returns: - A bool describing if the linter checks passed. This is used as the action's - output value (a soft exit code). - """ - comments_url = base_url + "pulls/comments/" # for use with comment_id - payload = list_diff_comments(2) # only focus on additions in diff - logger.info("Posting %d comments", len(payload)) - - # uncomment the next 3 lines for debug output without posting a comment - # for i, comment in enumerate(payload): - # logger.debug("comments %d: %s", i, json.dumps(comment, indent=2)) - # return - - # get existing review comments - reviews_url = base_url + f'pulls/{Globals.EVENT_PAYLOAD["number"]}/' - Globals.response_buffer = requests.get(reviews_url + "comments") - existing_comments = json.loads(Globals.response_buffer.text) - # filter out comments not made by our bot - for index, comment in enumerate(existing_comments): - if not comment["body"].startswith(""): - del existing_comments[index] - - # conditionally post comments in the diff - for i, body in enumerate(payload): - # check if comment is already there - already_posted = False - comment_id = None - for comment in existing_comments: - if ( - int(comment["user"]["id"]) == user_id - and comment["line"] == body["line"] - and comment["path"] == body["path"] - ): - already_posted = True - if comment["body"] != body["body"]: - comment_id = str(comment["id"]) # use this to update comment - else: - break - if already_posted and comment_id is None: - logger.info("comment %d already posted", i) - continue # don't bother re-posting the same comment - - # update ot create a review comment (in the diff) - logger.debug("Payload %d body = %s", i, json.dumps(body)) - if comment_id is not None: - Globals.response_buffer = requests.patch( - comments_url + comment_id, - headers=API_HEADERS, - data=json.dumps({"body": body["body"]}), - ) - logger.info( - "Got %d from PATCHing comment %d (%d)", - Globals.response_buffer.status_code, - i, - comment_id, - ) - log_response_msg() - else: - Globals.response_buffer = requests.post( - reviews_url + "comments", headers=API_HEADERS, data=json.dumps(body) - ) - logger.info( - "Got %d from POSTing review comment %d", - Globals.response_buffer.status_code, - i, - ) - log_response_msg() - return bool(payload) - - -def post_pr_comment(base_url: str, user_id: int) -> bool: - """POST action's results for a push event. - - Args: - base_url: The root of the url used to interact with the REST API via `requests`. - user_id: The user's account ID number. - - Returns: - A bool describing if the linter checks passed. This is used as the action's - output value (a soft exit code). - """ - comments_url = base_url + f'issues/{Globals.EVENT_PAYLOAD["number"]}/comments' - remove_bot_comments(comments_url, user_id) - payload = "" - if Globals.OUTPUT: - payload = json.dumps({"body": Globals.OUTPUT}) - logger.debug( - "payload body:\n%s", json.dumps({"body": Globals.OUTPUT}, indent=2) - ) - Globals.response_buffer = requests.post( - comments_url, headers=API_HEADERS, data=payload - ) - logger.info("Got %d from POSTing comment", Globals.response_buffer.status_code) - log_response_msg() - return bool(payload) - - -def post_results(use_diff_comments: bool, user_id: int = 41898282): - """Post action's results using REST API. - - Args: - use_diff_comments: This flag enables making/updating comments in the PR's diff - info. - user_id: The user's account ID number. Defaults to the generic bot's ID. - """ - if not GITHUB_TOKEN: - logger.error("The GITHUB_TOKEN is required!") - sys.exit(set_exit_code(1)) - - base_url = f"{GITHUB_API_URL}/repos/{GITHUB_REPOSITORY}/" - checks_passed = True - if GITHUB_EVENT_NAME == "pull_request": - checks_passed = post_pr_comment(base_url, user_id) - if use_diff_comments: - checks_passed = post_diff_comments(base_url, user_id) - elif GITHUB_EVENT_NAME == "push": - checks_passed = post_push_comment(base_url, user_id) - set_exit_code(1 if checks_passed else 0) - - -def make_annotations( - style: str, file_annotations: bool, lines_changed_only: int -) -> bool: - """Use github log commands to make annotations from clang-format and - clang-tidy output. - - Args: - style: The chosen code style guidelines. The value 'file' is replaced with - 'custom style'. - """ - count = 0 - files = ( - Globals.FILES - if GITHUB_EVENT_NAME == "pull_request" or isinstance(Globals.FILES, list) - else cast(Dict[str, Any], Globals.FILES)["files"] - ) - for advice, file in zip(GlobalParser.format_advice, files): - line_filter = range_of_changed_lines(file, lines_changed_only) - if advice.replaced_lines: - if file_annotations: - output = advice.log_command(style, line_filter) - if output is not None: - log_commander.info(output) - count += 1 - for note in GlobalParser.tidy_notes: - if lines_changed_only: - filename = note.filename.replace("\\", "/") - line_filter = [] - for file in files: - if filename == file["filename"]: - line_filter = range_of_changed_lines(file, lines_changed_only) - break - else: - continue - if note.line in line_filter: - count += 1 - log_commander.info(note.log_command()) - else: - count += 1 - log_commander.info(note.log_command()) - logger.info("Created %d annotations", count) - return bool(count) - - -def parse_ignore_option(paths: str) -> Tuple[List[str], List[str]]: - """Parse a given string of paths (separated by a '|') into `ignored` and - `not_ignored` lists of strings. - - Args: - paths: This argument conforms to the CLI arg `--ignore` (or `-i`). - - Returns: Returns a tuple of lists in which each list is a set of strings. - index 0 is the `ignored` list - index 1 is the `not_ignored` list - """ - ignored, not_ignored = ([], []) - - for path in paths.split("|"): - is_included = path.startswith("!") - if path.startswith("!./" if is_included else "./"): - path = path.replace("./", "", 1) # relative dir is assumed - path = path.strip() # strip leading/trailing spaces - if is_included: - not_ignored.append(path[1:]) # strip leading `!` - else: - ignored.append(path) - - # auto detect submodules - gitmodules = Path(".gitmodules") - if gitmodules.exists(): - submodules = configparser.ConfigParser() - submodules.read(gitmodules.resolve().as_posix()) - for module in submodules.sections(): - path = submodules[module]["path"] - if path not in not_ignored: - logger.info("Appending submodule to ignored paths: %s", path) - ignored.append(path) - - if ignored: - logger.info( - "Ignoring the following paths/files:\n\t./%s", - "\n\t./".join(f for f in ignored), - ) - if not_ignored: - logger.info( - "Not ignoring the following paths/files:\n\t./%s", - "\n\t./".join(f for f in not_ignored), - ) - return (ignored, not_ignored) - - -def main(): - """The main script.""" - - # The parsed CLI args - args = cli_arg_parser.parse_args() - - # force files-changed-only to reflect value of lines-changed-only - if args.lines_changed_only: - args.files_changed_only = True - - # set logging verbosity - logger.setLevel(int(args.verbosity)) - - # prepare ignored paths list - ignored, not_ignored = parse_ignore_option(args.ignore) - - logger.info("processing %s event", GITHUB_EVENT_NAME) - - # change working directory - os.chdir(args.repo_root) - - if GITHUB_EVENT_PATH: - # load event's json info about the workflow run - Globals.EVENT_PAYLOAD = json.loads( - Path(GITHUB_EVENT_PATH).read_text(encoding="utf-8") - ) - if logger.getEffectiveLevel() <= logging.DEBUG: - start_log_group("Event json from the runner") - logger.debug(json.dumps(Globals.EVENT_PAYLOAD)) - end_log_group() - - exit_early = False - if args.files_changed_only: - get_list_of_changed_files() - exit_early = not filter_out_non_source_files( - args.extensions, - ignored, - not_ignored, - ) - if not exit_early: - verify_files_are_present() - else: - exit_early = not list_source_files(args.extensions, ignored, not_ignored) - end_log_group() - if exit_early: - sys.exit(set_exit_code(0)) - - capture_clang_tools_output( - args.version, - args.tidy_checks, - args.style, - args.lines_changed_only, - args.database, - args.repo_root, - ) - - start_log_group("Posting comment(s)") - thread_comments_allowed = True - if GITHUB_EVENT_PATH and "private" in Globals.EVENT_PAYLOAD["repository"]: - thread_comments_allowed = ( - Globals.EVENT_PAYLOAD["repository"]["private"] is not True - ) - if args.thread_comments and thread_comments_allowed: - post_results(False) # False is hard-coded to disable diff comments. - set_exit_code( - int( - make_annotations(args.style, args.file_annotations, args.lines_changed_only) - ) - ) - end_log_group() - - -if __name__ == "__main__": - main() diff --git a/cpp_linter/thread_comments.py b/cpp_linter/thread_comments.py deleted file mode 100644 index 915eb776..00000000 --- a/cpp_linter/thread_comments.py +++ /dev/null @@ -1,260 +0,0 @@ -"""A module to house the various functions for traversing/adjusting comments""" -from typing import Union, cast, List, Optional, Dict, Any -import json -from pathlib import Path -import requests -from . import ( - Globals, - GlobalParser, - logger, - API_HEADERS, - GITHUB_SHA, - log_response_msg, - range_of_changed_lines, -) - - -def remove_bot_comments(comments_url: str, user_id: int): - """Traverse the list of comments made by a specific user - and remove all. - - Args: - comments_url: The URL used to fetch the comments. - user_id: The user's account id number. - """ - logger.info("comments_url: %s", comments_url) - Globals.response_buffer = requests.get(comments_url) - if not log_response_msg(): - return # error getting comments for the thread; stop here - comments = Globals.response_buffer.json() - for comment in comments: - # only search for comments from the user's ID and - # whose comment body begins with a specific html comment - if ( - int(comment["user"]["id"]) == user_id - # the specific html comment is our action's name - and comment["body"].startswith("") - ): - # remove other outdated comments but don't remove the last comment - Globals.response_buffer = requests.delete( - comment["url"], - headers=API_HEADERS, - ) - logger.info( - "Got %d from DELETE %s", - Globals.response_buffer.status_code, - comment["url"][comment["url"].find(".com") + 4 :], - ) - log_response_msg() - logger.debug( - "comment id %d from user %s (%d)", - comment["id"], - comment["user"]["login"], - comment["user"]["id"], - ) - with open("comments.json", "w", encoding="utf-8") as json_comments: - json.dump(comments, json_comments, indent=4) - - -def aggregate_tidy_advice(lines_changed_only: int) -> List[Dict[str, Any]]: - """Aggregate a list of json contents representing advice from clang-tidy - suggestions.""" - results = [] - for fixit, file in zip(GlobalParser.tidy_advice, Globals.FILES): - for diag in fixit.diagnostics: - ranges = range_of_changed_lines(file, lines_changed_only) - if lines_changed_only and diag.line not in ranges: - continue - - # base body of comment - body = "\n## :speech_balloon: Clang-tidy\n**" - body += diag.name + "**\n>" + diag.message - - # get original code - filename = Path(cast(str, file["filename"])) - # the list of lines in a file - lines = filename.read_text(encoding="utf-8").splitlines() - - # aggregate clang-tidy advice - suggestion = "\n```suggestion\n" - is_multiline_fix = False - fix_lines: List[int] = [] # a list of line numbers for the suggested fixes - line = "" # the line that concerns the fix/comment - for i, tidy_fix in enumerate(diag.replacements): - line = lines[tidy_fix.line - 1] - if not fix_lines: - fix_lines.append(tidy_fix.line) - elif tidy_fix.line not in fix_lines: - is_multiline_fix = True - break - if i: # if this isn't the first tidy_fix for the same line - last_fix = diag.replacements[i - 1] - suggestion += ( - line[last_fix.cols + last_fix.null_len - 1 : tidy_fix.cols - 1] - + tidy_fix.text.decode() - ) - else: - suggestion += line[: tidy_fix.cols - 1] + tidy_fix.text.decode() - if not is_multiline_fix and diag.replacements: - # complete suggestion with original src code and closing md fence - last_fix = diag.replacements[len(diag.replacements) - 1] - suggestion += line[last_fix.cols + last_fix.null_len - 1 : -1] + "\n```" - body += suggestion - - results.append( - dict( - body=body, - commit_id=GITHUB_SHA, - line=diag.line, - path=fixit.filename, - side="RIGHT", - ) - ) - return results - - -def aggregate_format_advice(lines_changed_only: int) -> List[Dict[str, Any]]: - """Aggregate a list of json contents representing advice from clang-format - suggestions.""" - results = [] - for fmt_advice, file in zip(GlobalParser.format_advice, Globals.FILES): - - # get original code - filename = Path(file["filename"]) - # the list of lines from the src file - lines = filename.read_text(encoding="utf-8").splitlines() - - # aggregate clang-format suggestion - line = "" # the line that concerns the fix - for fixed_line in fmt_advice.replaced_lines: - # clang-format can include advice that starts/ends outside the diff's domain - ranges = range_of_changed_lines(file, lines_changed_only) - if lines_changed_only and fixed_line.line not in ranges: - continue # line is out of scope for diff, so skip this fix - - # assemble the suggestion - body = "## :scroll: clang-format advice\n```suggestion\n" - line = lines[fixed_line.line - 1] - # logger.debug("%d >>> %s", fixed_line.line, line[:-1]) - for fix_index, line_fix in enumerate(fixed_line.replacements): - # logger.debug( - # "%s >>> %s", repr(line_fix), line_fix.text.encode("utf-8") - # ) - if fix_index: - last_fix = fixed_line.replacements[fix_index - 1] - body += line[ - last_fix.cols + last_fix.null_len - 1 : line_fix.cols - 1 - ] - body += line_fix.text - else: - body += line[: line_fix.cols - 1] + line_fix.text - # complete suggestion with original src code and closing md fence - last_fix = fixed_line.replacements[-1] - body += line[last_fix.cols + last_fix.null_len - 1 : -1] + "\n```" - # logger.debug("body <<< %s", body) - - # create a suggestion from clang-format advice - results.append( - dict( - body=body, - commit_id=GITHUB_SHA, - line=fixed_line.line, - path=fmt_advice.filename, - side="RIGHT", - ) - ) - return results - - -def concatenate_comments( - tidy_advice: list, format_advice: list -) -> List[Dict[str, Union[str, int]]]: - """Concatenate comments made to the same line of the same file.""" - # traverse comments from clang-format - for index, comment_body in enumerate(format_advice): - # check for comments from clang-tidy on the same line - comment_index = None - for i, payload in enumerate(tidy_advice): - if ( - payload["line"] == comment_body["line"] - and payload["path"] == comment_body["path"] - ): - comment_index = i # mark this comment for concatenation - break - if comment_index is not None: - # append clang-format advice to clang-tidy output/suggestion - tidy_advice[comment_index]["body"] += "\n" + comment_body["body"] - del format_advice[index] # remove duplicate comment - return tidy_advice + format_advice - - -def list_diff_comments(lines_changed_only: int) -> List[Dict[str, Union[str, int]]]: - """Aggregate list of comments for use in the event's diff. This function assumes - that the CLI option `--lines_changed_only` is set to True. - - Returns: - A list of comments (each element as json content). - """ - return concatenate_comments( - aggregate_tidy_advice(lines_changed_only), - aggregate_format_advice(lines_changed_only), - ) - - -def get_review_id(reviews_url: str, user_id: int) -> Optional[int]: - """Dismiss all stale reviews (only the ones made by our bot). - - Args: - reviews_url: The URL used to fetch the review comments. - user_id: The user's account id number. - Returns: - The ID number of the review created by the action's generic bot. - """ - logger.info(" review_url: %s", reviews_url) - Globals.response_buffer = requests.get(reviews_url) - review_id = find_review(json.loads(Globals.response_buffer.text), user_id) - if review_id is None: # create a PR review - Globals.response_buffer = requests.post( - reviews_url, - headers=API_HEADERS, - data=json.dumps( - { - "body": "\n" - "CPP Linter Action found no problems", - "event": "COMMENTED", - } - ), - ) - logger.info( - "Got %d from POSTing new(/temp) PR review", - Globals.response_buffer.status_code, - ) - Globals.response_buffer = requests.get(reviews_url) - if Globals.response_buffer.status_code != 200 and log_response_msg(): - raise RuntimeError("could not create a review for comments") - reviews = json.loads(Globals.response_buffer.text) - reviews.reverse() # traverse the list in reverse - review_id = find_review(reviews, user_id) - return review_id - - -def find_review(reviews: dict, user_id: int) -> Optional[int]: - """Find a review created by a certain user ID. - - Args: - reviews: the JSON object fetched via GIT REST API. - user_id: The user account's ID number - - Returns: - An ID that corresponds to the specified `user_id`. - """ - review_id = None - for review in reviews: - if int(review["user"]["id"]) == user_id and review["body"].startswith( - "" - ): - review_id = int(review["id"]) - break # there will only be 1 review from this action, so break when found - - logger.info(" review_id: %d", review_id) - return review_id diff --git a/docs/API Reference/cpp_linter.clang_format_xml.md b/docs/API Reference/cpp_linter.clang_format_xml.md deleted file mode 100644 index 8f7a76c8..00000000 --- a/docs/API Reference/cpp_linter.clang_format_xml.md +++ /dev/null @@ -1,6 +0,0 @@ -# clang_format_xml module - -!!! info - This API is experimental and not actually used in production. - -::: cpp_linter.clang_format_xml diff --git a/docs/API Reference/cpp_linter.clang_tidy.md b/docs/API Reference/cpp_linter.clang_tidy.md deleted file mode 100644 index 689b12e0..00000000 --- a/docs/API Reference/cpp_linter.clang_tidy.md +++ /dev/null @@ -1,3 +0,0 @@ -# clang_tidy module - -::: cpp_linter.clang_tidy diff --git a/docs/API Reference/cpp_linter.clang_tidy_yml.md b/docs/API Reference/cpp_linter.clang_tidy_yml.md deleted file mode 100644 index 7db0ae26..00000000 --- a/docs/API Reference/cpp_linter.clang_tidy_yml.md +++ /dev/null @@ -1,6 +0,0 @@ -# clang_tidy_yml module - -!!! info - This API is experimental and not actually used in production. - -::: cpp_linter.clang_tidy_yml diff --git a/docs/API Reference/cpp_linter.md b/docs/API Reference/cpp_linter.md deleted file mode 100644 index a20ce0cc..00000000 --- a/docs/API Reference/cpp_linter.md +++ /dev/null @@ -1,3 +0,0 @@ -# Base module - -::: cpp_linter diff --git a/docs/API Reference/cpp_linter.run.md b/docs/API Reference/cpp_linter.run.md deleted file mode 100644 index 4563d550..00000000 --- a/docs/API Reference/cpp_linter.run.md +++ /dev/null @@ -1,3 +0,0 @@ -# Run module - -::: cpp_linter.run diff --git a/docs/API Reference/cpp_linter.thread_comments.md b/docs/API Reference/cpp_linter.thread_comments.md deleted file mode 100644 index 17a801bc..00000000 --- a/docs/API Reference/cpp_linter.thread_comments.md +++ /dev/null @@ -1,3 +0,0 @@ -# thread_comments module - -::: cpp_linter.thread_comments diff --git a/docs/requirements.txt b/docs/requirements.txt index 36951be8..69de84c1 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,3 @@ mkdocs -mkdocs-autorefs mkdocs-include-markdown-plugin mkdocs-material -mkdocstrings[python] diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css index ea18395c..cd2c4f82 100644 --- a/docs/stylesheets/extra.css +++ b/docs/stylesheets/extra.css @@ -1,13 +1,3 @@ -:root>* { - --md-code-hl-number-color: #7e9b1e; - --md-code-hl-special-color: #499DC7; - --md-code-hl-constant-color: #48C999; - --md-code-hl-keyword-color: #499CD6; - --md-code-hl-string-color: #B88451; - --md-code-hl-comment-color: #5E9955; - /* --md-typeset-table-color: #ff000085; */ -} - .md-typeset table:not([class]) tbody tr:hover, tr:hover { background-color: var(--md-accent-fg-color--transparent); diff --git a/mkdocs.yml b/mkdocs.yml index 2c970a5c..2cfbc97c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -2,17 +2,10 @@ site_name: C/C++ Linter Action site_description: "Developer documentation from sources." site_url: "https://cpp-linter.github.io/cpp-linter-action" repo_url: "https://github.com/cpp-linter/cpp-linter-action" -edit_uri: "blob/master/docs/" +edit_uri: "" repo_name: "cpp-linter/cpp-linter-action" nav: - index.md - - 'Dev Docs': - - 'API Reference/cpp_linter.md' - - 'API Reference/cpp_linter.run.md' - - 'API Reference/cpp_linter.clang_tidy.md' - - 'API Reference/cpp_linter.clang_tidy_yml.md' - - 'API Reference/cpp_linter.clang_format_xml.md' - - 'API Reference/cpp_linter.thread_comments.md' theme: name: material @@ -40,26 +33,11 @@ extra_css: plugins: - search - include-markdown - - autorefs - - mkdocstrings: - default_handler: python - handlers: - python: - rendering: - # show_if_no_docstring: true - show_source: true - show_signature_annotations: true - heading_level: 2 - watch: - - cpp_linter markdown_extensions: - admonition - - attr_list - - pymdownx.details - pymdownx.emoji - pymdownx.superfences - - pymdownx.tabbed - pymdownx.tasklist - toc: permalink: true diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index c06ca881..00000000 --- a/pyproject.toml +++ /dev/null @@ -1,616 +0,0 @@ -[build-system] -requires = ["setuptools>=45", "setuptools-scm"] -build-backend = "setuptools.build_meta" - -[project] -name = "cpp-linter" -description = "Run clang-format and clang-tidy on a batch of files." -readme = "README.md" -keywords = ["clang", "clang-tools", "linter", "clang-tidy", "clang-format"] -license = {text = "MIT License"} -authors = [ - { name = "Brendan Doherty", email = "2bndy5@gmail.com" }, - { name = "Peter Shen", email = "xianpeng.shen@gmail.com" }, -] -dependencies = [ - "requests", - "pyyaml", -] -classifiers = [ - # https://pypi.org/pypi?%3Aaction=list_classifiers - "Development Status :: 5 - Production/Stable", - "License :: OSI Approved :: MIT License", - "Intended Audience :: Developers", - "Intended Audience :: System Administrators", - "Intended Audience :: Information Technology", - "Natural Language :: English", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX :: Linux", - "Operating System :: MacOS", - "Programming Language :: Python :: 3", - "Topic :: Software Development :: Build Tools", -] -dynamic = ["version"] - -[project.scripts] -cpp-linter = "cpp_linter.run:main" - -[project.urls] -source = "https://github.com/cpp-linter/cpp-linter-action" -tracker = "https://github.com/cpp-linter/cpp-linter-action/issues" - -# ... other project metadata fields as specified in: -# https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ - -[tool.setuptools] -zip-safe = false -packages = ["cpp_linter"] - -[tool.setuptools_scm] -# It would be nice to include the commit hash in the version, but that -# can't be done in a PEP 440-compatible way. -version_scheme= "no-guess-dev" -# Test PyPI does not support local versions. -local_scheme = "no-local-version" -fallback_version = "0.0.0" - -[tool.mypy] -show_error_codes = true -show_column_numbers = true - -[tool.pytest.ini_options] -minversion = "6.0" -addopts = "-vv" -testpaths = ["tests"] - -[tool.coverage] -[tool.coverage.run] -dynamic_context = "test_function" -omit = [ - # don't include tests in coverage - "tests/*", -] - -[tool.coverage.json] -pretty_print = true - -[tool.coverage.html] -show_contexts = true - -[tool.coverage.report] -# Regexes for lines to exclude from consideration -exclude_lines = [ - # Have to re-enable the standard pragma - "pragma: no cover", - # Don\'t complain about missing debug-only code: - "def __repr__", - # the point of unit tests is to test parts of main() - "def main", - # ignore any branch that makes the module executable - 'if __name__ == "__main__"', - # ignore branches specific to type checking - "if TYPE_CHECKING", - # ignore the local secific debug statement related to not having rich installed - "if not FOUND_RICH_LIB", -] - -[tool.pylint.main] -# Analyse import fallback blocks. This can be used to support both Python 2 and 3 -# compatible code, which means that the block might have code that exists only in -# one or another interpreter, leading to false positives when analysed. -# analyse-fallback-blocks = - -# Always return a 0 (non-error) status code, even if lint errors are found. This -# is primarily useful in continuous integration scripts. -# exit-zero = - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code. -# extension-pkg-allow-list = - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code. (This is an alternative name to extension-pkg-allow-list -# for backward compatibility.) -# extension-pkg-whitelist = - -# Return non-zero exit code if any of these messages/categories are detected, -# even if score is above --fail-under value. Syntax same as enable. Messages -# specified are enabled, while categories only check already-enabled messages. -# fail-on = - -# Specify a score threshold to be exceeded before program exits with error. -fail-under = 10 - -# Interpret the stdin as a python script, whose filename needs to be passed as -# the module_or_package argument. -# from-stdin = - -# Files or directories to be skipped. They should be base names, not paths. -ignore = ["CVS"] - -# Add files or directories matching the regex patterns to the ignore-list. The -# regex matches against paths and can be in Posix or Windows format. -# ignore-paths = - -# Files or directories matching the regex patterns are skipped. The regex matches -# against base names, not paths. The default value ignores Emacs file locks -# ignore-patterns = - -# List of module names for which member attributes should not be checked (useful -# for modules/projects where namespaces are manipulated during runtime and thus -# existing member attributes cannot be deduced by static analysis). It supports -# qualified module names, as well as Unix pattern matching. -# ignored-modules = - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -# init-hook = - -# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the -# number of processors available to use. -jobs = 2 - -# Control the amount of potential inferred values when inferring a single object. -# This can help the performance when dealing with large functions or complex, -# nested conditions. -limit-inference-results = 100 - -# List of plugins (as comma separated values of python module names) to load, -# usually to register additional checkers. -# load-plugins = - -# Pickle collected data for later comparisons. -persistent = true - -# Minimum Python version to use for version dependent checks. Will default to the -# version used to run pylint. -py-version = "3.10" - -# Discover python modules and packages in the file system subtree. -# recursive = - -# When enabled, pylint would attempt to guess common misconfiguration and emit -# user-friendly hints instead of false-positive error messages. -suggestion-mode = true - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -# unsafe-load-any-extension = - -[tool.pylint.basic] -# Naming style matching correct argument names. -argument-naming-style = "snake_case" - -# Regular expression matching correct argument names. Overrides argument-naming- -# style. If left empty, argument names will be checked with the set naming style. -argument-rgx = "(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$" - -# Naming style matching correct attribute names. -attr-naming-style = "snake_case" - -# Regular expression matching correct attribute names. Overrides attr-naming- -# style. If left empty, attribute names will be checked with the set naming -# style. -attr-rgx = "(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$" - -# Bad variable names which should always be refused, separated by a comma. -bad-names = ["foo", "bar", "baz", "toto", "tutu", "tata"] - -# Bad variable names regexes, separated by a comma. If names match any regex, -# they will always be refused -# bad-names-rgxs = - -# Naming style matching correct class attribute names. -class-attribute-naming-style = "any" - -# Regular expression matching correct class attribute names. Overrides class- -# attribute-naming-style. If left empty, class attribute names will be checked -# with the set naming style. -class-attribute-rgx = "([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$" - -# Naming style matching correct class constant names. -class-const-naming-style = "UPPER_CASE" - -# Regular expression matching correct class constant names. Overrides class- -# const-naming-style. If left empty, class constant names will be checked with -# the set naming style. -# class-const-rgx = - -# Naming style matching correct class names. -class-naming-style = "PascalCase" - -# Regular expression matching correct class names. Overrides class-naming-style. -# If left empty, class names will be checked with the set naming style. -class-rgx = "[A-Z_][a-zA-Z0-9_]+$" - -# Naming style matching correct constant names. -const-naming-style = "UPPER_CASE" - -# Regular expression matching correct constant names. Overrides const-naming- -# style. If left empty, constant names will be checked with the set naming style. -const-rgx = "(([A-Z_][A-Z0-9_]*)|(__.*__))$" - -# Minimum line length for functions/classes that require docstrings, shorter ones -# are exempt. -docstring-min-length = -1 - -# Naming style matching correct function names. -function-naming-style = "snake_case" - -# Regular expression matching correct function names. Overrides function-naming- -# style. If left empty, function names will be checked with the set naming style. -function-rgx = "(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$" - -# Good variable names which should always be accepted, separated by a comma. -good-names = ["r", "g", "b", "w", "i", "j", "k", "n", "x", "y", "z", "ex", "ok", "Run", "_"] - -# Good variable names regexes, separated by a comma. If names match any regex, -# they will always be accepted -# good-names-rgxs = - -# Include a hint for the correct naming format with invalid-name. -# include-naming-hint = - -# Naming style matching correct inline iteration names. -inlinevar-naming-style = "any" - -# Regular expression matching correct inline iteration names. Overrides -# inlinevar-naming-style. If left empty, inline iteration names will be checked -# with the set naming style. -inlinevar-rgx = "[A-Za-z_][A-Za-z0-9_]*$" - -# Naming style matching correct method names. -method-naming-style = "snake_case" - -# Regular expression matching correct method names. Overrides method-naming- -# style. If left empty, method names will be checked with the set naming style. -method-rgx = "(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$" - -# Naming style matching correct module names. -module-naming-style = "snake_case" - -# Regular expression matching correct module names. Overrides module-naming- -# style. If left empty, module names will be checked with the set naming style. -module-rgx = "(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$" - -# Colon-delimited sets of names that determine each other's naming style when the -# name regexes allow several styles. -# name-group = - -# Regular expression which should only match function or class names that do not -# require a docstring. -no-docstring-rgx = "^_" - -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. These -# decorators are taken in consideration only for invalid-name. -property-classes = ["abc.abstractproperty"] - -# Regular expression matching correct type variable names. If left empty, type -# variable names will be checked with the set naming style. -# typevar-rgx = - -# Naming style matching correct variable names. -variable-naming-style = "snake_case" - -# Regular expression matching correct variable names. Overrides variable-naming- -# style. If left empty, variable names will be checked with the set naming style. -variable-rgx = "(([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$" - -[tool.pylint.classes] -# Warn about protected attribute access inside special methods -# check-protected-access-in-special-methods = - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods = ["__init__", "__new__", "setUp"] - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected = ["_asdict", "_fields", "_replace", "_source", "_make"] - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg = ["cls"] - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg = ["mcs"] - -[tool.pylint.design] -# List of regular expressions of class ancestor names to ignore when counting -# public methods (see R0903) -# exclude-too-few-public-methods = - -# List of qualified class names to ignore when counting class parents (see R0901) -# ignored-parents = - -# Maximum number of arguments for function / method. -max-args = 8 - -# Maximum number of attributes for a class (see R0902). -max-attributes = 11 - -# Maximum number of boolean expressions in an if statement (see R0916). -max-bool-expr = 5 - -# Maximum number of branch for function / method body. -max-branches = 12 - -# Maximum number of locals for function / method body. -max-locals = 18 - -# Maximum number of parents for a class (see R0901). -max-parents = 7 - -# Maximum number of public methods for a class (see R0904). -max-public-methods = 20 - -# Maximum number of return / yield for function / method body. -max-returns = 6 - -# Maximum number of statements in function / method body. -max-statements = 50 - -# Minimum number of public methods for a class (see R0903). -min-public-methods = 1 - -[tool.pylint.exceptions] -# Exceptions that will emit a warning when caught. -overgeneral-exceptions = ["Exception"] - -[tool.pylint.format] -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -expected-line-ending-format = "LF" - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines = "^\\s*(# )??$" - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren = 4 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string = " " - -# Maximum number of characters on a single line. -max-line-length = 88 - -# Maximum number of lines in a module. -max-module-lines = 1000 - -# Allow the body of a class to be on the same line as the declaration if body -# contains single statement. -# single-line-class-stmt = - -# Allow the body of an if to be on the same line as the test if there is no else. -# single-line-if-stmt = - -[tool.pylint.imports] -# List of modules that can be imported at any level, not just the top level one. -# allow-any-import-level = - -# Allow wildcard imports from modules that define __all__. -# allow-wildcard-with-all = - -# Deprecated modules which should not be used, separated by a comma. -deprecated-modules = ["optparse", "tkinter.tix"] - -# Output a graph (.gv or any supported image format) of external dependencies to -# the given file (report RP0402 must not be disabled). -# ext-import-graph = - -# Output a graph (.gv or any supported image format) of all (i.e. internal and -# external) dependencies to the given file (report RP0402 must not be disabled). -# import-graph = - -# Output a graph (.gv or any supported image format) of internal dependencies to -# the given file (report RP0402 must not be disabled). -# int-import-graph = - -# Force import order to recognize a module as part of the standard compatibility -# libraries. -# known-standard-library = - -# Force import order to recognize a module as part of a third party library. -known-third-party = ["enchant"] - -# Couples of modules and preferred modules, separated by a comma. -# preferred-modules = - -[tool.pylint.logging] -# The type of string formatting that logging methods do. `old` means using % -# formatting, `new` is for `{}` formatting. -logging-format-style = "old" - -# Logging modules to check that the string format arguments are in logging -# function parameter format. -logging-modules = ["logging"] - -[tool.pylint."messages control"] -# Only show warnings with the listed confidence levels. Leave empty to show all. -# Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, UNDEFINED. -confidence = ["HIGH", "CONTROL_FLOW", "INFERENCE", "INFERENCE_FAILURE", "UNDEFINED"] - -# Disable the message, report, category or checker with the given id(s). You can -# either give multiple identifiers separated by comma (,) or put this option -# multiple times (only on the command line, not in the configuration file where -# it should appear only once). You can also use "--disable=all" to disable -# everything first and then re-enable specific checks. For example, if you want -# to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use "--disable=all --enable=classes -# --disable=W". -disable = ["raw-checker-failed", "bad-inline-option", "locally-disabled", "file-ignored", "suppressed-message", "useless-suppression", "deprecated-pragma", "use-symbolic-message-instead", "invalid-sequence-index", "anomalous-backslash-in-string", "too-few-public-methods", "consider-using-f-string", "subprocess-run-check"] - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where it -# should appear only once). See also the "--disable" option for examples. -enable = ["c-extension-no-member"] - -[tool.pylint.miscellaneous] -# List of note tags to take in consideration, separated by a comma. -notes = ["FIXME", "XXX"] - -# Regular expression of note tags to take in consideration. -# notes-rgx = - -[tool.pylint.refactoring] -# Maximum number of nested blocks for function / method body -max-nested-blocks = 5 - -# Complete name of functions that never returns. When checking for inconsistent- -# return-statements if a never returning function is called then it will be -# considered as an explicit return statement and no message will be printed. -never-returning-functions = ["sys.exit", "argparse.parse_error"] - -[tool.pylint.reports] -# Python expression which should return a score less than or equal to 10. You -# have access to the variables 'fatal', 'error', 'warning', 'refactor', -# 'convention', and 'info' which contain the number of messages in each category, -# as well as 'statement' which is the total number of statements analyzed. This -# score is used by the global evaluation report (RP0004). -evaluation = "10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)" - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details. -# msg-template = - -# Set the output format. Available formats are text, parseable, colorized, json -# and msvs (visual studio). You can also give a reporter class, e.g. -# mypackage.mymodule.MyReporterClass. -# output-format = - -# Tells whether to display a full report or only the messages. -# reports = - -# Activate the evaluation score. -score = true - -[tool.pylint.similarities] -# Comments are removed from the similarity computation -ignore-comments = true - -# Docstrings are removed from the similarity computation -ignore-docstrings = true - -# Imports are removed from the similarity computation -# ignore-imports = - -# Signatures are removed from the similarity computation -ignore-signatures = true - -# Minimum lines number of a similarity. -min-similarity-lines = 4 - -[tool.pylint.spelling] -# Limits count of emitted suggestions for spelling mistakes. -max-spelling-suggestions = 4 - -# Spelling dictionary name. Available dictionaries: none. To make it work, -# install the 'python-enchant' package. -# spelling-dict = - -# List of comma separated words that should be considered directives if they -# appear at the beginning of a comment and should not be checked. -spelling-ignore-comment-directives = "fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy:" - -# List of comma separated words that should not be checked. -# spelling-ignore-words = - -# A path to a file that contains the private dictionary; one word per line. -# spelling-private-dict-file = - -# Tells whether to store unknown words to the private dictionary (see the -# --spelling-private-dict-file option) instead of raising a message. -# spelling-store-unknown-words = - -[tool.pylint.string] -# This flag controls whether inconsistent-quotes generates a warning when the -# character used as a quote delimiter is used inconsistently within a module. -# check-quote-consistency = - -# This flag controls whether the implicit-str-concat should generate a warning on -# implicit string concatenation in sequences defined over several lines. -# check-str-concat-over-line-jumps = - -[tool.pylint.typecheck] -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators = ["contextlib.contextmanager"] - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -# generated-members = - -# Tells whether missing members accessed in mixin class should be ignored. A -# class is considered mixin if its name matches the mixin-class-rgx option. -# Tells whether to warn about missing members when the owner of the attribute is -# inferred to be None. -ignore-none = true - -# This flag controls whether pylint should warn about no-member and similar -# checks whenever an opaque object is returned when inferring. The inference can -# return multiple potential results while evaluating a Python object, but some -# branches might not be evaluated, which results in partial inference. In that -# case, it might be useful to still emit no-member and other checks for the rest -# of the inferred objects. -ignore-on-opaque-inference = true - -# List of symbolic message names to ignore for Mixin members. -ignored-checks-for-mixins = ["no-member", "not-async-context-manager", "not-context-manager", "attribute-defined-outside-init"] - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes = ["optparse.Values", "thread._local", "_thread._local"] - -# Show a hint with possible names when a member name was not found. The aspect of -# finding the hint is based on edit distance. -missing-member-hint = true - -# The minimum edit distance a name should have in order to be considered a -# similar match for a missing member name. -missing-member-hint-distance = 1 - -# The total number of similar names that should be taken in consideration when -# showing a hint for a missing member. -missing-member-max-choices = 1 - -# Regex pattern to define which classes are considered mixins. -mixin-class-rgx = ".*[Mm]ixin" - -# List of decorators that change the signature of a decorated function. -# signature-mutators = - -[tool.pylint.variables] -# List of additional names supposed to be defined in builtins. Remember that you -# should avoid defining new builtins when possible. -# additional-builtins = - -# Tells whether unused global variables should be treated as a violation. -allow-global-unused-variables = true - -# List of names allowed to shadow builtins -# allowed-redefined-builtins = - -# List of strings which can identify a callback function by name. A callback name -# must start or end with one of those strings. -callbacks = ["cb_", "_cb", "_callback"] - -# A regular expression matching the name of dummy variables (i.e. expected to not -# be used). -dummy-variables-rgx = "_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_" - -# Argument names that match this expression will be ignored. Default to name with -# leading underscore. -ignored-argument-names = "_.*|^ignored_|^unused_" - -# Tells whether we should check for unused import in __init__ files. -# init-import = - -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules = ["six.moves", "future.builtins"] diff --git a/requirements-dev.txt b/requirements-dev.txt deleted file mode 100644 index fe21d76f..00000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,7 +0,0 @@ -coverage[toml] -mypy -pylint -pytest -rich -types-PyYAML -types-requests diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 1c6d8b40..00000000 --- a/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -pyyaml -requests diff --git a/setup.py b/setup.py index 1698e52c..561028e8 100644 --- a/setup.py +++ b/setup.py @@ -4,8 +4,12 @@ Since using setup.py is no longer std convention, all install information is located in pyproject.toml """ - import setuptools - -setuptools.setup() +# needed to install a blank pkg & redirect to newer pkg on PyPI +setuptools.setup( + name="cpp-linter-deprecated", + version="0.0.0", + install_requires=["cpp-linter"], + py_modules=[""], +) diff --git a/tests/capture_tools_output/.clang-format b/tests/capture_tools_output/.clang-format deleted file mode 100644 index 69971928..00000000 --- a/tests/capture_tools_output/.clang-format +++ /dev/null @@ -1,148 +0,0 @@ ---- -Language: Cpp -# BasedOnStyle: LLVM -AccessModifierOffset: -2 -AlignAfterOpenBracket: Align -AlignConsecutiveMacros: true -AlignConsecutiveAssignments: false -AlignConsecutiveBitFields: false -AlignConsecutiveDeclarations: false -AlignEscapedNewlines: Right -AlignOperands: Align -AlignTrailingComments: true -AllowAllArgumentsOnNextLine: true -AllowAllConstructorInitializersOnNextLine: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortEnumsOnASingleLine: true -AllowShortBlocksOnASingleLine: Never -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: None -AllowShortLambdasOnASingleLine: All -AllowShortIfStatementsOnASingleLine: Never -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: MultiLine -BinPackArguments: true -BinPackParameters: true -BraceWrapping: - AfterCaseLabel: false - AfterClass: true - AfterControlStatement: Always - AfterEnum: true - AfterFunction: true - AfterNamespace: true - AfterObjCDeclaration: false - AfterStruct: true - AfterUnion: true - AfterExternBlock: false - BeforeCatch: false - BeforeElse: true - BeforeLambdaBody: false - BeforeWhile: false - IndentBraces: false - SplitEmptyFunction: true - SplitEmptyRecord: true - SplitEmptyNamespace: true -BreakBeforeBinaryOperators: None -BreakBeforeBraces: Custom -BreakBeforeInheritanceComma: false -BreakInheritanceList: BeforeColon -BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false -BreakConstructorInitializers: BeforeColon -BreakAfterJavaFieldAnnotations: false -BreakStringLiterals: true -ColumnLimit: 80 -CommentPragmas: '^ IWYU pragma:' -CompactNamespaces: false -ConstructorInitializerAllOnOneLineOrOnePerLine: false -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: true -DeriveLineEnding: true -DerivePointerAlignment: false -DisableFormat: false -ExperimentalAutoDetectBinPacking: false -FixNamespaceComments: true -ForEachMacros: - - foreach - - Q_FOREACH - - BOOST_FOREACH -IncludeBlocks: Preserve -IncludeCategories: - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Priority: 2 - SortPriority: 0 - - Regex: '^(<|"(gtest|gmock|isl|json)/)' - Priority: 3 - SortPriority: 0 - - Regex: '.*' - Priority: 1 - SortPriority: 0 -IncludeIsMainRegex: '(Test)?$' -IncludeIsMainSourceRegex: '' -IndentCaseLabels: false -IndentCaseBlocks: false -IndentGotoLabels: true -IndentPPDirectives: None -IndentExternBlock: AfterExternBlock -IndentWidth: 4 -IndentWrappedFunctionNames: false -InsertTrailingCommas: None -JavaScriptQuotes: Leave -JavaScriptWrapImports: true -KeepEmptyLinesAtTheStartOfBlocks: true -MacroBlockBegin: '' -MacroBlockEnd: '' -MaxEmptyLinesToKeep: 2 -NamespaceIndentation: None -ObjCBinPackProtocolList: Auto -ObjCBlockIndentWidth: 2 -ObjCBreakBeforeNestedBlockParam: true -ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: true -PenaltyBreakAssignment: 2 -PenaltyBreakBeforeFirstCallParameter: 19 -PenaltyBreakComment: 300 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakString: 1000 -PenaltyBreakTemplateDeclaration: 10 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 60 -PointerAlignment: Right -ReflowComments: false -SortIncludes: false -SortUsingDeclarations: true -SpaceAfterCStyleCast: false -SpaceAfterLogicalNot: false -SpaceAfterTemplateKeyword: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeCpp11BracedList: false -SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true -SpaceBeforeParens: ControlStatements -SpaceBeforeRangeBasedForLoopColon: true -SpaceInEmptyBlock: false -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: false -SpacesInConditionalStatement: false -SpacesInContainerLiterals: true -SpacesInCStyleCastParentheses: false -SpacesInParentheses: false -SpacesInSquareBrackets: false -SpaceBeforeSquareBrackets: false -Standard: Latest -StatementMacros: - - Q_UNUSED - - QT_REQUIRE_VERSION -TabWidth: 8 -UseCRLF: false -UseTab: Never -WhitespaceSensitiveMacros: - - STRINGIZE - - PP_STRINGIZE - - BOOST_PP_STRINGIZE -... diff --git a/tests/capture_tools_output/.clang-tidy b/tests/capture_tools_output/.clang-tidy deleted file mode 100644 index 19dc3ea0..00000000 --- a/tests/capture_tools_output/.clang-tidy +++ /dev/null @@ -1,349 +0,0 @@ ---- -Checks: 'clang-diagnostic-*,clang-analyzer-*,-boost-*,bugprone-*,performance-*,readability-*,portability-*,modernize-*,clang-analyzer-*,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers' -WarningsAsErrors: '' -HeaderFilterRegex: '' -AnalyzeTemporaryDtors: false -FormatStyle: none -User: ytreh -CheckOptions: - - key: modernize-replace-auto-ptr.IncludeStyle - value: llvm - - key: cppcoreguidelines-no-malloc.Reallocations - value: '::realloc' - - key: cppcoreguidelines-owning-memory.LegacyResourceConsumers - value: '::free;::realloc;::freopen;::fclose' - - key: readability-static-accessed-through-instance.NameSpecifierNestingThreshold - value: '3' - - key: readability-function-size.VariableThreshold - value: '4294967295' - - key: modernize-use-auto.MinTypeNameLength - value: '5' - - key: bugprone-reserved-identifier.Invert - value: 'false' - - key: performance-move-const-arg.CheckTriviallyCopyableMove - value: 'true' - - key: cert-dcl16-c.NewSuffixes - value: 'L;LL;LU;LLU' - - key: bugprone-narrowing-conversions.WarnOnFloatingPointNarrowingConversion - value: 'true' - - key: readability-identifier-naming.GetConfigPerFile - value: 'true' - - key: bugprone-narrowing-conversions.PedanticMode - value: 'false' - - key: readability-inconsistent-declaration-parameter-name.Strict - value: 'false' - - key: cppcoreguidelines-macro-usage.CheckCapsOnly - value: 'false' - - key: bugprone-unused-return-value.CheckedFunctions - value: '::std::async;::std::launder;::std::remove;::std::remove_if;::std::unique;::std::unique_ptr::release;::std::basic_string::empty;::std::vector::empty;::std::back_inserter;::std::distance;::std::find;::std::find_if;::std::inserter;::std::lower_bound;::std::make_pair;::std::map::count;::std::map::find;::std::map::lower_bound;::std::multimap::equal_range;::std::multimap::upper_bound;::std::set::count;::std::set::find;::std::setfill;::std::setprecision;::std::setw;::std::upper_bound;::std::vector::at;::bsearch;::ferror;::feof;::isalnum;::isalpha;::isblank;::iscntrl;::isdigit;::isgraph;::islower;::isprint;::ispunct;::isspace;::isupper;::iswalnum;::iswprint;::iswspace;::isxdigit;::memchr;::memcmp;::strcmp;::strcoll;::strncmp;::strpbrk;::strrchr;::strspn;::strstr;::wcscmp;::access;::bind;::connect;::difftime;::dlsym;::fnmatch;::getaddrinfo;::getopt;::htonl;::htons;::iconv_open;::inet_addr;::isascii;::isatty;::mmap;::newlocale;::openat;::pathconf;::pthread_equal;::pthread_getspecific;::pthread_mutex_trylock;::readdir;::readlink;::recvmsg;::regexec;::scandir;::semget;::setjmp;::shm_open;::shmget;::sigismember;::strcasecmp;::strsignal;::ttyname' - - key: modernize-use-default-member-init.UseAssignment - value: 'false' - - key: readability-function-size.NestingThreshold - value: '4294967295' - - key: modernize-use-override.AllowOverrideAndFinal - value: 'false' - - key: readability-function-size.ParameterThreshold - value: '4294967295' - - key: modernize-pass-by-value.ValuesOnly - value: 'false' - - key: modernize-loop-convert.IncludeStyle - value: llvm - - key: cert-str34-c.DiagnoseSignedUnsignedCharComparisons - value: '0' - - key: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison - value: 'false' - - key: cppcoreguidelines-explicit-virtual-functions.AllowOverrideAndFinal - value: 'false' - - key: readability-redundant-smartptr-get.IgnoreMacros - value: 'true' - - key: readability-identifier-naming.AggressiveDependentMemberLookup - value: 'false' - - key: bugprone-suspicious-string-compare.WarnOnImplicitComparison - value: 'true' - - key: modernize-use-emplace.TupleTypes - value: '::std::pair;::std::tuple' - - key: modernize-use-emplace.TupleMakeFunctions - value: '::std::make_pair;::std::make_tuple' - - key: cppcoreguidelines-owning-memory.LegacyResourceProducers - value: '::malloc;::aligned_alloc;::realloc;::calloc;::fopen;::freopen;::tmpfile' - - key: bugprone-argument-comment.CommentNullPtrs - value: '0' - - key: bugprone-argument-comment.StrictMode - value: '0' - - key: cppcoreguidelines-init-variables.IncludeStyle - value: llvm - - key: modernize-use-nodiscard.ReplacementString - value: '[[nodiscard]]' - - key: modernize-loop-convert.MakeReverseRangeHeader - value: '' - - key: modernize-replace-random-shuffle.IncludeStyle - value: llvm - - key: cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion - value: 'true' - - key: modernize-use-bool-literals.IgnoreMacros - value: 'true' - - key: bugprone-unhandled-self-assignment.WarnOnlyIfThisHasSuspiciousField - value: 'true' - - key: google-readability-namespace-comments.ShortNamespaceLines - value: '10' - - key: bugprone-suspicious-string-compare.StringCompareLikeFunctions - value: '' - - key: modernize-avoid-bind.PermissiveParameterList - value: 'false' - - key: modernize-use-override.FinalSpelling - value: final - - key: performance-move-constructor-init.IncludeStyle - value: llvm - - key: modernize-loop-convert.UseCxx20ReverseRanges - value: 'true' - - key: modernize-use-noexcept.ReplacementString - value: '' - - key: modernize-use-using.IgnoreMacros - value: 'true' - - key: performance-type-promotion-in-math-fn.IncludeStyle - value: llvm - - key: cppcoreguidelines-explicit-virtual-functions.FinalSpelling - value: final - - key: modernize-loop-convert.NamingStyle - value: CamelCase - - key: bugprone-suspicious-include.ImplementationFileExtensions - value: 'c;cc;cpp;cxx' - - key: cppcoreguidelines-pro-type-member-init.UseAssignment - value: 'false' - - key: modernize-loop-convert.MakeReverseRangeFunction - value: '' - - key: bugprone-suspicious-include.HeaderFileExtensions - value: ';h;hh;hpp;hxx' - - key: performance-no-automatic-move.AllowedTypes - value: '' - - key: performance-for-range-copy.WarnOnAllAutoCopies - value: 'false' - - key: bugprone-argument-comment.CommentIntegerLiterals - value: '0' - - key: bugprone-suspicious-missing-comma.SizeThreshold - value: '5' - - key: readability-inconsistent-declaration-parameter-name.IgnoreMacros - value: 'true' - - key: readability-identifier-naming.IgnoreFailedSplit - value: 'false' - - key: modernize-pass-by-value.IncludeStyle - value: llvm - - key: bugprone-sizeof-expression.WarnOnSizeOfThis - value: 'true' - - key: readability-qualified-auto.AddConstToQualified - value: 'true' - - key: bugprone-string-constructor.WarnOnLargeLength - value: 'true' - - key: bugprone-too-small-loop-variable.MagnitudeBitsUpperLimit - value: '16' - - key: readability-simplify-boolean-expr.ChainedConditionalReturn - value: 'false' - - key: cppcoreguidelines-explicit-virtual-functions.OverrideSpelling - value: override - - key: readability-else-after-return.WarnOnConditionVariables - value: 'true' - - key: readability-uppercase-literal-suffix.IgnoreMacros - value: 'true' - - key: modernize-use-nullptr.NullMacros - value: 'NULL' - - key: modernize-make-shared.IgnoreMacros - value: 'true' - - key: bugprone-dynamic-static-initializers.HeaderFileExtensions - value: ';h;hh;hpp;hxx' - - key: bugprone-suspicious-enum-usage.StrictMode - value: 'false' - - key: performance-unnecessary-copy-initialization.AllowedTypes - value: '' - - key: bugprone-suspicious-missing-comma.MaxConcatenatedTokens - value: '5' - - key: modernize-use-transparent-functors.SafeMode - value: 'false' - - key: cppcoreguidelines-macro-usage.AllowedRegexp - value: '^DEBUG_*' - - key: modernize-make-shared.IgnoreDefaultInitialization - value: 'true' - - key: bugprone-argument-comment.CommentCharacterLiterals - value: '0' - - key: cppcoreguidelines-narrowing-conversions.PedanticMode - value: 'false' - - key: bugprone-not-null-terminated-result.WantToUseSafeFunctions - value: 'true' - - key: modernize-make-shared.IncludeStyle - value: llvm - - key: bugprone-string-constructor.LargeLengthThreshold - value: '8388608' - - key: readability-simplify-boolean-expr.ChainedConditionalAssignment - value: 'false' - - key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctions - value: 'false' - - key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField - value: '0' - - key: bugprone-exception-escape.FunctionsThatShouldNotThrow - value: '' - - key: bugprone-signed-char-misuse.CharTypdefsToIgnore - value: '' - - key: performance-inefficient-vector-operation.EnableProto - value: 'false' - - key: modernize-loop-convert.MaxCopySize - value: '16' - - key: bugprone-argument-comment.CommentFloatLiterals - value: '0' - - key: readability-function-size.LineThreshold - value: '4294967295' - - key: portability-simd-intrinsics.Suggest - value: 'false' - - key: modernize-make-shared.MakeSmartPtrFunction - value: 'std::make_shared' - - key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors - value: 'true' - - key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader - value: '' - - key: modernize-make-unique.IgnoreMacros - value: 'true' - - key: modernize-make-shared.MakeSmartPtrFunctionHeader - value: '' - - key: performance-for-range-copy.AllowedTypes - value: '' - - key: modernize-use-override.IgnoreDestructors - value: 'false' - - key: bugprone-sizeof-expression.WarnOnSizeOfConstant - value: 'true' - - key: readability-redundant-string-init.StringNames - value: '::std::basic_string_view;::std::basic_string' - - key: modernize-make-unique.IgnoreDefaultInitialization - value: 'true' - - key: modernize-use-emplace.ContainersWithPushBack - value: '::std::vector;::std::list;::std::deque' - - key: modernize-make-unique.IncludeStyle - value: llvm - - key: readability-braces-around-statements.ShortStatementLines - value: '0' - - key: bugprone-argument-comment.CommentUserDefinedLiterals - value: '0' - - key: bugprone-argument-comment.CommentBoolLiterals - value: '0' - - key: modernize-use-override.OverrideSpelling - value: override - - key: performance-inefficient-string-concatenation.StrictMode - value: 'false' - - key: readability-implicit-bool-conversion.AllowPointerConditions - value: 'false' - - key: readability-redundant-declaration.IgnoreMacros - value: 'true' - - key: google-readability-braces-around-statements.ShortStatementLines - value: '1' - - key: modernize-make-unique.MakeSmartPtrFunction - value: 'std::make_unique' - - key: cppcoreguidelines-pro-type-member-init.IgnoreArrays - value: 'false' - - key: readability-else-after-return.WarnOnUnfixable - value: 'true' - - key: bugprone-reserved-identifier.AllowedIdentifiers - value: '' - - key: modernize-use-emplace.IgnoreImplicitConstructors - value: 'false' - - key: modernize-make-unique.MakeSmartPtrFunctionHeader - value: '' - - key: portability-restrict-system-includes.Includes - value: '*' - - key: modernize-use-equals-delete.IgnoreMacros - value: 'true' - - key: cppcoreguidelines-pro-bounds-constant-array-index.IncludeStyle - value: llvm - - key: cppcoreguidelines-macro-usage.IgnoreCommandLineMacros - value: 'true' - - key: bugprone-misplaced-widening-cast.CheckImplicitCasts - value: 'false' - - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnorePublicMemberVariables - value: 'false' - - key: modernize-loop-convert.MinConfidence - value: reasonable - - key: performance-unnecessary-value-param.AllowedTypes - value: '' - - key: bugprone-suspicious-missing-comma.RatioThreshold - value: '0.200000' - - key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctionsWhenCopyIsDeleted - value: 'false' - - key: readability-uppercase-literal-suffix.NewSuffixes - value: '' - - key: google-readability-namespace-comments.SpacesBeforeComments - value: '2' - - key: readability-function-cognitive-complexity.Threshold - value: '25' - - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic - value: 'true' - - key: bugprone-argument-comment.IgnoreSingleArgument - value: '0' - - key: cppcoreguidelines-no-malloc.Allocations - value: '::malloc;::calloc' - - key: modernize-use-noexcept.UseNoexceptFalse - value: 'true' - - key: bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression - value: 'false' - - key: performance-faster-string-find.StringLikeClasses - value: '::std::basic_string;::std::basic_string_view' - - key: bugprone-assert-side-effect.CheckFunctionCalls - value: 'false' - - key: readability-function-size.BranchThreshold - value: '4294967295' - - key: bugprone-string-constructor.StringNames - value: '::std::basic_string;::std::basic_string_view' - - key: bugprone-assert-side-effect.AssertMacros - value: assert - - key: bugprone-exception-escape.IgnoredExceptions - value: '' - - key: readability-function-size.StatementThreshold - value: '800' - - key: modernize-use-default-member-init.IgnoreMacros - value: 'true' - - key: llvm-qualified-auto.AddConstToQualified - value: '0' - - key: bugprone-argument-comment.CommentStringLiterals - value: '0' - - key: readability-identifier-naming.IgnoreMainLikeFunctions - value: 'false' - - key: bugprone-signed-char-misuse.DiagnoseSignedUnsignedCharComparisons - value: 'true' - - key: readability-implicit-bool-conversion.AllowIntegerConditions - value: 'false' - - key: cppcoreguidelines-init-variables.MathHeader - value: '' - - key: google-readability-function-size.StatementThreshold - value: '800' - - key: llvm-else-after-return.WarnOnConditionVariables - value: '0' - - key: bugprone-sizeof-expression.WarnOnSizeOfCompareToConstant - value: 'true' - - key: bugprone-reserved-identifier.AggressiveDependentMemberLookup - value: 'false' - - key: modernize-raw-string-literal.DelimiterStem - value: lit - - key: modernize-use-equals-default.IgnoreMacros - value: 'true' - - key: cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor - value: 'false' - - key: modernize-raw-string-literal.ReplaceShorterLiterals - value: 'false' - - key: modernize-use-emplace.SmartPointers - value: '::std::shared_ptr;::std::unique_ptr;::std::auto_ptr;::std::weak_ptr' - - key: cppcoreguidelines-no-malloc.Deallocations - value: '::free' - - key: modernize-use-auto.RemoveStars - value: 'false' - - key: bugprone-dangling-handle.HandleClasses - value: 'std::basic_string_view;std::experimental::basic_string_view' - - key: performance-inefficient-vector-operation.VectorLikeClasses - value: '::std::vector' - - key: portability-simd-intrinsics.Std - value: '' - - key: performance-unnecessary-value-param.IncludeStyle - value: llvm - - key: readability-redundant-member-init.IgnoreBaseInCopyConstructors - value: 'false' - - key: modernize-replace-disallow-copy-and-assign-macro.MacroName - value: DISALLOW_COPY_AND_ASSIGN - - key: llvm-else-after-return.WarnOnUnfixable - value: '0' - - key: readability-simplify-subscript-expr.Types - value: '::std::basic_string;::std::basic_string_view;::std::vector;::std::array' -... diff --git a/tests/capture_tools_output/event_files.json b/tests/capture_tools_output/event_files.json deleted file mode 100644 index ba8947ac..00000000 --- a/tests/capture_tools_output/event_files.json +++ /dev/null @@ -1,230 +0,0 @@ -[ - { - "sha": "7f1eed09c6c07682738de7b5141fd151d16cf368", - "filename": "CMakeLists.txt", - "status": "modified", - "additions": 14, - "deletions": 2, - "changes": 16, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/CMakeLists.txt", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/CMakeLists.txt", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/CMakeLists.txt?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -28,9 +28,21 @@ else()\n \"-Wredundant-decls\")\n endif()\n \n+option(ENABLE_SDL2_NET \"Enable SDL2_net\" On)\n+option(ENABLE_SDL2_MIXER \"Enable SDL2_mixer\" On)\n+\n find_package(SDL2 2.0.7)\n-find_package(SDL2_mixer 2.0.2)\n-find_package(SDL2_net 2.0.0)\n+if(ENABLE_SDL2_MIXER)\n+ find_package(SDL2_mixer 2.0.2)\n+else()\n+ add_compile_definitions(DISABLE_SDL2MIXER=1)\n+endif()\n+\n+if(ENABLE_SDL2_NET)\n+ find_package(SDL2_net 2.0.0)\n+else()\n+ add_compile_definitions(DISABLE_SDL2NET=1)\n+endif()\n \n # Check for libsamplerate.\n find_package(samplerate)" - }, - { - "sha": "fd5d8bcecd8a6edb6d77c8686ae32a995b571066", - "filename": "configure.ac", - "status": "modified", - "additions": 17, - "deletions": 2, - "changes": 19, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/configure.ac", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/configure.ac", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/configure.ac?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -32,8 +32,23 @@ then\n fi\n \n PKG_CHECK_MODULES(SDL, [sdl2 >= 2.0.7])\n-PKG_CHECK_MODULES(SDLMIXER, [SDL2_mixer >= 2.0.2])\n-PKG_CHECK_MODULES(SDLNET, [SDL2_net >= 2.0.0])\n+# Check for SDL2_mixer\n+AC_ARG_ENABLE([sdl2mixer],\n+AS_HELP_STRING([--disable-sdl2mixer], [Disable SDL2_mixer support])\n+)\n+AS_IF([test \"x$enable_sdl2mixer\" != xno], [\n+ PKG_CHECK_MODULES(SDLMIXER, [SDL2_mixer >= 2.0.2])], [\n+ AC_DEFINE([DISABLE_SDL2MIXER], [1], [SDL2_mixer disabled])\n+])\n+\n+# Check for networking\n+AC_ARG_ENABLE([sdl2net],\n+AS_HELP_STRING([--disable-sdl2net], [Disable SDL2_net support])\n+)\n+AS_IF([test \"x$enable_sdl2net\" != xno], [\n+ PKG_CHECK_MODULES(SDLNET, [SDL2_net >= 2.0.0])], [\n+ AC_DEFINE([DISABLE_SDL2NET], [1], [SDL2_net disabled])\n+])\n \n # Check for bash-completion.\n AC_ARG_ENABLE([bash-completion]," - }, - { - "sha": "151f7617dde7d1216f7212b45bb5aeb7661bc86b", - "filename": "opl/CMakeLists.txt", - "status": "modified", - "additions": 4, - "deletions": 1, - "changes": 5, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/opl%2FCMakeLists.txt", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/opl%2FCMakeLists.txt", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/opl%2FCMakeLists.txt?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -12,4 +12,7 @@ add_library(opl STATIC\n target_include_directories(opl\n INTERFACE \".\"\n PRIVATE \"${CMAKE_CURRENT_BINARY_DIR}/../\")\n-target_link_libraries(opl SDL2::mixer)\n+target_link_libraries(opl SDL2::SDL2)\n+if(ENABLE_SDL2_mixer)\n+ target_link_libraries(opl SDL2::mixer)\n+endif()" - }, - { - "sha": "46e082cf77c5e60affc7689f7357c926fc00cda3", - "filename": "opl/opl.c", - "status": "modified", - "additions": 2, - "deletions": 0, - "changes": 2, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/opl%2Fopl.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/opl%2Fopl.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/opl%2Fopl.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -50,7 +50,9 @@ static opl_driver_t *drivers[] =\n #ifdef _WIN32\n &opl_win32_driver,\n #endif\n+#ifndef DISABLE_SDL2MIXER\n &opl_sdl_driver,\n+#endif // DISABLE_SDL2MIXER\n NULL\n };\n " - }, - { - "sha": "6bd4e7e1f3374e289d3dc19972dcb1d5379d6b03", - "filename": "opl/opl_sdl.c", - "status": "modified", - "additions": 6, - "deletions": 0, - "changes": 6, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/opl%2Fopl_sdl.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/opl%2Fopl_sdl.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/opl%2Fopl_sdl.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -33,6 +33,10 @@\n \n #include \"opl_queue.h\"\n \n+\n+#ifndef DISABLE_SDL2MIXER\n+\n+\n #define MAX_SOUND_SLICE_TIME 100 /* ms */\n \n typedef struct\n@@ -511,3 +515,5 @@ opl_driver_t opl_sdl_driver =\n OPL_SDL_AdjustCallbacks,\n };\n \n+\n+#endif // DISABLE_SDL2MIXER" - }, - { - "sha": "9924263aea24261091948e455dfd2521787a04c4", - "filename": "pcsound/CMakeLists.txt", - "status": "modified", - "additions": 4, - "deletions": 1, - "changes": 5, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/pcsound%2FCMakeLists.txt", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/pcsound%2FCMakeLists.txt", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/pcsound%2FCMakeLists.txt?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -8,4 +8,7 @@ add_library(pcsound STATIC\n target_include_directories(pcsound\n INTERFACE \".\"\n PRIVATE \"${CMAKE_CURRENT_BINARY_DIR}/../\")\n-target_link_libraries(pcsound SDL2::mixer)\n+target_link_libraries(pcsound SDL2::SDL2)\n+if(ENABLE_SDL2_mixer)\n+ target_link_libraries(pcsound SDL2::mixer)\n+endif()" - }, - { - "sha": "58f9b75c2affd5f1dd990aaedab79d834575bf83", - "filename": "pcsound/pcsound.c", - "status": "modified", - "additions": 2, - "deletions": 0, - "changes": 2, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/pcsound%2Fpcsound.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/pcsound%2Fpcsound.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/pcsound%2Fpcsound.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -56,7 +56,9 @@ static pcsound_driver_t *drivers[] =\n #ifdef _WIN32\n &pcsound_win32_driver,\n #endif\n+#ifndef DISABLE_SDL2MIXER\n &pcsound_sdl_driver,\n+#endif // DISABLE_SDL2MIXER\n NULL,\n };\n " - }, - { - "sha": "e77c7b0d29de1b0c665686004dfda311c9d96719", - "filename": "pcsound/pcsound_sdl.c", - "status": "modified", - "additions": 6, - "deletions": 0, - "changes": 6, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/pcsound%2Fpcsound_sdl.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/pcsound%2Fpcsound_sdl.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/pcsound%2Fpcsound_sdl.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -24,6 +24,10 @@\n #include \"pcsound.h\"\n #include \"pcsound_internal.h\"\n \n+\n+#ifndef DISABLE_SDL2MIXER\n+\n+\n #define MAX_SOUND_SLICE_TIME 70 /* ms */\n #define SQUARE_WAVE_AMP 0x2000\n \n@@ -248,3 +252,5 @@ pcsound_driver_t pcsound_sdl_driver =\n PCSound_SDL_Shutdown,\n };\n \n+\n+#endif // DISABLE_SDL2MIXER" - }, - { - "sha": "bbb877641f2a8de6e6eb7dad5b8c866e147faf7d", - "filename": "src/CMakeLists.txt", - "status": "modified", - "additions": 18, - "deletions": 3, - "changes": 21, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2FCMakeLists.txt", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2FCMakeLists.txt", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/src%2FCMakeLists.txt?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -32,7 +32,10 @@ set(DEDSERV_FILES\n add_executable(\"${PROGRAM_PREFIX}server\" WIN32 ${COMMON_SOURCE_FILES} ${DEDSERV_FILES})\n target_include_directories(\"${PROGRAM_PREFIX}server\"\n PRIVATE \"${CMAKE_CURRENT_BINARY_DIR}/../\")\n-target_link_libraries(\"${PROGRAM_PREFIX}server\" SDL2::SDL2main SDL2::net)\n+target_link_libraries(\"${PROGRAM_PREFIX}server\" SDL2::SDL2main SDL2::SDL2)\n+if(ENABLE_SDL2_NET)\n+ target_link_libraries(\"${PROGRAM_PREFIX}server\" SDL2::net)\n+endif()\n \n # Source files used by the game binaries (chocolate-doom, etc.)\n \n@@ -121,7 +124,13 @@ set(DEHACKED_SOURCE_FILES\n set(SOURCE_FILES ${COMMON_SOURCE_FILES} ${GAME_SOURCE_FILES})\n set(SOURCE_FILES_WITH_DEH ${SOURCE_FILES} ${DEHACKED_SOURCE_FILES})\n \n-set(EXTRA_LIBS SDL2::SDL2main SDL2::SDL2 SDL2::mixer SDL2::net textscreen pcsound opl)\n+set(EXTRA_LIBS SDL2::SDL2main SDL2::SDL2 textscreen pcsound opl)\n+if(ENABLE_SDL2_MIXER)\n+ list(APPEND EXTRA_LIBS SDL2::mixer)\n+endif()\n+if(ENABLE_SDL2_NET)\n+ list(APPEND EXTRA_LIBS SDL2::net)\n+endif()\n if(SAMPLERATE_FOUND)\n list(APPEND EXTRA_LIBS samplerate::samplerate)\n endif()\n@@ -213,7 +222,13 @@ endif()\n \n target_include_directories(\"${PROGRAM_PREFIX}setup\"\n PRIVATE \"${CMAKE_CURRENT_BINARY_DIR}/../\")\n-target_link_libraries(\"${PROGRAM_PREFIX}setup\" SDL2::SDL2main SDL2::SDL2 SDL2::mixer SDL2::net setup textscreen)\n+target_link_libraries(\"${PROGRAM_PREFIX}setup\" SDL2::SDL2main SDL2::SDL2 setup textscreen)\n+if(ENABLE_SDL2_mixer)\n+ target_link_libraries(\"${PROGRAM_PREFIX}setup\" SDL2::mixer)\n+endif()\n+if(ENABLE_SDL2_NET)\n+ target_link_libraries(\"${PROGRAM_PREFIX}setup\" SDL2::net)\n+endif()\n \n if(MSVC)\n set_target_properties(\"${PROGRAM_PREFIX}setup\" PROPERTIES" - }, - { - "sha": "82b114b4178595085c6745bc70a570922415be1f", - "filename": "src/doom/CMakeLists.txt", - "status": "modified", - "additions": 7, - "deletions": 1, - "changes": 8, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fdoom%2FCMakeLists.txt", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fdoom%2FCMakeLists.txt", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/src%2Fdoom%2FCMakeLists.txt?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -68,4 +68,10 @@ add_library(doom STATIC\n wi_stuff.c wi_stuff.h)\n \n target_include_directories(doom PRIVATE \"../\" \"${CMAKE_CURRENT_BINARY_DIR}/../../\")\n-target_link_libraries(doom SDL2::SDL2 SDL2::mixer SDL2::net)\n+target_link_libraries(doom SDL2::SDL2)\n+if(ENABLE_SDL2_mixer)\n+ target_link_libraries(doom SDL2::mixer)\n+endif()\n+if(ENABLE_SDL2_NET)\n+ target_link_libraries(doom SDL2::net)\n+endif()" - }, - { - "sha": "1ea060bfdb8b3147e36b3431fee27934c8a93b34", - "filename": "src/heretic/CMakeLists.txt", - "status": "modified", - "additions": 7, - "deletions": 1, - "changes": 8, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fheretic%2FCMakeLists.txt", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fheretic%2FCMakeLists.txt", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/src%2Fheretic%2FCMakeLists.txt?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -54,4 +54,10 @@ add_library(heretic STATIC\n s_sound.c s_sound.h)\n \n target_include_directories(heretic PRIVATE \"../\" \"${CMAKE_CURRENT_BINARY_DIR}/../../\")\n-target_link_libraries(heretic textscreen SDL2::SDL2 SDL2::mixer SDL2::net)\n+target_link_libraries(heretic textscreen SDL2::SDL2)\n+if(ENABLE_SDL2_mixer)\n+ target_link_libraries(heretic SDL2::mixer)\n+endif()\n+if(ENABLE_SDL2_NET)\n+ target_link_libraries(heretic SDL2::net)\n+endif()" - }, - { - "sha": "0dbd170bfdb06c8209ec654d4d5377e334be886e", - "filename": "src/hexen/CMakeLists.txt", - "status": "modified", - "additions": 7, - "deletions": 1, - "changes": 8, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fhexen%2FCMakeLists.txt", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fhexen%2FCMakeLists.txt", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/src%2Fhexen%2FCMakeLists.txt?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -55,4 +55,10 @@ add_library(hexen STATIC\n xddefs.h)\n \n target_include_directories(hexen PRIVATE \"../\" \"${CMAKE_CURRENT_BINARY_DIR}/../../\")\n-target_link_libraries(hexen SDL2::SDL2 SDL2::mixer SDL2::net)\n+target_link_libraries(hexen SDL2::SDL2)\n+if(ENABLE_SDL2_mixer)\n+ target_link_libraries(hexen SDL2::mixer)\n+endif()\n+if(ENABLE_SDL2_NET)\n+ target_link_libraries(hexen SDL2::net)\n+endif()" - }, - { - "sha": "3facce6f01d02c5e8eef3088fa60576b9e949829", - "filename": "src/i_musicpack.c", - "status": "modified", - "additions": 87, - "deletions": 1, - "changes": 88, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fi_musicpack.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fi_musicpack.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/src%2Fi_musicpack.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -44,6 +44,13 @@\n #include \"w_wad.h\"\n #include \"z_zone.h\"\n \n+\n+char *music_pack_path = \"\";\n+\n+\n+#ifndef DISABLE_SDL2MIXER\n+\n+\n #define MID_HEADER_MAGIC \"MThd\"\n #define MUS_HEADER_MAGIC \"MUS\\x1a\"\n \n@@ -99,7 +106,6 @@ static boolean music_initialized = false;\n \n static boolean sdl_was_initialized = false;\n \n-char *music_pack_path = \"\";\n \n // If true, we are playing a substitute digital track rather than in-WAD\n // MIDI/MUS track, and file_metadata contains loop metadata.\n@@ -1375,3 +1381,83 @@ music_module_t music_pack_module =\n I_MP_PollMusic,\n };\n \n+\n+#else // DISABLE_SDL2MIXER\n+\n+\n+static boolean I_NULL_InitMusic(void)\n+{\n+ return false;\n+}\n+\n+\n+static void I_NULL_ShutdownMusic(void)\n+{\n+}\n+\n+\n+static void I_NULL_SetMusicVolume(int volume)\n+{\n+}\n+\n+\n+static void I_NULL_PauseSong(void)\n+{\n+}\n+\n+\n+static void I_NULL_ResumeSong(void)\n+{\n+}\n+\n+\n+static void *I_NULL_RegisterSong(void *data, int len)\n+{\n+ return NULL;\n+}\n+\n+\n+static void I_NULL_UnRegisterSong(void *handle)\n+{\n+}\n+\n+\n+static void I_NULL_PlaySong(void *handle, boolean looping)\n+{\n+}\n+\n+\n+static void I_NULL_StopSong(void)\n+{\n+}\n+\n+\n+static boolean I_NULL_MusicIsPlaying(void)\n+{\n+ return false;\n+}\n+\n+\n+static void I_NULL_PollMusic(void)\n+{\n+}\n+\n+music_module_t music_pack_module =\n+{\n+ NULL,\n+ 0,\n+ I_NULL_InitMusic,\n+ I_NULL_ShutdownMusic,\n+ I_NULL_SetMusicVolume,\n+ I_NULL_PauseSong,\n+ I_NULL_ResumeSong,\n+ I_NULL_RegisterSong,\n+ I_NULL_UnRegisterSong,\n+ I_NULL_PlaySong,\n+ I_NULL_StopSong,\n+ I_NULL_MusicIsPlaying,\n+ I_NULL_PollMusic,\n+};\n+\n+\n+#endif // DISABLE_SDL2MIXER" - }, - { - "sha": "48fedfbd7608ad8c6575a4bd82a5e1cb3646e071", - "filename": "src/i_sdlmusic.c", - "status": "modified", - "additions": 21, - "deletions": 13, - "changes": 34, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fi_sdlmusic.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fi_sdlmusic.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/src%2Fi_sdlmusic.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -44,19 +44,6 @@\n #include \"w_wad.h\"\n #include \"z_zone.h\"\n \n-#define MAXMIDLENGTH (96 * 1024)\n-\n-static boolean music_initialized = false;\n-\n-// If this is true, this module initialized SDL sound and has the \n-// responsibility to shut it down\n-\n-static boolean sdl_was_initialized = false;\n-\n-static boolean win_midi_stream_opened = false;\n-\n-static boolean musicpaused = false;\n-static int current_music_volume;\n \n char *fluidsynth_sf_path = \"\";\n char *timidity_cfg_path = \"\";\n@@ -138,6 +125,25 @@ void I_InitTimidityConfig(void)\n }\n }\n \n+\n+#ifndef DISABLE_SDL2MIXER\n+\n+\n+#define MAXMIDLENGTH (96 * 1024)\n+\n+static boolean music_initialized = false;\n+\n+// If this is true, this module initialized SDL sound and has the\n+// responsibility to shut it down\n+\n+static boolean sdl_was_initialized = false;\n+\n+static boolean win_midi_stream_opened = false;\n+\n+static boolean musicpaused = false;\n+static int current_music_volume;\n+\n+\n // Remove the temporary config file generated by I_InitTimidityConfig().\n \n static void RemoveTimidityConfig(void)\n@@ -588,3 +594,5 @@ music_module_t music_sdl_module =\n NULL, // Poll\n };\n \n+\n+#endif // DISABLE_SDL2MIXER" - }, - { - "sha": "7f2a26096b218c5323f5dc569c6f70ab399782bf", - "filename": "src/i_sdlsound.c", - "status": "modified", - "additions": 17, - "deletions": 9, - "changes": 26, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fi_sdlsound.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fi_sdlsound.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/src%2Fi_sdlsound.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -41,6 +41,21 @@\n \n #include \"doomtype.h\"\n \n+\n+int use_libsamplerate = 0;\n+\n+// Scale factor used when converting libsamplerate floating point numbers\n+// to integers. Too high means the sounds can clip; too low means they\n+// will be too quiet. This is an amount that should avoid clipping most\n+// of the time: with all the Doom IWAD sound effects, at least. If a PWAD\n+// is used, clipping might occur.\n+\n+float libsamplerate_scale = 0.65f;\n+\n+\n+#ifndef DISABLE_SDL2MIXER\n+\n+\n #define LOW_PASS_FILTER\n //#define DEBUG_DUMP_WAVS\n #define NUM_CHANNELS 16\n@@ -77,15 +92,6 @@ static allocated_sound_t *allocated_sounds_head = NULL;\n static allocated_sound_t *allocated_sounds_tail = NULL;\n static int allocated_sounds_size = 0;\n \n-int use_libsamplerate = 0;\n-\n-// Scale factor used when converting libsamplerate floating point numbers\n-// to integers. Too high means the sounds can clip; too low means they\n-// will be too quiet. This is an amount that should avoid clipping most\n-// of the time: with all the Doom IWAD sound effects, at least. If a PWAD\n-// is used, clipping might occur.\n-\n-float libsamplerate_scale = 0.65f;\n \n // Hook a sound into the linked list at the head.\n \n@@ -1135,3 +1141,5 @@ sound_module_t sound_sdl_module =\n I_SDL_PrecacheSounds,\n };\n \n+\n+#endif // DISABLE_SDL2MIXER" - }, - { - "sha": "9cf1fd95db13504ffc6f98ead8c9150f03db72aa", - "filename": "src/i_sound.c", - "status": "modified", - "additions": 4, - "deletions": 0, - "changes": 4, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fi_sound.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fi_sound.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/src%2Fi_sound.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -99,7 +99,9 @@ static int snd_mport = 0;\n \n static sound_module_t *sound_modules[] = \n {\n+#ifndef DISABLE_SDL2MIXER\n &sound_sdl_module,\n+#endif // DISABLE_SDL2MIXER\n &sound_pcsound_module,\n NULL,\n };\n@@ -108,7 +110,9 @@ static sound_module_t *sound_modules[] =\n \n static music_module_t *music_modules[] =\n {\n+#ifndef DISABLE_SDL2MIXER\n &music_sdl_module,\n+#endif // DISABLE_SDL2MIXER\n &music_opl_module,\n NULL,\n };" - }, - { - "sha": "c1f701c0b9f653eb3a36b71627747a6eda963d8f", - "filename": "src/net_sdl.c", - "status": "modified", - "additions": 63, - "deletions": 0, - "changes": 63, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fnet_sdl.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fnet_sdl.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/src%2Fnet_sdl.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -33,6 +33,10 @@\n // NETWORKING\n //\n \n+\n+#ifndef DISABLE_SDL2NET\n+\n+\n #include \n \n #define DEFAULT_PORT 2342\n@@ -376,3 +380,62 @@ net_module_t net_sdl_module =\n NET_SDL_ResolveAddress,\n };\n \n+\n+#else // DISABLE_SDL2NET\n+\n+// no-op implementation\n+\n+\n+static boolean NET_NULL_InitClient(void)\n+{\n+ return false;\n+}\n+\n+\n+static boolean NET_NULL_InitServer(void)\n+{\n+ return false;\n+}\n+\n+\n+static void NET_NULL_SendPacket(net_addr_t *addr, net_packet_t *packet)\n+{\n+}\n+\n+\n+static boolean NET_NULL_RecvPacket(net_addr_t **addr, net_packet_t **packet)\n+{\n+ return false;\n+}\n+\n+\n+static void NET_NULL_AddrToString(net_addr_t *addr, char *buffer, int buffer_len)\n+{\n+\n+}\n+\n+\n+static void NET_NULL_FreeAddress(net_addr_t *addr)\n+{\n+}\n+\n+\n+net_addr_t *NET_NULL_ResolveAddress(const char *address)\n+{\n+ return NULL;\n+}\n+\n+\n+net_module_t net_sdl_module =\n+{\n+ NET_NULL_InitClient,\n+ NET_NULL_InitServer,\n+ NET_NULL_SendPacket,\n+ NET_NULL_RecvPacket,\n+ NET_NULL_AddrToString,\n+ NET_NULL_FreeAddress,\n+ NET_NULL_ResolveAddress,\n+};\n+\n+\n+#endif // DISABLE_SDL2NET" - }, - { - "sha": "90df2114163152ff732a9ba4a8bc18ef3d45d1bd", - "filename": "src/setup/CMakeLists.txt", - "status": "modified", - "additions": 4, - "deletions": 1, - "changes": 5, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fsetup%2FCMakeLists.txt", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fsetup%2FCMakeLists.txt", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/src%2Fsetup%2FCMakeLists.txt?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -15,4 +15,7 @@ add_library(setup STATIC\n txt_mouseinput.c txt_mouseinput.h)\n \n target_include_directories(setup PRIVATE \"../\" \"${CMAKE_CURRENT_BINARY_DIR}/../../\")\n-target_link_libraries(setup textscreen SDL2::SDL2 SDL2::mixer)\n+target_link_libraries(setup textscreen SDL2::SDL2)\n+if(ENABLE_SDL2_mixer)\n+ target_link_libraries(setup SDL2::mixer)\n+endif()" - }, - { - "sha": "37b17ade983155369c0897c0935d40dfeb2048c7", - "filename": "src/strife/CMakeLists.txt", - "status": "modified", - "additions": 7, - "deletions": 1, - "changes": 8, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fstrife%2FCMakeLists.txt", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fstrife%2FCMakeLists.txt", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/src%2Fstrife%2FCMakeLists.txt?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -70,4 +70,10 @@ set(STRIFE_SOURCES\n add_library(strife STATIC ${STRIFE_SOURCES})\n \n target_include_directories(strife PRIVATE \"../\" \"../../win32/\" \"${CMAKE_CURRENT_BINARY_DIR}/../../\")\n-target_link_libraries(strife textscreen SDL2::SDL2 SDL2::mixer SDL2::net)\n+target_link_libraries(strife textscreen SDL2::SDL2)\n+if(ENABLE_SDL2_mixer)\n+ target_link_libraries(strife SDL2::mixer)\n+endif()\n+if(ENABLE_SDL2_NET)\n+ target_link_libraries(strife SDL2::net)\n+endif()" - } -] diff --git a/tests/capture_tools_output/expected_result.json b/tests/capture_tools_output/expected_result.json deleted file mode 100644 index 0912b966..00000000 --- a/tests/capture_tools_output/expected_result.json +++ /dev/null @@ -1,320 +0,0 @@ -[ - { - "sha": "46e082cf77c5e60affc7689f7357c926fc00cda3", - "filename": "opl/opl.c", - "status": "modified", - "additions": 2, - "deletions": 0, - "changes": 2, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/opl%2Fopl.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/opl%2Fopl.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/opl%2Fopl.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -50,7 +50,9 @@ static opl_driver_t *drivers[] =\n #ifdef _WIN32\n &opl_win32_driver,\n #endif\n+#ifndef DISABLE_SDL2MIXER\n &opl_sdl_driver,\n+#endif // DISABLE_SDL2MIXER\n NULL\n };\n ", - "line_filter": { - "diff_chunks": [ - [ - 50, - 59 - ] - ], - "lines_added": [ - [ - 53, - 54 - ], - [ - 55, - 56 - ] - ] - } - }, - { - "sha": "6bd4e7e1f3374e289d3dc19972dcb1d5379d6b03", - "filename": "opl/opl_sdl.c", - "status": "modified", - "additions": 6, - "deletions": 0, - "changes": 6, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/opl%2Fopl_sdl.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/opl%2Fopl_sdl.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/opl%2Fopl_sdl.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -33,6 +33,10 @@\n \n #include \"opl_queue.h\"\n \n+\n+#ifndef DISABLE_SDL2MIXER\n+\n+\n #define MAX_SOUND_SLICE_TIME 100 /* ms */\n \n typedef struct\n@@ -511,3 +515,5 @@ opl_driver_t opl_sdl_driver =\n OPL_SDL_AdjustCallbacks,\n };\n \n+\n+#endif // DISABLE_SDL2MIXER", - "line_filter": { - "diff_chunks": [ - [ - 33, - 43 - ], - [ - 515, - 520 - ] - ], - "lines_added": [ - [ - 36, - 40 - ], - [ - 518, - 520 - ] - ] - } - }, - { - "sha": "58f9b75c2affd5f1dd990aaedab79d834575bf83", - "filename": "pcsound/pcsound.c", - "status": "modified", - "additions": 2, - "deletions": 0, - "changes": 2, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/pcsound%2Fpcsound.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/pcsound%2Fpcsound.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/pcsound%2Fpcsound.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -56,7 +56,9 @@ static pcsound_driver_t *drivers[] =\n #ifdef _WIN32\n &pcsound_win32_driver,\n #endif\n+#ifndef DISABLE_SDL2MIXER\n &pcsound_sdl_driver,\n+#endif // DISABLE_SDL2MIXER\n NULL,\n };\n ", - "line_filter": { - "diff_chunks": [ - [ - 56, - 65 - ] - ], - "lines_added": [ - [ - 59, - 60 - ], - [ - 61, - 62 - ] - ] - } - }, - { - "sha": "e77c7b0d29de1b0c665686004dfda311c9d96719", - "filename": "pcsound/pcsound_sdl.c", - "status": "modified", - "additions": 6, - "deletions": 0, - "changes": 6, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/pcsound%2Fpcsound_sdl.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/pcsound%2Fpcsound_sdl.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/pcsound%2Fpcsound_sdl.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -24,6 +24,10 @@\n #include \"pcsound.h\"\n #include \"pcsound_internal.h\"\n \n+\n+#ifndef DISABLE_SDL2MIXER\n+\n+\n #define MAX_SOUND_SLICE_TIME 70 /* ms */\n #define SQUARE_WAVE_AMP 0x2000\n \n@@ -248,3 +252,5 @@ pcsound_driver_t pcsound_sdl_driver =\n PCSound_SDL_Shutdown,\n };\n \n+\n+#endif // DISABLE_SDL2MIXER", - "line_filter": { - "diff_chunks": [ - [ - 24, - 34 - ], - [ - 252, - 257 - ] - ], - "lines_added": [ - [ - 27, - 31 - ], - [ - 255, - 257 - ] - ] - } - }, - { - "sha": "3facce6f01d02c5e8eef3088fa60576b9e949829", - "filename": "src/i_musicpack.c", - "status": "modified", - "additions": 87, - "deletions": 1, - "changes": 88, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fi_musicpack.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fi_musicpack.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/src%2Fi_musicpack.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -44,6 +44,13 @@\n #include \"w_wad.h\"\n #include \"z_zone.h\"\n \n+\n+char *music_pack_path = \"\";\n+\n+\n+#ifndef DISABLE_SDL2MIXER\n+\n+\n #define MID_HEADER_MAGIC \"MThd\"\n #define MUS_HEADER_MAGIC \"MUS\\x1a\"\n \n@@ -99,7 +106,6 @@ static boolean music_initialized = false;\n \n static boolean sdl_was_initialized = false;\n \n-char *music_pack_path = \"\";\n \n // If true, we are playing a substitute digital track rather than in-WAD\n // MIDI/MUS track, and file_metadata contains loop metadata.\n@@ -1375,3 +1381,83 @@ music_module_t music_pack_module =\n I_MP_PollMusic,\n };\n \n+\n+#else // DISABLE_SDL2MIXER\n+\n+\n+static boolean I_NULL_InitMusic(void)\n+{\n+ return false;\n+}\n+\n+\n+static void I_NULL_ShutdownMusic(void)\n+{\n+}\n+\n+\n+static void I_NULL_SetMusicVolume(int volume)\n+{\n+}\n+\n+\n+static void I_NULL_PauseSong(void)\n+{\n+}\n+\n+\n+static void I_NULL_ResumeSong(void)\n+{\n+}\n+\n+\n+static void *I_NULL_RegisterSong(void *data, int len)\n+{\n+ return NULL;\n+}\n+\n+\n+static void I_NULL_UnRegisterSong(void *handle)\n+{\n+}\n+\n+\n+static void I_NULL_PlaySong(void *handle, boolean looping)\n+{\n+}\n+\n+\n+static void I_NULL_StopSong(void)\n+{\n+}\n+\n+\n+static boolean I_NULL_MusicIsPlaying(void)\n+{\n+ return false;\n+}\n+\n+\n+static void I_NULL_PollMusic(void)\n+{\n+}\n+\n+music_module_t music_pack_module =\n+{\n+ NULL,\n+ 0,\n+ I_NULL_InitMusic,\n+ I_NULL_ShutdownMusic,\n+ I_NULL_SetMusicVolume,\n+ I_NULL_PauseSong,\n+ I_NULL_ResumeSong,\n+ I_NULL_RegisterSong,\n+ I_NULL_UnRegisterSong,\n+ I_NULL_PlaySong,\n+ I_NULL_StopSong,\n+ I_NULL_MusicIsPlaying,\n+ I_NULL_PollMusic,\n+};\n+\n+\n+#endif // DISABLE_SDL2MIXER", - "line_filter": { - "diff_chunks": [ - [ - 44, - 57 - ], - [ - 106, - 112 - ], - [ - 1381, - 1464 - ] - ], - "lines_added": [ - [ - 47, - 54 - ], - [ - 1384, - 1464 - ] - ] - } - }, - { - "sha": "48fedfbd7608ad8c6575a4bd82a5e1cb3646e071", - "filename": "src/i_sdlmusic.c", - "status": "modified", - "additions": 21, - "deletions": 13, - "changes": 34, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fi_sdlmusic.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fi_sdlmusic.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/src%2Fi_sdlmusic.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -44,19 +44,6 @@\n #include \"w_wad.h\"\n #include \"z_zone.h\"\n \n-#define MAXMIDLENGTH (96 * 1024)\n-\n-static boolean music_initialized = false;\n-\n-// If this is true, this module initialized SDL sound and has the \n-// responsibility to shut it down\n-\n-static boolean sdl_was_initialized = false;\n-\n-static boolean win_midi_stream_opened = false;\n-\n-static boolean musicpaused = false;\n-static int current_music_volume;\n \n char *fluidsynth_sf_path = \"\";\n char *timidity_cfg_path = \"\";\n@@ -138,6 +125,25 @@ void I_InitTimidityConfig(void)\n }\n }\n \n+\n+#ifndef DISABLE_SDL2MIXER\n+\n+\n+#define MAXMIDLENGTH (96 * 1024)\n+\n+static boolean music_initialized = false;\n+\n+// If this is true, this module initialized SDL sound and has the\n+// responsibility to shut it down\n+\n+static boolean sdl_was_initialized = false;\n+\n+static boolean win_midi_stream_opened = false;\n+\n+static boolean musicpaused = false;\n+static int current_music_volume;\n+\n+\n // Remove the temporary config file generated by I_InitTimidityConfig().\n \n static void RemoveTimidityConfig(void)\n@@ -588,3 +594,5 @@ music_module_t music_sdl_module =\n NULL, // Poll\n };\n \n+\n+#endif // DISABLE_SDL2MIXER", - "line_filter": { - "diff_chunks": [ - [ - 44, - 50 - ], - [ - 125, - 150 - ], - [ - 594, - 599 - ] - ], - "lines_added": [ - [ - 128, - 147 - ], - [ - 597, - 599 - ] - ] - } - }, - { - "sha": "7f2a26096b218c5323f5dc569c6f70ab399782bf", - "filename": "src/i_sdlsound.c", - "status": "modified", - "additions": 17, - "deletions": 9, - "changes": 26, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fi_sdlsound.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fi_sdlsound.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/src%2Fi_sdlsound.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -41,6 +41,21 @@\n \n #include \"doomtype.h\"\n \n+\n+int use_libsamplerate = 0;\n+\n+// Scale factor used when converting libsamplerate floating point numbers\n+// to integers. Too high means the sounds can clip; too low means they\n+// will be too quiet. This is an amount that should avoid clipping most\n+// of the time: with all the Doom IWAD sound effects, at least. If a PWAD\n+// is used, clipping might occur.\n+\n+float libsamplerate_scale = 0.65f;\n+\n+\n+#ifndef DISABLE_SDL2MIXER\n+\n+\n #define LOW_PASS_FILTER\n //#define DEBUG_DUMP_WAVS\n #define NUM_CHANNELS 16\n@@ -77,15 +92,6 @@ static allocated_sound_t *allocated_sounds_head = NULL;\n static allocated_sound_t *allocated_sounds_tail = NULL;\n static int allocated_sounds_size = 0;\n \n-int use_libsamplerate = 0;\n-\n-// Scale factor used when converting libsamplerate floating point numbers\n-// to integers. Too high means the sounds can clip; too low means they\n-// will be too quiet. This is an amount that should avoid clipping most\n-// of the time: with all the Doom IWAD sound effects, at least. If a PWAD\n-// is used, clipping might occur.\n-\n-float libsamplerate_scale = 0.65f;\n \n // Hook a sound into the linked list at the head.\n \n@@ -1135,3 +1141,5 @@ sound_module_t sound_sdl_module =\n I_SDL_PrecacheSounds,\n };\n \n+\n+#endif // DISABLE_SDL2MIXER", - "line_filter": { - "diff_chunks": [ - [ - 41, - 62 - ], - [ - 92, - 98 - ], - [ - 1141, - 1146 - ] - ], - "lines_added": [ - [ - 44, - 59 - ], - [ - 1144, - 1146 - ] - ] - } - }, - { - "sha": "9cf1fd95db13504ffc6f98ead8c9150f03db72aa", - "filename": "src/i_sound.c", - "status": "modified", - "additions": 4, - "deletions": 0, - "changes": 4, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fi_sound.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fi_sound.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/src%2Fi_sound.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -99,7 +99,9 @@ static int snd_mport = 0;\n \n static sound_module_t *sound_modules[] = \n {\n+#ifndef DISABLE_SDL2MIXER\n &sound_sdl_module,\n+#endif // DISABLE_SDL2MIXER\n &sound_pcsound_module,\n NULL,\n };\n@@ -108,7 +110,9 @@ static sound_module_t *sound_modules[] =\n \n static music_module_t *music_modules[] =\n {\n+#ifndef DISABLE_SDL2MIXER\n &music_sdl_module,\n+#endif // DISABLE_SDL2MIXER\n &music_opl_module,\n NULL,\n };", - "line_filter": { - "diff_chunks": [ - [ - 99, - 108 - ], - [ - 110, - 119 - ] - ], - "lines_added": [ - [ - 102, - 103 - ], - [ - 104, - 105 - ], - [ - 113, - 114 - ], - [ - 115, - 116 - ] - ] - } - }, - { - "sha": "c1f701c0b9f653eb3a36b71627747a6eda963d8f", - "filename": "src/net_sdl.c", - "status": "modified", - "additions": 63, - "deletions": 0, - "changes": 63, - "blob_url": "https://github.com/chocolate-doom/chocolate-doom/blob/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fnet_sdl.c", - "raw_url": "https://github.com/chocolate-doom/chocolate-doom/raw/3c35acde7d398c32f6fad50fa902de391f573ffa/src%2Fnet_sdl.c", - "contents_url": "https://api.github.com/repos/chocolate-doom/chocolate-doom/contents/src%2Fnet_sdl.c?ref=3c35acde7d398c32f6fad50fa902de391f573ffa", - "patch": "@@ -33,6 +33,10 @@\n // NETWORKING\n //\n \n+\n+#ifndef DISABLE_SDL2NET\n+\n+\n #include \n \n #define DEFAULT_PORT 2342\n@@ -376,3 +380,62 @@ net_module_t net_sdl_module =\n NET_SDL_ResolveAddress,\n };\n \n+\n+#else // DISABLE_SDL2NET\n+\n+// no-op implementation\n+\n+\n+static boolean NET_NULL_InitClient(void)\n+{\n+ return false;\n+}\n+\n+\n+static boolean NET_NULL_InitServer(void)\n+{\n+ return false;\n+}\n+\n+\n+static void NET_NULL_SendPacket(net_addr_t *addr, net_packet_t *packet)\n+{\n+}\n+\n+\n+static boolean NET_NULL_RecvPacket(net_addr_t **addr, net_packet_t **packet)\n+{\n+ return false;\n+}\n+\n+\n+static void NET_NULL_AddrToString(net_addr_t *addr, char *buffer, int buffer_len)\n+{\n+\n+}\n+\n+\n+static void NET_NULL_FreeAddress(net_addr_t *addr)\n+{\n+}\n+\n+\n+net_addr_t *NET_NULL_ResolveAddress(const char *address)\n+{\n+ return NULL;\n+}\n+\n+\n+net_module_t net_sdl_module =\n+{\n+ NET_NULL_InitClient,\n+ NET_NULL_InitServer,\n+ NET_NULL_SendPacket,\n+ NET_NULL_RecvPacket,\n+ NET_NULL_AddrToString,\n+ NET_NULL_FreeAddress,\n+ NET_NULL_ResolveAddress,\n+};\n+\n+\n+#endif // DISABLE_SDL2NET", - "line_filter": { - "diff_chunks": [ - [ - 33, - 43 - ], - [ - 380, - 442 - ] - ], - "lines_added": [ - [ - 36, - 40 - ], - [ - 383, - 442 - ] - ] - } - } -] diff --git a/tests/capture_tools_output/test_database_path.py b/tests/capture_tools_output/test_database_path.py deleted file mode 100644 index da275a30..00000000 --- a/tests/capture_tools_output/test_database_path.py +++ /dev/null @@ -1,57 +0,0 @@ -"""Tests specific to specifying the compilation database path.""" -from typing import List -from pathlib import Path, PurePath -import logging -import re -import pytest -from cpp_linter import logger -import cpp_linter.run -from cpp_linter.run import run_clang_tidy - -CLANG_TIDY_COMMAND = re.compile(r"\"clang-tidy(.*)(?:\")") - -ABS_DB_PATH = str(Path(PurePath(__file__).parent / "../../demo").resolve()) - - -@pytest.mark.parametrize( - "database,expected_args", - [ - # implicit path to the compilation database - ("", []), - # explicit relative path to the compilation database - ("../../demo", ["-p", ABS_DB_PATH]), - # explicit absolute path to the compilation database - (ABS_DB_PATH, ["-p", ABS_DB_PATH]), - ], -) -def test_db_detection( - caplog: pytest.LogCaptureFixture, - monkeypatch: pytest.MonkeyPatch, - database: str, - expected_args: List[str], -): - """test clang-tidy using a implicit path to the compilation database.""" - monkeypatch.chdir(PurePath(__file__).parent.as_posix()) - demo_src = "../../demo/demo.cpp" - rel_root = str(Path(*Path(__file__).parts[-2:])) - cpp_linter.run.RUNNER_WORKSPACE = ( - Path(PurePath(__file__).parent / "../../").resolve().as_posix() - ) - caplog.set_level(logging.DEBUG, logger=logger.name) - run_clang_tidy( - filename=(demo_src), - file_obj={}, # only used when filtering lines - version="", - checks="", # let clang-tidy use a .clang-tidy config file - lines_changed_only=0, # analyze complete file - database=database, - repo_root=rel_root, - ) - matched_args = [] - for record in caplog.records: - msg_match = CLANG_TIDY_COMMAND.search(record.message) - if msg_match is not None: - matched_args = msg_match.group(0)[:-1].split()[2:] - assert "Error while trying to load a compilation database" not in record.message - expected_args.append(demo_src) - assert matched_args == expected_args diff --git a/tests/capture_tools_output/test_tools_output.py b/tests/capture_tools_output/test_tools_output.py deleted file mode 100644 index c7467fa3..00000000 --- a/tests/capture_tools_output/test_tools_output.py +++ /dev/null @@ -1,207 +0,0 @@ -"""Various tests related to the ``lines_changed_only`` option.""" -import os -import logging -from typing import Dict, Any, cast, List, Optional -from pathlib import Path -import json -import re -import pytest -import cpp_linter -from cpp_linter.run import ( - filter_out_non_source_files, - verify_files_are_present, - capture_clang_tools_output, - make_annotations, - log_commander, -) -from cpp_linter.thread_comments import list_diff_comments - -CLANG_VERSION = os.getenv("CLANG_VERSION", "12") - - -@pytest.mark.parametrize( - "extensions", [(["c"]), pytest.param(["h"], marks=pytest.mark.xfail)] -) -def test_lines_changed_only( - monkeypatch: pytest.MonkeyPatch, - caplog: pytest.LogCaptureFixture, - extensions: List[str], -): - """Test for lines changes in diff. - - This checks for - 1. ranges of diff chunks. - 2. ranges of lines in diff that only contain additions. - """ - monkeypatch.chdir(str(Path(__file__).parent)) - caplog.set_level(logging.DEBUG, logger=cpp_linter.logger.name) - cpp_linter.Globals.FILES = json.loads( - Path("event_files.json").read_text(encoding="utf-8") - ) - if filter_out_non_source_files( - ext_list=extensions, - ignored=[".github"], - not_ignored=[], - ): - test_result = Path("expected_result.json").read_text(encoding="utf-8") - for file, result in zip( - cpp_linter.Globals.FILES, - json.loads(test_result), - ): - expected = result["line_filter"]["diff_chunks"] - assert file["line_filter"]["diff_chunks"] == expected - expected = result["line_filter"]["lines_added"] - assert file["line_filter"]["lines_added"] == expected - else: - raise RuntimeError("test failed to find files") - - -TEST_REPO = re.compile(r".*github.com/(?:\w|\-|_)+/((?:\w|\-|_)+)/.*") - - -@pytest.fixture(autouse=True) -def setup_test_repo(monkeypatch: pytest.MonkeyPatch) -> None: - """Setup a test repo to run the rest of the tests in this module.""" - test_root = Path(__file__).parent - cpp_linter.Globals.FILES = json.loads( - Path(test_root / "expected_result.json").read_text(encoding="utf-8") - ) - # flush output from any previous tests - cpp_linter.Globals.OUTPUT = "" - cpp_linter.GlobalParser.format_advice = [] - cpp_linter.GlobalParser.tidy_notes = [] - cpp_linter.GlobalParser.tidy_advice = [] - - repo_root = TEST_REPO.sub("\\1", cpp_linter.Globals.FILES[0]["blob_url"]) - return_path = test_root / repo_root - if not return_path.exists(): - return_path.mkdir() - monkeypatch.chdir(str(return_path)) - verify_files_are_present() - - -def match_file_json(filename: str) -> Optional[Dict[str, Any]]: - """A helper function to match a given filename with a file's JSON object.""" - for file in cpp_linter.Globals.FILES: - if file["filename"] == filename: - return file - print("file", filename, "not found in expected_result.json") - return None - - -RECORD_FILE = re.compile(r".*file=(.*?),.*") -FORMAT_RECORD = re.compile(r"Run clang-format on ") -FORMAT_RECORD_LINES = re.compile(r".*\(lines (.*)\).*") -TIDY_RECORD = re.compile(r":\d+:\d+ \[.*\]::") -TIDY_RECORD_LINE = re.compile(r".*,line=(\d+).*") - - -@pytest.mark.parametrize( - "lines_changed_only", [0, 1, 2], ids=["all lines", "only diff", "only added"] -) -@pytest.mark.parametrize("style", ["file", "llvm", "google"]) -def test_format_annotations( - caplog: pytest.LogCaptureFixture, - lines_changed_only: int, - style: str, -): - """Test clang-format annotations.""" - capture_clang_tools_output( - version=CLANG_VERSION, - checks="-*", # disable clang-tidy output - style=style, - lines_changed_only=lines_changed_only, - database="", - repo_root="", - ) - assert "Output from `clang-tidy`" not in cpp_linter.Globals.OUTPUT - caplog.set_level(logging.INFO, logger=log_commander.name) - log_commander.propagate = True - make_annotations( - style=style, file_annotations=True, lines_changed_only=lines_changed_only - ) - for message in [r.message for r in caplog.records if r.levelno == logging.INFO]: - if FORMAT_RECORD.search(message) is not None: - lines = [ - int(l.strip()) - for l in FORMAT_RECORD_LINES.sub("\\1", message).split(",") - ] - file = match_file_json(RECORD_FILE.sub("\\1", message).replace("\\", "/")) - if file is None: - continue - ranges = cpp_linter.range_of_changed_lines(file, lines_changed_only) - if ranges: # an empty list if lines_changed_only == 0 - for line in lines: - assert line in ranges - else: - raise RuntimeWarning(f"unrecognized record: {message}") - - -@pytest.mark.parametrize( - "lines_changed_only", [0, 1, 2], ids=["all lines", "only diff", "only added"] -) -@pytest.mark.parametrize( - "checks", - [ - "", - "boost-*,bugprone-*,performance-*,readability-*,portability-*,modernize-*," - "clang-analyzer-*,cppcoreguidelines-*", - ], - ids=["config file", "action defaults"], -) -def test_tidy_annotations( - caplog: pytest.LogCaptureFixture, - lines_changed_only: int, - checks: str, -): - """Test clang-tidy annotations.""" - capture_clang_tools_output( - version=CLANG_VERSION, - checks=checks, - style="", # disable clang-format output - lines_changed_only=lines_changed_only, - database="", - repo_root="", - ) - assert "Run `clang-format` on the following files" not in cpp_linter.Globals.OUTPUT - caplog.set_level(logging.INFO, logger=log_commander.name) - log_commander.propagate = True - make_annotations( - style="", file_annotations=True, lines_changed_only=lines_changed_only - ) - for message in [r.message for r in caplog.records if r.levelno == logging.INFO]: - if TIDY_RECORD.search(message) is not None: - line = int(TIDY_RECORD_LINE.sub("\\1", message)) - file = match_file_json(RECORD_FILE.sub("\\1", message).replace("\\", "/")) - if file is None: - continue - ranges = cpp_linter.range_of_changed_lines(file, lines_changed_only) - if ranges: # an empty list if lines_changed_only == 0 - assert line in ranges - else: - raise RuntimeWarning(f"unrecognized record: {message}") - - -@pytest.mark.parametrize("lines_changed_only", [1, 2], ids=["only diff", "only added"]) -def test_diff_comment(lines_changed_only: int): - """Tests code that isn't actually used (yet) for posting - comments (not annotations) in the event's diff. - - Remember, diff comments should only focus on lines in the diff.""" - capture_clang_tools_output( - version=CLANG_VERSION, - checks="", - style="file", - lines_changed_only=lines_changed_only, - database="", - repo_root="", - ) - diff_comments = list_diff_comments(lines_changed_only) - # output = Path(__file__).parent / "diff_comments.json" - # output.write_text(json.dumps(diff_comments, indent=2), encoding="utf-8") - for comment in diff_comments: - file = match_file_json(cast(str, comment["path"])) - if file is None: - continue - ranges = cpp_linter.range_of_changed_lines(file, lines_changed_only) - assert comment["line"] in ranges diff --git a/tests/ignored_paths/.gitmodules b/tests/ignored_paths/.gitmodules deleted file mode 100644 index 3696a312..00000000 --- a/tests/ignored_paths/.gitmodules +++ /dev/null @@ -1,12 +0,0 @@ -[submodule "RF24"] - path = RF24 - url = https://github.com/nRF24/RF24.git -[submodule "RF24Network"] - path = RF24Network - url = https://github.com/nRF24/RF24Network.git -[submodule "RF24Mesh"] - path = RF24Mesh - url = https://github.com/nRF24/RF24Mesh.git -[submodule "pybind11"] - path = pybind11 - url = https://github.com/pybind/pybind11.git diff --git a/tests/ignored_paths/test_ignored_paths.py b/tests/ignored_paths/test_ignored_paths.py deleted file mode 100644 index b27d3b8c..00000000 --- a/tests/ignored_paths/test_ignored_paths.py +++ /dev/null @@ -1,32 +0,0 @@ -"""Tests that focus on the ``ignore`` option's parsing.""" -from pathlib import Path -from typing import List -import pytest -from cpp_linter.run import parse_ignore_option, is_file_in_list - - -@pytest.mark.parametrize( - "user_in,is_ignored,is_not_ignored,expected", - [ - ("src", "src", "src", [True, False]), - ("!src|./", "", "src", [True, True]), - ], -) -def test_ignore( - user_in: str, is_ignored: str, is_not_ignored: str, expected: List[bool] -): - """test ignoring of a specified path.""" - ignored, not_ignored = parse_ignore_option(user_in) - assert expected == [ - is_file_in_list(ignored, is_ignored, "ignored"), - is_file_in_list(not_ignored, is_not_ignored, "not ignored"), - ] - - -def test_ignore_submodule(monkeypatch: pytest.MonkeyPatch): - """test auto detection of submodules and ignore the paths appropriately.""" - monkeypatch.chdir(str(Path(__file__).parent)) - ignored, not_ignored = parse_ignore_option("!pybind11") - for ignored_submodule in ["RF24", "RF24Network", "RF24Mesh"]: - assert ignored_submodule in ignored - assert "pybind11" in not_ignored diff --git a/tests/test_cli_args.py b/tests/test_cli_args.py deleted file mode 100644 index 58c2dc37..00000000 --- a/tests/test_cli_args.py +++ /dev/null @@ -1,75 +0,0 @@ -"""Tests related parsing input from CLI arguments.""" -from typing import List, Union -import pytest -from cpp_linter.run import cli_arg_parser - - -class Args: - """A pseudo namespace declaration. Each attribute is initialized with the - corresponding CLI arg's default value.""" - - verbosity: int = 10 - database: str = "" - style: str = "llvm" - tidy_checks: str = ( - "boost-*,bugprone-*,performance-*,readability-*,portability-*,modernize-*," - "clang-analyzer-*,cppcoreguidelines-*" - ) - version: str = "" - extensions: List[str] = [ - "c", - "h", - "C", - "H", - "cpp", - "hpp", - "cc", - "hh", - "c++", - "h++", - "cxx", - "hxx", - ] - repo_root: str = "." - ignore: str = ".github" - lines_changed_only: int = 0 - files_changed_only: bool = False - thread_comments: bool = False - file_annotations: bool = True - - -def test_defaults(): - """test default values""" - args = cli_arg_parser.parse_args("") - for key in args.__dict__.keys(): - assert args.__dict__[key] == getattr(Args, key) - - -@pytest.mark.parametrize( - "arg_name,arg_value,attr_name,attr_value", - [ - ("verbosity", "20", "verbosity", 20), - ("database", "build", "database", "build"), - ("style", "file", "style", "file"), - ("tidy-checks", "-*", "tidy_checks", "-*"), - ("version", "14", "version", "14"), - ("extensions", ".cpp, .h", "extensions", ["cpp", "h"]), - ("extensions", "cxx,.hpp", "extensions", ["cxx", "hpp"]), - ("repo-root", "src", "repo_root", "src"), - ("ignore", "!src|", "ignore", "!src|"), - ("lines-changed-only", "True", "lines_changed_only", 2), - ("lines-changed-only", "Diff", "lines_changed_only", 1), - ("files-changed-only", "True", "files_changed_only", True), - ("thread-comments", "True", "thread_comments", True), - ("file-annotations", "False", "file_annotations", False), - ], -) -def test_arg_parser( - arg_name: str, - arg_value: str, - attr_name: str, - attr_value: Union[int, str, List[str], bool], -): - """parameterized test of specific args compared to their parsed value""" - args = cli_arg_parser.parse_args([f"--{arg_name}={arg_value}"]) - assert getattr(args, attr_name) == attr_value diff --git a/tests/test_misc.py b/tests/test_misc.py deleted file mode 100644 index df624fb6..00000000 --- a/tests/test_misc.py +++ /dev/null @@ -1,104 +0,0 @@ -"""Tests that complete coverage that aren't prone to failure.""" -import logging -from pathlib import Path -from typing import List -import pytest -import requests -import cpp_linter -import cpp_linter.run -from cpp_linter import Globals, log_response_msg, get_line_cnt_from_cols -from cpp_linter.run import ( - log_commander, - start_log_group, - end_log_group, - set_exit_code, - list_source_files, - get_list_of_changed_files, -) - - -def test_exit_override(): - """Test exit code that indicates if action encountered lining errors.""" - assert 1 == set_exit_code(1) - - -def test_exit_implicit(): - """Test the exit code issued when a thread comment is to be made.""" - Globals.OUTPUT = "TEST" # fake content for a thread comment - assert 1 == set_exit_code() - - -# see https://github.com/pytest-dev/pytest/issues/5997 -def test_end_group(caplog: pytest.LogCaptureFixture): - """Test the output that concludes a group of runner logs.""" - caplog.set_level(logging.INFO, logger=log_commander.name) - log_commander.propagate = True - end_log_group() - messages = caplog.messages - assert "::endgroup::" in messages - - -# see https://github.com/pytest-dev/pytest/issues/5997 -def test_start_group(caplog: pytest.LogCaptureFixture): - """Test the output that begins a group of runner logs.""" - caplog.set_level(logging.INFO, logger=log_commander.name) - log_commander.propagate = True - start_log_group("TEST") - messages = caplog.messages - assert "::group::TEST" in messages - - -@pytest.mark.parametrize( - "url", - [ - ("https://api.github.com/users/cpp-linter/starred"), - pytest.param(("https://github.com/cpp-linter/repo"), marks=pytest.mark.xfail), - ], -) -def test_response_logs(url: str): - """Test the log output for a requests.response buffer.""" - Globals.response_buffer = requests.get(url) - assert log_response_msg() - - -@pytest.mark.parametrize( - "extensions", - [ - (["cpp", "hpp"]), - pytest.param(["cxx", "h"], marks=pytest.mark.xfail), - ], -) -def test_list_src_files( - monkeypatch: pytest.MonkeyPatch, - caplog: pytest.LogCaptureFixture, - extensions: List[str], -): - """List the source files in the demo folder of this repo.""" - Globals.FILES = [] - monkeypatch.chdir(Path(__file__).parent.parent.as_posix()) - caplog.set_level(logging.DEBUG, logger=cpp_linter.logger.name) - assert list_source_files(ext_list=extensions, ignored_paths=[], not_ignored=[]) - - -def test_get_changed_files(caplog: pytest.LogCaptureFixture): - """test getting a list of changed files for an event. - - This is expected to fail if a github token not supplied as an env var. - We don't need to supply one for this test because the tested code will - execute anyway. - """ - caplog.set_level(logging.DEBUG, logger=cpp_linter.logger.name) - cpp_linter.run.GITHUB_REPOSITORY = "cpp-linter/test-cpp-linter-action" - cpp_linter.run.GITHUB_SHA = "76adde5367196cd57da5bef49a4f09af6175fd3f" - cpp_linter.run.GITHUB_EVENT_NAME = "push" - get_list_of_changed_files() - # pylint: disable=no-member - assert Globals.FILES - # pylint: enable=no-member - - -@pytest.mark.parametrize("line,cols,offset", [(13, 5, 144), (19, 1, 189)]) -def test_file_offset_translation(line: int, cols: int, offset: int): - """Validate output from ``get_line_cnt_from_cols()``""" - test_file = str(Path("demo/demo.cpp").resolve()) - assert (line, cols) == get_line_cnt_from_cols(test_file, offset)