From 303ccca7c62bd48b9f6a519549caf0d0f3d2624e Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Sat, 21 Oct 2023 17:40:27 +1100 Subject: [PATCH] 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 --- .github/workflows/code_formatting.yml | 4 +-- .github/workflows/ruff.yml | 5 ++-- .pre-commit-config.yaml | 7 +++-- pyproject.toml | 22 +++++++++----- tools/ci.sh | 11 ++++--- tools/codeformat.py | 42 ++++++--------------------- 6 files changed, 38 insertions(+), 53 deletions(-) diff --git a/.github/workflows/code_formatting.yml b/.github/workflows/code_formatting.yml index cab0ae55b2..53055a8441 100644 --- a/.github/workflows/code_formatting.yml +++ b/.github/workflows/code_formatting.yml @@ -13,9 +13,9 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 - 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 - run: source tools/ci.sh && ci_code_formatting_run + run: source tools/ci.sh && ci_c_code_formatting_run - name: Check code formatting run: git diff --exit-code diff --git a/.github/workflows/ruff.yml b/.github/workflows/ruff.yml index 0374d766f5..1159a1882d 100644 --- a/.github/workflows/ruff.yml +++ b/.github/workflows/ruff.yml @@ -1,10 +1,11 @@ # 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] jobs: ruff: runs-on: ubuntu-latest steps: - 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 format --diff . diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bfce6a2468..3004bc5677 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,8 +2,8 @@ repos: - repo: local hooks: - id: codeformat - name: MicroPython codeformat.py for changed files - entry: tools/codeformat.py -v -f + name: MicroPython codeformat.py for changed C files + entry: tools/codeformat.py -v -c -f language: python - id: verifygitlog name: MicroPython git commit message format checker @@ -12,6 +12,7 @@ repos: verbose: true stages: [commit-msg] - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.1.0 + rev: v0.1.3 hooks: - id: ruff + - id: ruff-format diff --git a/pyproject.toml b/pyproject.toml index 96e2e3a890..6c813f5a1f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,3 @@ -[tool.black] -line-length = 99 - [tool.codespell] count = "" ignore-regex = '\b[A-Z]{3}\b' @@ -24,7 +21,12 @@ ACKNOWLEDGEMENTS,\ """ [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"] ignore = [ "E401", @@ -37,15 +39,21 @@ ignore = [ "F405", "PLC1901", ] -line-length = 337 -target-version = "py37" [tool.ruff.mccabe] max-complexity = 40 [tool.ruff.per-file-ignores] +# Exclude all tests from linting (does not apply to formatting). +"tests/**/*.py" = ["ALL"] "ports/cc3200/tools/uniflash.py" = ["E711"] - # manifest.py files are evaluated with some global names pre-defined "**/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"] diff --git a/tools/ci.sh b/tools/ci.sh index 53e3425699..8dcbbf7765 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -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 - pip3 install black uncrustify --version - black --version } -function ci_code_formatting_run { - tools/codeformat.py -v +function ci_c_code_formatting_run { + # Only run on C files. The ruff rule runs separately on Python. + tools/codeformat.py -v -c } ######################################################################################## diff --git a/tools/codeformat.py b/tools/codeformat.py index aee9894345..bd37aec467 100755 --- a/tools/codeformat.py +++ b/tools/codeformat.py @@ -34,7 +34,6 @@ import subprocess # Relative to top-level repo dir. PATHS = [ - # C "drivers/ninaw10/*.[ch]", "extmod/*.[ch]", "extmod/btstack/*.[ch]", @@ -47,14 +46,6 @@ PATHS = [ "mpy-cross/*.[ch]", "ports/**/*.[ch]", "py/*.[ch]", - # Python - "drivers/**/*.py", - "examples/**/*.py", - "extmod/**/*.py", - "ports/**/*.py", - "py/**/*.py", - "tools/**/*.py", - "tests/**/*.py", ] EXCLUSIONS = [ @@ -78,23 +69,12 @@ EXCLUSIONS = [ "ports/stm32/usbhost/**/*.[ch]", # STM32 build includes generated Python code. "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. TOP = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) 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=""): @@ -182,16 +162,11 @@ def main(): else: 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). - def batch(cmd, files, N=200): + def batch(cmd, N=200): + files_iter = iter(files) while True: - file_args = list(itertools.islice(files, N)) + file_args = list(itertools.islice(files_iter, N)) if not file_args: break subprocess.check_call(cmd + file_args) @@ -201,18 +176,19 @@ def main(): command = ["uncrustify", "-c", UNCRUSTIFY_CFG, "-lC", "--no-backup"] if not args.v: command.append("-q") - batch(command, lang_files(C_EXTS)) - for file in lang_files(C_EXTS): + batch(command) + for file in files: fixup_c(file) - # Format Python files with black. + # Format Python files with "ruff format" (using config in pyproject.toml). if format_py: - command = ["black", "--fast", "--config={}".format(PYPROJECT_TOML)] + command = ["ruff", "format"] if args.v: command.append("-v") else: command.append("-q") - batch(command, lang_files(PY_EXTS)) + command.append(".") + subprocess.check_call(command, cwd=TOP) if __name__ == "__main__":