Skip to content

Commit

Permalink
lsp: Fix handling of paths relative to ~
Browse files Browse the repository at this point in the history
  • Loading branch information
alcarney committed Mar 20, 2022
1 parent 1702adc commit 853e7b9
Show file tree
Hide file tree
Showing 3 changed files with 223 additions and 3 deletions.
1 change: 1 addition & 0 deletions lib/esbonio/changes/342.fix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The language server should now correctly handle ``buildDir``, ``confDir`` and ``srcDir`` config values containing paths relative to ``~``
10 changes: 7 additions & 3 deletions lib/esbonio/esbonio/lsp/sphinx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,7 @@ def expand_conf_dir(root_dir: str, conf_dir: str) -> pathlib.Path:

match = PATH_VAR_PATTERN.match(conf_dir)
if not match or match.group(1) not in {"workspaceRoot", "workspaceFolder"}:
return pathlib.Path(conf_dir)
return pathlib.Path(conf_dir).expanduser()

conf = pathlib.Path(conf_dir).parts[1:]
return pathlib.Path(root_dir, *conf).resolve()
Expand Down Expand Up @@ -887,7 +887,7 @@ def get_src_dir(
src = pathlib.Path(src_dir).parts[1:]
return pathlib.Path(conf_dir, *src).resolve()

return pathlib.Path(src_dir)
return pathlib.Path(src_dir).expanduser()


def get_build_dir(
Expand Down Expand Up @@ -942,7 +942,11 @@ def get_build_dir(
build_uri = Uri.from_fs_path(config.build_dir)
build_dir = Uri.to_fs_path(build_uri)

return pathlib.Path(build_dir)
# But make sure paths starting with '~' are not corrupted
if build_dir.startswith("/~"):
build_dir = build_dir.replace("/~", "~")

return pathlib.Path(build_dir).expanduser()


cli = setup_cli("esbonio.lsp.sphinx", "Esbonio's Sphinx language server.")
Expand Down
215 changes: 215 additions & 0 deletions lib/esbonio/tests/test_sphinx.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,227 @@
from esbonio.lsp import create_language_server
from esbonio.lsp import ESBONIO_SERVER_PREVIEW
from esbonio.lsp.sphinx import DEFAULT_MODULES
from esbonio.lsp.sphinx import expand_conf_dir
from esbonio.lsp.sphinx import get_build_dir
from esbonio.lsp.sphinx import get_src_dir
from esbonio.lsp.sphinx import InitializationOptions
from esbonio.lsp.sphinx import SphinxConfig
from esbonio.lsp.sphinx import SphinxLanguageServer
from esbonio.lsp.testing import ClientServer


@py.test.mark.parametrize(
"setup, expected",
[
(
(
"/path/to/root",
"/path/to/config",
),
pathlib.Path("/path/to/config"),
),
(
(
"/path/to/root",
"~/path/to/config",
),
pathlib.Path("~/path/to/config").expanduser(),
),
(
(
"/path/to/root",
"${workspaceRoot}/config",
),
pathlib.Path("/path/to/root/config"),
),
(
(
"/path/to/root",
"${workspaceRoot}/../config",
),
pathlib.Path("/path/to/config"),
),
(
(
"/path/to/root",
"${workspaceFolder}/config",
),
pathlib.Path("/path/to/root/config"),
),
(
(
"/path/to/root",
"${workspaceFolder}/../config",
),
pathlib.Path("/path/to/config"),
),
],
)
def test_expand_conf_dir(setup, expected):
"""Ensure that the ``expand_conf_dir`` function works as expected."""

root_uri, conf_dir = setup

actual = expand_conf_dir(root_uri, conf_dir)
assert actual == expected


@py.test.mark.parametrize(
"setup, expected",
[
(
(
"file:///path/to/root",
pathlib.Path("/path/to/config"),
SphinxConfig(srcDir="/path/to/src"),
),
pathlib.Path("/path/to/src"),
),
(
(
"file:///path/to/root",
pathlib.Path("/path/to/config"),
SphinxConfig(srcDir="~/path/to/src"),
),
pathlib.Path("~/path/to/src").expanduser(),
),
(
(
"file:///path/to/root",
pathlib.Path("/path/to/config"),
SphinxConfig(srcDir="${workspaceRoot}/src"),
),
pathlib.Path("/path/to/root/src"),
),
(
(
"file:///path/to/root",
pathlib.Path("/path/to/config"),
SphinxConfig(srcDir="${workspaceRoot}/../src"),
),
pathlib.Path("/path/to/src"),
),
(
(
"file:///path/to/root",
pathlib.Path("/path/to/config"),
SphinxConfig(srcDir="${workspaceFolder}/src"),
),
pathlib.Path("/path/to/root/src"),
),
(
(
"file:///path/to/root",
pathlib.Path("/path/to/config"),
SphinxConfig(srcDir="${workspaceFolder}/../src"),
),
pathlib.Path("/path/to/src"),
),
(
(
"file:///path/to/root",
pathlib.Path("/path/to/config"),
SphinxConfig(srcDir="${confDir}/src"),
),
pathlib.Path("/path/to/config/src"),
),
(
(
"file:///path/to/root",
pathlib.Path("/path/to/config"),
SphinxConfig(srcDir="${confDir}/../src"),
),
pathlib.Path("/path/to/src"),
),
],
)
def test_get_src_dir(setup, expected):
"""Ensure that the ``get_src_dir`` function works as expected."""

root_uri, conf_dir, sphinx_config = setup

actual = get_src_dir(root_uri, conf_dir, sphinx_config)
assert actual == expected


@py.test.mark.parametrize(
"setup, expected",
[
(
(
"file:///path/to/root",
pathlib.Path("/path/to/config"),
SphinxConfig(buildDir="/path/to/build"),
),
pathlib.Path("/path/to/build"),
),
(
(
"file:///path/to/root",
pathlib.Path("/path/to/config"),
SphinxConfig(buildDir="~/path/to/build"),
),
pathlib.Path("~/path/to/build").expanduser(),
),
(
(
"file:///path/to/root",
pathlib.Path("/path/to/config"),
SphinxConfig(buildDir="${workspaceRoot}/build"),
),
pathlib.Path("/path/to/root/build"),
),
(
(
"file:///path/to/root",
pathlib.Path("/path/to/config"),
SphinxConfig(buildDir="${workspaceRoot}/../build"),
),
pathlib.Path("/path/to/build"),
),
(
(
"file:///path/to/root",
pathlib.Path("/path/to/config"),
SphinxConfig(buildDir="${workspaceFolder}/build"),
),
pathlib.Path("/path/to/root/build"),
),
(
(
"file:///path/to/root",
pathlib.Path("/path/to/config"),
SphinxConfig(buildDir="${workspaceFolder}/../build"),
),
pathlib.Path("/path/to/build"),
),
(
(
"file:///path/to/root",
pathlib.Path("/path/to/config"),
SphinxConfig(buildDir="${confDir}/build"),
),
pathlib.Path("/path/to/config/build"),
),
(
(
"file:///path/to/root",
pathlib.Path("/path/to/config"),
SphinxConfig(buildDir="${confDir}/../build"),
),
pathlib.Path("/path/to/build"),
),
],
)
def test_get_build_dir(setup, expected):
"""Ensure that the ``get_build_dir`` function works as expected."""

root_uri, conf_dir, sphinx_config = setup

actual = get_build_dir(root_uri, conf_dir, sphinx_config)
assert actual == expected


@py.test.fixture(scope="function")
async def cs():
"""A disposable version of the 'client_server' fixture.
Expand Down

0 comments on commit 853e7b9

Please sign in to comment.