diff --git a/dev-packages/cli/README.md b/dev-packages/cli/README.md index c90bfade9a1cb..5412e8b766731 100644 --- a/dev-packages/cli/README.md +++ b/dev-packages/cli/README.md @@ -12,31 +12,35 @@ ## Outline -- [**Description**](#description) -- [**Getting Started**](#getting-started) -- [**Configure**](#configure) - - [**Application Properties**](#application-properties) - - [**Default Preferences**](#default-preferences) - - [**Default Theme**](#default-theme) - - [**Build Target**](#build-target) - - [**Electron Frontend Application Config**](#electron-frontend-application-config) - - [**Using Latest Builds**](#using-latest-builds) -- [**Building**](#building) - - [**Build**](#build) - - [**Watch**](#watch) - - [**Clean**](#clean) -- [**Rebuilding Native Modules**](#rebuilding-native-modules) -- [**Running**](#running) -- [**Debugging**](#debugging) -- [**Testing**](#testing) - - [**Enabling Tests**](#enabling-tests) - - [**Writing Tests**](#writing-tests) - - [**Running Tests**](#running-tests) - - [**Configuring Tests**](#configuring-tests) - - [**Inspecting Tests**](#inspecting-tests) - - [**Reporting Test Coverage**](#reporting-test-coverage) -- [**Downloading Plugins**](#downloading-plugins) -- [**Autogenerated Application**](#autogenerated-application) +- [Outline](#outline) +- [Description](#description) +- [Getting Started](#getting-started) +- [Configure](#configure) + - [Application Properties](#application-properties) + - [Default Preferences](#default-preferences) + - [Default Theme](#default-theme) + - [Build Target](#build-target) + - [Electron Frontend Application Config](#electron-frontend-application-config) + - [Using Latest Builds](#using-latest-builds) +- [Building](#building) + - [Build](#build) + - [Watch](#watch) + - [Clean](#clean) +- [Rebuilding Native Modules](#rebuilding-native-modules) +- [Running](#running) +- [Debugging](#debugging) +- [Testing](#testing) + - [Enabling Tests](#enabling-tests) + - [Writing Tests](#writing-tests) + - [Running Tests](#running-tests) + - [Configuring Tests](#configuring-tests) + - [Inspecting Tests](#inspecting-tests) + - [Reporting Test Coverage](#reporting-test-coverage) +- [Downloading Plugins](#downloading-plugins) +- [Autogenerated Application](#autogenerated-application) +- [Additional Information](#additional-information) +- [License](#license) +- [Trademark](#trademark) ## Description @@ -301,7 +305,7 @@ The `@theia/cli` package provides a utility for applications to define and downl theia download:plugins -This utility works by declaring in the `package.json` a location to store downloaded plugins, as well defining each plugin the application wishes to download. +This utility works by declaring in the `package.json` a location to store downloaded plugins, as well as defining each plugin the application wishes to download. The property `theiaPluginsDir` describes the location of which to download plugins (relative to the `package.json`), for example: @@ -317,8 +321,11 @@ The property `theiaPlugins` describes the list of plugins to download, for examp "vscode-builtin-extension-pack": "https://open-vsx.org/api/eclipse-theia/builtin-extension-pack/1.50.0/file/eclipse-theia.builtin-extension-pack-1.50.0.vsix", "vscode-editorconfig": "https://open-vsx.org/api/EditorConfig/EditorConfig/0.14.4/file/EditorConfig.EditorConfig-0.14.4.vsix", "vscode-eslint": "https://open-vsx.org/api/dbaeumer/vscode-eslint/2.1.1/file/dbaeumer.vscode-eslint-2.1.1.vsix", + "rust-analyzer": "https://open-vsx.org/api/rust-lang/rust-analyzer/${targetPlatform}/0.4.1473/file/rust-lang.rust-analyzer-0.4.1473@${targetPlatform}.vsix" } ``` +As seen in the `rust-analyzer` entry we can use placeholders in the URLs. Supported placeholders are: +- The `${targetPlatform}` Placeholder, which resolves to a string like `win32-x64` describing the local system and architecture. This is useful for adding non-universal plugins. Please note that in order to use `extensionPacks` properly you should use `namespace.name` as the `id` you give extensions so that when resolving the pack we do not re-download an existing plugin under a different name. diff --git a/dev-packages/cli/package.json b/dev-packages/cli/package.json index 169a071658582..76fb3f149c70d 100644 --- a/dev-packages/cli/package.json +++ b/dev-packages/cli/package.json @@ -42,6 +42,7 @@ "chai": "^4.2.0", "chalk": "4.0.0", "decompress": "^4.2.1", + "escape-string-regexp": "4.0.0", "glob": "^8.0.3", "limiter": "^2.1.0", "log-update": "^4.0.0", diff --git a/dev-packages/cli/src/download-plugins.ts b/dev-packages/cli/src/download-plugins.ts index 95f54f5c150b2..dc5da1c7744f6 100644 --- a/dev-packages/cli/src/download-plugins.ts +++ b/dev-packages/cli/src/download-plugins.ts @@ -33,6 +33,7 @@ import { NodeRequestService } from '@theia/request/lib/node-request-service'; import { DEFAULT_SUPPORTED_API_VERSION } from '@theia/application-package/lib/api'; import { RequestContext } from '@theia/request'; import { RateLimiter } from 'limiter'; +import escapeStringRegexp = require('escape-string-regexp'); temp.track(); @@ -145,7 +146,7 @@ export default async function downloadPlugins(options: DownloadPluginsOptions = // This will include both "normal" plugins as well as "extension packs". const pluginsToDownload = Object.entries(pck.theiaPlugins) .filter((entry: [string, unknown]): entry is [string, string] => typeof entry[1] === 'string') - .map(([pluginId, url]) => ({ id: pluginId, downloadUrl: url })); + .map(([pluginId, url]) => ({ id: pluginId, downloadUrl: resolveDownloadUrlPlaceholders(url) })); await downloader(pluginsToDownload); const handleDependencyList = async (dependencies: Array) => { @@ -195,6 +196,16 @@ export default async function downloadPlugins(options: DownloadPluginsOptions = } } +const placeholders: Record = { + targetPlatform: `${process.platform}-${process.arch}` +}; +function resolveDownloadUrlPlaceholders(url: string): string { + for (const [name, value] of Object.entries(placeholders)) { + url = url.replace(new RegExp(escapeStringRegexp(`\${${name}}`), 'g'), value); + } + return url; +} + /** * Downloads a plugin, will make multiple attempts before actually failing. * @param failures reference to an array storing all failures.