mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-11 03:13:51 +00:00
Merge pull request #1617 from Lauritz-Timm/fix/windows-csharp-startup-install
Fix Windows C# startup and Roslyn install
This commit is contained in:
4 files changed
+82
-6
No files matched your search
@@ -6,6 +6,7 @@ import logging
|
||||
import os
|
||||
import platform
|
||||
import shutil
|
||||
import tempfile
|
||||
import threading
|
||||
from collections.abc import Hashable, Iterable
|
||||
from dataclasses import replace
|
||||
@@ -34,6 +35,8 @@ log = logging.getLogger(__name__)
|
||||
|
||||
NUGET_ALLOWED_HOSTS = ("www.nuget.org", "nuget.org", "globalcdn.nuget.org")
|
||||
DEFAULT_CSHARP_LANGUAGE_SERVER_VERSION = "5.5.0-2.26078.4"
|
||||
WINDOWS_MAX_PATH = 260
|
||||
ROSLYN_LONGEST_KNOWN_PACKAGE_MEMBER = "Microsoft.CodeAnalysis.ExternalAccess.CompilerDeveloperSDK.dll"
|
||||
|
||||
_RUNTIME_DEPENDENCIES = [
|
||||
RuntimeDependency(
|
||||
@@ -460,12 +463,15 @@ class CSharpLanguageServer(SolidLanguageServer):
|
||||
if url is None:
|
||||
raise SolidLSPException(f"No URL specified for package {package_name} version {package_version}")
|
||||
|
||||
temp_dir = Path(self._ls_resources_dir) / "temp_downloads"
|
||||
temp_dir.mkdir(parents=True, exist_ok=True)
|
||||
package_extract_dir = Path(self._ls_resources_dir) / "temp_downloads" / f"{package_name}.{package_version}"
|
||||
projected_path = package_extract_dir / (dependency.extract_path or "") / ROSLYN_LONGEST_KNOWN_PACKAGE_MEMBER
|
||||
if platform.system() == "Windows" and len(str(projected_path)) >= WINDOWS_MAX_PATH:
|
||||
log.warning("Using a short temporary directory for Roslyn package extraction because the configured cache path is too deep")
|
||||
package_extract_dir = Path(tempfile.mkdtemp(prefix="serena-roslyn-")) / package_extract_dir.name
|
||||
package_extract_dir.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
try:
|
||||
log.debug(f"Downloading package from: {url}")
|
||||
package_extract_dir = temp_dir / f"{package_name}.{package_version}"
|
||||
FileUtils.download_and_extract_archive_verified(
|
||||
url,
|
||||
str(package_extract_dir),
|
||||
|
||||
@@ -415,5 +415,10 @@ class OmniSharp(SolidLanguageServer):
|
||||
if "referencesProvider" in init_response["capabilities"] and init_response["capabilities"]["referencesProvider"]:
|
||||
self.references_available.set()
|
||||
|
||||
self.definition_available.wait()
|
||||
self.references_available.wait()
|
||||
missing_capabilities = [
|
||||
name
|
||||
for event, name in ((self.definition_available, "definition"), (self.references_available, "references"))
|
||||
if not event.is_set()
|
||||
]
|
||||
if missing_capabilities:
|
||||
log.warning("OmniSharp did not advertise capabilities during initialization: %s", ", ".join(missing_capabilities))
|
||||
@@ -7,7 +7,7 @@ from unittest.mock import patch
|
||||
import pytest
|
||||
|
||||
from solidlsp.language_servers.common import RuntimeDependency
|
||||
from solidlsp.language_servers.csharp_language_server import CSharpLanguageServer
|
||||
from solidlsp.language_servers.csharp_language_server import ROSLYN_LONGEST_KNOWN_PACKAGE_MEMBER, CSharpLanguageServer
|
||||
from solidlsp.settings import SolidLSPSettings
|
||||
|
||||
|
||||
@@ -128,3 +128,33 @@ class TestNuGetOrgDownload:
|
||||
"solidlsp.language_servers.csharp_language_server.FileUtils.download_and_extract_archive_verified",
|
||||
):
|
||||
dependency_provider._download_nuget_package(test_dependency)
|
||||
|
||||
def test_download_nuget_package_uses_short_extraction_path_for_deep_windows_cache(self, tmp_path: Path):
|
||||
provider = object.__new__(CSharpLanguageServer.DependencyProvider)
|
||||
provider._ls_resources_dir = str(tmp_path.joinpath(*(["nested-cache-root"] * 8)))
|
||||
|
||||
test_dependency = RuntimeDependency(
|
||||
id="TestPackage",
|
||||
package_name="roslyn-language-server.win-x64",
|
||||
package_version="5.5.0-2.26078.4",
|
||||
url="https://www.nuget.org/api/v2/package/roslyn-language-server.win-x64/5.5.0-2.26078.4",
|
||||
extract_path="tools/net10.0/win-x64",
|
||||
)
|
||||
|
||||
def fake_download_and_extract(
|
||||
_url: str,
|
||||
target_path: str,
|
||||
*_args: object,
|
||||
**_kwargs: object,
|
||||
) -> None:
|
||||
deepest_package_member = Path(target_path) / f"tools/net10.0/win-x64/{ROSLYN_LONGEST_KNOWN_PACKAGE_MEMBER}"
|
||||
assert len(str(deepest_package_member)) < 260
|
||||
|
||||
with (
|
||||
patch("solidlsp.language_servers.csharp_language_server.platform.system", return_value="Windows"),
|
||||
patch(
|
||||
"solidlsp.language_servers.csharp_language_server.FileUtils.download_and_extract_archive_verified",
|
||||
side_effect=fake_download_and_extract,
|
||||
),
|
||||
):
|
||||
provider._download_nuget_package(test_dependency)
|
||||
@@ -0,0 +1,35 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
from solidlsp.language_servers.omnisharp import OmniSharp
|
||||
|
||||
|
||||
class _NoWaitEvent:
|
||||
def is_set(self) -> bool:
|
||||
return False
|
||||
|
||||
def wait(self, timeout: float | None = None) -> bool:
|
||||
raise AssertionError("OmniSharp startup must not wait for dynamic capability registration")
|
||||
|
||||
|
||||
@pytest.mark.csharp
|
||||
def test_omnisharp_startup_does_not_wait_for_capability_registration(tmp_path: Path) -> None:
|
||||
omnisharp = OmniSharp.__new__(OmniSharp)
|
||||
omnisharp.repository_root_path = str(tmp_path)
|
||||
omnisharp.server = SimpleNamespace(
|
||||
send=SimpleNamespace(initialize=lambda _params: {"capabilities": {}}),
|
||||
notify=SimpleNamespace(initialized=lambda _params: None, workspace_did_change_configuration=lambda _params: None),
|
||||
on_request=lambda *_args: None,
|
||||
on_notification=lambda *_args: None,
|
||||
start=lambda: None,
|
||||
)
|
||||
omnisharp.server_ready = _NoWaitEvent()
|
||||
omnisharp.definition_available = _NoWaitEvent()
|
||||
omnisharp.references_available = _NoWaitEvent()
|
||||
omnisharp.completions_available = _NoWaitEvent()
|
||||
|
||||
omnisharp._start_server()
|
||||
Reference in new issue
Block a user