-
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
10 changed files
with
324 additions
and
125 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
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,44 @@ | ||
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 find_dev_environment_handler_class(dev_environment: str) -> type[BaseDevEnvironmentHandler] | None: | ||
return first_true( | ||
list_dev_environment_handler_classes(), | ||
pred=lambda handler_cls: handler_cls.can_support(dev_environment), | ||
) | ||
|
||
|
||
def get_dev_environment_handler( | ||
dev_environment: str, | ||
*, | ||
server_dir: str | Path, | ||
workspace_folders: Sequence[str], | ||
) -> BaseDevEnvironmentHandler | None: | ||
if handler_cls := find_dev_environment_handler_class(dev_environment): | ||
return handler_cls( | ||
server_dir=server_dir, | ||
workspace_folders=workspace_folders, | ||
) | ||
return None | ||
|
||
|
||
def list_dev_environment_handler_classes() -> Generator[type[BaseDevEnvironmentHandler], None, None]: | ||
yield BlenderDevEnvironmentHandler | ||
yield GdbDevEnvironmentHandler | ||
yield SublimeText33DevEnvironmentHandler | ||
yield SublimeText38DevEnvironmentHandler | ||
yield 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,17 @@ | ||
from __future__ import annotations | ||
|
||
from .blender import BlenderDevEnvironmentHandler | ||
from .gdb import GdbDevEnvironmentHandler | ||
from .sublime_text import ( | ||
SublimeText33DevEnvironmentHandler, | ||
SublimeText38DevEnvironmentHandler, | ||
SublimeTextDevEnvironmentHandler, | ||
) | ||
|
||
__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,50 @@ | ||
from __future__ import annotations | ||
|
||
import json | ||
import tempfile | ||
from pathlib import Path | ||
|
||
from LSP.plugin.core.collections import DottedDict | ||
|
||
from ...utils import run_shell_command | ||
from ..interfaces import BaseDevEnvironmentHandler | ||
|
||
|
||
class BlenderDevEnvironmentHandler(BaseDevEnvironmentHandler): | ||
def handle(self, *, settings: DottedDict) -> None: | ||
self._inject_extra_paths(settings=settings, paths=self.find_paths(settings)) | ||
|
||
@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_subsetting(settings, "binary"), | ||
"--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,46 @@ | ||
from __future__ import annotations | ||
|
||
import json | ||
import tempfile | ||
from pathlib import Path | ||
|
||
from LSP.plugin.core.collections import DottedDict | ||
|
||
from ...utils import run_shell_command | ||
from ..interfaces import BaseDevEnvironmentHandler | ||
|
||
|
||
class GdbDevEnvironmentHandler(BaseDevEnvironmentHandler): | ||
def handle(self, *, settings: DottedDict) -> None: | ||
self._inject_extra_paths(settings=settings, paths=self.find_paths(settings)) | ||
|
||
@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_subsetting(settings, "binary"), | ||
"--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}") |
Oops, something went wrong.