From 24eb2e76b0c92ee88f2d1d65a70486496362a7e7 Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Thu, 30 Oct 2025 05:28:59 +0200 Subject: [PATCH 01/20] feat: support install python wheels --- README.rst | 4 +++- clang_tools/wheel.py | 29 +++++++++++++++++++++++++++++ pyproject.toml | 7 +++++++ tests/test_wheel.py | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 clang_tools/wheel.py create mode 100644 tests/test_wheel.py diff --git a/README.rst b/README.rst index 1117701..d133151 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ clang-tools CLI =============== -**Install clang-format, clang-tidy, clang-query, and clang-apply-replacements binaries with clang-tools CLI.** +**Install clang-format, clang-tidy, clang-query, and clang-apply-replacements binaries and Python wheels with clang-tools CLI.** .. |latest-version| image:: https://img.shields.io/pypi/v/clang-tools?color=blue :target: https://pypi.org/project/clang-tools/ @@ -29,6 +29,8 @@ clang-tools CLI are installed using this package's executable script. It does not intend to change or modify any binary executable installed from other sources (like LLVM releases). + For Python wheels, this CLI only support clang-format and clang-tidy tools. + Features -------- diff --git a/clang_tools/wheel.py b/clang_tools/wheel.py new file mode 100644 index 0000000..0c35d44 --- /dev/null +++ b/clang_tools/wheel.py @@ -0,0 +1,29 @@ +from argparse import ArgumentParser +from cpp_linter_hooks.util import _resolve_install + + +def main() -> int: + parser = ArgumentParser(description="Install specified clang tool wheel") + parser.add_argument( + "--tool", + default="clang-format", + choices=["clang-format", "clang-tidy"], + help="Tool to install (clang-format or clang-tidy)", + ) + parser.add_argument( + "--version", + default=None, + help="Version to install (e.g., 21 or 21.1.2). Defaults to latest compatible version.", + ) + args = parser.parse_args() + path = _resolve_install(args.tool, args.version) + if path: + print(f"{args.tool} installed at: {path}") + return 0 + else: + print(f"Failed to install {args.tool} version {args.version}") + return 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/pyproject.toml b/pyproject.toml index ab5308b..26df57c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,10 +30,17 @@ classifiers = [ "Programming Language :: Python :: 3.14", "Topic :: Software Development :: Build Tools", ] + +dependencies = [ + "cpp-linter-hooks>=1.1.6", +] + dynamic = ["version"] [project.scripts] clang-tools = "clang_tools.main:main" +clang-tools-binary = "clang_tools.main:main" +clang-tools-wheel = "clang_tools.wheel:main" [project.urls] source = "https://github.com/cpp-linter/clang-tools-pip" diff --git a/tests/test_wheel.py b/tests/test_wheel.py new file mode 100644 index 0000000..3153321 --- /dev/null +++ b/tests/test_wheel.py @@ -0,0 +1,38 @@ +import sys +from clang_tools.wheel import main + + +def test_main_success(monkeypatch): + # Patch _resolve_install to simulate success + monkeypatch.setattr( + "clang_tools.wheel._resolve_install", + lambda tool, version: "/usr/bin/clang-format", + ) + monkeypatch.setattr( + sys, "argv", ["util.py", "--tool", "clang-format", "--version", "15.0.7"] + ) + exit_code = main() + assert exit_code == 0 + + +def test_main_failure(monkeypatch): + # Patch _resolve_install to simulate failure + monkeypatch.setattr( + "clang_tools.wheel._resolve_install", lambda tool, version: None + ) + monkeypatch.setattr( + sys, "argv", ["util.py", "--tool", "clang-format", "--version", "99.99.99"] + ) + exit_code = main() + assert exit_code == 1 + + +def test_main_default_tool(monkeypatch): + # Patch _resolve_install to simulate success for default tool + monkeypatch.setattr( + "clang_tools.wheel._resolve_install", + lambda tool, version: "/usr/bin/clang-format", + ) + monkeypatch.setattr(sys, "argv", ["util.py"]) + exit_code = main() + assert exit_code == 0 From 1679bac9009cb1a7991039da761dabcab07cfe34 Mon Sep 17 00:00:00 2001 From: Xianpeng Shen Date: Thu, 30 Oct 2025 09:29:44 +0200 Subject: [PATCH 02/20] fix: Update python-test.yml to upload only clang-tools wheel --- .github/workflows/python-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index eb3ca20..f09792d 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -71,7 +71,7 @@ jobs: uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 #v4 with: name: clang-tools-pip_wheel - path: dist/*.whl + path: dist/clang_tools*.whl install: needs: [build] From f15f170fd7429fffd8f149f9444248c34c82ab4d Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Fri, 31 Oct 2025 07:49:29 +0200 Subject: [PATCH 03/20] chore: save progress --- README.rst | 47 ++++++++++++++++++++---- clang_tools/wheel.py | 19 +++++++++- docs/api.rst | 3 ++ docs/conf.py | 80 +++++++++++++++++++++++------------------ docs/index.rst | 1 + docs/usage.rst | 4 +-- docs/wheel_cli_args.rst | 20 +++++++++++ pyproject.toml | 1 - 8 files changed, 131 insertions(+), 44 deletions(-) create mode 100644 docs/wheel_cli_args.rst diff --git a/README.rst b/README.rst index d133151..e07625b 100644 --- a/README.rst +++ b/README.rst @@ -34,6 +34,7 @@ clang-tools CLI Features -------- +- Support clang tools binaries and Python wheels. - Binaries are statically linked for improved portability. - Binaries can be specified installed for increased flexibility. - Binaries are checked with SHA512 checksum. This ensures: @@ -50,6 +51,7 @@ Features category. - Customizable install path. + Install clang-tools CLI ----------------------- @@ -85,14 +87,15 @@ Install `clang-tools` from git repo pip install git+https://github.com/cpp-linter/clang-tools-pip.git@main + CLI Usage --------- For a list of supported Command Line Interface options, see `the CLI documentation `_ -Examples -******** +Install binaries examples +~~~~~~~~~~~~~~~~~~~~~~~~~ Use ``clang-tools`` command to install version 13 binaries. @@ -128,13 +131,35 @@ If the installed directory is in your path, you can run the installed tools. Default target: x86_64-unknown-linux-gnu Host CPU: skylake -Supported versions + +Install wheels examples +~~~~~~~~~~~~~~~~~~~~~~~~~ + +After installing the ``clang-tools`` CLI, you can install the Python wheels by running: ``clang-tools-wheel`` command. + +.. important:: + It is just used for cpp-linter projects to install clang tools Python wheels. For other use cases, please install the wheels with ``pip``, ``pipx``, ``uv``, or other tools. + + +.. code-block:: shell + + # Install latest clang-format wheel + clang-tools-wheel --tool clang-format --version 21 + # Install latest clang-tidy wheel + clang-tools-wheel --tool clang-tidy --version 21 + + +Supported Versions ------------------ -clang-format, clang-tidy, clang-query, clang-apply-replacements -*************************************************************** + +clang tools binaries +~~~~~~~~~~~~~~~~~~~~ + +The following table shows the supported versions of clang-format, clang-tidy, clang-query, and clang-apply-replacements binaries for each platform: + .. csv-table:: - :header: "Version", "21", "20", "19", "18", "17", "16", "15", "14", "13", "12", "11", "10", "9" + :header: "Platform", "21", "20", "19", "18", "17", "16", "15", "14", "13", "12", "11", "10", "9" :stub-columns: 1 Linux,✔️,✔️,✔️,✔️,✔️,✔️,✔️,✔️,✔️,✔️,✔️,✔️,✔️ @@ -142,3 +167,13 @@ clang-format, clang-tidy, clang-query, clang-apply-replacements macOS,✔️,✔️,✔️,✔️,✔️,✔️,✔️,✔️,✔️,✔️,✔️,✔️,✔️ For more details, visit the `clang-tools-static-binaries `_ repository. + +clang tools Python wheels +~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following Python wheels are supported: + +- `clang-format `_ +- `clang-tidy `_ + +Check the respective PyPI pages for available versions and platform support. diff --git a/clang_tools/wheel.py b/clang_tools/wheel.py index 0c35d44..b41f699 100644 --- a/clang_tools/wheel.py +++ b/clang_tools/wheel.py @@ -2,7 +2,8 @@ from cpp_linter_hooks.util import _resolve_install -def main() -> int: +def get_parser() -> ArgumentParser: + """Get and parser to interpret CLI args.""" parser = ArgumentParser(description="Install specified clang tool wheel") parser.add_argument( "--tool", @@ -15,6 +16,22 @@ def main() -> int: default=None, help="Version to install (e.g., 21 or 21.1.2). Defaults to latest compatible version.", ) + return parser + + +def main() -> int: + parser = get_parser() + args = parser.parse_args() + args = parser.parse_args() + path = _resolve_install(args.tool, args.version) + if path: + print(f"{args.tool} installed at: {path}") + return 0 + parser.add_argument( + "--version", + default=None, + help="Version to install (e.g., 21 or 21.1.2). Defaults to latest compatible version.", + ) args = parser.parse_args() path = _resolve_install(args.tool, args.version) if path: diff --git a/docs/api.rst b/docs/api.rst index e10d56f..e177401 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -9,3 +9,6 @@ API Reference .. automodule:: clang_tools.util :members: + +.. automodule:: clang_tools.wheel + :members: diff --git a/docs/conf.py b/docs/conf.py index f91fe21..415377e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,6 +14,7 @@ from sphinx.util.docutils import SphinxRole from sphinx_immaterial.inline_icons import load_svg_into_builder_env from clang_tools.main import get_parser +from clang_tools.wheel import get_parser as get_wheel_parser # -- Path setup -------------------------------------------------------------- @@ -207,38 +208,49 @@ def setup(app: Sphinx): app.add_role("badge-default", CliBadgeDefault()) app.add_role("badge-switch", CliBadgeSwitch()) + def write_cli_doc(doc_path, parser, prog_name): + with open(doc_path, mode="w") as doc: + doc.write(f"{prog_name} --help\n{'=' * 30}\n\n") + doc.write( + ".. code-block:: text\n :caption: Usage\n :class: no-copy\n\n" + ) + parser.prog = prog_name + str_buf = StringIO() + parser.print_usage(str_buf) + usage = str_buf.getvalue() + start = usage.find(parser.prog) + for line in usage.splitlines(): + doc.write(f" {line[start:]}\n") + args = parser._optionals._actions + for arg in args: + aliases = arg.option_strings + if not aliases or arg.default == "==SUPPRESS==": + continue + assert arg.help is not None + doc.write("\n.. std:option:: " + ", ".join(aliases) + "\n") + req_ver = next( + ( + ver + for ver, names in REQUIRED_VERSIONS.items() + if arg.dest in names + ), + "0.1.0", + ) + doc.write(f"\n :badge-version:`{req_ver}` ") + if arg.default: + default = ( + " ".join(arg.default) + if isinstance(arg.default, list) + else arg.default + ) + doc.write(f":badge-default:`{default}` ") + if isinstance(arg, _StoreTrueAction): + doc.write(":badge-switch:`Accepts no value` ") + doc.write("\n\n ") + doc.write("\n ".join(arg.help.splitlines()) + "\n") + cli_doc = Path(app.srcdir, "cli_args.rst") - with open(cli_doc, mode="w") as doc: - doc.write("Command Line Interface Options\n==============================\n\n") - parser = get_parser() - doc.write(".. code-block:: text\n :caption: Usage\n :class: no-copy\n\n") - parser.prog = "clang-tools" - str_buf = StringIO() - parser.print_usage(str_buf) - usage = str_buf.getvalue() - start = usage.find(parser.prog) - for line in usage.splitlines(): - doc.write(f" {line[start:]}\n") - - args = parser._optionals._actions - for arg in args: - aliases = arg.option_strings - if not aliases or arg.default == "==SUPPRESS==": - continue - assert arg.help is not None - doc.write("\n.. std:option:: " + ", ".join(aliases) + "\n") - req_ver = "0.1.0" - for ver, names in REQUIRED_VERSIONS.items(): - if arg.dest in names: - req_ver = ver - break - doc.write(f"\n :badge-version:`{req_ver}` ") - if arg.default: - default = arg.default - if isinstance(arg.default, list): - default = " ".join(arg.default) - doc.write(f":badge-default:`{default}` ") - if isinstance(arg, _StoreTrueAction): - doc.write(":badge-switch:`Accepts no value` ") - doc.write("\n\n ") - doc.write("\n ".join(arg.help.splitlines()) + "\n") + write_cli_doc(cli_doc, get_parser(), "clang-tools") + + wheel_cli_doc = Path(app.srcdir, "wheel_cli_args.rst") + write_cli_doc(wheel_cli_doc, get_wheel_parser(), "clang-tools-wheel") diff --git a/docs/index.rst b/docs/index.rst index 03b61da..56f28a1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -11,6 +11,7 @@ :hidden: cli_args + wheel_cli_args .. toctree:: :hidden: diff --git a/docs/usage.rst b/docs/usage.rst index 7fb9428..e8bf318 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -1,5 +1,5 @@ -Using a Custom Binary Repository --------------------------------- +Custom Binary Repository +------------------------ You can override the default source for downloading **clang-tools** by setting the following environment variables: diff --git a/docs/wheel_cli_args.rst b/docs/wheel_cli_args.rst new file mode 100644 index 0000000..ec98580 --- /dev/null +++ b/docs/wheel_cli_args.rst @@ -0,0 +1,20 @@ +clang-tools-wheel --help +============================== + +.. code-block:: text + :caption: Usage + :class: no-copy + + clang-tools-wheel [-h] [--tool {clang-format,clang-tidy}] [--version VERSION] + +.. std:option:: --tool + + :badge-version:`0.11.0` :badge-default:`clang-format` + + Tool to install (clang-format or clang-tidy) + +.. std:option:: --version + + :badge-version:`0.1.0` + + Version to install (e.g., 21 or 21.1.2). Defaults to latest compatible version. diff --git a/pyproject.toml b/pyproject.toml index 26df57c..df459df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,7 +39,6 @@ dynamic = ["version"] [project.scripts] clang-tools = "clang_tools.main:main" -clang-tools-binary = "clang_tools.main:main" clang-tools-wheel = "clang_tools.wheel:main" [project.urls] From 84f20d36455ecd0224f447d5db922ce617cfdd9d Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Fri, 31 Oct 2025 20:18:59 +0200 Subject: [PATCH 04/20] fix: remove duplicate code --- clang_tools/wheel.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/clang_tools/wheel.py b/clang_tools/wheel.py index b41f699..8a3cd71 100644 --- a/clang_tools/wheel.py +++ b/clang_tools/wheel.py @@ -22,17 +22,6 @@ def get_parser() -> ArgumentParser: def main() -> int: parser = get_parser() args = parser.parse_args() - args = parser.parse_args() - path = _resolve_install(args.tool, args.version) - if path: - print(f"{args.tool} installed at: {path}") - return 0 - parser.add_argument( - "--version", - default=None, - help="Version to install (e.g., 21 or 21.1.2). Defaults to latest compatible version.", - ) - args = parser.parse_args() path = _resolve_install(args.tool, args.version) if path: print(f"{args.tool} installed at: {path}") From 8736bd2852e8b32409799a3f6614638494fae92f Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Fri, 31 Oct 2025 20:53:34 +0200 Subject: [PATCH 05/20] test: add test to test wheel --- .github/workflows/python-test.yml | 31 +++++++++++++++++++++++++++++++ .pre-commit-config.yaml | 8 ++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index f09792d..43adc8e 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -150,6 +150,37 @@ jobs: clang-apply-replacements-${{ matrix.version }} --version fi + - name: Install clang-tools wheels + run: | + clang-tools-wheel --tool clang-format --version ${{ matrix.version }} + clang-tools-wheel --tool clang-tidy --version ${{ matrix.version }} + + - name: Check clang tool wheels + run: | + set -e + echo "Checking clang-format and clang-tidy versions..." + clang-format --version + clang-tidy --version + + # Verify versions contain expected string + clang_format_version=$(clang-format --version) + clang_tidy_version=$(clang-tidy --version) + + echo "clang-format version: $clang_format_version" + echo "clang-tidy version: $clang_tidy_version" + + if ! echo "$clang_format_version" | grep -q "version ${{ matrix.version }}"; then + echo "❌ Unexpected clang-format version!" + exit 1 + fi + + if ! echo "$clang_tidy_version" | grep -q "version ${{ matrix.version }}"; then + echo "❌ Unexpected clang-tidy version!" + exit 1 + fi + + echo "✅ Versions are correct." + docs: uses: cpp-linter/.github/.github/workflows/sphinx.yml@main with: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fc59073..522b669 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: - id: trailing-whitespace exclude: \.output @@ -12,13 +12,13 @@ repos: - id: debug-statements - id: requirements-txt-fixer - repo: https://github.com/asottile/pyupgrade - rev: v3.20.0 + rev: v3.21.0 hooks: - id: pyupgrade - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.11.11 + rev: v0.14.3 hooks: - - id: ruff + - id: ruff-check - id: ruff-format # - repo: local # hooks: From a21141dbafd4a2753d82fab550e665b496fb97a7 Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Fri, 31 Oct 2025 21:00:32 +0200 Subject: [PATCH 06/20] test: add condition to test --- .github/workflows/python-test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/python-test.yml b/.github/workflows/python-test.yml index 43adc8e..c3db51f 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/python-test.yml @@ -151,11 +151,14 @@ jobs: fi - name: Install clang-tools wheels + if: matrix.version >= 13 # Only versions 13 and above have wheels run: | clang-tools-wheel --tool clang-format --version ${{ matrix.version }} clang-tools-wheel --tool clang-tidy --version ${{ matrix.version }} - name: Check clang tool wheels + if: matrix.version >= 13 + shell: bash run: | set -e echo "Checking clang-format and clang-tidy versions..." From 28994b0c68b10a0380521d62110d1ab150fdb521 Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Fri, 31 Oct 2025 21:05:28 +0200 Subject: [PATCH 07/20] test: add condition to test --- .github/workflows/{python-test.yml => test.yml} | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) rename .github/workflows/{python-test.yml => test.yml} (93%) diff --git a/.github/workflows/python-test.yml b/.github/workflows/test.yml similarity index 93% rename from .github/workflows/python-test.yml rename to .github/workflows/test.yml index c3db51f..070aa83 100644 --- a/.github/workflows/python-test.yml +++ b/.github/workflows/test.yml @@ -1,6 +1,3 @@ -# This workflow will install Python dependencies, run tests and lint with a single version of Python -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions - name: Test on: @@ -101,7 +98,7 @@ jobs: - name: Install clang-tools binaries run: clang-tools --install ${{ matrix.version }} --tool clang-format clang-tidy clang-query clang-apply-replacements - - name: Show path of binaries + - name: Show path of clang-tools binaries shell: bash run: | if [ "${{ matrix.version }}" = "15" -o "${{ matrix.version }}" = "16" ] && [ "${{ matrix.os }}" = "windows-latest" ]; then @@ -116,7 +113,7 @@ jobs: which "clang-apply-replacements-${{ matrix.version }}" fi - - name: Check clang-tools on Windows + - name: Check clang-tools binaries on Windows if: matrix.os == 'windows-latest' shell: bash run: | @@ -135,7 +132,7 @@ jobs: ;; esac - - name: Check clang-tools on Unix + - name: Check clang-tools binaries on Unix if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' run: | if [ "${{ matrix.version }}" = "12.0.1" -a "${{ matrix.os }}" = "ubuntu-latest" ]; then @@ -156,7 +153,7 @@ jobs: clang-tools-wheel --tool clang-format --version ${{ matrix.version }} clang-tools-wheel --tool clang-tidy --version ${{ matrix.version }} - - name: Check clang tool wheels + - name: Check clang-tools wheels if: matrix.version >= 13 shell: bash run: | From 036159ccb3f04e2d57fdc135448fc4ca37b7a456 Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Fri, 31 Oct 2025 21:16:07 +0200 Subject: [PATCH 08/20] docs: update readme --- README.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index e07625b..6e2f196 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ clang-tools CLI =============== -**Install clang-format, clang-tidy, clang-query, and clang-apply-replacements binaries and Python wheels with clang-tools CLI.** +Install clang-format, clang-tidy, clang-query, and clang-apply-replacements binaries and Python wheels with ``clang-tools`` CLI. .. |latest-version| image:: https://img.shields.io/pypi/v/clang-tools?color=blue :target: https://pypi.org/project/clang-tools/ @@ -75,13 +75,13 @@ Install clang-tools CLI 2. the installed path (for MacOS and Windows) is within the environment's variable ``PATH``. -Install `clang-tools` command with pip +Install ``clang-tools`` command with pip .. code-block:: shell pip install clang-tools -Install `clang-tools` from git repo +Install ``clang-tools`` from git repo .. code-block:: shell @@ -135,10 +135,12 @@ If the installed directory is in your path, you can run the installed tools. Install wheels examples ~~~~~~~~~~~~~~~~~~~~~~~~~ -After installing the ``clang-tools`` CLI, you can install the Python wheels by running: ``clang-tools-wheel`` command. +After installing the ``clang-tools`` CLI, you can install the Python wheels using the ``clang-tools-wheel`` command. .. important:: - It is just used for cpp-linter projects to install clang tools Python wheels. For other use cases, please install the wheels with ``pip``, ``pipx``, ``uv``, or other tools. + + The ``clang-tools-wheel`` command is primarily intended for cpp-linter projects to simplify installing clang tools Python wheels. + For general use, it is recommended to install the wheels directly using ``pip``, ``pipx``, ``uv``, or similar tools. .. code-block:: shell From 735240cff5bfd90ddc4d77f1f5aeca754868a987 Mon Sep 17 00:00:00 2001 From: Xianpeng Shen Date: Sat, 1 Nov 2025 01:08:08 +0200 Subject: [PATCH 09/20] Update clang_tools/wheel.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- clang_tools/wheel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang_tools/wheel.py b/clang_tools/wheel.py index 8a3cd71..be4669d 100644 --- a/clang_tools/wheel.py +++ b/clang_tools/wheel.py @@ -27,7 +27,8 @@ def main() -> int: print(f"{args.tool} installed at: {path}") return 0 else: - print(f"Failed to install {args.tool} version {args.version}") + version_str = f" version {args.version}" if args.version else "" + print(f"Failed to install {args.tool}{version_str}") return 1 From 0f3c94078e21761d8afee47f991ffbd75afb7611 Mon Sep 17 00:00:00 2001 From: Xianpeng Shen Date: Sat, 1 Nov 2025 01:08:35 +0200 Subject: [PATCH 10/20] Update clang_tools/wheel.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- clang_tools/wheel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang_tools/wheel.py b/clang_tools/wheel.py index be4669d..3545f6f 100644 --- a/clang_tools/wheel.py +++ b/clang_tools/wheel.py @@ -3,7 +3,7 @@ def get_parser() -> ArgumentParser: - """Get and parser to interpret CLI args.""" + """Get a parser to interpret CLI args.""" parser = ArgumentParser(description="Install specified clang tool wheel") parser.add_argument( "--tool", From d70b181db2d42c92553934389e0b527bd921d5b3 Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Sat, 1 Nov 2025 01:49:15 +0200 Subject: [PATCH 11/20] fix: add version_str to show version --- clang_tools/wheel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang_tools/wheel.py b/clang_tools/wheel.py index 3545f6f..95ee942 100644 --- a/clang_tools/wheel.py +++ b/clang_tools/wheel.py @@ -23,11 +23,11 @@ def main() -> int: parser = get_parser() args = parser.parse_args() path = _resolve_install(args.tool, args.version) + version_str = f" version {args.version}" if args.version else " latest version" if path: - print(f"{args.tool} installed at: {path}") + print(f"{args.tool}{version_str} installed at: {path}") return 0 else: - version_str = f" version {args.version}" if args.version else "" print(f"Failed to install {args.tool}{version_str}") return 1 From df41efccf366c17f7e9514f89e1e76bfcdf88ca1 Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Sat, 1 Nov 2025 02:31:47 +0200 Subject: [PATCH 12/20] fix: update dependencies and use public function --- clang_tools/wheel.py | 4 ++-- pyproject.toml | 2 +- tests/test_wheel.py | 20 +++++++++----------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/clang_tools/wheel.py b/clang_tools/wheel.py index 95ee942..6775f48 100644 --- a/clang_tools/wheel.py +++ b/clang_tools/wheel.py @@ -1,5 +1,5 @@ from argparse import ArgumentParser -from cpp_linter_hooks.util import _resolve_install +from cpp_linter_hooks.util import resolve_install def get_parser() -> ArgumentParser: @@ -22,7 +22,7 @@ def get_parser() -> ArgumentParser: def main() -> int: parser = get_parser() args = parser.parse_args() - path = _resolve_install(args.tool, args.version) + path = resolve_install(args.tool, args.version) version_str = f" version {args.version}" if args.version else " latest version" if path: print(f"{args.tool}{version_str} installed at: {path}") diff --git a/pyproject.toml b/pyproject.toml index df459df..d331739 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,7 @@ classifiers = [ ] dependencies = [ - "cpp-linter-hooks>=1.1.6", + "cpp-linter-hooks>=1.1.7", ] dynamic = ["version"] diff --git a/tests/test_wheel.py b/tests/test_wheel.py index 3153321..039d7b8 100644 --- a/tests/test_wheel.py +++ b/tests/test_wheel.py @@ -3,36 +3,34 @@ def test_main_success(monkeypatch): - # Patch _resolve_install to simulate success + # Patch resolve_install to simulate success monkeypatch.setattr( - "clang_tools.wheel._resolve_install", + "clang_tools.wheel.resolve_install", lambda tool, version: "/usr/bin/clang-format", ) monkeypatch.setattr( - sys, "argv", ["util.py", "--tool", "clang-format", "--version", "15.0.7"] + sys, "argv", ["wheel.py", "--tool", "clang-format", "--version", "15.0.7"] ) exit_code = main() assert exit_code == 0 def test_main_failure(monkeypatch): - # Patch _resolve_install to simulate failure + # Patch resolve_install to simulate failure + monkeypatch.setattr("clang_tools.wheel.resolve_install", lambda tool, version: None) monkeypatch.setattr( - "clang_tools.wheel._resolve_install", lambda tool, version: None - ) - monkeypatch.setattr( - sys, "argv", ["util.py", "--tool", "clang-format", "--version", "99.99.99"] + sys, "argv", ["wheel.py", "--tool", "clang-format", "--version", "99.99.99"] ) exit_code = main() assert exit_code == 1 def test_main_default_tool(monkeypatch): - # Patch _resolve_install to simulate success for default tool + # Patch resolve_install to simulate success for default tool monkeypatch.setattr( - "clang_tools.wheel._resolve_install", + "clang_tools.wheel.resolve_install", lambda tool, version: "/usr/bin/clang-format", ) - monkeypatch.setattr(sys, "argv", ["util.py"]) + monkeypatch.setattr(sys, "argv", ["wheel.py"]) exit_code = main() assert exit_code == 0 From 5d9b3642bc87391b4e574dd48b89a8cdab41cf7c Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Sat, 1 Nov 2025 02:47:15 +0200 Subject: [PATCH 13/20] docs: udpate README.rst --- README.rst | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index 6e2f196..a77c8d7 100644 --- a/README.rst +++ b/README.rst @@ -1,14 +1,14 @@ clang-tools CLI =============== -Install clang-format, clang-tidy, clang-query, and clang-apply-replacements binaries and Python wheels with ``clang-tools`` CLI. +Easily install clang-format, clang-tidy, clang-query, and clang-apply-replacements static binaries or Python wheels using the ``clang-tools`` CLI. .. |latest-version| image:: https://img.shields.io/pypi/v/clang-tools?color=blue :target: https://pypi.org/project/clang-tools/ :alt: PyPI -.. |python-test| image:: https://github.com/cpp-linter/clang-tools-pip/actions/workflows/python-test.yml/badge.svg - :target: https://github.com/cpp-linter/clang-tools-pip/actions/workflows/python-test.yml - :alt: Python test +.. |test| image:: https://github.com/cpp-linter/clang-tools-pip/actions/workflows/test.yml/badge.svg + :target: https://github.com/cpp-linter/clang-tools-pip/actions/workflows/test.yml + :alt: test .. |codecov-badge| image:: https://codecov.io/gh/cpp-linter/clang-tools-pip/branch/main/graph/badge.svg?token=40G5ZOIRRR :target: https://codecov.io/gh/cpp-linter/clang-tools-pip :alt: codecov @@ -22,7 +22,7 @@ Install clang-format, clang-tidy, clang-query, and clang-apply-replacements bina :target: https://pypistats.org/packages/clang-tools :alt: PyPI - Downloads -|latest-version| |python-test| |codecov-badge| |sonar-badge| |platform-badge| |pypi-badge| +|latest-version| |test| |codecov-badge| |sonar-badge| |platform-badge| |pypi-badge| .. important:: This package only manages binary executables (& corresponding symbolic links) that @@ -146,7 +146,12 @@ After installing the ``clang-tools`` CLI, you can install the Python wheels usin .. code-block:: shell # Install latest clang-format wheel + clang-tools-wheel --tool clang-format + # Install specific version clang-format wheel clang-tools-wheel --tool clang-format --version 21 + + # Install latest clang-tidy wheel + clang-tools-wheel --tool clang-tidy # Install latest clang-tidy wheel clang-tools-wheel --tool clang-tidy --version 21 From dd6befe1fa55a84585b90c61b0e8640cb6e5918f Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Sat, 1 Nov 2025 03:00:23 +0200 Subject: [PATCH 14/20] docs: udpate README.rst --- README.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index a77c8d7..704e2ee 100644 --- a/README.rst +++ b/README.rst @@ -1,8 +1,6 @@ clang-tools CLI =============== -Easily install clang-format, clang-tidy, clang-query, and clang-apply-replacements static binaries or Python wheels using the ``clang-tools`` CLI. - .. |latest-version| image:: https://img.shields.io/pypi/v/clang-tools?color=blue :target: https://pypi.org/project/clang-tools/ :alt: PyPI @@ -24,6 +22,10 @@ Easily install clang-format, clang-tidy, clang-query, and clang-apply-replacemen |latest-version| |test| |codecov-badge| |sonar-badge| |platform-badge| |pypi-badge| + +Easily install clang-format, clang-tidy, clang-query, and clang-apply-replacements static binaries or Python wheels using the ``clang-tools`` CLI. + + .. important:: This package only manages binary executables (& corresponding symbolic links) that are installed using this package's executable script. It does not intend to change or From aa417d4ecba9612dbcf564b1b11e2f813223149f Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Sat, 1 Nov 2025 10:03:27 +0200 Subject: [PATCH 15/20] fix: add required=True and update test.yml --- .github/workflows/test.yml | 35 ++++++++++++++++++++++------------- clang_tools/wheel.py | 1 + 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 070aa83..52419da 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -147,39 +147,48 @@ jobs: clang-apply-replacements-${{ matrix.version }} --version fi - - name: Install clang-tools wheels - if: matrix.version >= 13 # Only versions 13 and above have wheels - run: | - clang-tools-wheel --tool clang-format --version ${{ matrix.version }} - clang-tools-wheel --tool clang-tidy --version ${{ matrix.version }} - - - name: Check clang-tools wheels - if: matrix.version >= 13 + - name: Install and check clang-format wheels shell: bash run: | set -e - echo "Checking clang-format and clang-tidy versions..." + clang-tools-wheel --tool clang-format --version ${{ matrix.version }} + + echo "Checking clang-format versions..." clang-format --version - clang-tidy --version # Verify versions contain expected string clang_format_version=$(clang-format --version) - clang_tidy_version=$(clang-tidy --version) echo "clang-format version: $clang_format_version" - echo "clang-tidy version: $clang_tidy_version" if ! echo "$clang_format_version" | grep -q "version ${{ matrix.version }}"; then echo "❌ Unexpected clang-format version!" exit 1 fi + echo "✅ clang-format Versions are correct." + + - name: Install and check clang-tidy wheels + if: matrix.version >= 13 # Only versions 13 and above have wheels + shell: bash + run: | + set -e + clang-tools-wheel --tool clang-tidy --version ${{ matrix.version }} + + echo "Checking clang-tidy versions..." + clang-tidy --version + + # Verify versions contain expected string + clang_tidy_version=$(clang-tidy --version) + + echo "clang-tidy version: $clang_tidy_version" + if ! echo "$clang_tidy_version" | grep -q "version ${{ matrix.version }}"; then echo "❌ Unexpected clang-tidy version!" exit 1 fi - echo "✅ Versions are correct." + echo "✅ clang-tidy Versions are correct." docs: uses: cpp-linter/.github/.github/workflows/sphinx.yml@main diff --git a/clang_tools/wheel.py b/clang_tools/wheel.py index 6775f48..631d00d 100644 --- a/clang_tools/wheel.py +++ b/clang_tools/wheel.py @@ -8,6 +8,7 @@ def get_parser() -> ArgumentParser: parser.add_argument( "--tool", default="clang-format", + required=True, choices=["clang-format", "clang-tidy"], help="Tool to install (clang-format or clang-tidy)", ) From 819ef8dbdabd75e842aaf51a8266453885f2e399 Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Sat, 1 Nov 2025 10:06:02 +0200 Subject: [PATCH 16/20] test: update to fix test --- tests/test_wheel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_wheel.py b/tests/test_wheel.py index 039d7b8..56cf27b 100644 --- a/tests/test_wheel.py +++ b/tests/test_wheel.py @@ -31,6 +31,7 @@ def test_main_default_tool(monkeypatch): "clang_tools.wheel.resolve_install", lambda tool, version: "/usr/bin/clang-format", ) - monkeypatch.setattr(sys, "argv", ["wheel.py"]) + # The CLI requires --tool; simulate running with the default tool explicitly + monkeypatch.setattr(sys, "argv", ["wheel.py", "--tool", "clang-format"]) exit_code = main() assert exit_code == 0 From a4f89d9c1b0dc9e450540f00d1600bf39720ef02 Mon Sep 17 00:00:00 2001 From: Xianpeng Shen Date: Sat, 1 Nov 2025 17:50:16 +0200 Subject: [PATCH 17/20] Update clang_tools/wheel.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- clang_tools/wheel.py | 1 - 1 file changed, 1 deletion(-) diff --git a/clang_tools/wheel.py b/clang_tools/wheel.py index 631d00d..c8f9b7d 100644 --- a/clang_tools/wheel.py +++ b/clang_tools/wheel.py @@ -7,7 +7,6 @@ def get_parser() -> ArgumentParser: parser = ArgumentParser(description="Install specified clang tool wheel") parser.add_argument( "--tool", - default="clang-format", required=True, choices=["clang-format", "clang-tidy"], help="Tool to install (clang-format or clang-tidy)", From a907e823cde0ca80ff64864119e790da490ec559 Mon Sep 17 00:00:00 2001 From: Xianpeng Shen Date: Sat, 1 Nov 2025 17:50:42 +0200 Subject: [PATCH 18/20] Update README.rst Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 704e2ee..2846020 100644 --- a/README.rst +++ b/README.rst @@ -154,7 +154,7 @@ After installing the ``clang-tools`` CLI, you can install the Python wheels usin # Install latest clang-tidy wheel clang-tools-wheel --tool clang-tidy - # Install latest clang-tidy wheel + # Install specific version clang-tidy wheel clang-tools-wheel --tool clang-tidy --version 21 From f9c71c86eafbe1c88627768d8a43dd71e3775b2a Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Sat, 1 Nov 2025 17:57:39 +0200 Subject: [PATCH 19/20] fix: update if condition using fromJSON --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 52419da..65f64c9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -148,6 +148,7 @@ jobs: fi - name: Install and check clang-format wheels + if: ${{ fromJSON(matrix.version) >= 10 }} # Version 9 failed on MacOS and Windows shell: bash run: | set -e @@ -169,7 +170,7 @@ jobs: echo "✅ clang-format Versions are correct." - name: Install and check clang-tidy wheels - if: matrix.version >= 13 # Only versions 13 and above have wheels + if: ${{ fromJSON(matrix.version) >= 13 }} # Only versions 13 and above have wheels shell: bash run: | set -e From 1ab92d5eefa515e4d57398814a1f14d792003a30 Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Sat, 1 Nov 2025 18:23:33 +0200 Subject: [PATCH 20/20] fix: skip 12.0.1 --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 65f64c9..645a9c0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -148,7 +148,7 @@ jobs: fi - name: Install and check clang-format wheels - if: ${{ fromJSON(matrix.version) >= 10 }} # Version 9 failed on MacOS and Windows + if: ${{ matrix.version != '12.0.1' && fromJSON(matrix.version) >= 10 }} # Skip 12.0.1 shell: bash run: | set -e @@ -170,7 +170,7 @@ jobs: echo "✅ clang-format Versions are correct." - name: Install and check clang-tidy wheels - if: ${{ fromJSON(matrix.version) >= 13 }} # Only versions 13 and above have wheels + if: ${{ matrix.version != '12.0.1' && fromJSON(matrix.version) >= 13 }} shell: bash run: | set -e