Skip to content

Commit

Permalink
Keep Python script limited to sysconfig usage (#511)
Browse files Browse the repository at this point in the history
## Summary

This PR makes progress towards #476 and #479 by making the following
changes:
* Update the `ruff_server.py` script to limit itself to just getting the
Ruff binary path using `sysconfig`
* Use the `which` dependency and move the logic of locating the Ruff
binary from `PATH` to TypeScript
* Add log messages similar to `ruff-lsp`

## Test Plan

### 1

```json
{
  "ruff.nativeServer": true
}
```
Or
```json
{
  "ruff.nativeServer": true,
  "ruff.importStrategy": "fromEnvironment"
}
```

Logs:

When the `ruff` binary is installed in the current virtual environment:
```
2024-07-03 15:28:35.674 [info] Using the Ruff binary: /Users/dhruv/work/astral/ruff-vscode/.venv/bin/ruff
2024-07-03 15:28:35.675 [info] Server run command: /Users/dhruv/work/astral/ruff-vscode/.venv/bin/ruff server --preview
```

If there's no `ruff` binary in the current virtual environment:
```
2024-07-03 15:25:19.605 [info] Using the Ruff binary: /Users/dhruv/.local/bin/ruff
2024-07-03 15:25:19.606 [info] Server run command: /Users/dhruv/.local/bin/ruff server --preview
```

If the `ruff` binary is only available via `PATH`:
```
2024-07-03 15:32:12.172 [info] Using environment executable: /opt/homebrew/bin/ruff
2024-07-03 15:32:12.173 [info] Server run command: /opt/homebrew/bin/ruff server --preview
```

And, if there's no `ruff` binary anywhere on the system, use the bundled
binary:
```
2024-07-03 15:29:47.948 [info] Falling back to bundled executable: /Users/dhruv/work/astral/ruff-vscode/bundled/libs/bin/ruff
2024-07-03 15:29:47.948 [info] Server run command: /Users/dhruv/work/astral/ruff-vscode/bundled/libs/bin/ruff server --preview
```

### 2

```json
{
  "ruff.nativeServer": true,
  "ruff.importStrategy": "useBundled"
}
```

Logs:
```
2024-07-03 15:26:28.767 [info] Using bundled executable: /Users/dhruv/work/astral/ruff-vscode/bundled/libs/bin/ruff
2024-07-03 15:26:28.767 [info] Server run command: /Users/dhruv/work/astral/ruff-vscode/bundled/libs/bin/ruff server --preview
```

### 3

```json
{
  "ruff.nativeServer": true,
  "ruff.path": ["/Users/dhruv/work/astral/ruff/target/debug/ruff"]
}
```

Logs:
```
2024-07-03 15:27:42.342 [info] Using 'path' setting: /Users/dhruv/work/astral/ruff/target/debug/ruff
2024-07-03 15:27:42.342 [info] Server run command: /Users/dhruv/work/astral/ruff/target/debug/ruff server --preview
```

### 4

```json
{
  "ruff.nativeServer": true,
  "ruff.interpreter": [
    "/Users/dhruv/work/astral/ruff-lsp/.venv/bin/python"
  ]
}
```

Logs:
```
2024-07-03 15:35:23.578 [info] Using the Ruff binary: /Users/dhruv/work/astral/ruff-lsp/.venv/bin/ruff
2024-07-03 15:35:23.578 [info] Server run command: /Users/dhruv/work/astral/ruff-lsp/.venv/bin/ruff server --preview
```

### 5

What if the script failed? I modified the script path in TypeScript code
and we get the following logs:

```
2024-07-03 15:42:41.035 [error] Error while trying to find the Ruff binary: Error: Command failed: /Users/dhruv/work/astral/ruff-lsp/.venv/bin/python /Users/dhruv/work/astral/ruff-vscode/bundled/tool/find_ruff_binary_pat.py
/Users/dhruv/work/astral/ruff-lsp/.venv/bin/python: can't open file '/Users/dhruv/work/astral/ruff-vscode/bundled/tool/find_ruff_binary_pat.py': [Errno 2] No such file or directory

2024-07-03 15:42:41.037 [info] Using environment executable: /Users/dhruv/.local/bin/ruff
2024-07-03 15:42:41.040 [info] Server run command: /Users/dhruv/.local/bin/ruff server --preview
```
  • Loading branch information
dhruvmanila authored Jul 4, 2024
1 parent e34ffba commit fbb0467
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 150 deletions.
35 changes: 35 additions & 0 deletions bundled/tool/find_ruff_binary_path.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import os
import sys
import sysconfig
from pathlib import Path
from typing import Optional

RUFF_EXE = "ruff.exe" if sys.platform == "win32" else "ruff"


def find_ruff_binary_path() -> Optional[Path]:
"""Return the ruff binary path if it exists, `None` otherwise."""
bin_path = Path(sysconfig.get_path("scripts")) / RUFF_EXE
if bin_path.is_file():
return bin_path

if sys.version_info >= (3, 10):
user_scheme = sysconfig.get_preferred_scheme("user")
elif os.name == "nt":
user_scheme = "nt_user"
elif sys.platform == "darwin" and sys._framework:
user_scheme = "osx_framework_user"
else:
user_scheme = "posix_user"

scripts_path = Path(sysconfig.get_path("scripts", scheme=user_scheme)) / RUFF_EXE
if scripts_path.is_file():
return scripts_path

return None


if __name__ == "__main__":
ruff_binary_path = find_ruff_binary_path()
if ruff_binary_path:
print(os.fsdecode(str(ruff_binary_path)), flush=True)
92 changes: 0 additions & 92 deletions bundled/tool/ruff_server.py

This file was deleted.

98 changes: 77 additions & 21 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -386,13 +386,15 @@
"dependencies": {
"fs-extra": "^11.1.1",
"ovsx": "^0.7.1",
"vscode-languageclient": "^8.1.0"
"vscode-languageclient": "^8.1.0",
"which": "^4.0.0"
},
"devDependencies": {
"@types/fs-extra": "^11.0.1",
"@types/glob": "^8.1.0",
"@types/node": "^20.3.1",
"@types/vscode": "1.75.0",
"@types/which": "^3.0.4",
"@typescript-eslint/eslint-plugin": "^5.59.2",
"@typescript-eslint/parser": "^5.59.2",
"@vscode/vsce": "^2.19.0",
Expand Down
11 changes: 5 additions & 6 deletions src/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,15 @@ export const DEBUG_SERVER_SCRIPT_PATH = path.join(
);

/**
* Path to the Python script that starts the native language server with an
* appropriate `ruff` executable.
* Path to the Python script that tries to find the Ruff binary path.
*
* This should only be used as a fallback if the user has not specified either
* the `path` setting or is not using the bundled import strategy.
* This should only be used as a fallback if there is no valid `ruff` binary in
* the user's `path` setting or the import strategy isn't `useBundled`.
*/
export const NATIVE_SERVER_SCRIPT_PATH = path.join(
export const FIND_RUFF_BINARY_SCRIPT_PATH = path.join(
BUNDLED_PYTHON_SCRIPTS_DIR,
"tool",
"ruff_server.py",
"find_ruff_binary_path.py",
);

/**
Expand Down
Loading

0 comments on commit fbb0467

Please sign in to comment.