Skip to content

Migration: From Clang Tools Binaries to Python Wheels #87

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jul 5, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ result.txt
testing/main.c
*/*compile_commands.json

# Ignore clang-tools binaries
# Ignore Python wheel packages (clang-format, clang-tidy)
clang-tidy-1*
clang-tidy-2*
clang-format-1*
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
entry: clang-format-hook
language: python
files: \.(h\+\+|h|hh|hxx|hpp|c|cc|cpp|c\+\+|cxx)$
require_serial: true
require_serial: false

- id: clang-tidy
name: clang-tidy
description: Automatically install any specific version of clang-tidy and diagnose/fix typical programming errors
entry: clang-tidy-hook
language: python
files: \.(h\+\+|h|hh|hxx|hpp|c|cc|cpp|c\+\+|cxx)$
require_serial: true
require_serial: false
111 changes: 111 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Migration Guide: From clang-tools to Python Wheels

## Overview

Starting from version 0.9.0, `cpp-linter-hooks` has migrated from using the `clang-tools` package to using Python wheel packages for `clang-format` and `clang-tidy`. This change provides better cross-platform compatibility, easier installation, and more reliable dependency management.

## What Changed

### Dependencies
- **Before**: Used `clang-tools==0.15.1` package
- **After**: Uses `clang-format` and `clang-tidy` wheel packages from PyPI

### Installation Method
- **Before**: clang-format and clang-tidy were installed via `clang-tools` package which managed binaries
- **After**: clang-format and clang-tidy are installed as Python packages and available as executables

### Benefits of Migration

1. **Better Cross-Platform Support**: Python wheels work consistently across different operating systems
2. **Simplified Installation**: No need to manage binary installations separately
3. **More Reliable**: No more issues with binary compatibility or single threaded execution
4. **Better Version Management**: Each tool version is a separate package release

## Breaking Changes

### For End Users

- **No breaking changes**: The pre-commit hook configuration remains exactly the same
- All existing `.pre-commit-config.yaml` files will continue to work without modification

### For Developers
- The internal `ensure_installed()` function now returns the tool name instead of a Path object
- The `util.py` module has been rewritten to use `shutil.which()` instead of `clang_tools.install`
- Tests have been updated to mock the new wheel-based installation

## Migration Steps

### For End Users
No action required! Your existing configuration will continue to work.

### For Developers/Contributors
1. Update your development environment:
```bash
pip install clang-format clang-tidy
```

2. If you were importing from the utility module:
```python
# Before
from cpp_linter_hooks.util import ensure_installed
path = ensure_installed("clang-format", "18")
command = [str(path), "--version"]

# After
from cpp_linter_hooks.util import ensure_installed
tool_name = ensure_installed("clang-format", "18")
command = [tool_name, "--version"]
```

## Version Support

The wheel packages support the same LLVM versions as before:
- LLVM 16, 17, 18, 19, 20+
- The `--version` argument continues to work as expected

## Troubleshooting

### Tool Not Found Error
If you encounter "command not found" errors:

1. Ensure the wheel packages are installed:
```bash
pip install clang-format clang-tidy
```

2. Verify the tools are available:
```bash
clang-format --version
clang-tidy --version
```

3. Check that the tools are in your PATH:
```bash
which clang-format
which clang-tidy
```

### Version Mismatch
If you need a specific version, you can install it explicitly:
```bash
pip install clang-format==18.1.8
pip install clang-tidy==18.1.8
```

## Support

If you encounter any issues after the migration, please:
1. Check this migration guide
2. Search existing [issues](https://github.com/cpp-linter/cpp-linter-hooks/issues)
3. Create a new issue with:
- Your operating system
- Python version
- The exact error message
- Your `.pre-commit-config.yaml` configuration

## References

- [clang-format wheel package](https://github.com/ssciwr/clang-format-wheel)
- [clang-tidy wheel package](https://github.com/ssciwr/clang-tidy-wheel)
- [PyPI clang-format](https://pypi.org/project/clang-format/)
- [PyPI clang-tidy](https://pypi.org/project/clang-tidy/)
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ repos:

### Custom Clang Tool Version

To use specific versions of [clang-tools](https://github.com/cpp-linter/clang-tools-pip?tab=readme-ov-file#supported-versions):
To use specific versions of clang-format and clang-tidy (using Python wheel packages):

```yaml
repos:
Expand All @@ -67,6 +67,9 @@ repos:
args: [--checks=.clang-tidy, --version=18] # Specifies version
```

> [!NOTE]
> Starting from version 0.9.0, this package uses Python wheel packages ([clang-format](https://pypi.org/project/clang-format/) and [clang-tidy](https://pypi.org/project/clang-tidy/)) instead of the previous clang-tools binaries. The wheel packages provide better cross-platform compatibility and easier installation.

## Output

### clang-format Output
Expand Down
8 changes: 4 additions & 4 deletions cpp_linter_hooks/clang_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
from argparse import ArgumentParser
from typing import Tuple

from .util import ensure_installed, DEFAULT_CLANG_VERSION
from .util import ensure_installed, DEFAULT_CLANG_FORMAT_VERSION


parser = ArgumentParser()
parser.add_argument("--version", default=DEFAULT_CLANG_VERSION)
parser.add_argument("--version", default=DEFAULT_CLANG_FORMAT_VERSION)
parser.add_argument(
"-v", "--verbose", action="store_true", help="Enable verbose output"
)


def run_clang_format(args=None) -> Tuple[int, str]:
hook_args, other_args = parser.parse_known_args(args)
path = ensure_installed("clang-format", hook_args.version)
command = [str(path), "-i"]
tool_name = ensure_installed("clang-format", hook_args.version)
command = [tool_name, "-i"]

# Add verbose flag if requested
if hook_args.verbose:
Expand Down
8 changes: 4 additions & 4 deletions cpp_linter_hooks/clang_tidy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
from argparse import ArgumentParser
from typing import Tuple

from .util import ensure_installed, DEFAULT_CLANG_VERSION
from .util import ensure_installed, DEFAULT_CLANG_TIDY_VERSION


parser = ArgumentParser()
parser.add_argument("--version", default=DEFAULT_CLANG_VERSION)
parser.add_argument("--version", default=DEFAULT_CLANG_TIDY_VERSION)


def run_clang_tidy(args=None) -> Tuple[int, str]:
hook_args, other_args = parser.parse_known_args(args)
path = ensure_installed("clang-tidy", hook_args.version)
command = [str(path)]
tool_name = ensure_installed("clang-tidy", hook_args.version)
command = [tool_name]
command.extend(other_args)

retval = 0
Expand Down
Loading
Loading