-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: dev_environment handlers abstraction
Signed-off-by: Jack Cherng <[email protected]>
- Loading branch information
Showing
11 changed files
with
305 additions
and
119 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
from __future__ import annotations | ||
|
||
from pathlib import Path | ||
from typing import Generator, Sequence | ||
|
||
from more_itertools import first_true | ||
|
||
from .impl import ( | ||
BlenderDevEnvironmentHandler, | ||
GdbDevEnvironmentHandler, | ||
SublimeText33DevEnvironmentHandler, | ||
SublimeText38DevEnvironmentHandler, | ||
SublimeTextDevEnvironmentHandler, | ||
) | ||
from .interfaces import BaseDevEnvironmentHandler | ||
|
||
|
||
def list_dev_environment_handler_classes() -> Generator[type[BaseDevEnvironmentHandler], None, None]: | ||
yield BlenderDevEnvironmentHandler | ||
yield GdbDevEnvironmentHandler | ||
yield SublimeText33DevEnvironmentHandler | ||
yield SublimeText38DevEnvironmentHandler | ||
yield SublimeTextDevEnvironmentHandler | ||
|
||
|
||
def find_dev_environment_handler( | ||
dev_environment: str, | ||
*, | ||
server_dir: Path, | ||
workspace_folders: Sequence[str], | ||
) -> BaseDevEnvironmentHandler | None: | ||
if handler_cls := first_true( | ||
list_dev_environment_handler_classes(), | ||
pred=lambda cls_: cls_.can_support(dev_environment), | ||
): | ||
return handler_cls(server_dir=server_dir, workspace_folders=workspace_folders) | ||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from __future__ import annotations | ||
|
||
from .blender import BlenderDevEnvironmentHandler | ||
from .gdb import GdbDevEnvironmentHandler | ||
from .sublime_text import SublimeTextDevEnvironmentHandler | ||
from .sublime_text_33 import SublimeText33DevEnvironmentHandler | ||
from .sublime_text_38 import SublimeText38DevEnvironmentHandler | ||
|
||
__all__ = ( | ||
"BlenderDevEnvironmentHandler", | ||
"GdbDevEnvironmentHandler", | ||
"SublimeText33DevEnvironmentHandler", | ||
"SublimeText38DevEnvironmentHandler", | ||
"SublimeTextDevEnvironmentHandler", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
from __future__ import annotations | ||
|
||
import json | ||
import tempfile | ||
from pathlib import Path | ||
|
||
from LSP.plugin.core.collections import DottedDict | ||
|
||
from ...constants import SERVER_SETTING_ANALYSIS_EXTRAPATHS | ||
from ...utils import run_shell_command | ||
from ..interfaces import BaseDevEnvironmentHandler | ||
|
||
|
||
class BlenderDevEnvironmentHandler(BaseDevEnvironmentHandler): | ||
def handle(self, *, settings: DottedDict) -> None: | ||
extra_paths: list[str] = settings.get(SERVER_SETTING_ANALYSIS_EXTRAPATHS) or [] | ||
extra_paths.extend(self.find_paths(settings)) | ||
settings.set(SERVER_SETTING_ANALYSIS_EXTRAPATHS, extra_paths) | ||
|
||
@classmethod | ||
def find_paths(cls, settings: DottedDict) -> list[str]: | ||
with tempfile.TemporaryDirectory() as tmpdir: | ||
filepath = Path(tmpdir) / "print_sys_path.py" | ||
filepath.write_text( | ||
R""" | ||
import sys | ||
import json | ||
json.dump({"executable": sys.executable, "paths": sys.path}, sys.stdout) | ||
exit(0) | ||
""".strip(), | ||
encoding="utf-8", | ||
) | ||
args = (cls._get_dev_environment_binary(settings), "--background", "--python", str(filepath)) | ||
result = run_shell_command(args, shell=False) | ||
|
||
if not result or result[2] != 0: | ||
raise RuntimeError(f"Failed to run command: {args}") | ||
|
||
# Blender prints a bunch of general information to stdout before printing the output of the python | ||
# script. We want to ignore that initial information. We do that by finding the start of the JSON | ||
# dict. This is a bit hacky and there must be a better way. | ||
if (index := result[0].find('\n{"')) == -1: | ||
raise RuntimeError("Unexpected output when calling blender") | ||
|
||
try: | ||
return json.loads(result[0][index:])["paths"] | ||
except json.JSONDecodeError as e: | ||
raise RuntimeError(f"Failed to parse JSON: {e}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
from __future__ import annotations | ||
|
||
import json | ||
import tempfile | ||
from pathlib import Path | ||
|
||
from LSP.plugin.core.collections import DottedDict | ||
|
||
from ...constants import SERVER_SETTING_ANALYSIS_EXTRAPATHS | ||
from ...utils import run_shell_command | ||
from ..interfaces import BaseDevEnvironmentHandler | ||
|
||
|
||
class GdbDevEnvironmentHandler(BaseDevEnvironmentHandler): | ||
def handle(self, *, settings: DottedDict) -> None: | ||
extra_paths: list[str] = settings.get(SERVER_SETTING_ANALYSIS_EXTRAPATHS) or [] | ||
extra_paths.extend(self.find_paths(settings)) | ||
settings.set(SERVER_SETTING_ANALYSIS_EXTRAPATHS, extra_paths) | ||
|
||
@classmethod | ||
def find_paths(cls, settings: DottedDict) -> list[str]: | ||
with tempfile.TemporaryDirectory() as tmpdir: | ||
filepath = Path(tmpdir) / "print_sys_path.commands" | ||
filepath.write_text( | ||
R""" | ||
python | ||
import sys | ||
import json | ||
json.dump({"executable": sys.executable, "paths": sys.path}, sys.stdout) | ||
end | ||
exit | ||
""".strip(), | ||
encoding="utf-8", | ||
) | ||
args = (cls._get_dev_environment_binary(settings), "--batch", "--command", str(filepath)) | ||
result = run_shell_command(args, shell=False) | ||
|
||
if not result or result[2] != 0: | ||
raise RuntimeError(f"Failed to run command: {args}") | ||
|
||
try: | ||
return json.loads(result[0])["paths"] | ||
except json.JSONDecodeError as e: | ||
raise RuntimeError(f"Failed to parse JSON: {e}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
from __future__ import annotations | ||
|
||
from pathlib import Path | ||
|
||
import sublime | ||
from LSP.plugin.core.collections import DottedDict | ||
|
||
from ..interfaces import BaseSublimeTextDevEnvironmentHandler | ||
from .sublime_text_33 import SublimeText33DevEnvironmentHandler | ||
from .sublime_text_38 import SublimeText38DevEnvironmentHandler | ||
|
||
|
||
class SublimeTextDevEnvironmentHandler(BaseSublimeTextDevEnvironmentHandler): | ||
def handle(self, *, settings: DottedDict) -> None: | ||
py_ver = self.detect_st_py_ver() | ||
handler_cls: type[BaseSublimeTextDevEnvironmentHandler] | ||
|
||
if py_ver == (3, 3): | ||
handler_cls = SublimeText33DevEnvironmentHandler | ||
elif py_ver == (3, 8): | ||
handler_cls = SublimeText38DevEnvironmentHandler | ||
else: | ||
return | ||
|
||
handler_cls(server_dir=self.server_dir, workspace_folders=self.workspace_folders).handle(settings=settings) | ||
|
||
def detect_st_py_ver(self) -> tuple[int, int]: | ||
if not self.workspace_folders: | ||
return self.python_version | ||
|
||
try: | ||
# ST auto uses py38 for files in "Packages/User/" | ||
if (first_folder := Path(self.workspace_folders[0]).resolve()) == Path(sublime.packages_path()) / "User": | ||
return (3, 8) | ||
# the project wants to use py38 | ||
if (first_folder / ".python-version").read_bytes().strip() == b"3.8": | ||
return (3, 8) | ||
except Exception: | ||
pass | ||
return self.python_version |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from __future__ import annotations | ||
|
||
from ..interfaces import BaseSublimeTextDevEnvironmentHandler | ||
|
||
|
||
class SublimeText33DevEnvironmentHandler(BaseSublimeTextDevEnvironmentHandler): | ||
@classmethod | ||
def name(cls) -> str: | ||
return "sublime_text_33" | ||
|
||
@property | ||
def python_version(self) -> tuple[int, int]: | ||
return (3, 3) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from __future__ import annotations | ||
|
||
from ..interfaces import BaseSublimeTextDevEnvironmentHandler | ||
|
||
|
||
class SublimeText38DevEnvironmentHandler(BaseSublimeTextDevEnvironmentHandler): | ||
@classmethod | ||
def name(cls) -> str: | ||
return "sublime_text_38" | ||
|
||
@property | ||
def python_version(self) -> tuple[int, int]: | ||
return (3, 8) |
Oops, something went wrong.