Skip to content

fix: move clang tools dependencies to optional #92

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 8 commits into from
Jul 16, 2025
Merged
Show file tree
Hide file tree
Changes from 2 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
7 changes: 5 additions & 2 deletions cpp_linter_hooks/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ def get_version_from_dependency(tool: str) -> Optional[str]:
return None
with open(pyproject_path, "rb") as f:
data = tomllib.load(f)
dependencies = data.get("project", {}).get("dependencies", [])
for dep in dependencies:
# First try project.optional-dependencies.tools
optional_deps = data.get("project", {}).get("optional-dependencies", {})
tools_deps = optional_deps.get("tools", [])
for dep in tools_deps:
if dep.startswith(f"{tool}=="):
return dep.split("==")[1]

return None


Expand Down
8 changes: 6 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ classifiers = [
"Topic :: Software Development :: Build Tools",
]
dependencies = [
"clang-format==20.1.7",
"clang-tidy==20.1.0",
"tomli>=1.1.0; python_version < '3.11'",
]
dynamic = ["version"]
Expand All @@ -47,6 +45,12 @@ source = "https://github.com/cpp-linter/cpp-linter-hooks"
tracker = "https://github.com/cpp-linter/cpp-linter-hooks/issues"

[project.optional-dependencies]
# only clang tools can added to this section to make hooks work
tools = [
"clang-format==20.1.7",
"clang-tidy==20.1.0",
]

dev = [
"coverage",
"pre-commit",
Expand Down
40 changes: 34 additions & 6 deletions tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,13 @@ def test_get_version_from_dependency_success():
"""Test get_version_from_dependency with valid pyproject.toml."""
mock_toml_content = {
"project": {
"dependencies": [
"clang-format==20.1.7",
"clang-tidy==20.1.0",
"other-package==1.0.0",
]
"optional-dependencies": {
"tools": [
"clang-format==20.1.7",
"clang-tidy==20.1.0",
"other-package==1.0.0",
]
}
}
}

Expand All @@ -132,7 +134,9 @@ def test_get_version_from_dependency_missing_file():
@pytest.mark.benchmark
def test_get_version_from_dependency_missing_dependency():
"""Test get_version_from_dependency with missing dependency."""
mock_toml_content = {"project": {"dependencies": ["other-package==1.0.0"]}}
mock_toml_content = {
"project": {"optional-dependencies": {"tools": ["other-package==1.0.0"]}}
}

with (
patch("pathlib.Path.exists", return_value=True),
Expand All @@ -155,6 +159,30 @@ def test_get_version_from_dependency_malformed_toml():
assert result is None


@pytest.mark.benchmark
def test_get_version_from_dependency_fallback_to_dependencies():
"""Test get_version_from_dependency falls back to project.dependencies."""
mock_toml_content = {
"project": {
"dependencies": [
"clang-format==20.1.7",
"clang-tidy==20.1.0",
"other-package==1.0.0",
]
}
}

with (
patch("pathlib.Path.exists", return_value=True),
patch("cpp_linter_hooks.util.tomllib.load", return_value=mock_toml_content),
):
result = get_version_from_dependency("clang-format")
assert result == "20.1.7"

result = get_version_from_dependency("clang-tidy")
assert result == "20.1.0"

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Test expects fallback behavior that's missing in implementation.

This test validates fallback to the old dependencies structure, but the current implementation in cpp_linter_hooks/util.py doesn't include this fallback logic. The test will fail because the function only checks optional-dependencies.tools and returns None if not found there.

This test confirms that fallback functionality should exist but is missing from the implementation. Run this test to verify it fails:


🏁 Script executed:

#!/bin/bash
# Description: Run the specific fallback test to verify it fails due to missing implementation

python -m pytest tests/test_util.py::test_get_version_from_dependency_fallback_to_dependencies -v

Length of output: 9788


🏁 Script executed:

#!/bin/bash
rg -n "def get_version_from_dependency" -A 20 -B 5 cpp_linter_hooks/util.py

Length of output: 1002


Implement fallback to project.dependencies in get_version_from_dependency
The test test_get_version_from_dependency_fallback_to_dependencies fails because the function only looks under project.optional-dependencies.tools and never falls back to project.dependencies. You’ll need to update cpp_linter_hooks/util.py to try the old dependencies list before returning None.

Locations to update:
• cpp_linter_hooks/util.py, inside get_version_from_dependency (around lines 23–30)

Suggested patch:

     # First try project.optional-dependencies.tools
     optional_deps = data.get("project", {}).get("optional-dependencies", {})
     tools_deps = optional_deps.get("tools", [])
     for dep in tools_deps:
         if dep.startswith(f"{tool}=="):
             return dep.split("==")[1]

+    # Fallback to project.dependencies
+    project_deps = data.get("project", {}).get("dependencies", [])
+    for dep in project_deps:
+        if dep.startswith(f"{tool}=="):
+            return dep.split("==")[1]
+
     return None

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In cpp_linter_hooks/util.py around lines 23 to 30, the function
get_version_from_dependency currently only checks
project.optional-dependencies.tools for the package version and does not fall
back to project.dependencies. Update the function to first attempt to find the
version in project.optional-dependencies.tools, and if not found, then search in
project.dependencies before returning None. This ensures the fallback behavior
tested in tests/test_util.py lines 162 to 184 works correctly.


# Tests for _resolve_version
@pytest.mark.benchmark
@pytest.mark.parametrize(
Expand Down
Loading