Skip to content

feat: unify CLI entry point - eliminate binary/wheel split#179

Merged
shenxianpeng merged 15 commits into
mainfrom
feature/unify-cli-entry
Jun 13, 2026
Merged

feat: unify CLI entry point - eliminate binary/wheel split#179
shenxianpeng merged 15 commits into
mainfrom
feature/unify-cli-entry

Conversation

@shenxianpeng

@shenxianpeng shenxianpeng commented Jun 12, 2026

Copy link
Copy Markdown
Member

Summary

Eliminates the binary/wheel CLI split by providing a single unified clang-tools command.

Before (confusing for users)

clang-tools --install 18              # binary only
clang-tools-wheel --tool clang-format  # wheel only

After (unified)

clang-tools install 18                 # auto-detect (binary first, fallback wheel)
clang-tools install 18 --binary       # force binary
clang-tools install 18 --wheel        # force wheel
clang-tools install clang-format --wheel           # wheel by tool name (latest)
clang-tools install clang-format --wheel --version 21  # wheel by tool + version
clang-tools uninstall 18              # remove installed tools

Auto-detection logic

Target type Behavior
Version in range (e.g. 18) Try binary → fallback to wheel
Version out of range (e.g. 99) Wheel only
Tool name (e.g. clang-format) Wheel only
Unknown target Error with helpful message

Backward compatibility

Legacy --install/--uninstall top-level flags are preserved:

clang-tools --install 13 --tool clang-format   # still works (deprecated)
clang-tools --uninstall 13                      # still works (deprecated)

Changes

  • clang_tools/main.py: Rewritten with subcommand-based CLI, auto-detection, and fallback logic
  • pyproject.toml: Removed clang-tools-wheel entry point
  • Tests: 57 tests covering all new CLI paths, auto-detection, error cases, and legacy compat
  • Docs: Updated README, mkdocs, API docs, and CLI reference to reflect unified command
  • Full test suite: 142 passed (existing + new)

Breaking change

The separate clang-tools-wheel command is removed. Users should migrate:

Old New
clang-tools-wheel --tool clang-format clang-tools install clang-format --wheel
clang-tools-wheel --tool clang-tidy --version 21 clang-tools install clang-tidy --wheel --version 21

Summary by CodeRabbit

  • New Features

    • Redesigned CLI: subcommands clang-tools install <target> and clang-tools uninstall <version>; explicit --binary / --wheel options with auto-detect fallback.
    • Wheel installs via clang-tools install --wheel with optional --version; wheel install support limited to supported tools.
  • Documentation

    • Updated CLI usage examples, docs, README, and added "Related Projects" and "Acknowledgments".
  • Tests

    • Expanded unit/integration tests covering install/uninstall, auto-detect, wheel behavior, and edge cases.
  • Chores

    • Removed standalone clang-tools-wheel command; CI updated to use unified CLI.

BREAKING CHANGE: The separate  command is removed.
Wheel installation is now available through the unified
command.

New subcommand-based CLI:
  clang-tools install <version>             # auto-detect binary/wheel
  clang-tools install <version> --binary    # force binary
  clang-tools install <version> --wheel     # force wheel
  clang-tools install <tool-name> --wheel   # wheel install by tool name
  clang-tools uninstall <version>           # remove installed tools

Auto-detection logic:
- Version-like targets in supported range → binary first, fallback wheel
- Version-like targets out of range → wheel
- Tool name targets → wheel

Legacy / flags are preserved for backward
compatibility.
Drop --install/--uninstall top-level flags. Only subcommands remain:
  clang-tools install <target> [options]
  clang-tools uninstall <version> [options]

Also fix Python 3.9 type annotation compatibility (str | None -> Optional[str]).
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

This PR refactors the clang-tools CLI from top-level --install/--uninstall flags to subcommands (install/uninstall), integrating wheel installation into a unified clang-tools install flow with automatic binary-first selection and fallback, while updating tests, documentation, CI workflows, and package configuration to match the new contract.

Changes

Unified clang-tools CLI subcommand refactor

Layer / File(s) Summary
CLI subcommand interface: parser, handlers, and entry point
clang_tools/main.py
Adds version-target detection (_is_version_like), wheel-tool allowlist (WHEEL_TOOLS), and installation handlers for binary, wheel, and auto-detect modes. Rewrites get_parser() with install and uninstall subcommands including --binary, --wheel, --version, --tool, --directory, --overwrite, and --no-progress-bar flags. Updates main() to dispatch by subcommand, print help on no-args, and return explicit exit codes (0/1); changes module entry point to raise SystemExit(main()).
Install/uninstall function signatures
clang_tools/install.py
Updates install_clang_tools and uninstall_clang_tools function parameters: tools is now list[str] (previously str) to align with iteration loops that process each tool name.
Test suite: parser and main() integration
tests/test_main.py
Replaces legacy flag-based tests with subcommand-focused coverage: parameterized unit test for _is_version_like, parser tests asserting install/uninstall subcommand defaults and option effects, and integration tests for main() covering binary/wheel success paths, mutual-exclusivity validation, version forwarding, auto-detect fallback behavior, and error cases (unsupported wheels, invalid targets, bad semver).
Test suite: install utility coverage
tests/test_install.py, tests/test_util.py
Adds platform-specific and symlink creation tests: binary URL generation on Linux, default install directory expansion, non-existent symlink destination creation, and amd64 architecture detection from x86_64.
Documentation: CLI usage examples and API reference
README.md, docs/index.md, docs/api.md, clang_tools/util.py, clang_tools/wheel.py
Updates CLI examples to use clang-tools install <version> (binary) and clang-tools install <tool> --wheel (wheel) syntax, removing old --install flag and clang-tools-wheel CLI references. Adds "Related Projects" and "Acknowledgments" sections. Updates API documentation and docstrings to reflect unified CLI integration.
CLI documentation generation refactor
docs/gen_cli_docs.py
Refactors to generate only cli_args.md (removes wheel_cli_args.md generation). Introduces _action_doc helper to format per-argument documentation, rewrites _write_cli_doc to iterate parser actions and handle subparsers separately, and updates final generation to use get_parser().
Configuration, navigation, and CI updates
mkdocs.yml, pyproject.toml, CONTRIBUTING.md, .github/workflows/test.yml
Removes clang-tools-wheel from mkdocs navigation and console scripts, updates CONTRIBUTING.md build steps to use clang-tools install 13, and rewrites CI test job to install binaries via clang-tools install ... --tool ... and wheels via clang-tools install <tool> --wheel --version ....

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • cpp-linter/clang-tools-pip#133: Adds the standalone clang-tools-wheel console script backed by clang_tools/wheel.py, while this PR removes that script and integrates wheel installation into the unified clang-tools install --wheel flow.
  • cpp-linter/clang-tools-pip#177: Modifies docs/gen_cli_docs.py to generate CLI documentation pages, while this PR refactors the same script to generate only cli_args.md and adjust the argparse-to-Markdown rendering logic.
  • cpp-linter/clang-tools-pip#168: Updates test coverage for clang_tools.main.main()'s install/uninstall/no-args CLI behavior, directly overlapping with this PR's comprehensive CLI-argument parsing and integration test refactor.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.42% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title directly and accurately summarizes the main change: unifying the CLI entry point by eliminating the binary/wheel split into a single subcommand-based interface.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/unify-cli-entry

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@shenxianpeng shenxianpeng force-pushed the feature/unify-cli-entry branch from 9ee22bf to 736cc4f Compare June 12, 2026 17:26

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/gen_cli_docs.py (1)

37-45: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Include subparser options when generating CLI docs.

_write_cli_doc() only walks top-level parser._actions, so unified subcommand options are omitted from generated docs. With the new CLI design, this makes cli_args.md incomplete.

Also applies to: 73-73

🧹 Nitpick comments (2)
tests/test_main.py (1)

154-181: ⚡ Quick win

Strengthen uninstall tests to assert actual removal.

These tests currently pass on log text + exit code only. Add assertions that the expected binary/symlink no longer exists so API-order regressions are caught.

✅ Suggested assertion additions
 def test_main_legacy_uninstall(
@@
     assert "Uninstalling" in result.out
     assert exit_code == 0
+    assert not dummy_bin.exists()

 def test_main_uninstall_subcommand(
@@
     assert exit_code == 0
     assert "Uninstalling" in result.out
+    assert not dummy_bin.exists()

Also applies to: 513-540

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_main.py` around lines 154 - 181, The test
test_main_legacy_uninstall currently only asserts log output and exit code but
doesn't verify that the installed binary/symlink was actually removed; update
this test (and the similar tests around lines 513-540) to assert the filesystem
state after calling main(): check that the path represented by dummy_bin (and
any expected symlink in install_dir) does not exist (use install_dir, tool_name,
version and suffix to compute the expected path) so the uninstall behavior of
main() is validated end-to-end.
clang_tools/main.py (1)

183-324: 🏗️ Heavy lift

Refactor main() into smaller handlers before this grows further.

Current cognitive complexity is high and already hides cross-path contract mistakes. Please split into focused handlers (e.g., legacy flow, install flow, uninstall flow, and install mode selection).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@clang_tools/main.py` around lines 183 - 324, The main() function has grown
too complex—split it into focused handler functions to reduce cognitive
complexity and avoid hidden contract bugs: extract the legacy flow into a
handler (e.g., handle_legacy_flags(args) calling uninstall_clang_tools and
install_clang_tools), move uninstall branch into handle_uninstall(args) that
calls uninstall_clang_tools, and move the install branch into
handle_install(args) that encapsulates mode selection (wheel vs binary vs
auto-detect) using helpers that call _wheel_install, install_clang_tools, and
use _is_version_like and WHEEL_TOOLS for validation; update main() to only parse
args and dispatch to these handlers, returning their exit codes.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@clang_tools/main.py`:
- Around line 30-31: WHEEL_TOOLS currently includes "clang-query" and
"clang-apply-replacements" but the docs/state that wheel support is only for
"clang-format" and "clang-tidy", causing _wheel_install() to later fail; update
the WHEEL_TOOLS constant to only {"clang-format", "clang-tidy"} and remove any
other occurrences or references to "clang-query" and "clang-apply-replacements"
(including the duplicate definition/uses around the later block that mirrors
314-322) so accepted targets align with what _wheel_install() supports.
- Around line 194-196: The uninstall_clang_tools call arguments are in the wrong
order: uninstall_clang_tools expects (tools, version, directory) but the diff
passes (version, tools, directory); update both call sites (the one using
args._legacy_uninstall at the uninstall dispatch and the other at line 228) to
call uninstall_clang_tools(args.tool, args._legacy_uninstall, args.directory)
(or the equivalent ordering using the function's parameter names) so tools is
passed first, then version, then directory.

---

Nitpick comments:
In `@clang_tools/main.py`:
- Around line 183-324: The main() function has grown too complex—split it into
focused handler functions to reduce cognitive complexity and avoid hidden
contract bugs: extract the legacy flow into a handler (e.g.,
handle_legacy_flags(args) calling uninstall_clang_tools and
install_clang_tools), move uninstall branch into handle_uninstall(args) that
calls uninstall_clang_tools, and move the install branch into
handle_install(args) that encapsulates mode selection (wheel vs binary vs
auto-detect) using helpers that call _wheel_install, install_clang_tools, and
use _is_version_like and WHEEL_TOOLS for validation; update main() to only parse
args and dispatch to these handlers, returning their exit codes.

In `@tests/test_main.py`:
- Around line 154-181: The test test_main_legacy_uninstall currently only
asserts log output and exit code but doesn't verify that the installed
binary/symlink was actually removed; update this test (and the similar tests
around lines 513-540) to assert the filesystem state after calling main(): check
that the path represented by dummy_bin (and any expected symlink in install_dir)
does not exist (use install_dir, tool_name, version and suffix to compute the
expected path) so the uninstall behavior of main() is validated end-to-end.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6c580859-64b5-4814-a44b-a5f8a0a714bc

📥 Commits

Reviewing files that changed from the base of the PR and between f9e7f18 and d31f76c.

📒 Files selected for processing (8)
  • README.md
  • clang_tools/main.py
  • docs/api.md
  • docs/gen_cli_docs.py
  • docs/index.md
  • mkdocs.yml
  • pyproject.toml
  • tests/test_main.py
💤 Files with no reviewable changes (2)
  • mkdocs.yml
  • pyproject.toml

Comment thread clang_tools/main.py Outdated
Comment thread clang_tools/main.py Outdated
@shenxianpeng shenxianpeng added major A major version bump breaking Breaking change labels Jun 12, 2026
- Version.__init__() in clang_tools/util.py
- main() in clang_tools/wheel.py
@shenxianpeng shenxianpeng force-pushed the feature/unify-cli-entry branch from 7eb59f9 to d023586 Compare June 12, 2026 17:57
clang-query and clang-apply-replacements are binary-only and not
available as wheels via cpp-linter-hooks. Add validation in --wheel
path and new test for unsupported tool error.
@shenxianpeng shenxianpeng force-pushed the feature/unify-cli-entry branch from 2302f07 to 29569e2 Compare June 12, 2026 17:58
- Split main() into _handle_install/_handle_wheel/_handle_binary/
  _handle_auto_detect handlers (fixes C901 complexity)
- Replace blind except Exception with specific OSError/ValueError/
  SystemExit (fixes BLE001)
- Remove unnecessary else after return (fixes RET505)
- Remove unused MIN_VERSION/MAX_VERSION imports
- Update gen_cli_docs.py to handle subparsers
- Extract _validate_wheel_tool helper
@shenxianpeng shenxianpeng force-pushed the feature/unify-cli-entry branch from 72a2885 to d4b5186 Compare June 12, 2026 18:03
@shenxianpeng shenxianpeng force-pushed the feature/unify-cli-entry branch from 0d0e80c to 19798a9 Compare June 12, 2026 18:16
@github-actions github-actions Bot added documentation Improvements or additions to documentation enhancement New feature or request labels Jun 12, 2026
@codecov

codecov Bot commented Jun 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.87%. Comparing base (f9e7f18) to head (16b8978).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #179      +/-   ##
==========================================
+ Coverage   99.64%   99.87%   +0.23%     
==========================================
  Files           9        9              
  Lines         558      824     +266     
==========================================
+ Hits          556      823     +267     
+ Misses          2        1       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

shenxianpeng and others added 2 commits June 13, 2026 07:04
- Fix uninstall_clang_tools argument order (version/tools were swapped)
- Update CI workflow to use new subcommand syntax (clang-tools install, not --install)
- Fix type annotations: tools: str → list[str] in install.py
- Strengthen uninstall test to assert actual filesystem removal

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
clang_tools/install.py (1)

250-260: 💤 Low value

Docstring missing :param tools: description.

The function signature now accepts tools: list[str], but the docstring doesn't document this parameter.

📝 Suggested docstring update
 def uninstall_clang_tools(tools: list[str], version: str, directory: str):
     """Uninstall a clang tool of a given version.

+    :param tools: The list of tool names to uninstall.
     :param version: The version of the clang-tools to remove.
     :param directory: The directory from which to remove the
         installed clang-tools.
     """
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@clang_tools/install.py` around lines 250 - 260, The docstring for
uninstall_clang_tools is missing documentation for the tools parameter; update
the docstring to add a :param tools: entry describing that it is a list of clang
tool names to uninstall (e.g., "list of tool names to remove"), and mention the
expected element type (str) and how it's used (each tool is passed to
uninstall_tool with the given version and install_dir) so the parameters section
documents tools, version, and directory consistently for the
uninstall_clang_tools function.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@clang_tools/main.py`:
- Around line 137-144: The except block in install_clang_tools currently catches
SystemExit (masking permission errors from move_and_chmod_bin) and then falls
back to _wheel_install; change the except to only catch OSError and ValueError
so SystemExit is allowed to propagate; specifically, update the except line in
install_clang_tools from "except (OSError, ValueError, SystemExit) as exc:" to
"except (OSError, ValueError) as exc:" (no other changes
needed—move_and_chmod_bin should still raise SystemExit and _wheel_install
remains the fallback for the caught errors).

---

Nitpick comments:
In `@clang_tools/install.py`:
- Around line 250-260: The docstring for uninstall_clang_tools is missing
documentation for the tools parameter; update the docstring to add a :param
tools: entry describing that it is a list of clang tool names to uninstall
(e.g., "list of tool names to remove"), and mention the expected element type
(str) and how it's used (each tool is passed to uninstall_tool with the given
version and install_dir) so the parameters section documents tools, version, and
directory consistently for the uninstall_clang_tools function.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3f1b5e20-ba52-4f1e-8e51-1a4b3fece6e5

📥 Commits

Reviewing files that changed from the base of the PR and between d31f76c and 3788a5e.

📒 Files selected for processing (8)
  • .github/workflows/test.yml
  • CONTRIBUTING.md
  • clang_tools/install.py
  • clang_tools/main.py
  • clang_tools/util.py
  • clang_tools/wheel.py
  • docs/gen_cli_docs.py
  • tests/test_main.py
✅ Files skipped from review due to trivial changes (3)
  • CONTRIBUTING.md
  • clang_tools/wheel.py
  • clang_tools/util.py

Comment thread clang_tools/main.py Outdated
shenxianpeng added a commit that referenced this pull request Jun 13, 2026
Bandit B101 ('Use of assert detected') is a well-known false positive
for pytest test files where assert is the standard assertion mechanism.
Exclude the tests/ directory from Bandit analysis to prevent 32 false
positives on PR #179.
- Add Bandit to pre-commit hooks
- Add Bandit as dev dependency
- Add security CI job running Bandit on production code
- Exclude tests/ from Bandit (assert is standard in pytest)
- Codacy webhook deleted via GitHub API
@shenxianpeng shenxianpeng force-pushed the feature/unify-cli-entry branch from fb767c0 to 946113c Compare June 13, 2026 04:32

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/test.yml:
- Around line 33-35: The CI step named "Run Bandit security scan" currently has
continue-on-error: true which allows security findings to be ignored; change
that so the Bandit step fails the job by removing the continue-on-error key or
setting it to false, or implement a conditional gating strategy (e.g., set
continue-on-error based on an input/secret or a workflow variable like
allow_known_findings) and ensure any conditional logic (used to bypass failures)
is explicit and reviewed; update the step that runs bandit (the "Run Bandit
security scan" step) accordingly so security scan failures are blocking unless
intentionally and explicitly allowed.
- Around line 20-21: The new GitHub Actions job named "security" lacks an
explicit permissions block; add one to grant the minimal read-only scope
required for a Bandit scan by adding a permissions section under the "security"
job with at least "contents: read" (e.g., permissions: { contents: read }) so
the job uses least-privilege for GITHUB_TOKEN.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 24e37547-d782-4c63-858b-29857a3f67f6

📥 Commits

Reviewing files that changed from the base of the PR and between 3788a5e and 946113c.

📒 Files selected for processing (3)
  • .github/workflows/test.yml
  • .pre-commit-config.yaml
  • pyproject.toml
🚧 Files skipped from review as they are similar to previous changes (1)
  • pyproject.toml

Comment thread .github/workflows/test.yml Outdated
Comment thread .github/workflows/test.yml Outdated
Comment on lines +33 to +35
- name: Run Bandit security scan
continue-on-error: true
run: bandit -c pyproject.toml -r clang_tools/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Make the security scan blocking (or gate failures conditionally).

Line 34 sets continue-on-error: true, which allows known security findings to pass CI silently. That weakens the intended security gate for this workflow.

Suggested fix
      - name: Run Bandit security scan
-       continue-on-error: true
        run: bandit -c pyproject.toml -r clang_tools/
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 20-35: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/test.yml around lines 33 - 35, The CI step named "Run
Bandit security scan" currently has continue-on-error: true which allows
security findings to be ignored; change that so the Bandit step fails the job by
removing the continue-on-error key or setting it to false, or implement a
conditional gating strategy (e.g., set continue-on-error based on an
input/secret or a workflow variable like allow_known_findings) and ensure any
conditional logic (used to bypass failures) is explicit and reviewed; update the
step that runs bandit (the "Run Bandit security scan" step) accordingly so
security scan failures are blocking unless intentionally and explicitly allowed.

- Remove Bandit from pre-commit hooks (kept in CI security job only)
- Add test for check_install_arch() amd64 branch
- Add test for clang_tools_binary_url() non-macOS platform branch
- Add test for install_dir_name() Linux default directory
- Add test for create_sym_link() mkdir when directory doesn't exist
- Add tests for _wheel_install() success and failure paths
- Add test for _handle_binary with zeroed-out version (0.0.0)

Production code coverage: clang_tools/*.py -> 100%
@shenxianpeng shenxianpeng force-pushed the feature/unify-cli-entry branch from e6e3a80 to 30488b2 Compare June 13, 2026 12:17
- Remove SystemExit from except clause in _handle_auto_detect to avoid
  masking permission and unsupported-OS errors (SonarCloud python:S5754)
- Fix type mismatch in test_install.py: pass list[str] instead of str
  to install_clang_tools (SonarCloud python:S5655 x3)
- Add missing :param tools: docstring to uninstall_clang_tools
- Wrap wheel install examples in code fences inside admonition in docs/index.md
- Update REQUIRED_VERSIONS in gen_cli_docs.py with new CLI arg dests
- Add tests for _wheel_install with version=None (latest), multi-tool
  mixed results, and _handle_auto_detect bad-semver path
@shenxianpeng shenxianpeng changed the title feat: unify CLI entry point - eliminate binary/wheel split (P0) feat: unify CLI entry point - eliminate binary/wheel split Jun 13, 2026
@sonarqubecloud

Copy link
Copy Markdown

@shenxianpeng shenxianpeng removed the documentation Improvements or additions to documentation label Jun 13, 2026
@shenxianpeng shenxianpeng merged commit 5b30734 into main Jun 13, 2026
66 checks passed
@shenxianpeng shenxianpeng deleted the feature/unify-cli-entry branch June 13, 2026 19:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Breaking change enhancement New feature or request major A major version bump

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant