From d46bf96b4cf69f7e7b99cb7f564a353cea3b4213 Mon Sep 17 00:00:00 2001 From: Felix Williams Date: Tue, 30 Jan 2024 13:30:22 +0000 Subject: [PATCH 1/4] suppress stderr in call to ruff --- jupyterlab_code_formatter/formatters.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/jupyterlab_code_formatter/formatters.py b/jupyterlab_code_formatter/formatters.py index 46c10b9..52114f6 100644 --- a/jupyterlab_code_formatter/formatters.py +++ b/jupyterlab_code_formatter/formatters.py @@ -456,6 +456,8 @@ def format_code(self, code: str, notebook: bool, args: List[str] = [], **options class RuffFixFormatter(CommandLineFormatter): + ruff_args = ["check", "-eq", "--fix-only", "-"] + @property def label(self) -> str: return f"Apply ruff Formatter" @@ -467,7 +469,11 @@ def __init__(self): ruff_command = find_ruff_bin() except (ImportError, FileNotFoundError): ruff_command = "ruff" - self.command = [ruff_command, "check", "--fix-only", "-"] + self.command = [ruff_command, *self.ruff_args] + + +class RuffFormatFormatter(RuffFixFormatter): + ruff_args = ["format", "-q", "-"] SERVER_FORMATTERS = { @@ -477,6 +483,7 @@ def __init__(self): "yapf": YapfFormatter(), "isort": IsortFormatter(), "ruff": RuffFixFormatter(), + "ruffformat": RuffFormatFormatter(), "formatR": FormatRFormatter(), "styler": StylerFormatter(), "scalafmt": CommandLineFormatter(command=["scalafmt", "--stdin"]), From f1d225a5b97f6dd35429dc2ec0dc3286f72c0a42 Mon Sep 17 00:00:00 2001 From: Felix Williams Date: Mon, 22 Jul 2024 12:31:29 +0100 Subject: [PATCH 2/4] add separate ruffformat options to schema --- schema/settings.json | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/schema/settings.json b/schema/settings.json index f5d3c03..36fdf2f 100644 --- a/schema/settings.json +++ b/schema/settings.json @@ -208,6 +208,13 @@ "additionalProperties": false, "type": "object" }, + "ruffformat": { + "properties": { + "args": { "type": "array", "items": { "type": "string" } } + }, + "additionalProperties": false, + "type": "object" + }, "formatR": { "properties": { "comment": { @@ -407,11 +414,19 @@ } }, "ruff": { - "title": "Ruff Config", - "description": "Command line options to be passed to ruff.", + "title": "Ruff Check Config", + "description": "Command line options to be passed to ruff check. Default is to organise imports.", "$ref": "#/definitions/ruff", "default": { - "args": ["--select=I"] + "args": ["--select=I001"] + } + }, + "ruffformat": { + "title": "Ruff Format Config", + "description": "Command line options to be passed to ruff format.", + "$ref": "#/definitions/ruffformat", + "default": { + "args": [] } }, "suppressFormatterErrors": { From f2946ea26b38245e5e4f7ad4e649253a76719cdf Mon Sep 17 00:00:00 2001 From: Felix Williams Date: Mon, 22 Jul 2024 12:33:13 +0100 Subject: [PATCH 3/4] add tests for ruff fix and format --- jupyterlab_code_formatter/formatters.py | 6 +- .../tests/test_handlers.py | 56 +++++++++++++++++-- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/jupyterlab_code_formatter/formatters.py b/jupyterlab_code_formatter/formatters.py index 52114f6..ac7d668 100644 --- a/jupyterlab_code_formatter/formatters.py +++ b/jupyterlab_code_formatter/formatters.py @@ -460,7 +460,7 @@ class RuffFixFormatter(CommandLineFormatter): @property def label(self) -> str: - return f"Apply ruff Formatter" + return "Apply ruff fix" def __init__(self): try: @@ -473,6 +473,10 @@ def __init__(self): class RuffFormatFormatter(RuffFixFormatter): + @property + def label(self) -> str: + return "Apply ruff formatter" + ruff_args = ["format", "-q", "-"] diff --git a/jupyterlab_code_formatter/tests/test_handlers.py b/jupyterlab_code_formatter/tests/test_handlers.py index 7493af1..4d118ca 100644 --- a/jupyterlab_code_formatter/tests/test_handlers.py +++ b/jupyterlab_code_formatter/tests/test_handlers.py @@ -588,11 +588,15 @@ async def test_can_rustfmt(request_format): # type: ignore[no-untyped-def] assert json_result["code"][0]["code"] == expected -@pytest.mark.xfail(reason="Rust toolchain isn't respected in test for some reason atm.") -async def test_can_apply_ruff(request_format): # type: ignore[no-untyped-def] - """Check that it can apply black with simple config.""" +IMPORT_SORTING_EXAMPLE = ( + "import numpy as np\nimport sys,os\nfrom enum import IntEnum\nfrom enum import auto" +) + + +async def test_can_apply_ruff_formatter(request_format): # type: ignore[no-untyped-def] + """Check that it can apply ruff with simple config.""" response: HTTPResponse = await request_format( - formatter="ruff", + formatter="ruffformat", code=[SIMPLE_VALID_PYTHON_CODE], options={}, ) @@ -602,3 +606,47 @@ async def test_can_apply_ruff(request_format): # type: ignore[no-untyped-def] expected_schema=EXPECTED_FROMAT_SCHEMA, ) assert json_result["code"][0]["code"] == "x = 22\ne = 1" + + +async def test_can_apply_ruff_import_fix(request_format): # type: ignore[no-untyped-def] + """Check that it can organize imports with ruff.""" + + given = "import foo\nimport numpy as np\nimport sys,os\nfrom enum import IntEnum\nfrom enum import auto" + expected = "import os\nimport sys\nfrom enum import IntEnum, auto\n\nimport numpy as np\n\nimport foo" + response: HTTPResponse = await request_format( + formatter="ruff", + code=[given], + options={ + "args": [ + "--select=I001", + "--config", + "lint.isort.known-first-party=['foo']", + ] + }, + ) + json_result = _check_http_code_and_schema( + response=response, + expected_code=200, + expected_schema=EXPECTED_FROMAT_SCHEMA, + ) + assert json_result["code"][0]["code"] == expected + + +async def test_can_apply_ruff_fix_unsafe(request_format): # type: ignore[no-untyped-def] + """Check that it can apply unsafe fixes.""" + + given = """if arg != None: + pass""" + expected = """if arg is not None: + pass""" + response: HTTPResponse = await request_format( + formatter="ruff", + code=[given], + options={"args": ["--select=E711", "--unsafe-fixes"]}, + ) + json_result = _check_http_code_and_schema( + response=response, + expected_code=200, + expected_schema=EXPECTED_FROMAT_SCHEMA, + ) + assert json_result["code"][0]["code"] == expected From 9448aa6888f7cbe360e64bb244fb760ae224c7ab Mon Sep 17 00:00:00 2001 From: Felix Williams Date: Mon, 22 Jul 2024 13:57:45 +0100 Subject: [PATCH 4/4] add ruff as a test dependency --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 26cac4a..8ae98b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,6 +53,7 @@ test = [ "yapf", "rpy2", "importlib_metadata; python_version<'3.8'", + "ruff", ] [tool.hatch.version]