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:
parent
7ad84e0422
commit
303ccca7c6
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 .
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"]
|
||||||
|
|
11
tools/ci.sh
11
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
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
########################################################################################
|
########################################################################################
|
||||||
|
|
|
@ -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__":
|
||||||
|
|
Loading…
Reference in New Issue