Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: swyddfa/esbonio
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: esbonio-extensions-v0.2.3
Choose a base ref
...
head repository: swyddfa/esbonio
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: develop
Choose a head ref

Commits on Sep 22, 2024

  1. Copy the full SHA
    5f1a6e0 View commit details
  2. Copy the full SHA
    44daa57 View commit details

Commits on Sep 29, 2024

  1. Copy the full SHA
    e439b05 View commit details
  2. lsp: Implement a ${defaultBuildDir} config variable

    Unless esbonio finds a `sphinx-build` command to use from the
    user's config it will attempt to guess something reasonable. During
    this process it generates a default build directory to use, in a
    subfolder of `platformdirs.user_cache_dir()` so that it does not
    interfere with the user's files.
    
    Up until now, the moment a user sets their own `sphinx-build` command
    this behavior is lost, which can lead to issues on some systems
    (see #865).
    
    This commit introduces a `${defaultBuildDir}` placeholder value that
    the user can use to provide their own build flags, while maintaining
    the default choice of build dir provided by esbonio.
    alcarney committed Sep 29, 2024
    Copy the full SHA
    f2b0082 View commit details
  3. lsp: mypy fixes

    alcarney committed Sep 29, 2024
    Copy the full SHA
    dd55dd9 View commit details
  4. docs: Update dependencies

    alcarney committed Sep 29, 2024
    Copy the full SHA
    0027e53 View commit details
  5. Copy the full SHA
    ea91f01 View commit details
  6. Copy the full SHA
    7f19d97 View commit details
  7. lsp: Ensure filepaths are properly escaped

    Backslashes in Windows filepaths can cause issues
    
    ```python
    >>> import re
    >>> VARIABLE = re.compile(r"\$\{(\w+)\}")
    >>> VARIABLE.sub('\\path\\to\\cache', '${defaultBuildDir}/doctrees')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib64/python3.12/re/__init__.py", line 334, in _compile_template
        return _sre.template(pattern, _parser.parse_template(repl, pattern))
                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib64/python3.12/re/_parser.py", line 1075, in parse_template
        raise s.error('bad escape %s' % this, len(this)) from None
    re.error: bad escape \p at position 0
    ```
    
    Calling `re.escape` on the replacement ensures that characters like
    backslashes are escaped correctly
    
    ```python
    >>> VARIABLE.sub(re.escape('\\path\\to\\cache'), '${defaultBuildDir}/doctrees')
    '\\path\\to\\cache/doctrees'
    >>>
    ```
    alcarney committed Sep 29, 2024
    Copy the full SHA
    3e1eb23 View commit details
  8. lsp: Create a placeholder for a client at the given scope

    When `manager.get_client` is called many times in quick
    succession (such as on server restart with N files open) this can fool
    the `SphinxManager` into creating multiple client instances for a
    given configuration scope.
    
    By storing a ``None`` at the relevant scope we allow the SphinxManager
    to detect that the scope has already been handled, preventing the
    spawning of duplicated client instances.
    
    This should, finally, fix the flaky test issue (#859)
    alcarney committed Sep 29, 2024
    Copy the full SHA
    c89ec6b View commit details
  9. Copy the full SHA
    ca88887 View commit details
  10. code: Compare the string representation of URIs

    For some reason, the object representation of the same URI is not stable
    leading to synchronised scrolling breaking after scrolling the preview
    window.
    
    Instead, compare the string representation of the uris which should
    work around the differences that should not matter.
    alcarney committed Sep 29, 2024
    Copy the full SHA
    8f0e644 View commit details
  11. sphinx-agent: Rewrite internal links

    As part of its initial setup, the injected `webview.js` script now
    rewrites any `a.internal` links to include the port number of the
    current websocket connection. This ensures that as the user navigates
    by clicking on links on the page the websocket connection to the
    language server is preserved.
    
    Also by doing an initial scroll sync on page load, this ensures that
    the editor is kept in sync with the change! There is a chance for this
    to be a bit flaky as this in direct conflict with the initial sync an
    editor might want to make if it initiates the preview of a page.
    
    By introducing a small delay on the sync made by the webview, we are
    relying on the editor winning the race and getting its message in
    first... I'm sure that will never cause an issue in the future!
    alcarney committed Sep 29, 2024
    Copy the full SHA
    7f16384 View commit details

Commits on Oct 7, 2024

  1. Copy the full SHA
    493eaac View commit details
  2. code: Derive CSP string from asExternalUri

    In addition to running the preview uri from the server through `vscode.env.asExternalUri`
    we need to make sure that the CSP for the embedded iframe is given the correct origin.
    alcarney committed Oct 7, 2024
    Copy the full SHA
    3f03231 View commit details
  3. Copy the full SHA
    79d8eb8 View commit details
  4. Copy the full SHA
    d424314 View commit details
  5. Copy the full SHA
    0594794 View commit details
  6. sphinx-agent: Take entire websocket URL from query parameter

    The injected `webview.js` script now assumes that the `ws` query
    parameter contains the entire URI to use when creating the websocket
    connection
    alcarney committed Oct 7, 2024
    Copy the full SHA
    576c53f View commit details
  7. Copy the full SHA
    4ced573 View commit details

Commits on Oct 9, 2024

  1. Copy the full SHA
    34d4e51 View commit details
  2. build(deps-dev): bump ovsx from 0.9.4 to 0.9.5 in /code

    Bumps [ovsx](https://github.com/eclipse/openvsx/tree/HEAD/cli) from 0.9.4 to 0.9.5.
    - [Release notes](https://github.com/eclipse/openvsx/releases)
    - [Changelog](https://github.com/eclipse/openvsx/blob/master/cli/CHANGELOG.md)
    - [Commits](https://github.com/eclipse/openvsx/commits/v0.9.5/cli)
    
    ---
    updated-dependencies:
    - dependency-name: ovsx
      dependency-type: direct:development
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    dependabot[bot] authored and alcarney committed Oct 9, 2024
    Copy the full SHA
    33a8865 View commit details
  3. [pre-commit.ci] pre-commit autoupdate

    updates:
    - [github.com/pre-commit/pre-commit-hooks: v4.6.0 → v5.0.0](pre-commit/pre-commit-hooks@v4.6.0...v5.0.0)
    - [github.com/astral-sh/ruff-pre-commit: v0.6.5 → v0.6.9](astral-sh/ruff-pre-commit@v0.6.5...v0.6.9)
    pre-commit-ci[bot] authored and alcarney committed Oct 9, 2024
    Copy the full SHA
    1880f9d View commit details
  4. build(deps-dev): bump esbuild from 0.23.1 to 0.24.0 in /code

    Bumps [esbuild](https://github.com/evanw/esbuild) from 0.23.1 to 0.24.0.
    - [Release notes](https://github.com/evanw/esbuild/releases)
    - [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
    - [Commits](evanw/esbuild@v0.23.1...v0.24.0)
    
    ---
    updated-dependencies:
    - dependency-name: esbuild
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    dependabot[bot] authored and alcarney committed Oct 9, 2024
    Copy the full SHA
    33bf8ba View commit details

Commits on Oct 13, 2024

  1. build(deps-dev): bump @vscode/vsce from 3.1.0 to 3.1.1 in /code

    Bumps [@vscode/vsce](https://github.com/Microsoft/vsce) from 3.1.0 to 3.1.1.
    - [Release notes](https://github.com/Microsoft/vsce/releases)
    - [Commits](microsoft/vscode-vsce@v3.1.0...v3.1.1)
    
    ---
    updated-dependencies:
    - dependency-name: "@vscode/vsce"
      dependency-type: direct:development
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    dependabot[bot] authored and alcarney committed Oct 13, 2024
    Copy the full SHA
    db519b0 View commit details

Commits on Oct 16, 2024

  1. Copy the full SHA
    3d88524 View commit details
  2. sphinx-agent: Suppress and report extension errors

    The sphinx-agent will no longer crash if the configured environment is
    missing an extension. Instead the error is suppressed and the agent
    will attempt to report it to the user as a diagnostic
    
    However, the diagnostic will only work if the extensions are declared
    in `conf.py` using the "standard" Sphinx format i.e.
    
    ```python
    extensions = [
        'a',
        'b',
        ...
    ]
    ```
    alcarney committed Oct 16, 2024
    Copy the full SHA
    179730c View commit details
  3. vscode: Clean up launch.json

    alcarney committed Oct 16, 2024
    Copy the full SHA
    eca2086 View commit details

Commits on Oct 20, 2024

  1. Copy the full SHA
    d6462b2 View commit details
  2. Copy the full SHA
    aff08eb View commit details
  3. Copy the full SHA
    07121fc View commit details
  4. lsp: Use fallback env when possible

    If a client provides the `esbonio.sphinx.fallbackEnv`, repurpose the server's Python interpreter
    to launch the Sphinx agent.
    alcarney committed Oct 20, 2024
    Copy the full SHA
    4e1ca8b View commit details
  5. Copy the full SHA
    a0755c5 View commit details
  6. ci: Limit PR builds to 20min

    Most runs conclude on the order 5min +/- 2min, so if we hit the 20min
    mark chances are something has hung.
    alcarney committed Oct 20, 2024
    Copy the full SHA
    d9466d7 View commit details
  7. Copy the full SHA
    6701fe2 View commit details
  8. sphinx-agent: Expose the AST for conf.py via an attribute

    This allows us to parse the file once in a central location
    alcarney committed Oct 20, 2024
    Copy the full SHA
    c2c90bd View commit details
  9. sphinx-agent: Implement a fallback html_theme

    The sphinx agent can now handle the case where the requested
    `html_theme` is not available in the environment by suppressing the
    raised error, overriding the value of `html_theme` and attempting to
    run `Sphinx.__init__` again.
    alcarney committed Oct 20, 2024
    Copy the full SHA
    591748e View commit details
  10. code: Update changelog

    alcarney committed Oct 20, 2024
    Copy the full SHA
    7d98957 View commit details
  11. Merge pull request #917 from swyddfa/develop

    New Release
    alcarney authored Oct 20, 2024
    Copy the full SHA
    d3aae44 View commit details
  12. Copy the full SHA
    dcd9b3a View commit details
  13. Copy the full SHA
    a474a07 View commit details

Commits on Oct 21, 2024

  1. Copy the full SHA
    1aec147 View commit details
  2. devenv: Bump nodejs to 20.x

    alcarney committed Oct 21, 2024
    Copy the full SHA
    87784e5 View commit details
  3. Copy the full SHA
    884c233 View commit details
  4. Copy the full SHA
    efde2cf View commit details
  5. Copy the full SHA
    f1ec7fc View commit details

Commits on Dec 1, 2024

  1. lsp: Bump pygls to v2.0a2

    alcarney committed Dec 1, 2024
    Copy the full SHA
    f8b5992 View commit details
  2. lsp: Use concurrent.futures.Future instead of asyncio.Future

    pygls in `v2.0a2` switched from using the low-level asyncio APIs to
    using the high-level one and surprisingly, this broke `esbonio`.
    
    The server would start ok, but wouldn't launch Sphinx processes, the
    preview command did nothing, it wouldn't even produce any log
    messages! That is, until the user changed a configuration setting.
    
    After changing a setting - any setting, the server suddenly springs
    into life, logs, previews, sphinx processes all of them would start
    working as if nothing was wrong.
    
    I eventually managed to figure out that the callbacks registered by
    the configuration system on the server's `ready` future were never
    being called.
    
    ```
    self.server.ready.add_done_callback(self._notify_subscriptions)
    ```
    
    By why would changing the asyncio API in use break these callbacks?!
    After spending some time with the debugger I eventually spotted the culprit
    
    ```
    >>> asyncio.get_running_loop()
    <_UnixSelectorEventLoop running=True closed=False debug=False>
    
    >>> self.server.ready._loop
    <_UnixSelectorEventLoop running=False closed=False debug=False>
    ```
    
    The server's `ready` future was using a different event loop and
    because the event loop is not running, when the future is resolved,
    the callbacks were never scheduled!
    
    While I cannot explain why this was not an issue before, I can explain
    why it is an issue now.
    
    The `ready` future is created in the constructor of the
    `EsbonioLanguageServer` class - before any event loop has been created
    and so it uses a new one based on the current event loop policy[1][2].
    
    Unfortunately, when pygls later starts its main loop by calling
    `asyncio.run()` it creates a new event loop, orphaning the `ready`
    future in its unused event loop[3]
    
    Since we don't need to use the `ready` future asynchronously, the
    simplest fix is to convert it to future from the `concurrent.futures`
    module, removing the need for an event loop completely.
    
    [1]: https://github.com/python/cpython/blob/307c63358681d669ae39e5ecd814bded4a93443a/Lib/asyncio/futures.py#L79
    [2]: https://github.com/python/cpython/blob/307c63358681d669ae39e5ecd814bded4a93443a/Lib/asyncio/events.py#L791
    [3]: https://github.com/python/cpython/blob/307c63358681d669ae39e5ecd814bded4a93443a/Lib/asyncio/runners.py#L146
    alcarney committed Dec 1, 2024
    Copy the full SHA
    bd9ff91 View commit details
  3. Copy the full SHA
    811c519 View commit details
  4. lsp: Refactor WebviewServer

    - Use new `pygls.io_` infrastructure
    - Use new `websockets.asyncio` API
    alcarney committed Dec 1, 2024
    Copy the full SHA
    f0bc363 View commit details
Showing with 9,357 additions and 2,121 deletions.
  1. +1 −4 .devcontainer/Dockerfile
  2. +59 −48 .devcontainer/tools.mk
  3. +0 −6 .github/dependabot.yml
  4. +1 −0 .github/workflows/lsp-pr.yml
  5. +3 −3 .github/workflows/lsp-release.yml
  6. +39 −2 .github/workflows/vscode-pr.yml
  7. +5 −5 .pre-commit-config.yaml
  8. +19 −50 .vscode/launch.json
  9. +2 −1 code/.gitignore
  10. +13 −0 code/.vscode-test.js
  11. +6 −2 code/.vscodeignore
  12. +63 −0 code/CHANGELOG.md
  13. +32 −8 code/Makefile
  14. +0 −1 code/changes/785.enhancement.md
  15. +0 −1 code/changes/858.misc.md
  16. +0 −1 code/changes/859.misc.md
  17. +0 −1 code/changes/881.enchancement.md
  18. +0 −7 code/changes/881.misc.md
  19. +0 −10 code/hatch.toml
  20. +3,634 −757 code/package-lock.json
  21. +32 −8 code/package.json
  22. +24 −0 code/requirements-env.in
  23. +356 −0 code/requirements-env.txt
  24. +17 −0 code/requirements-libs.in
  25. +147 −0 code/requirements-libs.txt
  26. +0 −17 code/requirements.in
  27. +0 −140 code/requirements.txt
  28. +16 −48 code/src/node/client.ts
  29. +7 −1 code/src/node/extension.ts
  30. +89 −32 code/src/node/preview.ts
  31. +3 −3 code/src/node/processTreeView.ts
  32. +16 −0 code/src/node/python.ts
  33. +17 −0 code/src/test/suite/extension.test.ts
  34. +0 −48 docs/contributing/devenvs.rst
  35. +10 −0 docs/contributing/howto.rst
  36. +253 −0 docs/contributing/howto/setup-development-environment.rst
  37. +9 −0 docs/extending/api-reference.rst
  38. +10 −0 docs/extending/common-api.rst
  39. +7 −0 docs/extending/common-api/directives.rst
  40. +7 −0 docs/extending/common-api/roles.rst
  41. +8 −0 docs/extending/common-api/uri.rst
  42. +10 −0 docs/extending/server-api.rst
  43. +21 −0 docs/extending/server-api/directives.rst
  44. +16 −0 docs/extending/server-api/language-features.rst
  45. +10 −0 docs/extending/sphinx-api.rst
  46. +10 −0 docs/extending/sphinx-api/application.rst
  47. +7 −0 docs/extending/sphinx-api/database.rst
  48. BIN docs/images/book-icon.png
  49. BIN docs/images/globe-icon.png
  50. +1 −0 docs/index.rst
  51. +2 −0 docs/integrating/getting-started.rst
  52. +169 −3 docs/lsp/getting-started.rst
  53. +54 −8 docs/lsp/howto/use-esbonio-with.rst
  54. +67 −11 docs/lsp/reference/configuration.rst
  55. +6 −2 docs/pyproject.toml
  56. +87 −0 lib/esbonio/CHANGES.md
  57. +1 −0 lib/esbonio/changes/646.fix.md
  58. +0 −1 lib/esbonio/changes/785.enhancement.md
  59. +0 −1 lib/esbonio/changes/858.misc.md
  60. +0 −1 lib/esbonio/changes/859.misc.md
  61. +0 −1 lib/esbonio/changes/866.misc.md
  62. +0 −1 lib/esbonio/changes/874.fix.md
  63. +0 −1 lib/esbonio/changes/882.misc.md
  64. +1 −0 lib/esbonio/changes/951.fix.md
  65. +1 −0 lib/esbonio/changes/970.fix.md
  66. +2 −0 lib/esbonio/esbonio/server/__init__.py
  67. +85 −41 lib/esbonio/esbonio/server/_configuration.py
  68. +34 −0 lib/esbonio/esbonio/server/feature.py
  69. +190 −18 lib/esbonio/esbonio/server/features/directives/__init__.py
  70. +92 −6 lib/esbonio/esbonio/server/features/directives/completion.py
  71. +207 −0 lib/esbonio/esbonio/server/features/directives/providers.py
  72. +68 −9 lib/esbonio/esbonio/server/features/myst/directives.py
  73. +42 −0 lib/esbonio/esbonio/server/features/myst/roles.py
  74. +31 −18 lib/esbonio/esbonio/server/features/preview_manager/__init__.py
  75. +32 −21 lib/esbonio/esbonio/server/features/preview_manager/preview.py
  76. +17 −18 lib/esbonio/esbonio/server/features/preview_manager/webview.py
  77. +4 −0 lib/esbonio/esbonio/server/features/project_manager/manager.py
  78. +39 −1 lib/esbonio/esbonio/server/features/project_manager/project.py
  79. +59 −15 lib/esbonio/esbonio/server/features/roles/__init__.py
  80. +192 −0 lib/esbonio/esbonio/server/features/roles/providers.py
  81. +62 −2 lib/esbonio/esbonio/server/features/rst/directives.py
  82. +42 −0 lib/esbonio/esbonio/server/features/rst/roles.py
  83. +1 −0 lib/esbonio/esbonio/server/features/sphinx_manager/client.py
  84. +13 −6 lib/esbonio/esbonio/server/features/sphinx_manager/client_subprocess.py
  85. +111 −25 lib/esbonio/esbonio/server/features/sphinx_manager/config.py
  86. +80 −13 lib/esbonio/esbonio/server/features/sphinx_manager/manager.py
  87. +47 −10 lib/esbonio/esbonio/server/features/sphinx_support/directives.py
  88. +99 −4 lib/esbonio/esbonio/server/features/sphinx_support/roles.py
  89. +1 −1 lib/esbonio/esbonio/server/features/sphinx_support/symbols.py
  90. +7 −4 lib/esbonio/esbonio/server/server.py
  91. +31 −27 lib/esbonio/esbonio/server/setup.py
  92. +312 −2 lib/esbonio/esbonio/sphinx_agent/app.py
  93. +45 −1 lib/esbonio/esbonio/sphinx_agent/config.py
  94. +5 −3 lib/esbonio/esbonio/sphinx_agent/handlers/__init__.py
  95. +9 −6 lib/esbonio/esbonio/sphinx_agent/handlers/diagnostics.py
  96. +57 −15 lib/esbonio/esbonio/sphinx_agent/handlers/directives.py
  97. +18 −2 lib/esbonio/esbonio/sphinx_agent/handlers/domains.py
  98. +12 −0 lib/esbonio/esbonio/sphinx_agent/handlers/roles.py
  99. +8 −7 lib/esbonio/esbonio/sphinx_agent/handlers/webview.py
  100. +1 −2 lib/esbonio/esbonio/sphinx_agent/log.py
  101. +204 −60 lib/esbonio/esbonio/sphinx_agent/static/webview.js
  102. +21 −414 lib/esbonio/esbonio/sphinx_agent/types/__init__.py
  103. +170 −0 lib/esbonio/esbonio/sphinx_agent/types/directives.py
  104. +1 −1 lib/esbonio/esbonio/sphinx_agent/types/roles.py
  105. +325 −0 lib/esbonio/esbonio/sphinx_agent/types/uri.py
  106. +4 −2 lib/esbonio/esbonio/sphinx_agent/util.py
  107. +0 −1 lib/esbonio/hatch.toml
  108. +1 −1 lib/esbonio/pyproject.toml
  109. +7 −7 lib/esbonio/ruff_defaults.toml
  110. +15 −0 lib/esbonio/tests/conftest.py
  111. +15 −11 lib/esbonio/tests/e2e/conftest.py
  112. +19 −24 lib/esbonio/tests/e2e/test_e2e_diagnostics.py
  113. +201 −2 lib/esbonio/tests/e2e/test_e2e_directives.py
  114. +211 −0 lib/esbonio/tests/e2e/test_e2e_roles.py
  115. +100 −46 lib/esbonio/tests/e2e/test_sphinx_manager.py
  116. +1 −5 lib/esbonio/tests/server/conftest.py
  117. +1 −1 lib/esbonio/tests/server/features/test_directive_completion.py
  118. +251 −3 lib/esbonio/tests/server/features/test_sphinx_config.py
  119. +1 −2 lib/esbonio/tests/server/test_patterns.py
  120. +0 −4 lib/esbonio/tests/sphinx-agent/conftest.py
  121. +48 −10 lib/esbonio/tests/sphinx-agent/handlers/test_diagnostics.py
  122. 0 lib/esbonio/tests/sphinx-agent/{test_app.py → test_sa_database.py}
  123. +99 −0 lib/esbonio/tests/sphinx-agent/test_sa_diagnostics.py
  124. +105 −3 lib/esbonio/tests/sphinx-agent/test_sa_unit.py
  125. +1 −0 lib/esbonio/tests/workspaces/demo/conf.py
  126. +2 −0 lib/esbonio/tests/workspaces/demo/index.rst
  127. +1 −2 lib/esbonio/tests/workspaces/demo/myst/diagnostics.md
  128. +41 −2 lib/esbonio/tests/workspaces/demo/myst/directives.md
  129. +24 −3 lib/esbonio/tests/workspaces/demo/myst/roles.md
  130. +1 −1 lib/esbonio/tests/workspaces/demo/rst/diagnostics.rst
  131. +39 −2 lib/esbonio/tests/workspaces/demo/rst/directives.rst
  132. +25 −3 lib/esbonio/tests/workspaces/demo/rst/roles.rst
5 changes: 1 addition & 4 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -2,8 +2,5 @@ FROM mcr.microsoft.com/devcontainers/base:jammy

COPY tools.mk /

RUN apt-get update \
&& export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends python3-venv \
&& su vscode -c "make -f tools.mk tools" \
RUN su vscode -c "make -f tools.mk tools" \
&& rm tools.mk
107 changes: 59 additions & 48 deletions .devcontainer/tools.mk
Original file line number Diff line number Diff line change
@@ -5,32 +5,43 @@ ifeq ($(strip $(ARCH)),)
$(error Unable to determine platform architecture)
endif

NODE_VERSION := 18.20.4
NODE_VERSION := 20.18.0
UV_VERSION := 0.5.21

# The versions of Python we support
PYXX_versions := 3.9 3.10 3.11 3.12
PY_INTERPRETERS =
UV ?= $(shell command -v uv)
UVX ?= $(shell command -v uvx)

# Hatch is not only used for building packages, but bootstrapping any missing
# interpreters
HATCH ?= $(or $(shell command -v hatch), $(BIN)/hatch)
ifeq ($(strip $(UV)),)

UV := $(BIN)/uv
UVX := $(BIN)/uvx

$(HATCH):
curl -L --output /tmp/hatch.tar.gz https://github.com/pypa/hatch/releases/latest/download/hatch-$(ARCH)-unknown-linux-gnu.tar.gz
tar -xf /tmp/hatch.tar.gz -C /tmp
rm /tmp/hatch.tar.gz
$(UV):
curl -L --output /tmp/uv.tar.gz https://github.com/astral-sh/uv/releases/download/$(UV_VERSION)/uv-$(ARCH)-unknown-linux-gnu.tar.gz
tar -xf /tmp/uv.tar.gz -C /tmp
rm /tmp/uv.tar.gz

test -d $(BIN) || mkdir -p $(BIN)
mv /tmp/hatch $(HATCH)

mv /tmp/uv-$(ARCH)-unknown-linux-gnu/uv $@
mv /tmp/uv-$(ARCH)-unknown-linux-gnu/uvx $(UVX)

$@ --version
touch $@
$(UVX) --version

endif

# The versions of Python we support
PYXX_versions := 3.9 3.10 3.11 3.12 3.13

# Our default Python version
PY_VERSION := 3.13

# This effectively defines a function `PYXX` that takes a Python version number
# (e.g. 3.8) and expands it out into a common block of code that will ensure a
# verison of that interpreter is available to be used.
#
# The is perhaps a bit more complicated than I'd like, but it should mean that
# This is perhaps a bit more complicated than I'd like, but it should mean that
# the project's makefiles are useful both inside and outside of a devcontainer.
#
# `PYXX` has the following behavior:
@@ -40,7 +51,7 @@ $(HATCH):
# - The user may force a specific interpreter to be used by setting the
# variable when running make e.g. PYXX=/path/to/pythonX.X make ...
#
# - Otherwise, `make` will use `$(HATCH)` to install the given version of
# - Otherwise, `make` will use `$(UV)` to install the given version of
# Python under `$(BIN)`
#
# See: https://www.gnu.org/software/make/manual/html_node/Eval-Function.html
@@ -52,71 +63,68 @@ ifeq ($$(strip $$(PY$(subst .,,$1))),)

PY$(subst .,,$1) := $$(BIN)/python$1

$$(PY$(subst .,,$1)): $$(HATCH)
$$(HATCH) python find $1 || $$(HATCH) python install $1
ln -s $$$$($$(HATCH) python find $1) $$@
$$(PY$(subst .,,$1)): | $$(UV)
$$(UV) python find $1 || $$(UV) python install $1
ln -s $$$$($$(UV) python find $1) $$@

$$@ --version
touch $$@

endif

PY_INTERPRETERS += $$(PY$(subst .,,$1))
endef

# Uncomment the following line to see what this expands into.
#$(foreach version,$(PYXX_versions),$(info $(call PYXX,$(version))))
$(foreach version,$(PYXX_versions),$(eval $(call PYXX,$(version))))

# Set a default `python` command if there is not one already
PY ?= $(shell command -v python3)

ifeq ($(strip $(PY)),)
PY := $(BIN)/python

$(PY): $(PY312)
ln -s $< $@
$@ --version
touch $@
endif

PY_INTERPRETERS += $(PY)
#$(info $(PY_INTERPRETERS))

PIPX ?= $(shell command -v pipx)
# Hatch is not only used for building packages, but bootstrapping any missing
# interpreters
HATCH ?= $(shell command -v hatch)

ifeq ($(strip $(PIPX)),)
PIPX := $(BIN)/pipx
PIPX_VERSION := 1.5.0
ifeq ($(strip $(HATCH)),)

$(PIPX):
curl -L -o $(BIN)/pipx.pyz https://github.com/pypa/pipx/releases/download/$(PIPX_VERSION)/pipx.pyz
echo '#!/bin/bash\nexec $(PY) $(BIN)/pipx.pyz "$$@"' > $(PIPX)
HATCH := $(BIN)/hatch

chmod +x $(PIPX)
$(HATCH): | $(UV)
$(UV) tool install hatch
$@ --version
touch $@

endif

PRE_COMMIT ?= $(shell command -v pre-commit)

ifeq ($(strip $(PRE_COMMIT)),)
PRE_COMMIT := $(BIN)/pre-commit

$(PRE_COMMIT): $(PIPX)
$(PIPX) install pre-commit
$(PRE_COMMIT): | $(UV)
$(UV) tool install pre-commit
$@ --version
touch $@

endif

PY_TOOLS := $(HATCH) $(PIPX) $(PRE_COMMIT)
PY_TOOLS := $(HATCH) $(PRE_COMMIT)

# Set a default `python` command if there is not one already
PY ?= $(shell command -v python)

ifeq ($(strip $(PY)),)
PY := $(BIN)/python

$(PY): | $(UV)
$(UV) python install $(PY_VERSION)
ln -s $$($(UV) python find $(PY_VERSION)) $@
$@ --version
endif

# Node JS
NPM ?= $(shell command -v npm)
NPX ?= $(shell command -v npx)

ifeq ($(strip $(NPM)),)

NPM := $(BIN)/npm
NPX := $(BIN)/npx
NODE := $(BIN)/node
NODE_DIR := $(HOME)/.local/node

@@ -131,12 +139,15 @@ $(NPM):
[ -d $(BIN) ] || mkdir -p $(BIN)
ln -s $(NODE_DIR)/bin/node $(NODE)
ln -s $(NODE_DIR)/bin/npm $(NPM)
ln -s $(NODE_DIR)/bin/npx $(NPX)

$(NODE) --version
PATH=$(BIN) $(NPM) --version
PATH=$(BIN) $(NPX) --version

endif

# One command to bootstrap all tools and check their versions
tools: $(PY_INTERPRETERS) $(PY_TOOLS) $(NPM)
.PHONY: tools
tools: $(UV) $(PY) $(PY_TOOLS) $(NPM) $(NPX)
for prog in $^ ; do echo -n "$${prog}\t" ; PATH=$(BIN) $${prog} --version; done
6 changes: 0 additions & 6 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -17,12 +17,6 @@ updates:
schedule:
interval: "monthly"

- package-ecosystem: "pip"
directory: "/code"
target-branch: "develop"
schedule:
interval: "monthly"

- package-ecosystem: "pip"
directory: "/lib/esbonio/tests/workspaces/demo"
target-branch: "develop"
1 change: 1 addition & 0 deletions .github/workflows/lsp-pr.yml
Original file line number Diff line number Diff line change
@@ -42,6 +42,7 @@ jobs:
test:
name: "Python v${{ matrix.python-version }} -- ${{ matrix.os }}"
runs-on: ${{ matrix.os }}
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
6 changes: 3 additions & 3 deletions .github/workflows/lsp-release.yml
Original file line number Diff line number Diff line change
@@ -114,7 +114,7 @@ jobs:

- uses: 'actions/setup-node@v4'
with:
node-version: 18.x
node-version: 20.x
cache: 'npm'
cache-dependency-path: 'code/package-lock.json'

@@ -178,7 +178,7 @@ jobs:

- uses: 'actions/setup-node@v4'
with:
node-version: 18.x
node-version: 20.x
cache: 'npm'
cache-dependency-path: 'code/package-lock.json'

@@ -208,7 +208,7 @@ jobs:

- uses: 'actions/setup-node@v4'
with:
node-version: 18.x
node-version: 20.x
cache: 'npm'
cache-dependency-path: 'code/package-lock.json'

41 changes: 39 additions & 2 deletions .github/workflows/vscode-pr.yml
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ jobs:

- uses: 'actions/setup-node@v4'
with:
node-version: 18.x
node-version: 20.x
cache: 'npm'
cache-dependency-path: 'code/package-lock.json'

@@ -28,7 +28,7 @@ jobs:
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-vscode-pip-deps-${{ hashFiles('code/requirements.txt') }}
key: ${{ runner.os }}-vscode-pip-deps-${{ hashFiles('code/requirements-*.txt') }}
restore-keys: |
${{ runner.os }}-vscode-pip-deps
@@ -68,3 +68,40 @@ jobs:
path: code/*.vsix
if-no-files-found: error
retention-days: 7

test:
name: "Python v${{ matrix.python-version }}"
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v4

- uses: 'actions/setup-node@v4'
with:
node-version: 20.x
cache: 'npm'
cache-dependency-path: 'code/package-lock.json'

- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true

- run: |
cd code/
make dev-deps
npx tsc -p .
# Force the extension to use this version of Python
python --version
export ESBONIO_SERVER_PYCMD=$(command -v python)
echo $ESBONIO_SERVER_PYCMD
xvfb-run -a npm run test
name: Run Tests
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -4,14 +4,14 @@ ci:
repos:

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v5.0.0
hooks:
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.5
rev: v0.8.6
hooks:
- id: ruff
name: ruff (esbonio)
@@ -32,7 +32,7 @@ repos:
files: 'lib/esbonio-extensions/.*\.py'

- repo: https://github.com/pre-commit/mirrors-mypy
rev: 'v1.11.2'
rev: 'v1.14.1'
hooks:
- id: mypy
name: mypy (scripts)
@@ -45,8 +45,8 @@ repos:
additional_dependencies:
- aiosqlite
- platformdirs
- pygls>=2a0
- pytest_lsp>=0.3
- pygls>=2a2
- pytest_lsp>=1.0b2
- sphinx
- tomli
- types-docutils
Loading