Utilities¶
Constants¶
lsp_utils.HOST_ARCH
module-attribute
¶
The native architecture of the host machine: "x32", "x64" or "arm64".
Unlike sublime.arch(), it reports the architecture of the machine rather than of Sublime Text on Windows, for
example when an x64 build of Sublime Text runs emulated on an ARM64 machine.
lsp_utils.SETTINGS_FILENAME
module-attribute
¶
The name of the lsp_utils settings file.
Install directories¶
lsp_utils.InstallDirectory
¶
InstallDirectory(parent: Path, name: str, *hash_parts: bytes | str, legacy_dirs: Sequence[Path] = ())
A versioned installation directory of a server, named <parent>/<name>-<hash>.
The hash covers everything that affects the installation (for example the server version or the contents of a
lock file) so an update installs into a new directory instead of replacing files of a server that might still be
running. Installation directories of the same name that are no longer current are removed in the background
once they were last used by an earlier run of Sublime Text. Removal that fails (for example because files are
locked on Windows) is retried during the next run.
Example of an LspPlugin that downloads a server:
class MyPlugin(LspPlugin):
@classmethod
def on_pre_start_async(cls, context: OnPreStartContext) -> None:
install_dir = InstallDirectory(cls.plugin_storage_path, 'server', SERVER_VERSION)
server_dir = install_dir.install(download_and_extract_server)
context.variables['server_path'] = str(server_dir / 'bin' / 'server')
Create an installation directory of the given name, with a hash of hash_parts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
Path
|
The directory containing the installation directories. Typically the package storage. |
required |
name
|
str
|
The name of the installation directories, without the hash. Must not be shared with other kinds
of installations within the same |
required |
hash_parts
|
bytes | str
|
All inputs that affect the installation. |
()
|
legacy_dirs
|
Sequence[Path]
|
Unversioned installation directories used previously, to remove once unused. |
()
|
path
instance-attribute
¶
The path to the installation directory. Depends on the hash.
install
¶
Install into path unless already installed, and record it as used.
Call this before every start of the server so that the directory isn't removed while in use.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
installer
|
Callable[[Path], None]
|
Called with the empty installation directory to install into. Should raise on failure. |
required |
Returns:
| Type | Description |
|---|---|
Path
|
The path to the complete installation. |
Downloads¶
Installation of servers downloaded from a URL.
Combine with InstallDirectory so that every version is installed into its own directory.
lsp_utils.UnsupportedPlatformError
¶
Bases: RuntimeError
Raised when no asset is available for the current platform and architecture.
lsp_utils.PlatformAssets
module-attribute
¶
PlatformAssets = TypedDict('PlatformAssets', {'linux': str, 'linux-arm64': str, 'linux-x32': str, 'linux-x64': str, 'osx': str, 'osx-arm64': str, 'osx-x64': str, 'windows': str, 'windows-arm64': str, 'windows-x32': str, 'windows-x64': str}, total=False)
Assets (file names or URLs) by <platform>-<arch>, for select_platform_asset.
A key of just the <platform> matches any architecture of that platform.
lsp_utils.select_platform_asset
¶
select_platform_asset(assets: PlatformAssets) -> str
Return the asset for the current platform and architecture.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
assets
|
PlatformAssets
|
File names or URLs by |
required |
Raises:
| Type | Description |
|---|---|
UnsupportedPlatformError
|
When there is no asset for the current platform and architecture. |
lsp_utils.download_and_extract
¶
download_and_extract(url: str, target_directory: Path, *, filename: str | None = None, executables: Iterable[str] = (), sha256: str | None = None) -> None
Download a file into a directory, extracting or decompressing it depending on its file name.
- An archive (
.zip,.vsix,.tar.gz,.tgz,.tar.bz2or.tar.xz) is extracted. When all its files are in a single root directory, the contents of that directory are extracted. - A file compressed with gzip (
.gz) is decompressed and stored underfilenamewithout the.gzextension. - Any other file is stored as is under
filename.
An activity indicator is shown in the status bar of the active window in the meantime.
Typically called as the installer of an InstallDirectory:
VERSION = '1.2.3'
URL = f'https://example.com/server/{VERSION}/server-{sublime.platform()}.zip'
install_dir = InstallDirectory(storage_path, 'server', VERSION)
install_dir.install(lambda path: download_and_extract(URL, path, executables=['bin/server']))
For GitHub releases, see download_and_extract_github_asset.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
The URL to download. |
required |
target_directory
|
Path
|
The existing directory to store the file or its extracted contents in. |
required |
filename
|
str | None
|
The file name of the download, which determines how it's handled and what a file that isn't an
archive is stored as. Defaults to the last segment of the URL path. For example, pass
|
None
|
executables
|
Iterable[str]
|
Paths, relative to |
()
|
sha256
|
str | None
|
The expected SHA-256 hex digest of the download, verified before it's used. |
None
|
lsp_utils.download_file
¶
Download given URL to the specified target file path.
lsp_utils.extract_archive
¶
Extract all files from an archive.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
archive_file
|
Path
|
Path to the archive file to extract. |
required |
target_directory
|
Path
|
Directory where files will be extracted. |
required |
Returns:
| Type | Description |
|---|---|
Path | None
|
Path to the top-level directory within extracted files or |
lsp_utils.http_request
¶
http_request(url: str, *, method: str = 'GET') -> HTTPResponse
Send an HTTP request with the User-Agent of lsp_utils and a timeout. Use the response as a context manager.
GitHub releases¶
Installation of servers distributed as GitHub release assets.
Combine with InstallDirectory so that every release is installed into its own directory.
lsp_utils.download_and_extract_github_asset
¶
download_and_extract_github_asset(repo: str, tag: str, asset: str, target_directory: Path, *, executables: Iterable[str] = (), filename: str | None = None, sha256: str | None = None) -> None
Download an asset of a GitHub release into a directory.
Archives are extracted and gzipped files decompressed, the same as with download_and_extract.
Typically called as the installer of an InstallDirectory:
TAG = 'v1.2.3'
ASSETS: PlatformAssets = {
'linux-x64': 'server-x86_64-unknown-linux-gnu.tar.gz',
'osx-arm64': 'server-aarch64-apple-darwin.tar.gz',
'windows-x64': 'server-x86_64-pc-windows-msvc.zip',
}
BINARY = 'server.exe' if sublime.platform() == 'windows' else 'server'
install_dir = InstallDirectory(storage_path, 'server', TAG)
server_dir = install_dir.install(lambda path: download_and_extract_github_asset(
'owner/server', TAG, select_platform_asset(ASSETS), path, executables=[BINARY]))
binary_path = server_dir / BINARY
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
repo
|
str
|
The repository, as |
required |
tag
|
str
|
The tag of the release. |
required |
asset
|
str
|
The file name of the asset. |
required |
target_directory
|
Path
|
The existing directory to store the asset or its extracted contents in. |
required |
executables
|
Iterable[str]
|
Paths, relative to |
()
|
filename
|
str | None
|
The file name of the download, which determines how it's handled and what a file that isn't an
archive is stored as. Defaults to |
None
|
sha256
|
str | None
|
The expected SHA-256 hex digest of the asset, verified before it's used. |
None
|
lsp_utils.fetch_latest_github_release_tag
¶
Return the tag of the latest release of a GitHub repository.
Uses the redirect of the "latest release" page so that it's not subject to the rate limit of the GitHub API. Avoid calling it on every start of the server; check for updates periodically instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
repo
|
str
|
The repository, as |
required |
Helpers¶
prepend_to_path
¶
Return path (a PATH string or a list of its entries) with extra_paths put first.
Empty entries are dropped and entries of extra_paths that are already in path are moved to the front instead
of being added again.
run_command_sync
¶
run_command_sync(args: Sequence[str | PathLike[str]], cwd: str | PathLike[str] | None = None, env: dict[str, str] | None = None, extra_env: dict[str, str] | None = None, extra_paths: list[str] | None = None, *, shell: bool = is_windows) -> tuple[str, str | None]
Run the given command synchronously.
Returns:
| Type | Description |
|---|---|
tuple[str, str | None]
|
A two-element tuple with the returned value and an optional error. If running the command has failed, the
first tuple element will be empty string and the second will contain the potential |
run_command_async
¶
run_command_async(args: Sequence[str | PathLike[str]], on_success: StringCallback, on_error: StringCallback, **kwargs: Any) -> None
Run the given command asynchronously.
On success calls the provided on_success callback with the value the the command has returned.
On error calls the provided on_error callback with the potential stderr output.
decode_bytes
¶
Decode provided bytes using utf-8 decoding, ignoring potential decoding errors.
rmtree_ex
¶
Remove a directory tree like shutil.rmtree, including entries that shutil.rmtree fails to remove.
Removes read-only files and directories that can't be listed, and paths longer than 255 characters on Windows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
The directory to remove. |
required |
ignore_errors
|
bool
|
Ignore entries that can't be removed even after granting permissions. |
False
|