Skip to content

Conversation

ziuziakowska
Copy link

This replaces the existing ot-tidy.sh script with a new Python script.

This new script should make it easier to run the linter locally in the same way as CI, as the older wrapper script did not have any usage information.

The script also checks for some misconfigurations and reports those - such as QEMU not being configured to use Clang which results in a different incompatible set of warning flags to be used with GCC to be used for clang-tidy.

In addition, this script adds a -j flag to run linting in parallel, using the run-clang-tidy wrapper that comes with clang-tidy. On my machine, this reduced linting time on the same set of files as CI from ~3 minutes to 30 seconds.

Copy link

@jwnrt jwnrt left a comment

Choose a reason for hiding this comment

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

I get this error from the script:

$ scripts/opentitan/ot_tidy.py --ci-files
Could not parse 'clang-tidy' version string.

Here's my output of clang-tidy --version:

$ clang-tidy --version
LLVM (http://llvm.org/):
  LLVM version 16.0.2
  Optimized build.

I think it's because my version_line is the second line, not the first

This script is intended to replace the `ot-tidy.sh` script for running
clang-tidy on our part of the codebase.

A `-j` flag is added to run clang-tidy jobs in parallel, using the
run-clang-tidy script that comes with it. On my machine this speeds
up checking files for CI from >3 minutes to ~30 seconds.

The script also checks for some configuration issues, such as the C
compiler not being set to clang when configuring QEMU - this causes some
warnings to be enabled that are not recognised by clang and will show up
as errors.

Signed-off-by: Alice Ziuziakowska <[email protected]>
@ziuziakowska
Copy link
Author

I think it's because my version_line is the second line, not the first

Fixed it to look for that on any line.
Mine appeared like this:

$ clang-tidy-20 --version
Ubuntu LLVM version 20.1.2
  Optimized build.

@jwnrt
Copy link

jwnrt commented Sep 23, 2025

Yep, that works now, thanks

Replaces all usages, updates docs, and removes the older script.

Signed-off-by: Alice Ziuziakowska <[email protected]>
Copy link

@rivos-eblot rivos-eblot left a comment

Choose a reason for hiding this comment

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

I think several features are broken, and some are a bit fragile (parsing, ANSI management, ...).

Can you run flake8, as there are many outsized lines and argument aligment warning messages. Thanks.

# SPDX-License-Identifier: Apache2

"""
'clang-tidy' wrapper script

Choose a reason for hiding this comment

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

Maybe add a bit more info about the features of this wrapper (and maybe add that clang tidy is the LLVM C linter)?

eprint(f"No 'run-clang-tidy-{CLANG_MAJOR}' or suitable 'run-clang-tidy' in PATH.")
sys.exit(1)

def main():

Choose a reason for hiding this comment

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

Not a big deal, but can you try to make the syntax closer to existing scripts/opentitan/*.py scripts?

  • try/except exception, with-d to show the traceback
  • only exit from main, use exception to return error from subroutines
  • use argparser.error to report usage error

Please also keep single letter argument options.

parser.add_argument('-f', '--files', required=False, nargs="+", action='extend', default=[],
help="Files to run tidy on")

args = parser.parse_args()

Choose a reason for hiding this comment

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

It think there is a regression here (vs. .sh script): we need to be able to pass any argument to clang-tidy, not just files.

"""
)

parser.add_argument('--ci-files', required=False, action='store_true',

Choose a reason for hiding this comment

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

I think there is a regression vs the .sh script: how to specify the configuration file?

using the same parameters as the KeyManager DPE. It is dedicated to unit test purposes.
* `ot-format.sh` is a simple shell wrapper to run clang-format (code formatter) on OpenTitan files
* `ot-tidy.sh` is a simple shell wrapper to run clang-tidy (C linter) on OpenTitan files
* `ot_tidy.py` is a python wrapper script to run clang-tidy (C linter) on OpenTitan files, optionally in parallel and locally or in CI.

Choose a reason for hiding this comment

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

line width

eprint("'clang-tidy --version' failed.")
sys.exit(1)
version_found = False
for line in p.stdout.decode().split("\n"):

Choose a reason for hiding this comment

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

I missed this one: use text=True in run so you get a text stream rather than a byte stream you need to decode

if m.group(1) != str(CLANG_MAJOR):
eprint(f"'clang-tidy' is major version {m.group(1)}, expecting {CLANG_MAJOR}.")
sys.exit(1)
version_found = True

Choose a reason for hiding this comment

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

You can replace version_found with a else condition on the for loop: if break is not called (i.e. match), then the else condition is executed.

if which(f"clang-tidy-{CLANG_MAJOR}"):
return f"clang-tidy-{CLANG_MAJOR}"
# Otherwise, look for 'clang-tidy' and check its version
if which("clang-tidy"):

Choose a reason for hiding this comment

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

Note: which can be removed here: you can catch subprocess.run exception FileNotFoundError which indicates that it fails to resolve the path to the application and also catch CalledProcessError (with check=True) if --version fails.

Both syntax could even be combined (clang-tidy-{CLANG_MAJOR} and clang-tidy) so you could even ensure that a versioned version actually matches its real version (as clang-tidy-{CLANG_MAJOR} are often symlinks)

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.

3 participants