all: Replace "black" with "ruff format".

- Add config for [tool.ruff.format] to pyproject.toml.
- Update pre-commit to run both ruff and ruff-format (and only check C
  files when running codeformat.py)
- Update CI.
- Simplify codeformat.py to remove all the Python-specific logic (just run
  "ruff format" directly).

This work was funded through GitHub Sponsors.

Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This commit is contained in:
Jim Mussared 2023-10-21 17:40:27 +11:00 committed by Damien George
parent 7ad84e0422
commit 303ccca7c6
6 changed files with 38 additions and 53 deletions

View File

@ -13,9 +13,9 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-python@v4 - uses: actions/setup-python@v4
- name: Install packages - name: Install packages
run: source tools/ci.sh && ci_code_formatting_setup run: source tools/ci.sh && ci_c_code_formatting_setup
- name: Run code formatting - name: Run code formatting
run: source tools/ci.sh && ci_code_formatting_run run: source tools/ci.sh && ci_c_code_formatting_run
- name: Check code formatting - name: Check code formatting
run: git diff --exit-code run: git diff --exit-code

View File

@ -1,10 +1,11 @@
# https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python # https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
name: Python code lint with ruff name: Python code lint and formatting with ruff
on: [push, pull_request] on: [push, pull_request]
jobs: jobs:
ruff: ruff:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- run: pip install --user ruff==0.1.0 - run: pip install --user ruff==0.1.3
- run: ruff check --output-format=github . - run: ruff check --output-format=github .
- run: ruff format --diff .

View File

@ -2,8 +2,8 @@ repos:
- repo: local - repo: local
hooks: hooks:
- id: codeformat - id: codeformat
name: MicroPython codeformat.py for changed files name: MicroPython codeformat.py for changed C files
entry: tools/codeformat.py -v -f entry: tools/codeformat.py -v -c -f
language: python language: python
- id: verifygitlog - id: verifygitlog
name: MicroPython git commit message format checker name: MicroPython git commit message format checker
@ -12,6 +12,7 @@ repos:
verbose: true verbose: true
stages: [commit-msg] stages: [commit-msg]
- repo: https://github.com/charliermarsh/ruff-pre-commit - repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.1.0 rev: v0.1.3
hooks: hooks:
- id: ruff - id: ruff
- id: ruff-format

View File

@ -1,6 +1,3 @@
[tool.black]
line-length = 99
[tool.codespell] [tool.codespell]
count = "" count = ""
ignore-regex = '\b[A-Z]{3}\b' ignore-regex = '\b[A-Z]{3}\b'
@ -24,7 +21,12 @@ ACKNOWLEDGEMENTS,\
""" """
[tool.ruff] [tool.ruff]
exclude = ["lib", "tests"] # Exclude third-party code from linting and formatting
extend-exclude = ["lib"]
line-length = 99
target-version = "py37"
[tool.ruff.lint]
extend-select = ["C9", "PLC"] extend-select = ["C9", "PLC"]
ignore = [ ignore = [
"E401", "E401",
@ -37,15 +39,21 @@ ignore = [
"F405", "F405",
"PLC1901", "PLC1901",
] ]
line-length = 337
target-version = "py37"
[tool.ruff.mccabe] [tool.ruff.mccabe]
max-complexity = 40 max-complexity = 40
[tool.ruff.per-file-ignores] [tool.ruff.per-file-ignores]
# Exclude all tests from linting (does not apply to formatting).
"tests/**/*.py" = ["ALL"]
"ports/cc3200/tools/uniflash.py" = ["E711"] "ports/cc3200/tools/uniflash.py" = ["E711"]
# manifest.py files are evaluated with some global names pre-defined # manifest.py files are evaluated with some global names pre-defined
"**/manifest.py" = ["F821"] "**/manifest.py" = ["F821"]
"ports/**/boards/**/manifest_*.py" = ["F821"] "ports/**/boards/**/manifest_*.py" = ["F821"]
[tool.ruff.format]
# Exclude third-party code, and exclude the following tests:
# basics: needs careful attention before applying automatic formatting
# repl_: not real python files
# viper_args: uses f(*)
exclude = ["tests/basics/*.py", "tests/*/repl_*.py", "tests/micropython/viper_args.py"]

View File

@ -15,17 +15,16 @@ function ci_gcc_arm_setup {
} }
######################################################################################## ########################################################################################
# code formatting # c code formatting
function ci_code_formatting_setup { function ci_c_code_formatting_setup {
sudo apt-get install uncrustify sudo apt-get install uncrustify
pip3 install black
uncrustify --version uncrustify --version
black --version
} }
function ci_code_formatting_run { function ci_c_code_formatting_run {
tools/codeformat.py -v # Only run on C files. The ruff rule runs separately on Python.
tools/codeformat.py -v -c
} }
######################################################################################## ########################################################################################

View File

@ -34,7 +34,6 @@ import subprocess
# Relative to top-level repo dir. # Relative to top-level repo dir.
PATHS = [ PATHS = [
# C
"drivers/ninaw10/*.[ch]", "drivers/ninaw10/*.[ch]",
"extmod/*.[ch]", "extmod/*.[ch]",
"extmod/btstack/*.[ch]", "extmod/btstack/*.[ch]",
@ -47,14 +46,6 @@ PATHS = [
"mpy-cross/*.[ch]", "mpy-cross/*.[ch]",
"ports/**/*.[ch]", "ports/**/*.[ch]",
"py/*.[ch]", "py/*.[ch]",
# Python
"drivers/**/*.py",
"examples/**/*.py",
"extmod/**/*.py",
"ports/**/*.py",
"py/**/*.py",
"tools/**/*.py",
"tests/**/*.py",
] ]
EXCLUSIONS = [ EXCLUSIONS = [
@ -78,23 +69,12 @@ EXCLUSIONS = [
"ports/stm32/usbhost/**/*.[ch]", "ports/stm32/usbhost/**/*.[ch]",
# STM32 build includes generated Python code. # STM32 build includes generated Python code.
"ports/*/build*", "ports/*/build*",
# not real python files
"tests/**/repl_*.py",
# needs careful attention before applying automatic formatting
"tests/basics/*.py",
] ]
# Path to repo top-level dir. # Path to repo top-level dir.
TOP = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) TOP = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
UNCRUSTIFY_CFG = os.path.join(TOP, "tools/uncrustify.cfg") UNCRUSTIFY_CFG = os.path.join(TOP, "tools/uncrustify.cfg")
PYPROJECT_TOML = os.path.join(TOP, "pyproject.toml")
C_EXTS = (
".c",
".h",
)
PY_EXTS = (".py",)
def list_files(paths, exclusions=None, prefix=""): def list_files(paths, exclusions=None, prefix=""):
@ -182,16 +162,11 @@ def main():
else: else:
files = list_files(PATHS, EXCLUSIONS, TOP) files = list_files(PATHS, EXCLUSIONS, TOP)
# Extract files matching a specific language.
def lang_files(exts):
for file in files:
if os.path.splitext(file)[1].lower() in exts:
yield file
# Run tool on N files at a time (to avoid making the command line too long). # Run tool on N files at a time (to avoid making the command line too long).
def batch(cmd, files, N=200): def batch(cmd, N=200):
files_iter = iter(files)
while True: while True:
file_args = list(itertools.islice(files, N)) file_args = list(itertools.islice(files_iter, N))
if not file_args: if not file_args:
break break
subprocess.check_call(cmd + file_args) subprocess.check_call(cmd + file_args)
@ -201,18 +176,19 @@ def main():
command = ["uncrustify", "-c", UNCRUSTIFY_CFG, "-lC", "--no-backup"] command = ["uncrustify", "-c", UNCRUSTIFY_CFG, "-lC", "--no-backup"]
if not args.v: if not args.v:
command.append("-q") command.append("-q")
batch(command, lang_files(C_EXTS)) batch(command)
for file in lang_files(C_EXTS): for file in files:
fixup_c(file) fixup_c(file)
# Format Python files with black. # Format Python files with "ruff format" (using config in pyproject.toml).
if format_py: if format_py:
command = ["black", "--fast", "--config={}".format(PYPROJECT_TOML)] command = ["ruff", "format"]
if args.v: if args.v:
command.append("-v") command.append("-v")
else: else:
command.append("-q") command.append("-q")
batch(command, lang_files(PY_EXTS)) command.append(".")
subprocess.check_call(command, cwd=TOP)
if __name__ == "__main__": if __name__ == "__main__":