Skip to content

Linting#9734

Open
oharboe wants to merge 7 commits intoThe-OpenROAD-Project:masterfrom
Pinata-Consulting:linting
Open

Linting#9734
oharboe wants to merge 7 commits intoThe-OpenROAD-Project:masterfrom
Pinata-Consulting:linting

Conversation

@oharboe
Copy link
Collaborator

@oharboe oharboe commented Mar 12, 2026

Bazel lint and tidy targets for TCL

Summary

  • Add Bazel-managed tclint and tclfmt via py_console_script_binary — no manual pip installs
  • Umbrella targets: bazelisk test //:lint_test (all checks) and bazelisk run //:lint (auto-fix)
  • Runs in ~0.3s, no C++ build required
  • Designed for extension with additional linters (clang-tidy, clang-format, ruff, buildifier, shellcheck)

Motivation

The GitHub Actions workflow .github/workflows/github-actions-lint-tcl.yml runs tclint and
tclfmt checks by creating a virtualenv and pip install tclint==0.7.0 on every CI run. This
is brittle: the version is pinned in a YAML file that can drift, developers can't easily run
the same checks locally without replicating the CI environment, and there's no way to test the
linting setup itself.

By moving to Bazel, tool versions are pinned in bazel/requirements.in with a lock file for
reproducibility, Bazel manages the Python toolchain and all transitive dependencies hermetically,
and developers get a single command that works identically on every machine.

What changed

Commit Scope
pip: add tclint dependency tclint==0.7.0 in bazel/requirements.in, regenerated lock file
bazel: add tclint/tclfmt console script binaries py_console_script_binary targets in bazel/BUILD, wrapper shell scripts
bazel: add lint_test and lint umbrella targets sh_test, sh_binary, test_suite in root BUILD.bazel
docs: add lint targets documentation docs/contrib/LintTargets.md

Usage

# Run all lint checks (~0.3s)
bazelisk test //:lint_test

# Run individual checks
bazelisk test //:tcl_lint_test    # tclint rules
bazelisk test //:tcl_fmt_test     # tclfmt formatting check

# Auto-fix formatting
bazelisk run //:lint              # umbrella fix-all
bazelisk run //:tcl_tidy          # tcl-specific formatting

Design decisions

  1. py_console_script_binary: Idiomatic rules_python way to expose pip console scripts as
    Bazel targets — Bazel manages the full dependency tree hermetically
  2. tags = ["local"]: Lint checks need access to the full source tree spanning Bazel
    subpackages — local tag bypasses sandbox
  3. Umbrella targets: //:lint_test is a test_suite, //:lint is an sh_binary — both
    designed to grow as more linters are added (C++, Python, Bazel files, shell scripts)
  4. Wrapper scripts take tool path as $1: The $(rootpath //bazel:tclint) arg lets Bazel
    resolve the tool binary; scripts resolve it before cd to workspace root

Backwards compatibility

  • GitHub Actions workflow is unchanged — it continues to run independently
  • No existing Bazel targets are modified
  • All new targets are additive

Planned additions to //:lint_test and //:lint

  • C++ clang-tidy and clang-format
  • Python ruff (lint + format)
  • Buildifier (BUILD/bzl file lint + format)
  • ShellCheck (bash script lint)
  • Duplicate message ID check (replace Jenkins stage)
  • Doc consistency checks (replace Jenkins stage)

Test plan

  • bazelisk test //:lint_test — 2/2 pass (tcl_lint_test, tcl_fmt_test)
  • bazelisk run //:lint — auto-formats successfully
  • bazelisk run //:tcl_tidy — auto-formats successfully
  • No C++ build triggered
  • GitHub Actions TCL lint workflow continues to pass (no changes)

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a robust, Bazel-managed framework for TCL linting and formatting, which is a great improvement for developer experience and CI consistency. The use of py_console_script_binary to manage tool dependencies is excellent. The new umbrella targets //:lint_test and //:lint are well-designed for future extension. My feedback includes a couple of minor suggestions to improve maintainability and robustness.

@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@oharboe
Copy link
Collaborator Author

oharboe commented Mar 12, 2026

@hzeller Thoughs?

@oharboe oharboe requested a review from maliberty March 12, 2026 13:31
@maliberty
Copy link
Member

I'll wait for @hzeller 's thoughts

@hzeller
Copy link
Collaborator

hzeller commented Mar 12, 2026

This is now starting to use pip with OpenROAD, which is kindof side-stepping what bazel is doing (managing dependencies itself). It makes it harder to use, as this won't run on a hardened system anymore that prevents side-loading. So, I am not a fan.

So like clang-tidy and clang-format I suggest these to do just in separate scripts in etc/ for now.

oharboe added a commit to Pinata-Consulting/OpenROAD that referenced this pull request Mar 12, 2026
- Rename //:lint to //:fix_lint to clarify it modifies files (gadfort)
- Replace duplicated sh_binary with alias(actual = ":tcl_tidy") (gemini)
- Add BUILD_WORKSPACE_DIRECTORY fallback in tcl_tidy.sh (gemini)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@oharboe
Copy link
Collaborator Author

oharboe commented Mar 12, 2026

This is now starting to use pip with OpenROAD, which is kindof side-stepping what bazel is doing (managing dependencies itself). It makes it harder to use, as this won't run on a hardened system anymore that prevents side-loading. So, I am not a fan.

So like clang-tidy and clang-format I suggest these to do just in separate scripts in etc/ for now.

I find dependencies for all the CI rules to be a pain to manage, I much rather that the OpenROAD project takes responsibility for this and provides bazelisk run XXX to do whatever needs doing and bazel tests that I can run locally to check whatever needs checking without me having to worry about tools: fast local workflows for AI and hoomans.

@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

oharboe and others added 7 commits March 13, 2026 15:32
Add tclint==0.7.0 to pip requirements for Bazel-managed TCL linting
and formatting. This is the same version used by the GitHub Actions
workflow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Expose tclint and tclfmt as py_console_script_binary targets from the
pip-managed tclint package. Add wrapper shell scripts that invoke these
tools against the workspace root.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Add Bazel targets for TCL linting and formatting:
- //:tcl_lint_test — runs tclint (lint rules)
- //:tcl_fmt_test — runs tclfmt --check (formatting)
- //:tcl_tidy — runs tclfmt --in-place (auto-format)
- //:lint_test — umbrella test_suite for all lint checks
- //:lint — umbrella auto-fix target

Designed for extension with additional linters (C++ tidy, etc).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Document the new Bazel lint targets, usage, configuration, how to
add new linters, and planned additions (clang-tidy, clang-format,
ruff, buildifier, shellcheck, doc checks, duplicate ID checks).

Explain why Bazel is the right tool for managing linter dependencies:
hermetic, version-pinned, reproducible across dev machines and CI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
- Rename //:lint to //:fix_lint to clarify it modifies files (gadfort)
- Replace duplicated sh_binary with alias(actual = ":tcl_tidy") (gemini)
- Add BUILD_WORKSPACE_DIRECTORY fallback in tcl_tidy.sh (gemini)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Rename tcl_lint_test → lint_tcl_test, tcl_fmt_test → fmt_tcl_test,
tcl_tidy → tidy_tcl for consistent verb-first naming with _test suffix
per Bazel convention. Update docs to match.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants