From fad6c5858a029a65b7ae5d77f136c71b0b9ef4af Mon Sep 17 00:00:00 2001 From: Dave Gaeddert Date: Tue, 30 Jan 2024 21:25:27 -0600 Subject: [PATCH] Add bolt-code with ruff --- bolt-code/.gitignore | 16 +++++ bolt-code/bolt/code/__init__.py | 0 bolt-code/bolt/code/cli.py | 85 ++++++++++++++++++++++++++ bolt-code/bolt/code/ruff_defaults.toml | 19 ++++++ bolt-code/pyproject.toml | 29 +++++++++ 5 files changed, 149 insertions(+) create mode 100644 bolt-code/.gitignore create mode 100644 bolt-code/bolt/code/__init__.py create mode 100644 bolt-code/bolt/code/cli.py create mode 100644 bolt-code/bolt/code/ruff_defaults.toml create mode 100644 bolt-code/pyproject.toml diff --git a/bolt-code/.gitignore b/bolt-code/.gitignore new file mode 100644 index 0000000000..fd3ea8d98a --- /dev/null +++ b/bolt-code/.gitignore @@ -0,0 +1,16 @@ +# Local development files +/.env +/.bolt +*.sqlite3 + +# Publishing +/dist + +# Python +/.venv +__pycache__/ +*.py[cod] +*$py.class + +# OS files +.DS_Store diff --git a/bolt-code/bolt/code/__init__.py b/bolt-code/bolt/code/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/bolt-code/bolt/code/cli.py b/bolt-code/bolt/code/cli.py new file mode 100644 index 0000000000..9988de7bbe --- /dev/null +++ b/bolt-code/bolt/code/cli.py @@ -0,0 +1,85 @@ +import re +import subprocess +import sys +from pathlib import Path + +import click + +DEFAULT_RUFF_CONFIG = Path(__file__).parent / "ruff_defaults.toml" + + +@click.group() +def cli(): + """Standard code formatting and linting.""" + pass + + +@cli.command() +@click.argument("path", default=".") +@click.option("--fix/--no-fix", "do_fix", default=False) +def lint(path, do_fix): + ruff_args = [] + + if not user_has_ruff_config(): + click.secho("Using default bolt.code ruff config", italic=True, bold=True) + ruff_args.extend(["--config", str(DEFAULT_RUFF_CONFIG)]) + + if do_fix: + ruff_args.append("--fix") + + click.secho("Ruff check", bold=True) + result = subprocess.run(["ruff", "check", path, *ruff_args]) + + if result.returncode != 0: + sys.exit(result.returncode) + + +@cli.command() +@click.argument("path", default=".") +def format(path): + ruff_args = [] + + if not user_has_ruff_config(): + click.secho("Using default bolt.code ruff config", italic=True, bold=True) + ruff_args.extend(["--config", str(DEFAULT_RUFF_CONFIG)]) + + click.secho("Ruff format", bold=True) + result = subprocess.run(["ruff", "format", path, *ruff_args]) + + if result.returncode != 0: + sys.exit(result.returncode) + + +@cli.command() +@click.argument("path", default=".") +def fix(path): + """Lint and format the given path.""" + ruff_args = [] + + if not user_has_ruff_config(): + click.secho("Using default bolt.code ruff config", italic=True, bold=True) + ruff_args.extend(["--config", str(DEFAULT_RUFF_CONFIG)]) + + click.secho("Ruff check", bold=True) + result = subprocess.run(["ruff", "check", path, "--fix", *ruff_args]) + + if result.returncode != 0: + sys.exit(result.returncode) + + click.secho("Ruff format", bold=True) + result = subprocess.run(["ruff", "format", path, *ruff_args]) + + if result.returncode != 0: + sys.exit(result.returncode) + + +def user_has_ruff_config(): + try: + output = subprocess.check_output(["ruff", "check", ".", "--show-settings"]) + except subprocess.CalledProcessError: + return False + + if re.search("Settings path: (.+)", output.decode("utf-8")): + return True + else: + return False diff --git a/bolt-code/bolt/code/ruff_defaults.toml b/bolt-code/bolt/code/ruff_defaults.toml new file mode 100644 index 0000000000..3720b19245 --- /dev/null +++ b/bolt-code/bolt/code/ruff_defaults.toml @@ -0,0 +1,19 @@ +ignore = [ + "E501", # Never enforce `E501` (line length violations) + "S101", # pytest use of assert + "ISC001", # Implicit string concatenation +] +extend-select = [ + "I", # isort + # # "C90", # mccabe + # # "N", # pep8-naming + "UP", # pyupgrade + # "S", # bandit + # # "B", # bugbear + "C4", # flake8-comprehensions + # # "DTZ", # flake8-datetimez + "ISC", # flake8-implicit-str-concat + # # "G", # flake8-logging-format + # # "T20", # print + "PT", # pytest +] diff --git a/bolt-code/pyproject.toml b/bolt-code/pyproject.toml new file mode 100644 index 0000000000..6b97b86799 --- /dev/null +++ b/bolt-code/pyproject.toml @@ -0,0 +1,29 @@ +[tool.poetry] +name = "bolt-code" +packages = [ + { include = "bolt" }, +] + +version = "0.1.0" +description = "" +authors = ["Dave Gaeddert "] + +# Make the CLI available without adding to INSTALLED_APPS +[tool.poetry.plugins."bolt.cli"] +"code" = "bolt.code:cli" +"fix" = "bolt.code.cli:fix" + +[tool.poetry.dependencies] +python = "^3.8" +ruff = "^0.1.0" + +[tool.poetry.dev-dependencies] +pytest = "^7.1.2" +ipdb = "^0.13.9" +isort = "^5.10.1" +black = "^23.1.0" +pytest-django = "^4.5.2" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api"