mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-15 08:17:15 +00:00
Refine runtime dependency helpers (#286)
This commit is contained in:
1 parent
aa0c0e5373
commit
bb595eb7e7
9 files changed
+334
-287
No files matched your search
@@ -12,6 +12,7 @@ from solidlsp.ls import SolidLanguageServer
|
|||||||
from solidlsp.ls_config import LanguageServerConfig
|
from solidlsp.ls_config import LanguageServerConfig
|
||||||
from solidlsp.ls_logger import LanguageServerLogger
|
from solidlsp.ls_logger import LanguageServerLogger
|
||||||
from solidlsp.ls_utils import FileUtils, PlatformUtils
|
from solidlsp.ls_utils import FileUtils, PlatformUtils
|
||||||
|
from .common import RuntimeDependency, RuntimeDependencyCollection
|
||||||
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
|
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
|
||||||
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
||||||
|
|
||||||
@@ -47,58 +48,44 @@ class ClangdLanguageServer(SolidLanguageServer):
|
|||||||
"""
|
"""
|
||||||
platform_id = PlatformUtils.get_platform_id()
|
platform_id = PlatformUtils.get_platform_id()
|
||||||
|
|
||||||
runtime_dependencies = [
|
deps = RuntimeDependencyCollection(
|
||||||
{
|
[
|
||||||
"id": "Clangd",
|
RuntimeDependency(
|
||||||
"description": "Clangd for Linux (x64)",
|
id="Clangd",
|
||||||
"url": "https://github.com/clangd/clangd/releases/download/19.1.2/clangd-linux-19.1.2.zip",
|
description="Clangd for Linux (x64)",
|
||||||
"platformId": "linux-x64",
|
url="https://github.com/clangd/clangd/releases/download/19.1.2/clangd-linux-19.1.2.zip",
|
||||||
"archiveType": "zip",
|
platform_id="linux-x64",
|
||||||
"binaryName": "clangd",
|
archive_type="zip",
|
||||||
},
|
binary_name="clangd_19.1.2/bin/clangd",
|
||||||
{
|
),
|
||||||
"id": "Clangd",
|
RuntimeDependency(
|
||||||
"description": "Clangd for Windows (x64)",
|
id="Clangd",
|
||||||
"url": "https://github.com/clangd/clangd/releases/download/19.1.2/clangd-windows-19.1.2.zip",
|
description="Clangd for Windows (x64)",
|
||||||
"platformId": "win-x64",
|
url="https://github.com/clangd/clangd/releases/download/19.1.2/clangd-windows-19.1.2.zip",
|
||||||
"archiveType": "zip",
|
platform_id="win-x64",
|
||||||
"binaryName": "clangd.exe",
|
archive_type="zip",
|
||||||
},
|
binary_name="clangd_19.1.2/bin/clangd.exe",
|
||||||
{
|
),
|
||||||
"id": "Clangd",
|
RuntimeDependency(
|
||||||
"description": "Clangd for macOS (Arm64)",
|
id="Clangd",
|
||||||
"url": "https://github.com/clangd/clangd/releases/download/19.1.2/clangd-mac-19.1.2.zip",
|
description="Clangd for macOS (Arm64)",
|
||||||
"platformId": "osx-arm64",
|
url="https://github.com/clangd/clangd/releases/download/19.1.2/clangd-mac-19.1.2.zip",
|
||||||
"archiveType": "zip",
|
platform_id="osx-arm64",
|
||||||
"binaryName": "clangd",
|
archive_type="zip",
|
||||||
},
|
binary_name="clangd_19.1.2/bin/clangd",
|
||||||
]
|
),
|
||||||
|
]
|
||||||
assert platform_id.value in [
|
|
||||||
"linux-x64",
|
|
||||||
"win-x64",
|
|
||||||
"osx-arm64",
|
|
||||||
], (
|
|
||||||
"Unsupported platform: " + platform_id.value
|
|
||||||
)
|
)
|
||||||
|
|
||||||
runtime_dependencies = [dependency for dependency in runtime_dependencies if dependency["platformId"] == platform_id.value]
|
|
||||||
assert len(runtime_dependencies) == 1
|
|
||||||
# Select dependency matching the current platform
|
|
||||||
dependency = next((dep for dep in runtime_dependencies if dep["platformId"] == platform_id.value), None)
|
|
||||||
if dependency is None:
|
|
||||||
raise RuntimeError(f"No runtime dependency found for platform {platform_id.value}")
|
|
||||||
|
|
||||||
clangd_ls_dir = os.path.join(os.path.dirname(__file__), "static", "clangd")
|
clangd_ls_dir = os.path.join(os.path.dirname(__file__), "static", "clangd")
|
||||||
clangd_executable_path = os.path.join(clangd_ls_dir, "clangd_19.1.2", "bin", dependency["binaryName"])
|
dep = deps.single_for_current_platform()
|
||||||
|
clangd_executable_path = deps.binary_path(clangd_ls_dir)
|
||||||
if not os.path.exists(clangd_executable_path):
|
if not os.path.exists(clangd_executable_path):
|
||||||
clangd_url = dependency["url"]
|
logger.log(
|
||||||
logger.log(f"Clangd executable not found at {clangd_executable_path}. Downloading from {clangd_url}", logging.INFO)
|
f"Clangd executable not found at {clangd_executable_path}. Downloading from {dep.url}",
|
||||||
os.makedirs(clangd_ls_dir, exist_ok=True)
|
logging.INFO,
|
||||||
if dependency["archiveType"] == "zip":
|
)
|
||||||
FileUtils.download_and_extract_archive(logger, clangd_url, clangd_ls_dir, dependency["archiveType"])
|
deps.install(logger, clangd_ls_dir)
|
||||||
else:
|
|
||||||
raise RuntimeError(f"Unsupported archive type: {dependency['archiveType']}")
|
|
||||||
if not os.path.exists(clangd_executable_path):
|
if not os.path.exists(clangd_executable_path):
|
||||||
raise FileNotFoundError(
|
raise FileNotFoundError(
|
||||||
f"Clangd executable not found at {clangd_executable_path}.\n"
|
f"Clangd executable not found at {clangd_executable_path}.\n"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ from solidlsp.ls import SolidLanguageServer
|
|||||||
from solidlsp.ls_config import LanguageServerConfig
|
from solidlsp.ls_config import LanguageServerConfig
|
||||||
from solidlsp.ls_logger import LanguageServerLogger
|
from solidlsp.ls_logger import LanguageServerLogger
|
||||||
from solidlsp.ls_utils import FileUtils, PlatformUtils
|
from solidlsp.ls_utils import FileUtils, PlatformUtils
|
||||||
|
from .common import RuntimeDependency, RuntimeDependencyCollection
|
||||||
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
|
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
|
||||||
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
||||||
|
|
||||||
@@ -44,32 +45,38 @@ class ClojureLSP(SolidLanguageServer):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
clojure_lsp_releases = "https://github.com/clojure-lsp/clojure-lsp/releases/latest/download"
|
clojure_lsp_releases = "https://github.com/clojure-lsp/clojure-lsp/releases/latest/download"
|
||||||
runtime_dependencies = [
|
runtime_dependencies = RuntimeDependencyCollection(
|
||||||
{
|
[
|
||||||
"url": f"{clojure_lsp_releases}/clojure-lsp-native-macos-aarch64.zip",
|
RuntimeDependency(
|
||||||
"platformId": "osx-arm64",
|
id="clojure-lsp",
|
||||||
"archiveType": "zip",
|
url=f"{clojure_lsp_releases}/clojure-lsp-native-macos-aarch64.zip",
|
||||||
"binaryName": "clojure-lsp",
|
platform_id="osx-arm64",
|
||||||
},
|
archive_type="zip",
|
||||||
{
|
binary_name="clojure-lsp",
|
||||||
"url": f"{clojure_lsp_releases}/clojure-lsp-native-linux-aarch64.zip",
|
),
|
||||||
"platformId": "linux-arm64",
|
RuntimeDependency(
|
||||||
"archiveType": "zip",
|
id="clojure-lsp",
|
||||||
"binaryName": "clojure-lsp",
|
url=f"{clojure_lsp_releases}/clojure-lsp-native-linux-aarch64.zip",
|
||||||
},
|
platform_id="linux-arm64",
|
||||||
{
|
archive_type="zip",
|
||||||
"url": f"{clojure_lsp_releases}/clojure-lsp-native-linux-amd64.zip",
|
binary_name="clojure-lsp",
|
||||||
"platformId": "linux-x64",
|
),
|
||||||
"archiveType": "zip",
|
RuntimeDependency(
|
||||||
"binaryName": "clojure-lsp",
|
id="clojure-lsp",
|
||||||
},
|
url=f"{clojure_lsp_releases}/clojure-lsp-native-linux-amd64.zip",
|
||||||
{
|
platform_id="linux-x64",
|
||||||
"url": f"{clojure_lsp_releases}/clojure-lsp-native-windows-amd64.zip",
|
archive_type="zip",
|
||||||
"platformId": "win-x64",
|
binary_name="clojure-lsp",
|
||||||
"archiveType": "zip",
|
),
|
||||||
"binaryName": "clojure-lsp.exe",
|
RuntimeDependency(
|
||||||
},
|
id="clojure-lsp",
|
||||||
]
|
url=f"{clojure_lsp_releases}/clojure-lsp-native-windows-amd64.zip",
|
||||||
|
platform_id="win-x64",
|
||||||
|
archive_type="zip",
|
||||||
|
binary_name="clojure-lsp.exe",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
|
def __init__(self, config: LanguageServerConfig, logger: LanguageServerLogger, repository_root_path: str):
|
||||||
"""
|
"""
|
||||||
@@ -92,21 +99,18 @@ class ClojureLSP(SolidLanguageServer):
|
|||||||
def _setup_runtime_dependencies(logger: LanguageServerLogger, config: LanguageServerConfig) -> str:
|
def _setup_runtime_dependencies(logger: LanguageServerLogger, config: LanguageServerConfig) -> str:
|
||||||
"""Setup runtime dependencies for clojure-lsp and return the command to start the server."""
|
"""Setup runtime dependencies for clojure-lsp and return the command to start the server."""
|
||||||
verify_clojure_cli()
|
verify_clojure_cli()
|
||||||
platform_id = PlatformUtils.get_platform_id()
|
deps = ClojureLSP.runtime_dependencies
|
||||||
|
dependency = deps.single_for_current_platform()
|
||||||
runtime_dependencies = [
|
|
||||||
dependency for dependency in ClojureLSP.runtime_dependencies if dependency["platformId"] == platform_id.value
|
|
||||||
]
|
|
||||||
if len(runtime_dependencies) != 1:
|
|
||||||
raise RuntimeError(f"Could not find a suitable clojure-lsp runtime dependency for platform {platform_id.value}.")
|
|
||||||
dependency = runtime_dependencies[0]
|
|
||||||
|
|
||||||
clojurelsp_ls_dir = os.path.join(os.path.dirname(__file__), "static", "clojure-lsp")
|
clojurelsp_ls_dir = os.path.join(os.path.dirname(__file__), "static", "clojure-lsp")
|
||||||
clojurelsp_executable_path = os.path.join(clojurelsp_ls_dir, dependency["binaryName"])
|
clojurelsp_executable_path = deps.binary_path(clojurelsp_ls_dir)
|
||||||
if not os.path.exists(clojurelsp_executable_path):
|
if not os.path.exists(clojurelsp_executable_path):
|
||||||
os.makedirs(clojurelsp_ls_dir, exist_ok=True)
|
os.makedirs(clojurelsp_ls_dir, exist_ok=True)
|
||||||
logger.log(f"Downloading and extracting clojure-lsp from {dependency['url']} to {clojurelsp_ls_dir}", logging.INFO)
|
logger.log(
|
||||||
FileUtils.download_and_extract_archive(logger, dependency["url"], clojurelsp_ls_dir, dependency["archiveType"])
|
f"Downloading and extracting clojure-lsp from {dependency.url} to {clojurelsp_ls_dir}",
|
||||||
|
logging.INFO,
|
||||||
|
)
|
||||||
|
deps.install(logger, clojurelsp_ls_dir)
|
||||||
if not os.path.exists(clojurelsp_executable_path):
|
if not os.path.exists(clojurelsp_executable_path):
|
||||||
raise FileNotFoundError(f"Download failed? Could not find clojure-lsp executable at {clojurelsp_executable_path}")
|
raise FileNotFoundError(f"Download failed? Could not find clojure-lsp executable at {clojurelsp_executable_path}")
|
||||||
os.chmod(clojurelsp_executable_path, stat.S_IEXEC)
|
os.chmod(clojurelsp_executable_path, stat.S_IEXEC)
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Sequence, Dict
|
||||||
|
|
||||||
|
from solidlsp.ls_logger import LanguageServerLogger
|
||||||
|
from solidlsp.ls_utils import FileUtils, PlatformUtils
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(kw_only=True)
|
||||||
|
class RuntimeDependency:
|
||||||
|
"""Represents a runtime dependency for a language server."""
|
||||||
|
|
||||||
|
id: str
|
||||||
|
platform_id: str | None = None
|
||||||
|
url: str | None = None
|
||||||
|
archive_type: str | None = None
|
||||||
|
binary_name: str | None = None
|
||||||
|
command: str | None = None
|
||||||
|
package_name: str | None = None
|
||||||
|
package_version: str | None = None
|
||||||
|
extract_path: str | None = None
|
||||||
|
description: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class RuntimeDependencyCollection:
|
||||||
|
"""Utility to handle installation of runtime dependencies."""
|
||||||
|
|
||||||
|
def __init__(self, dependencies: Sequence[RuntimeDependency]):
|
||||||
|
self._dependencies = list(dependencies)
|
||||||
|
|
||||||
|
def for_platform(self, platform_id: str) -> list[RuntimeDependency]:
|
||||||
|
return [
|
||||||
|
d
|
||||||
|
for d in self._dependencies
|
||||||
|
if d.platform_id in (platform_id, "any", "platform-agnostic", None)
|
||||||
|
]
|
||||||
|
|
||||||
|
def for_current_platform(self) -> list[RuntimeDependency]:
|
||||||
|
return self.for_platform(PlatformUtils.get_platform_id().value)
|
||||||
|
|
||||||
|
def single_for_current_platform(self) -> RuntimeDependency:
|
||||||
|
deps = self.for_current_platform()
|
||||||
|
if len(deps) != 1:
|
||||||
|
raise RuntimeError(
|
||||||
|
f"Expected exactly one runtime dependency for {PlatformUtils.get_platform_id().value}, found {len(deps)}"
|
||||||
|
)
|
||||||
|
return deps[0]
|
||||||
|
|
||||||
|
def binary_path(self, target_dir: str) -> str:
|
||||||
|
dep = self.single_for_current_platform()
|
||||||
|
if not dep.binary_name:
|
||||||
|
return target_dir
|
||||||
|
return os.path.join(target_dir, dep.binary_name)
|
||||||
|
|
||||||
|
def install(self, logger: LanguageServerLogger, target_dir: str) -> Dict[str, str]:
|
||||||
|
"""Install all dependencies for the current platform into *target_dir*.
|
||||||
|
|
||||||
|
Returns a mapping from dependency id to the resolved binary path.
|
||||||
|
"""
|
||||||
|
os.makedirs(target_dir, exist_ok=True)
|
||||||
|
results: Dict[str, str] = {}
|
||||||
|
for dep in self.for_current_platform():
|
||||||
|
if dep.url:
|
||||||
|
self._install_from_url(dep, logger, target_dir)
|
||||||
|
if dep.command:
|
||||||
|
self._run_command(dep.command, target_dir)
|
||||||
|
if dep.binary_name:
|
||||||
|
results[dep.id] = os.path.join(target_dir, dep.binary_name)
|
||||||
|
else:
|
||||||
|
results[dep.id] = target_dir
|
||||||
|
return results
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _run_command(command: str, cwd: str) -> None:
|
||||||
|
if PlatformUtils.get_platform_id().value.startswith("win"):
|
||||||
|
subprocess.run(
|
||||||
|
command,
|
||||||
|
shell=True,
|
||||||
|
check=True,
|
||||||
|
cwd=cwd,
|
||||||
|
stdout=subprocess.DEVNULL,
|
||||||
|
stderr=subprocess.DEVNULL,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
import pwd
|
||||||
|
|
||||||
|
user = pwd.getpwuid(os.getuid()).pw_name
|
||||||
|
subprocess.run(
|
||||||
|
command,
|
||||||
|
shell=True,
|
||||||
|
check=True,
|
||||||
|
user=user,
|
||||||
|
cwd=cwd,
|
||||||
|
stdout=subprocess.DEVNULL,
|
||||||
|
stderr=subprocess.DEVNULL,
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _install_from_url(dep: RuntimeDependency, logger: LanguageServerLogger, target_dir: str) -> None:
|
||||||
|
if dep.archive_type == "gz" and dep.binary_name:
|
||||||
|
dest = os.path.join(target_dir, dep.binary_name)
|
||||||
|
FileUtils.download_and_extract_archive(logger, dep.url, dest, dep.archive_type)
|
||||||
|
else:
|
||||||
|
FileUtils.download_and_extract_archive(logger, dep.url, target_dir, dep.archive_type or "zip")
|
||||||
@@ -13,10 +13,11 @@ import tarfile
|
|||||||
import threading
|
import threading
|
||||||
import urllib.request
|
import urllib.request
|
||||||
import zipfile
|
import zipfile
|
||||||
from dataclasses import dataclass
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
|
||||||
|
from .common import RuntimeDependency
|
||||||
|
|
||||||
from overrides import override
|
from overrides import override
|
||||||
|
|
||||||
from solidlsp.ls import SolidLanguageServer
|
from solidlsp.ls import SolidLanguageServer
|
||||||
@@ -28,21 +29,6 @@ from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
|
|||||||
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
||||||
|
|
||||||
|
|
||||||
@dataclass(kw_only=True)
|
|
||||||
class RuntimeDependency:
|
|
||||||
"""Represents a runtime dependency for the C# language server."""
|
|
||||||
|
|
||||||
id: str
|
|
||||||
description: str | None
|
|
||||||
platform_id: str
|
|
||||||
archive_type: str
|
|
||||||
binary_name: str
|
|
||||||
package_name: str | None = None
|
|
||||||
package_version: str | None = None
|
|
||||||
extract_path: str | None = None
|
|
||||||
url: str | None = None
|
|
||||||
|
|
||||||
|
|
||||||
# Runtime dependencies configuration
|
# Runtime dependencies configuration
|
||||||
RUNTIME_DEPENDENCIES = [
|
RUNTIME_DEPENDENCIES = [
|
||||||
RuntimeDependency(
|
RuntimeDependency(
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import stat
|
|||||||
from solidlsp.ls import SolidLanguageServer
|
from solidlsp.ls import SolidLanguageServer
|
||||||
from solidlsp.ls_logger import LanguageServerLogger
|
from solidlsp.ls_logger import LanguageServerLogger
|
||||||
from solidlsp.ls_utils import FileUtils, PlatformUtils
|
from solidlsp.ls_utils import FileUtils, PlatformUtils
|
||||||
|
from .common import RuntimeDependency, RuntimeDependencyCollection
|
||||||
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
||||||
|
|
||||||
|
|
||||||
@@ -31,60 +32,57 @@ class DartLanguageServer(SolidLanguageServer):
|
|||||||
def _setup_runtime_dependencies(cls, logger: "LanguageServerLogger") -> str:
|
def _setup_runtime_dependencies(cls, logger: "LanguageServerLogger") -> str:
|
||||||
platform_id = PlatformUtils.get_platform_id()
|
platform_id = PlatformUtils.get_platform_id()
|
||||||
|
|
||||||
runtime_dependencies = [
|
deps = RuntimeDependencyCollection(
|
||||||
{
|
[
|
||||||
"id": "DartLanguageServer",
|
RuntimeDependency(
|
||||||
"description": "Dart Language Server for Linux (x64)",
|
id="DartLanguageServer",
|
||||||
"url": "https://storage.googleapis.com/dart-archive/channels/stable/release/3.7.1/sdk/dartsdk-linux-x64-release.zip",
|
description="Dart Language Server for Linux (x64)",
|
||||||
"platformId": "linux-x64",
|
url="https://storage.googleapis.com/dart-archive/channels/stable/release/3.7.1/sdk/dartsdk-linux-x64-release.zip",
|
||||||
"archiveType": "zip",
|
platform_id="linux-x64",
|
||||||
"binaryName": "dart-sdk/bin/dart",
|
archive_type="zip",
|
||||||
},
|
binary_name="dart-sdk/bin/dart",
|
||||||
{
|
),
|
||||||
"id": "DartLanguageServer",
|
RuntimeDependency(
|
||||||
"description": "Dart Language Server for Windows (x64)",
|
id="DartLanguageServer",
|
||||||
"url": "https://storage.googleapis.com/dart-archive/channels/stable/release/3.7.1/sdk/dartsdk-windows-x64-release.zip",
|
description="Dart Language Server for Windows (x64)",
|
||||||
"platformId": "win-x64",
|
url="https://storage.googleapis.com/dart-archive/channels/stable/release/3.7.1/sdk/dartsdk-windows-x64-release.zip",
|
||||||
"archiveType": "zip",
|
platform_id="win-x64",
|
||||||
"binaryName": "dart-sdk/bin/dart.exe",
|
archive_type="zip",
|
||||||
},
|
binary_name="dart-sdk/bin/dart.exe",
|
||||||
{
|
),
|
||||||
"id": "DartLanguageServer",
|
RuntimeDependency(
|
||||||
"description": "Dart Language Server for Windows (arm64)",
|
id="DartLanguageServer",
|
||||||
"url": "https://storage.googleapis.com/dart-archive/channels/stable/release/3.7.1/sdk/dartsdk-windows-arm64-release.zip",
|
description="Dart Language Server for Windows (arm64)",
|
||||||
"platformId": "win-arm64",
|
url="https://storage.googleapis.com/dart-archive/channels/stable/release/3.7.1/sdk/dartsdk-windows-arm64-release.zip",
|
||||||
"archiveType": "zip",
|
platform_id="win-arm64",
|
||||||
"binaryName": "dart-sdk/bin/dart.exe",
|
archive_type="zip",
|
||||||
},
|
binary_name="dart-sdk/bin/dart.exe",
|
||||||
{
|
),
|
||||||
"id": "DartLanguageServer",
|
RuntimeDependency(
|
||||||
"description": "Dart Language Server for macOS (x64)",
|
id="DartLanguageServer",
|
||||||
"url": "https://storage.googleapis.com/dart-archive/channels/stable/release/3.7.1/sdk/dartsdk-macos-x64-release.zip",
|
description="Dart Language Server for macOS (x64)",
|
||||||
"platformId": "osx-x64",
|
url="https://storage.googleapis.com/dart-archive/channels/stable/release/3.7.1/sdk/dartsdk-macos-x64-release.zip",
|
||||||
"archiveType": "zip",
|
platform_id="osx-x64",
|
||||||
"binaryName": "dart-sdk/bin/dart",
|
archive_type="zip",
|
||||||
},
|
binary_name="dart-sdk/bin/dart",
|
||||||
{
|
),
|
||||||
"id": "DartLanguageServer",
|
RuntimeDependency(
|
||||||
"description": "Dart Language Server for macOS (arm64)",
|
id="DartLanguageServer",
|
||||||
"url": "https://storage.googleapis.com/dart-archive/channels/stable/release/3.7.1/sdk/dartsdk-macos-arm64-release.zip",
|
description="Dart Language Server for macOS (arm64)",
|
||||||
"platformId": "osx-arm64",
|
url="https://storage.googleapis.com/dart-archive/channels/stable/release/3.7.1/sdk/dartsdk-macos-arm64-release.zip",
|
||||||
"archiveType": "zip",
|
platform_id="osx-arm64",
|
||||||
"binaryName": "dart-sdk/bin/dart",
|
archive_type="zip",
|
||||||
},
|
binary_name="dart-sdk/bin/dart",
|
||||||
]
|
),
|
||||||
|
]
|
||||||
runtime_dependencies = [dependency for dependency in runtime_dependencies if dependency["platformId"] == platform_id.value]
|
)
|
||||||
|
|
||||||
assert len(runtime_dependencies) == 1
|
|
||||||
dependency = runtime_dependencies[0]
|
|
||||||
|
|
||||||
dart_ls_dir = cls.ls_resources_dir()
|
dart_ls_dir = cls.ls_resources_dir()
|
||||||
dart_executable_path = os.path.join(dart_ls_dir, dependency["binaryName"])
|
dart_executable_path = deps.binary_path(dart_ls_dir)
|
||||||
|
|
||||||
if not os.path.exists(dart_ls_dir):
|
if not os.path.exists(dart_ls_dir):
|
||||||
os.makedirs(dart_ls_dir)
|
os.makedirs(dart_ls_dir)
|
||||||
FileUtils.download_and_extract_archive(logger, dependency["url"], dart_ls_dir, dependency["archiveType"])
|
deps.install(logger, dart_ls_dir)
|
||||||
|
|
||||||
assert os.path.exists(dart_executable_path)
|
assert os.path.exists(dart_executable_path)
|
||||||
os.chmod(dart_executable_path, stat.S_IEXEC)
|
os.chmod(dart_executable_path, stat.S_IEXEC)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from solidlsp.ls import SolidLanguageServer
|
|||||||
from solidlsp.ls_config import LanguageServerConfig
|
from solidlsp.ls_config import LanguageServerConfig
|
||||||
from solidlsp.ls_logger import LanguageServerLogger
|
from solidlsp.ls_logger import LanguageServerLogger
|
||||||
from solidlsp.ls_utils import PlatformId, PlatformUtils
|
from solidlsp.ls_utils import PlatformId, PlatformUtils
|
||||||
|
from .common import RuntimeDependency, RuntimeDependencyCollection
|
||||||
from solidlsp.lsp_protocol_handler.lsp_types import DefinitionParams, InitializeParams
|
from solidlsp.lsp_protocol_handler.lsp_types import DefinitionParams, InitializeParams
|
||||||
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
||||||
|
|
||||||
@@ -61,32 +62,16 @@ class Intelephense(SolidLanguageServer):
|
|||||||
os.makedirs(intelephense_ls_dir, exist_ok=True)
|
os.makedirs(intelephense_ls_dir, exist_ok=True)
|
||||||
intelephense_executable_path = os.path.join(intelephense_ls_dir, "node_modules", ".bin", "intelephense")
|
intelephense_executable_path = os.path.join(intelephense_ls_dir, "node_modules", ".bin", "intelephense")
|
||||||
if not os.path.exists(intelephense_executable_path):
|
if not os.path.exists(intelephense_executable_path):
|
||||||
install_command = "npm install --prefix ./ intelephense@1.14.4"
|
deps = RuntimeDependencyCollection(
|
||||||
is_windows = PlatformUtils.get_platform_id().value.startswith("win")
|
[
|
||||||
# Windows doesn't support the 'user' parameter and doesn't have pwd module
|
RuntimeDependency(
|
||||||
if is_windows:
|
id="intelephense",
|
||||||
subprocess.run(
|
command="npm install --prefix ./ intelephense@1.14.4",
|
||||||
install_command,
|
platform_id="any",
|
||||||
shell=True,
|
)
|
||||||
check=True,
|
]
|
||||||
cwd=intelephense_ls_dir,
|
)
|
||||||
stdout=subprocess.DEVNULL,
|
deps.install(logger, intelephense_ls_dir)
|
||||||
stderr=subprocess.DEVNULL,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# On Unix-like systems, run as non-root user
|
|
||||||
import pwd
|
|
||||||
|
|
||||||
user = pwd.getpwuid(os.getuid()).pw_name
|
|
||||||
subprocess.run(
|
|
||||||
install_command,
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
user=user,
|
|
||||||
cwd=intelephense_ls_dir,
|
|
||||||
stdout=subprocess.DEVNULL,
|
|
||||||
stderr=subprocess.DEVNULL,
|
|
||||||
)
|
|
||||||
|
|
||||||
assert os.path.exists(
|
assert os.path.exists(
|
||||||
intelephense_executable_path
|
intelephense_executable_path
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ from solidlsp.ls import SolidLanguageServer
|
|||||||
from solidlsp.ls_config import LanguageServerConfig
|
from solidlsp.ls_config import LanguageServerConfig
|
||||||
from solidlsp.ls_logger import LanguageServerLogger
|
from solidlsp.ls_logger import LanguageServerLogger
|
||||||
from solidlsp.ls_utils import FileUtils, PlatformUtils
|
from solidlsp.ls_utils import FileUtils, PlatformUtils
|
||||||
|
from .common import RuntimeDependency, RuntimeDependencyCollection
|
||||||
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
|
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
|
||||||
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
||||||
|
|
||||||
@@ -51,50 +52,47 @@ class RustAnalyzer(SolidLanguageServer):
|
|||||||
"""
|
"""
|
||||||
platform_id = PlatformUtils.get_platform_id()
|
platform_id = PlatformUtils.get_platform_id()
|
||||||
|
|
||||||
runtime_dependencies = [
|
deps = RuntimeDependencyCollection(
|
||||||
{
|
[
|
||||||
"id": "RustAnalyzer",
|
RuntimeDependency(
|
||||||
"description": "RustAnalyzer for Linux (x64)",
|
id="RustAnalyzer",
|
||||||
"url": "https://github.com/rust-lang/rust-analyzer/releases/download/2023-10-09/rust-analyzer-aarch64-apple-darwin.gz",
|
description="RustAnalyzer for macOS (arm64)",
|
||||||
"platformId": "osx-arm64",
|
url="https://github.com/rust-lang/rust-analyzer/releases/download/2023-10-09/rust-analyzer-aarch64-apple-darwin.gz",
|
||||||
"archiveType": "gz",
|
platform_id="osx-arm64",
|
||||||
"binaryName": "rust_analyzer",
|
archive_type="gz",
|
||||||
},
|
binary_name="rust_analyzer",
|
||||||
{
|
),
|
||||||
"id": "RustAnalyzer",
|
RuntimeDependency(
|
||||||
"description": "RustAnalyzer for Linux (x64)",
|
id="RustAnalyzer",
|
||||||
"url": "https://github.com/rust-lang/rust-analyzer/releases/download/2023-10-09/rust-analyzer-x86_64-unknown-linux-gnu.gz",
|
description="RustAnalyzer for Linux (x64)",
|
||||||
"platformId": "linux-x64",
|
url="https://github.com/rust-lang/rust-analyzer/releases/download/2023-10-09/rust-analyzer-x86_64-unknown-linux-gnu.gz",
|
||||||
"archiveType": "gz",
|
platform_id="linux-x64",
|
||||||
"binaryName": "rust_analyzer",
|
archive_type="gz",
|
||||||
},
|
binary_name="rust_analyzer",
|
||||||
{
|
),
|
||||||
"id": "RustAnalyzer",
|
RuntimeDependency(
|
||||||
"description": "RustAnalyzer for Windows (x64)",
|
id="RustAnalyzer",
|
||||||
"url": "https://github.com/rust-lang/rust-analyzer/releases/download/2023-10-09/rust-analyzer-x86_64-pc-windows-msvc.zip",
|
description="RustAnalyzer for Windows (x64)",
|
||||||
"platformId": "win-x64",
|
url="https://github.com/rust-lang/rust-analyzer/releases/download/2023-10-09/rust-analyzer-x86_64-pc-windows-msvc.zip",
|
||||||
"archiveType": "zip",
|
platform_id="win-x64",
|
||||||
"binaryName": "rust-analyzer.exe",
|
archive_type="zip",
|
||||||
},
|
binary_name="rust-analyzer.exe",
|
||||||
]
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# assert platform_id.value in [
|
# assert platform_id.value in [
|
||||||
# "linux-x64",
|
# "linux-x64",
|
||||||
# "win-x64",
|
# "win-x64",
|
||||||
# ], "Only linux-x64 and win-x64 platform is supported for in multilspy at the moment"
|
# ], "Only linux-x64 and win-x64 platform is supported for in multilspy at the moment"
|
||||||
|
|
||||||
runtime_dependencies = [dependency for dependency in runtime_dependencies if dependency["platformId"] == platform_id.value]
|
dependency = deps.single_for_current_platform()
|
||||||
assert len(runtime_dependencies) == 1
|
|
||||||
dependency = runtime_dependencies[0]
|
|
||||||
|
|
||||||
rustanalyzer_ls_dir = os.path.join(cls.ls_resources_dir(), "RustAnalyzer")
|
rustanalyzer_ls_dir = os.path.join(cls.ls_resources_dir(), "RustAnalyzer")
|
||||||
rustanalyzer_executable_path = os.path.join(rustanalyzer_ls_dir, dependency["binaryName"])
|
rustanalyzer_executable_path = deps.binary_path(rustanalyzer_ls_dir)
|
||||||
if not os.path.exists(rustanalyzer_ls_dir):
|
if not os.path.exists(rustanalyzer_ls_dir):
|
||||||
os.makedirs(rustanalyzer_ls_dir)
|
os.makedirs(rustanalyzer_ls_dir)
|
||||||
if dependency["archiveType"] == "gz":
|
deps.install(logger, rustanalyzer_ls_dir)
|
||||||
FileUtils.download_and_extract_archive(logger, dependency["url"], rustanalyzer_executable_path, dependency["archiveType"])
|
|
||||||
else:
|
|
||||||
FileUtils.download_and_extract_archive(logger, dependency["url"], rustanalyzer_ls_dir, dependency["archiveType"])
|
|
||||||
assert os.path.exists(rustanalyzer_executable_path)
|
assert os.path.exists(rustanalyzer_executable_path)
|
||||||
os.chmod(rustanalyzer_executable_path, stat.S_IEXEC)
|
os.chmod(rustanalyzer_executable_path, stat.S_IEXEC)
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from solidlsp.ls import SolidLanguageServer
|
|||||||
from solidlsp.ls_config import LanguageServerConfig
|
from solidlsp.ls_config import LanguageServerConfig
|
||||||
from solidlsp.ls_logger import LanguageServerLogger
|
from solidlsp.ls_logger import LanguageServerLogger
|
||||||
from solidlsp.ls_utils import FileUtils, PathUtils, PlatformUtils
|
from solidlsp.ls_utils import FileUtils, PathUtils, PlatformUtils
|
||||||
|
from .common import RuntimeDependency, RuntimeDependencyCollection
|
||||||
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
|
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
|
||||||
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
||||||
|
|
||||||
@@ -62,50 +63,48 @@ class TerraformLS(SolidLanguageServer):
|
|||||||
"""
|
"""
|
||||||
cls._ensure_tf_command_available(logger)
|
cls._ensure_tf_command_available(logger)
|
||||||
platform_id = PlatformUtils.get_platform_id()
|
platform_id = PlatformUtils.get_platform_id()
|
||||||
runtime_dependencies = [
|
deps = RuntimeDependencyCollection(
|
||||||
{
|
[
|
||||||
"id": "TerraformLS",
|
RuntimeDependency(
|
||||||
"description": "terraform-ls for macOS (ARM64)",
|
id="TerraformLS",
|
||||||
"url": "https://releases.hashicorp.com/terraform-ls/0.36.5/terraform-ls_0.36.5_darwin_arm64.zip",
|
description="terraform-ls for macOS (ARM64)",
|
||||||
"platformId": "osx-arm64",
|
url="https://releases.hashicorp.com/terraform-ls/0.36.5/terraform-ls_0.36.5_darwin_arm64.zip",
|
||||||
"archiveType": "zip",
|
platform_id="osx-arm64",
|
||||||
"binaryName": "terraform-ls",
|
archive_type="zip",
|
||||||
},
|
binary_name="terraform-ls",
|
||||||
{
|
),
|
||||||
"id": "TerraformLS",
|
RuntimeDependency(
|
||||||
"description": "terraform-ls for macOS (x64)",
|
id="TerraformLS",
|
||||||
"url": "https://releases.hashicorp.com/terraform-ls/0.36.5/terraform-ls_0.36.5_darwin_amd64.zip",
|
description="terraform-ls for macOS (x64)",
|
||||||
"platformId": "osx-x64",
|
url="https://releases.hashicorp.com/terraform-ls/0.36.5/terraform-ls_0.36.5_darwin_amd64.zip",
|
||||||
"archiveType": "zip",
|
platform_id="osx-x64",
|
||||||
"binaryName": "terraform-ls",
|
archive_type="zip",
|
||||||
},
|
binary_name="terraform-ls",
|
||||||
{
|
),
|
||||||
"id": "TerraformLS",
|
RuntimeDependency(
|
||||||
"description": "terraform-ls for Linux (x64)",
|
id="TerraformLS",
|
||||||
"url": "https://releases.hashicorp.com/terraform-ls/0.36.5/terraform-ls_0.36.5_linux_amd64.zip",
|
description="terraform-ls for Linux (x64)",
|
||||||
"platformId": "linux-x64",
|
url="https://releases.hashicorp.com/terraform-ls/0.36.5/terraform-ls_0.36.5_linux_amd64.zip",
|
||||||
"archiveType": "zip",
|
platform_id="linux-x64",
|
||||||
"binaryName": "terraform-ls",
|
archive_type="zip",
|
||||||
},
|
binary_name="terraform-ls",
|
||||||
{
|
),
|
||||||
"id": "TerraformLS",
|
RuntimeDependency(
|
||||||
"description": "terraform-ls for Windows (x64)",
|
id="TerraformLS",
|
||||||
"url": "https://releases.hashicorp.com/terraform-ls/0.36.5/terraform-ls_0.36.5_windows_amd64.zip",
|
description="terraform-ls for Windows (x64)",
|
||||||
"platformId": "win-x64",
|
url="https://releases.hashicorp.com/terraform-ls/0.36.5/terraform-ls_0.36.5_windows_amd64.zip",
|
||||||
"archiveType": "zip",
|
platform_id="win-x64",
|
||||||
"binaryName": "terraform-ls.exe",
|
archive_type="zip",
|
||||||
},
|
binary_name="terraform-ls.exe",
|
||||||
]
|
),
|
||||||
runtime_dependencies = [dependency for dependency in runtime_dependencies if dependency["platformId"] == platform_id.value]
|
]
|
||||||
assert (
|
)
|
||||||
len(runtime_dependencies) == 1
|
dependency = deps.single_for_current_platform()
|
||||||
), f"Expected exactly one runtime dependency for platform {platform_id.value}, found {len(runtime_dependencies)}"
|
|
||||||
dependency = runtime_dependencies[0]
|
|
||||||
|
|
||||||
terraform_ls_executable_path = os.path.join(cls.ls_resources_dir(), dependency["binaryName"])
|
terraform_ls_executable_path = deps.binary_path(cls.ls_resources_dir())
|
||||||
if not os.path.exists(terraform_ls_executable_path):
|
if not os.path.exists(terraform_ls_executable_path):
|
||||||
logger.log(f"Downloading terraform-ls from {dependency['url']}", logging.INFO)
|
logger.log(f"Downloading terraform-ls from {dependency.url}", logging.INFO)
|
||||||
FileUtils.download_and_extract_archive(logger, dependency["url"], cls.ls_resources_dir(), dependency["archiveType"])
|
deps.install(logger, cls.ls_resources_dir())
|
||||||
|
|
||||||
assert os.path.exists(terraform_ls_executable_path), f"terraform-ls executable not found at {terraform_ls_executable_path}"
|
assert os.path.exists(terraform_ls_executable_path), f"terraform-ls executable not found at {terraform_ls_executable_path}"
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ from solidlsp.ls import SolidLanguageServer
|
|||||||
from solidlsp.ls_config import LanguageServerConfig
|
from solidlsp.ls_config import LanguageServerConfig
|
||||||
from solidlsp.ls_logger import LanguageServerLogger
|
from solidlsp.ls_logger import LanguageServerLogger
|
||||||
from solidlsp.ls_utils import PlatformId, PlatformUtils
|
from solidlsp.ls_utils import PlatformId, PlatformUtils
|
||||||
|
from .common import RuntimeDependency, RuntimeDependencyCollection
|
||||||
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
|
from solidlsp.lsp_protocol_handler.lsp_types import InitializeParams
|
||||||
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
from solidlsp.lsp_protocol_handler.server import ProcessLaunchInfo
|
||||||
|
|
||||||
@@ -82,18 +83,22 @@ class TypeScriptLanguageServer(SolidLanguageServer):
|
|||||||
]
|
]
|
||||||
assert platform_id in valid_platforms, f"Platform {platform_id} is not supported for multilspy javascript/typescript at the moment"
|
assert platform_id in valid_platforms, f"Platform {platform_id} is not supported for multilspy javascript/typescript at the moment"
|
||||||
|
|
||||||
runtime_dependencies = [
|
deps = RuntimeDependencyCollection(
|
||||||
{
|
[
|
||||||
"id": "typescript",
|
RuntimeDependency(
|
||||||
"description": "typescript package for Linux, OSX, and Windows. Both x64 and arm64 are supported.",
|
id="typescript",
|
||||||
"command": "npm install --prefix ./ typescript@5.5.4",
|
description="typescript package",
|
||||||
},
|
command="npm install --prefix ./ typescript@5.5.4",
|
||||||
{
|
platform_id="any",
|
||||||
"id": "typescript-language-server",
|
),
|
||||||
"description": "typescript-language-server package for Linux, OSX, and Windows. Both x64 and arm64 are supported.",
|
RuntimeDependency(
|
||||||
"command": "npm install --prefix ./ typescript-language-server@4.3.3",
|
id="typescript-language-server",
|
||||||
},
|
description="typescript-language-server package",
|
||||||
]
|
command="npm install --prefix ./ typescript-language-server@4.3.3",
|
||||||
|
platform_id="any",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
tsserver_ls_dir = os.path.join(cls.ls_resources_dir(), "ts-lsp")
|
tsserver_ls_dir = os.path.join(cls.ls_resources_dir(), "ts-lsp")
|
||||||
tsserver_executable_path = os.path.join(tsserver_ls_dir, "typescript-language-server")
|
tsserver_executable_path = os.path.join(tsserver_ls_dir, "typescript-language-server")
|
||||||
|
|
||||||
@@ -106,29 +111,7 @@ class TypeScriptLanguageServer(SolidLanguageServer):
|
|||||||
# Install typescript and typescript-language-server if not already installed
|
# Install typescript and typescript-language-server if not already installed
|
||||||
if not os.path.exists(tsserver_ls_dir):
|
if not os.path.exists(tsserver_ls_dir):
|
||||||
os.makedirs(tsserver_ls_dir, exist_ok=True)
|
os.makedirs(tsserver_ls_dir, exist_ok=True)
|
||||||
for dependency in runtime_dependencies:
|
deps.install(logger, tsserver_ls_dir)
|
||||||
# Windows doesn't support the 'user' parameter and doesn't have pwd module
|
|
||||||
if PlatformUtils.get_platform_id().value.startswith("win"):
|
|
||||||
subprocess.run(
|
|
||||||
dependency["command"],
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
cwd=tsserver_ls_dir,
|
|
||||||
stdout=subprocess.DEVNULL,
|
|
||||||
stderr=subprocess.DEVNULL,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# On Unix-like systems, run as non-root user
|
|
||||||
user = pwd.getpwuid(os.getuid()).pw_name
|
|
||||||
subprocess.run(
|
|
||||||
dependency["command"],
|
|
||||||
shell=True,
|
|
||||||
check=True,
|
|
||||||
user=user,
|
|
||||||
cwd=tsserver_ls_dir,
|
|
||||||
stdout=subprocess.DEVNULL,
|
|
||||||
stderr=subprocess.DEVNULL,
|
|
||||||
)
|
|
||||||
|
|
||||||
tsserver_executable_path = os.path.join(tsserver_ls_dir, "node_modules", ".bin", "typescript-language-server")
|
tsserver_executable_path = os.path.join(tsserver_ls_dir, "node_modules", ".bin", "typescript-language-server")
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user