Skip to content

Commit

Permalink
lsp: Only attempt to parse the rootUri when it is set
Browse files Browse the repository at this point in the history
  • Loading branch information
alcarney committed Mar 7, 2024
1 parent b458428 commit 07b9824
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 14 deletions.
1 change: 1 addition & 0 deletions lib/esbonio/changes/718.fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The server will no longer raise a `ValueError` when used in a situation where there is an empty workspace
30 changes: 16 additions & 14 deletions lib/esbonio/esbonio/server/features/sphinx_manager/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,18 +141,23 @@ def _resolve_cwd(
if self.cwd:
return self.cwd

for folder_uri in workspace.folders.keys():
folder_uri = Uri.parse(folder_uri)
if folder_uri and str(uri).startswith(str(folder_uri)):
break
else:
folder_uri = Uri.parse(workspace.root_uri)

if folder_uri is None or (cwd := folder_uri.fs_path) is None:
logger.error("Unable to determine working directory from '%s'", folder_uri)
return None
candidates = [Uri.parse(f) for f in workspace.folders.keys()]

if workspace.root_uri is not None:
if (root_uri := Uri.parse(workspace.root_uri)) not in candidates:
candidates.append(root_uri)

for folder in candidates:
if str(uri).startswith(str(folder)):
if (cwd := folder.fs_path) is None:
logger.error(
"Unable to determine working directory from '%s'", folder
)
return None

return cwd
return cwd

return None

def _resolve_python_path(self, logger: logging.Logger) -> List[pathlib.Path]:
"""Return the list of paths to put on the sphinx agent's ``PYTHONPATH``
Expand All @@ -161,9 +166,6 @@ def _resolve_python_path(self, logger: logging.Logger) -> List[pathlib.Path]:
packages into the user's Python environment. This method will locate the
installation path of the sphinx agent and return it.
Additionally if the ``enable_dev_tools`` flag is set, this will attempt to
locate the ``lsp_devtools`` package
Parameters
----------
logger
Expand Down
161 changes: 161 additions & 0 deletions lib/esbonio/tests/server/features/test_sphinx_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import logging
import pathlib
from typing import Optional

import pytest
from lsprotocol.types import WorkspaceFolder
from pygls.workspace import Workspace

from esbonio.server import Uri
from esbonio.server.features.sphinx_manager import SphinxConfig

logger = logging.getLogger(__name__)


# Default values
CWD = "/path/to/workspace"
PYTHON_CMD = ["/bin/python"]
BUILD_CMD = ["sphinx-build", "-M", "html", "src", "dest"]
PYPATH = [pathlib.Path("/path/to/site-packages/esbonio")]


def mk_uri(path: str) -> str:
return str(Uri.for_file(path))


@pytest.mark.parametrize(
"uri, workspace, config, expected",
[
( # If no cwd is given, and there is no available workspace root the config
# should be considered invalid
"file:///path/to/file.rst",
Workspace(None),
SphinxConfig(
python_command=PYTHON_CMD,
build_command=BUILD_CMD,
python_path=PYPATH,
),
None,
),
( # If the workspace is empty, we should still be able to progress as long as
# the user provides a cwd
"file:///path/to/file.rst",
Workspace(None),
SphinxConfig(
python_command=PYTHON_CMD,
build_command=BUILD_CMD,
python_path=PYPATH,
cwd=CWD,
),
SphinxConfig(
python_command=PYTHON_CMD,
build_command=BUILD_CMD,
python_path=PYPATH,
cwd=CWD,
),
),
( # If only a ``root_uri`` is given use that.
"file:///path/to/workspace/file.rst",
Workspace(mk_uri(CWD)),
SphinxConfig(
python_command=PYTHON_CMD,
build_command=BUILD_CMD,
python_path=PYPATH,
),
SphinxConfig(
python_command=PYTHON_CMD,
build_command=BUILD_CMD,
python_path=PYPATH,
cwd=CWD,
),
),
( # Assuming that the requested uri resides within it.
"file:///path/to/other/workspace/file.rst",
Workspace(mk_uri(CWD)),
SphinxConfig(
python_command=PYTHON_CMD,
build_command=BUILD_CMD,
python_path=PYPATH,
),
None,
),
( # Otherwise, prefer workspace_folders.
"file:///path/to/workspace/file.rst",
Workspace(
"file:///path/to",
workspace_folders=[WorkspaceFolder(mk_uri(CWD), "workspace")],
),
SphinxConfig(
python_command=PYTHON_CMD,
build_command=BUILD_CMD,
python_path=PYPATH,
),
SphinxConfig(
python_command=PYTHON_CMD,
build_command=BUILD_CMD,
python_path=PYPATH,
cwd=CWD,
),
),
( # Handle multi-root scenarios.
"file:///path/to/workspace-b/file.rst",
Workspace(
"file:///path/to",
workspace_folders=[
WorkspaceFolder("file:///path/to/workspace-a", "workspace-a"),
WorkspaceFolder("file:///path/to/workspace-b", "workspace-b"),
],
),
SphinxConfig(
python_command=PYTHON_CMD,
build_command=BUILD_CMD,
python_path=PYPATH,
),
SphinxConfig(
python_command=PYTHON_CMD,
build_command=BUILD_CMD,
python_path=PYPATH,
cwd="/path/to/workspace-b",
),
),
( # Again, make sure the requested uri resides within the workspace.
"file:///path/for/workspace-c/file.rst",
Workspace(
"file:///path/to",
workspace_folders=[
WorkspaceFolder("file:///path/to/workspace-a", "workspace-a"),
WorkspaceFolder("file:///path/to/workspace-b", "workspace-b"),
],
),
SphinxConfig(
python_command=PYTHON_CMD,
build_command=BUILD_CMD,
python_path=PYPATH,
),
None,
),
],
)
def test_resolve(
uri: str,
workspace: Workspace,
config: SphinxConfig,
expected: Optional[SphinxConfig],
):
"""Ensure that we can resolve a user's configuration correctly.
Parameters
----------
uri
The uri the config should be resolved relative to
workspace
The workspace in which to resolve the configuration
config
The base configuration to resolve
expected
The expected outcome
"""
assert config.resolve(Uri.parse(uri), workspace, logger) == expected

0 comments on commit 07b9824

Please sign in to comment.