From 8d4e842d3880a5ebe494255afb058f4b0441f684 Mon Sep 17 00:00:00 2001 From: Neal Joslin Date: Wed, 21 Aug 2024 19:50:53 -0400 Subject: [PATCH] Closes #1 + removed ruff as main dependency + raises exception on zero targets --- .editorconfig | 2 +- .github/workflows/tox.yml | 4 ++ .gitignore | 7 +++ Makefile | 10 +++- README.md | 76 +++++++++++++++++++++++--- default.nix | 20 +++++++ poetry.lock | 7 ++- pyproject.toml | 14 +++-- shell.nix | 16 ++++++ src/ruff_quickfix/__init__.py | 2 +- src/ruff_quickfix/__main__.py | 13 +++++ src/ruff_quickfix/cli.py | 11 ++-- src/ruff_quickfix/{main.py => lint.py} | 6 +- tests/test_cli.py | 16 ++++-- tox.ini | 17 ++++-- 15 files changed, 184 insertions(+), 37 deletions(-) create mode 100644 default.nix create mode 100644 shell.nix create mode 100644 src/ruff_quickfix/__main__.py rename src/ruff_quickfix/{main.py => lint.py} (91%) diff --git a/.editorconfig b/.editorconfig index 99ed197..fd1bf71 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,7 +8,7 @@ indent_size = 4 indent_style = space insert_final_newline = true -[{*.json,*.yml,*.yaml}] +[{*.md,*.yml,*.yaml,*.nix}] indent_size = 2 [{Makefile,*.mk}] diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 5f78950..8de66be 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -38,3 +38,7 @@ jobs: run: tox -vv --notest - name: Run test suite run: tox --skip-pkg-install + env: + CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }} + GITHUB_SHA: $GITHUB_SHA + diff --git a/.gitignore b/.gitignore index e9192f9..f71ae7d 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,11 @@ __pycache__ *.pyc *.cpython-36 +# poetry build dist/ +# nix-build +result + +# tox / pipeline outputs +coverage.xml +codacy-coverage-reporter diff --git a/Makefile b/Makefile index 5766a34..169d26c 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,11 @@ -all: - poetry run python -m src.ruff_quickfix +run: + poetry run ruff-quickfix + +mrun: + python -m src.ruff-quickfix + +build: + poetry build test: poetry run pytest diff --git a/README.md b/README.md index 3895de7..5342617 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,13 @@ # ruff-quickfix -[![Python](https://img.shields.io/badge/Python-3776AB?style=for-the-badge&logo=python&logoColor=white)](https://www.python.org/) +[![Version](https://img.shields.io/pypi/v/ruff-quickfix?style=for-the-badge)](https://pypi.org/project/ruff-quickfix/) +![Python Versions](https://img.shields.io/pypi/pyversions/ruff-quickfix?style=for-the-badge&logo=python&logoColor=white) [![Poetry](https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json&style=for-the-badge)](https://python-poetry.org/) -![Python 3.8](http://img.shields.io/badge/python-3.8-3776AB.svg) -![Python 3.9](http://img.shields.io/badge/python-3.9-3776AB.svg) -![Python 3.10](http://img.shields.io/badge/python-3.10-3776AB.svg) -![Python 3.11](http://img.shields.io/badge/python-3.11-3776AB.svg) -![Python 3.12](http://img.shields.io/badge/python-3.12-3776AB.svg) +![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/Nealium/ruff-quickfix/tox.yml?style=for-the-badge) +![Codacy grade](https://img.shields.io/codacy/grade/604aba9fddc14c739a9148cd71efe5c4?style=for-the-badge) +![Codacy coverage](https://img.shields.io/codacy/coverage/604aba9fddc14c739a9148cd71efe5c4?style=for-the-badge) @@ -22,6 +21,68 @@ using an LSP. Also this is an excuse to learn publishing. ![Screenshot](screenshot.png) +## Install + +### [pipx](https://github.com/pypa/pipx) *(recommended)* + +**Note:** Normal pip works as well, though you should give pipx a try! + +* [PyPi](https://pypi.org/project/ruff-quickfix/): `pipx install ruff-quickfix` +* [GitHub](https://github.com/Nealium/ruff-quickfix): `pipx install git+https://github.com/Nealium/ruff-quickfix` +* If you don't already have ruff you include it as an "extra" + * `pipx install ruff-quickfix[ruff]` + * if zsh: `pipx install ruff-quickfix\[ruff\]` + +### Source + +Clone project: `git clone https://github.com/Nealium/ruff-quickfix.git` + +* Pipx: `pipx install .` +* Pip: `pip install .` +* Poetry: `poetry install` +* From Wheel: + * `poetry install` + * `poetry build` + * `pipx install dist/*.whl` + +### [Home Manager](https://github.com/nix-community/home-manager) *(nix)* + +**Note!** This **will** crash on the first run as the sha256 isn't *real*. Once +it crashes the error message will provide the *actual* sha256 that is required. + +1. Insert items into `home.nix` +2. Replace `rev` with the most recent commit's hash +3. Run +4. Replace placeholder `sha256` with actual hash from error message +5. Re-run +6. Validate: `ruff-quickfix --help` + +```nix +{ config, pkgs, ... }: +let + # other stuff.. + + ruff-quickfix = import + (pkgs.fetchFromGitHub + { + owner = "Nealium"; + repo = "ruff-quickfix"; + + # "commit hash" (can be found on GitHub) + rev = "{commit-hash}"; + + # placeholder hash (replace after 1st run) + sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; + } + ) { inherit pkgs; }; +in + home.packages = [ + # other packages.. + + ruff-quickfix + ] +``` + ## Config ### Neovim @@ -102,4 +163,5 @@ command Pruff call s:ProjectRuffMake() ## Extras Inside the extras directory you will find files that allow you to easily toggle -between pylint and ruff, as well as a standalone file of ruff-quickfix. +between pylint and ruff. It also contains a standalone file of ruff-quickfix +that doesn't require on [click](https://click.palletsprojects.com) diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..1fcf4bb --- /dev/null +++ b/default.nix @@ -0,0 +1,20 @@ +{ pkgs ? import {} }: + +with pkgs; + +python312Packages.buildPythonPackage { + pname = "ruff-quickfix"; + version = "0.1.1"; + pyproject = true; + + src = ./.; + + nativeBuildInputs = [ + python312Packages.poetry-core + ruff + ]; + + propagatedBuildInputs = with python312Packages; [ + click + ]; +} diff --git a/poetry.lock b/poetry.lock index fbc79e4..98492df 100644 --- a/poetry.lock +++ b/poetry.lock @@ -480,7 +480,7 @@ files = [ name = "ruff" version = "0.6.1" description = "An extremely fast Python linter and code formatter, written in Rust." -optional = false +optional = true python-versions = ">=3.7" files = [ {file = "ruff-0.6.1-py3-none-linux_armv6l.whl", hash = "sha256:b4bb7de6a24169dc023f992718a9417380301b0c2da0fe85919f47264fb8add9"}, @@ -572,7 +572,10 @@ platformdirs = ">=3.9.1,<5" docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] +[extras] +ruff = ["ruff"] + [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "e2965d6e5e247f65d7d631650f5844bd1bd8b260ab7c65b2890d89e8b1d383f6" +content-hash = "11f5fec2c77f8065011e205d9aebf91f6ff7efc19c8227fffa23843ff1c4f135" diff --git a/pyproject.toml b/pyproject.toml index a0be2a6..d832391 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,20 +1,26 @@ [tool.poetry] name = "ruff-quickfix" -version = "0.1.0" +version = "0.1.1" description = "Wrapper for the `ruff` command for (neo)vim's quickfix" authors = ["Neal Joslin "] readme = "README.md" license = "LICENSE" -keywords = ["ruff", "cli", "vim", "neovim", "nvim", "quickfix"] repository = "https://github.com/Nealium/ruff-quickfix" +keywords = ["ruff", "cli", "vim", "neovim", "nvim", "quickfix"] +packages = [ + { include = "ruff_quickfix", from = "src" }, +] [tool.poetry.scripts] -ruff-quickfix = "ruff_quickfix.cli:cli" +ruff-quickfix = "ruff_quickfix:cli" [tool.poetry.dependencies] python = "^3.8" click = "^8.1.7" -ruff = "^0.6.1" +ruff = { version = "^0.6.1", optional = true } + +[tool.poetry.extras] +ruff = ["ruff"] [tool.poetry.group.dev.dependencies] pre-commit = { version = "^3.8.0", python = "^3.9" } diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..443daa3 --- /dev/null +++ b/shell.nix @@ -0,0 +1,16 @@ +with import { }; + +mkShell { + name = "ruff-qf-dev"; + + buildInputs = [ + ruff + python312Packages.poetry-core + python312Packages.click + python312Packages.mypy + python312Packages.pytest + python312Packages.pytest-click + python312Packages.pytest-cov + python312Packages.tox + ]; +} diff --git a/src/ruff_quickfix/__init__.py b/src/ruff_quickfix/__init__.py index 5ef981e..ca32ff9 100644 --- a/src/ruff_quickfix/__init__.py +++ b/src/ruff_quickfix/__init__.py @@ -3,7 +3,7 @@ Author: Neal Joslin Date: 2024-08-17 Email: neal@joslin.io -Description: Wrapper for the `ruff` linter for (neo)vim's quickfix +Description: import entry """ from .cli import cli diff --git a/src/ruff_quickfix/__main__.py b/src/ruff_quickfix/__main__.py new file mode 100644 index 0000000..aea4fd8 --- /dev/null +++ b/src/ruff_quickfix/__main__.py @@ -0,0 +1,13 @@ +""" +File: ruff_quickfix/__main__.py +Author: Neal Joslin +Date: 2024-08-21 +Email: neal@joslin.io +Description: module entry +""" + +# TODO (Neal): figure out how to test this line +from . import cli # pragma: no cover + +if __name__ == "__main__": # pragma: no cover + cli(obj={}) diff --git a/src/ruff_quickfix/cli.py b/src/ruff_quickfix/cli.py index 3f35c81..0740663 100644 --- a/src/ruff_quickfix/cli.py +++ b/src/ruff_quickfix/cli.py @@ -1,5 +1,5 @@ """ -File: cli +File: ruff_quickfix/cli Author: Neal Joslin Date: 2024-08-17 Email: neal@joslin.io @@ -10,16 +10,15 @@ import click -from .main import lint +from .lint import lint @click.command() @click.argument("targets", nargs=-1) def cli(targets: list[str]) -> None: """Ruff wrapper for (neo)vim's quickfix""" + if not len(targets): + msg = "No targets" + raise click.UsageError(msg) for path in targets: lint(path) - - -if __name__ == "__main__": # pragma: no cover - cli(obj={}) diff --git a/src/ruff_quickfix/main.py b/src/ruff_quickfix/lint.py similarity index 91% rename from src/ruff_quickfix/main.py rename to src/ruff_quickfix/lint.py index 0860292..5135057 100644 --- a/src/ruff_quickfix/main.py +++ b/src/ruff_quickfix/lint.py @@ -1,9 +1,9 @@ """ -File: ruff_quickfix/main.py +File: ruff_quickfix/lint.py Author: Neal Joslin -Date: 2024-08-17 +Date: 2024-08-21 Email: neal@joslin.io -Description: Main functionality +Description: Linting and formatting """ import re diff --git a/tests/test_cli.py b/tests/test_cli.py index 071aedf..ab16e95 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -19,6 +19,10 @@ from click.testing import CliRunner +# Exit code constants +EXIT_SUCCESS = 0 +EXIT_MISUSE = 2 + def test_cli_file_single(tmp_path: Path, cli_runner: CliRunner) -> None: """ @@ -30,7 +34,7 @@ def test_cli_file_single(tmp_path: Path, cli_runner: CliRunner) -> None: """ file_path = create_temp_file(tmp_path, "test.py") result = cli_runner.invoke(cli, [file_path]) - assert result.exit_code == 0 + assert result.exit_code == EXIT_SUCCESS assert result.output == get_file_messages(file_path) @@ -45,7 +49,7 @@ def test_cli_file_multiple(tmp_path: Path, cli_runner: CliRunner) -> None: file_path_0 = create_temp_file(tmp_path, "test0.py") file_path_1 = create_temp_file(tmp_path, "test1.py") result = cli_runner.invoke(cli, [file_path_0, file_path_1]) - assert result.exit_code == 0 + assert result.exit_code == EXIT_SUCCESS assert result.output == ( get_file_messages(file_path_0) + get_file_messages(file_path_1) ) @@ -61,7 +65,7 @@ def test_cli_single_directory(tmp_path: Path, cli_runner: CliRunner) -> None: """ file_path = create_temp_file(tmp_path, "test.py") result = cli_runner.invoke(cli, [str(tmp_path.resolve())]) - assert result.exit_code == 0 + assert result.exit_code == EXIT_SUCCESS assert result.output == get_file_messages(file_path) @@ -76,7 +80,7 @@ def test_cli_multiple_directory(tmp_path: Path, cli_runner: CliRunner) -> None: file_path_0 = create_temp_file(tmp_path, "test0.py") file_path_1 = create_temp_file(tmp_path, "test1.py") result = cli_runner.invoke(cli, [str(tmp_path.resolve())]) - assert result.exit_code == 0 + assert result.exit_code == EXIT_SUCCESS assert result.output == ( get_file_messages(file_path_0) + get_file_messages(file_path_1) ) @@ -90,5 +94,5 @@ def test_cli_none(cli_runner: CliRunner) -> None: cli_runner (CliRunner): click runner """ result = cli_runner.invoke(cli) - assert result.exit_code == 0 - assert result.output == "" + assert result.exit_code == EXIT_MISUSE + assert "Error: No targets" in result.output diff --git a/tox.ini b/tox.ini index 93fb1e3..aae6785 100644 --- a/tox.ini +++ b/tox.ini @@ -5,11 +5,20 @@ env_list = type, lint, py{38, 39, 310, 311, 312} [testenv] description = run unit tests -allowlist_externals = poetry +allowlist_externals = + poetry + bash + ./codacy-coverage-reporter +passenv = + CODACY_PROJECT_TOKEN + GITHUB_SHA commands_pre = - poetry install --no-root --sync --with test + poetry install --no-root --sync --with test -E ruff commands = - poetry run pytest -vvv {posargs} + poetry run pytest --cov --cov-report xml --cov-report term -vvv {posargs} + bash -c "curl -Ls -o codacy-coverage-reporter \"$(curl -Ls https://api.github.com/repos/codacy/codacy-coverage-reporter/releases/latest | jq -r '.assets | map({name, browser_download_url} | select(.name | contains(\"codacy-coverage-reporter-linux\"))) | .[0].browser_download_url')\"" + bash -c "chmod +x codacy-coverage-reporter" + ./codacy-coverage-reporter report -r coverage.xml [testenv:type] description = run type checks @@ -20,8 +29,6 @@ commands = [testenv:lint] description = lint source code -deps = - ruff commands = ruff check . ruff format --check .