* Revert "fix #232043 (#233596)"
This reverts commit e9d6c6afc0
.
* #232043 revert cli command and support downloading VSIX in UI
This commit is contained in:
Родитель
02d23bdf5d
Коммит
653fd419de
|
@ -7,7 +7,7 @@ use std::collections::HashMap;
|
||||||
|
|
||||||
use cli::commands::args::{
|
use cli::commands::args::{
|
||||||
CliCore, Commands, DesktopCodeOptions, ExtensionArgs, ExtensionSubcommand,
|
CliCore, Commands, DesktopCodeOptions, ExtensionArgs, ExtensionSubcommand,
|
||||||
InstallExtensionArgs, ListExtensionArgs, UninstallExtensionArgs, DownloadExtensionArgs,
|
InstallExtensionArgs, ListExtensionArgs, UninstallExtensionArgs,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Tries to parse the argv using the legacy CLI interface, looking for its
|
/// Tries to parse the argv using the legacy CLI interface, looking for its
|
||||||
|
@ -64,7 +64,6 @@ pub fn try_parse_legacy(
|
||||||
// Now translate them to subcommands.
|
// Now translate them to subcommands.
|
||||||
// --list-extensions -> ext list
|
// --list-extensions -> ext list
|
||||||
// --update-extensions -> update
|
// --update-extensions -> update
|
||||||
// --download-extension -> ext download <id>
|
|
||||||
// --install-extension=id -> ext install <id>
|
// --install-extension=id -> ext install <id>
|
||||||
// --uninstall-extension=id -> ext uninstall <id>
|
// --uninstall-extension=id -> ext uninstall <id>
|
||||||
// --status -> status
|
// --status -> status
|
||||||
|
@ -80,17 +79,6 @@ pub fn try_parse_legacy(
|
||||||
})),
|
})),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
} else if let Some(exts) = args.get("download-extension") {
|
|
||||||
Some(CliCore {
|
|
||||||
subcommand: Some(Commands::Extension(ExtensionArgs {
|
|
||||||
subcommand: ExtensionSubcommand::Download(DownloadExtensionArgs {
|
|
||||||
id: exts.to_vec(),
|
|
||||||
location: get_first_arg_value("location"),
|
|
||||||
}),
|
|
||||||
desktop_code_options,
|
|
||||||
})),
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
} else if let Some(exts) = args.remove("install-extension") {
|
} else if let Some(exts) = args.remove("install-extension") {
|
||||||
Some(CliCore {
|
Some(CliCore {
|
||||||
subcommand: Some(Commands::Extension(ExtensionArgs {
|
subcommand: Some(Commands::Extension(ExtensionArgs {
|
||||||
|
|
|
@ -272,8 +272,6 @@ pub enum ExtensionSubcommand {
|
||||||
Uninstall(UninstallExtensionArgs),
|
Uninstall(UninstallExtensionArgs),
|
||||||
/// Update the installed extensions.
|
/// Update the installed extensions.
|
||||||
Update,
|
Update,
|
||||||
/// Download an extension.
|
|
||||||
Download(DownloadExtensionArgs),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtensionSubcommand {
|
impl ExtensionSubcommand {
|
||||||
|
@ -307,16 +305,6 @@ impl ExtensionSubcommand {
|
||||||
ExtensionSubcommand::Update => {
|
ExtensionSubcommand::Update => {
|
||||||
target.push("--update-extensions".to_string());
|
target.push("--update-extensions".to_string());
|
||||||
}
|
}
|
||||||
ExtensionSubcommand::Download(args) => {
|
|
||||||
for id in args.id.iter() {
|
|
||||||
target.push(format!("--download-extension={id}"));
|
|
||||||
}
|
|
||||||
if let Some(location) = &args.location {
|
|
||||||
if !location.is_empty() {
|
|
||||||
target.push(format!("--location={location}"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -359,21 +347,6 @@ pub struct UninstallExtensionArgs {
|
||||||
pub id: Vec<String>,
|
pub id: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Args, Debug, Clone)]
|
|
||||||
pub struct DownloadExtensionArgs {
|
|
||||||
/// Id of the extension to download. The identifier of an
|
|
||||||
/// extension is '${publisher}.${name}'. Should provide '--location' to specify the location to download the VSIX.
|
|
||||||
/// To download a specific version provide '@${version}'.
|
|
||||||
/// For example: 'vscode.csharp@1.2.3'.
|
|
||||||
#[clap(name = "ext-id")]
|
|
||||||
pub id: Vec<String>,
|
|
||||||
|
|
||||||
/// Specify the location to download the VSIX.
|
|
||||||
#[clap(long, value_name = "location")]
|
|
||||||
pub location: Option<String>,
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Args, Debug, Clone)]
|
#[derive(Args, Debug, Clone)]
|
||||||
pub struct VersionArgs {
|
pub struct VersionArgs {
|
||||||
#[clap(subcommand)]
|
#[clap(subcommand)]
|
||||||
|
|
|
@ -49,7 +49,7 @@ _@@APPNAME@@()
|
||||||
--list-extensions --show-versions --install-extension
|
--list-extensions --show-versions --install-extension
|
||||||
--uninstall-extension --enable-proposed-api --verbose --log -s
|
--uninstall-extension --enable-proposed-api --verbose --log -s
|
||||||
--status -p --performance --prof-startup --disable-extensions
|
--status -p --performance --prof-startup --disable-extensions
|
||||||
--disable-extension --inspect-extensions --update-extensions --download-extension
|
--disable-extension --inspect-extensions --update-extensions
|
||||||
--inspect-brk-extensions --disable-gpu' -- "$cur") )
|
--inspect-brk-extensions --disable-gpu' -- "$cur") )
|
||||||
[[ $COMPREPLY == *= ]] && compopt -o nospace
|
[[ $COMPREPLY == *= ]] && compopt -o nospace
|
||||||
return
|
return
|
||||||
|
|
|
@ -20,9 +20,8 @@ arguments=(
|
||||||
'--category[filters installed extension list by category, when using --list-extensions]'
|
'--category[filters installed extension list by category, when using --list-extensions]'
|
||||||
'--show-versions[show versions of installed extensions, when using --list-extensions]'
|
'--show-versions[show versions of installed extensions, when using --list-extensions]'
|
||||||
'--install-extension[install an extension]:id or path:_files -g "*.vsix(-.)"'
|
'--install-extension[install an extension]:id or path:_files -g "*.vsix(-.)"'
|
||||||
'--uninstall-extension[uninstall an extension]:id'
|
'--uninstall-extension[uninstall an extension]:id or path:_files -g "*.vsix(-.)"'
|
||||||
'--update-extensions[update the installed extensions]'
|
'--update-extensions[update the installed extensions]'
|
||||||
'--download-extension[download an extension]:id'
|
|
||||||
'--enable-proposed-api[enables proposed API features for extensions]::extension id: '
|
'--enable-proposed-api[enables proposed API features for extensions]::extension id: '
|
||||||
'--verbose[print verbose output (implies --wait)]'
|
'--verbose[print verbose output (implies --wait)]'
|
||||||
'--log[log level to use]:level [info]:(critical error warn info debug trace off)'
|
'--log[log level to use]:level [info]:(critical error warn info debug trace off)'
|
||||||
|
|
|
@ -33,7 +33,6 @@ function shouldSpawnCliProcess(argv: NativeParsedArgs): boolean {
|
||||||
return !!argv['install-source']
|
return !!argv['install-source']
|
||||||
|| !!argv['list-extensions']
|
|| !!argv['list-extensions']
|
||||||
|| !!argv['install-extension']
|
|| !!argv['install-extension']
|
||||||
|| !!argv['download-extension']
|
|
||||||
|| !!argv['uninstall-extension']
|
|| !!argv['uninstall-extension']
|
||||||
|| !!argv['update-extensions']
|
|| !!argv['update-extensions']
|
||||||
|| !!argv['locate-extension']
|
|| !!argv['locate-extension']
|
||||||
|
|
|
@ -282,14 +282,6 @@ class CliMain extends Disposable {
|
||||||
return instantiationService.createInstance(ExtensionManagementCLI, new ConsoleLogger(LogLevel.Info, false)).listExtensions(!!this.argv['show-versions'], this.argv['category'], profileLocation);
|
return instantiationService.createInstance(ExtensionManagementCLI, new ConsoleLogger(LogLevel.Info, false)).listExtensions(!!this.argv['show-versions'], this.argv['category'], profileLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download Extensions
|
|
||||||
else if (this.argv['download-extension']) {
|
|
||||||
if (!this.argv['location']) {
|
|
||||||
throw new Error('The location argument is required to download an extension.');
|
|
||||||
}
|
|
||||||
return instantiationService.createInstance(ExtensionManagementCLI, new ConsoleLogger(LogLevel.Info, false)).downloadExtensions(this.argv['download-extension'], URI.parse(this.argv['location']));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Install Extension
|
// Install Extension
|
||||||
else if (this.argv['install-extension'] || this.argv['install-builtin-extension']) {
|
else if (this.argv['install-extension'] || this.argv['install-builtin-extension']) {
|
||||||
const installOptions: InstallOptions = { isMachineScoped: !!this.argv['do-not-sync'], installPreReleaseVersion: !!this.argv['pre-release'], profileLocation };
|
const installOptions: InstallOptions = { isMachineScoped: !!this.argv['do-not-sync'], installPreReleaseVersion: !!this.argv['pre-release'], profileLocation };
|
||||||
|
|
|
@ -75,8 +75,6 @@ export interface NativeParsedArgs {
|
||||||
'disable-extensions'?: boolean;
|
'disable-extensions'?: boolean;
|
||||||
'disable-extension'?: string[]; // undefined or array of 1 or more
|
'disable-extension'?: string[]; // undefined or array of 1 or more
|
||||||
'list-extensions'?: boolean;
|
'list-extensions'?: boolean;
|
||||||
'download-extension'?: string[];
|
|
||||||
'location'?: string;
|
|
||||||
'show-versions'?: boolean;
|
'show-versions'?: boolean;
|
||||||
'category'?: string;
|
'category'?: string;
|
||||||
'install-extension'?: string[]; // undefined or array of 1 or more
|
'install-extension'?: string[]; // undefined or array of 1 or more
|
||||||
|
|
|
@ -97,7 +97,6 @@ export const OPTIONS: OptionDescriptions<Required<NativeParsedArgs>> = {
|
||||||
'list-extensions': { type: 'boolean', cat: 'e', description: localize('listExtensions', "List the installed extensions.") },
|
'list-extensions': { type: 'boolean', cat: 'e', description: localize('listExtensions', "List the installed extensions.") },
|
||||||
'show-versions': { type: 'boolean', cat: 'e', description: localize('showVersions', "Show versions of installed extensions, when using --list-extensions.") },
|
'show-versions': { type: 'boolean', cat: 'e', description: localize('showVersions', "Show versions of installed extensions, when using --list-extensions.") },
|
||||||
'category': { type: 'string', allowEmptyValue: true, cat: 'e', description: localize('category', "Filters installed extensions by provided category, when using --list-extensions."), args: 'category' },
|
'category': { type: 'string', allowEmptyValue: true, cat: 'e', description: localize('category', "Filters installed extensions by provided category, when using --list-extensions."), args: 'category' },
|
||||||
'download-extension': { type: 'string[]', cat: 'e', args: 'ext-id', description: localize('downloadExtension', "Downloads the extension VSIX that can be installable. The argument is an identifier of an extension that is '${publisher}.${name}'. To download a specific version provide '@${version}'. For example: 'vscode.csharp@1.2.3'. Should provide '--location' to specify the location to download the VSIX.") },
|
|
||||||
'install-extension': { type: 'string[]', cat: 'e', args: 'ext-id | path', description: localize('installExtension', "Installs or updates an extension. The argument is either an extension id or a path to a VSIX. The identifier of an extension is '${publisher}.${name}'. Use '--force' argument to update to latest version. To install a specific version provide '@${version}'. For example: 'vscode.csharp@1.2.3'.") },
|
'install-extension': { type: 'string[]', cat: 'e', args: 'ext-id | path', description: localize('installExtension', "Installs or updates an extension. The argument is either an extension id or a path to a VSIX. The identifier of an extension is '${publisher}.${name}'. Use '--force' argument to update to latest version. To install a specific version provide '@${version}'. For example: 'vscode.csharp@1.2.3'.") },
|
||||||
'pre-release': { type: 'boolean', cat: 'e', description: localize('install prerelease', "Installs the pre-release version of the extension, when using --install-extension") },
|
'pre-release': { type: 'boolean', cat: 'e', description: localize('install prerelease', "Installs the pre-release version of the extension, when using --install-extension") },
|
||||||
'uninstall-extension': { type: 'string[]', cat: 'e', args: 'ext-id', description: localize('uninstallExtension', "Uninstalls an extension.") },
|
'uninstall-extension': { type: 'string[]', cat: 'e', args: 'ext-id', description: localize('uninstallExtension', "Uninstalls an extension.") },
|
||||||
|
@ -164,7 +163,6 @@ export const OPTIONS: OptionDescriptions<Required<NativeParsedArgs>> = {
|
||||||
'file-chmod': { type: 'boolean' },
|
'file-chmod': { type: 'boolean' },
|
||||||
'install-builtin-extension': { type: 'string[]' },
|
'install-builtin-extension': { type: 'string[]' },
|
||||||
'force': { type: 'boolean' },
|
'force': { type: 'boolean' },
|
||||||
'location': { type: 'string' },
|
|
||||||
'do-not-sync': { type: 'boolean' },
|
'do-not-sync': { type: 'boolean' },
|
||||||
'trace': { type: 'boolean' },
|
'trace': { type: 'boolean' },
|
||||||
'trace-category-filter': { type: 'string' },
|
'trace-category-filter': { type: 'string' },
|
||||||
|
|
|
@ -14,7 +14,6 @@ import { EXTENSION_IDENTIFIER_REGEX, IExtensionGalleryService, IExtensionInfo, I
|
||||||
import { areSameExtensions, getExtensionId, getGalleryExtensionId, getIdAndVersion } from './extensionManagementUtil.js';
|
import { areSameExtensions, getExtensionId, getGalleryExtensionId, getIdAndVersion } from './extensionManagementUtil.js';
|
||||||
import { ExtensionType, EXTENSION_CATEGORIES, IExtensionManifest } from '../../extensions/common/extensions.js';
|
import { ExtensionType, EXTENSION_CATEGORIES, IExtensionManifest } from '../../extensions/common/extensions.js';
|
||||||
import { ILogger } from '../../log/common/log.js';
|
import { ILogger } from '../../log/common/log.js';
|
||||||
import { IUriIdentityService } from '../../uriIdentity/common/uriIdentity.js';
|
|
||||||
|
|
||||||
|
|
||||||
const notFound = (id: string) => localize('notFound', "Extension '{0}' not found.", id);
|
const notFound = (id: string) => localize('notFound', "Extension '{0}' not found.", id);
|
||||||
|
@ -29,7 +28,6 @@ export class ExtensionManagementCLI {
|
||||||
protected readonly logger: ILogger,
|
protected readonly logger: ILogger,
|
||||||
@IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService,
|
@IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService,
|
||||||
@IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService,
|
@IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService,
|
||||||
@IUriIdentityService private readonly uriIdentityService: IUriIdentityService,
|
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
protected get location(): string | undefined {
|
protected get location(): string | undefined {
|
||||||
|
@ -72,42 +70,6 @@ export class ExtensionManagementCLI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async downloadExtensions(extensions: string[], target: URI): Promise<void> {
|
|
||||||
if (!extensions.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.info(localize('downloadingExtensions', "Downloading extensions..."));
|
|
||||||
|
|
||||||
const extensionsInfo: IExtensionInfo[] = [];
|
|
||||||
for (const extension of extensions) {
|
|
||||||
const [id, version] = getIdAndVersion(extension);
|
|
||||||
extensionsInfo.push({ id, version: version !== 'prerelease' ? version : undefined, preRelease: version === 'prerelease' });
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const galleryExtensions = await this.extensionGalleryService.getExtensions(extensionsInfo, CancellationToken.None);
|
|
||||||
const targetPlatform = await this.extensionManagementService.getTargetPlatform();
|
|
||||||
await Promise.allSettled(extensionsInfo.map(async extensionInfo => {
|
|
||||||
const galleryExtension = galleryExtensions.find(e => areSameExtensions(e.identifier, { id: extensionInfo.id }));
|
|
||||||
if (!galleryExtension) {
|
|
||||||
this.logger.error(`${notFound(extensionInfo.id)}\n${useId}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const compatible = await this.extensionGalleryService.getCompatibleExtension(galleryExtension, !!extensionInfo.hasPreRelease, targetPlatform);
|
|
||||||
try {
|
|
||||||
await this.extensionGalleryService.download(compatible ?? galleryExtension, this.uriIdentityService.extUri.joinPath(target, `${galleryExtension.identifier.id}-${galleryExtension.version}.vsix`), InstallOperation.None);
|
|
||||||
this.logger.info(localize('successDownload', "Extension '{0}' was successfully downloaded.", extensionInfo.id));
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error(localize('error while downloading extension', "Error while downloading extension '{0}': {1}", extensionInfo.id, getErrorMessage(error)));
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error(localize('error while downloading extensions', "Error while downloading extensions: {0}", getErrorMessage(error)));
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async installExtensions(extensions: (string | URI)[], builtinExtensions: (string | URI)[], installOptions: InstallOptions, force: boolean): Promise<void> {
|
public async installExtensions(extensions: (string | URI)[], builtinExtensions: (string | URI)[], installOptions: InstallOptions, force: boolean): Promise<void> {
|
||||||
const failed: string[] = [];
|
const failed: string[] = [];
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ import { ServiceCollection } from '../../../platform/instantiation/common/servic
|
||||||
import { ILabelService } from '../../../platform/label/common/label.js';
|
import { ILabelService } from '../../../platform/label/common/label.js';
|
||||||
import { AbstractMessageLogger, ILogger, LogLevel } from '../../../platform/log/common/log.js';
|
import { AbstractMessageLogger, ILogger, LogLevel } from '../../../platform/log/common/log.js';
|
||||||
import { IOpenerService } from '../../../platform/opener/common/opener.js';
|
import { IOpenerService } from '../../../platform/opener/common/opener.js';
|
||||||
import { IUriIdentityService } from '../../../platform/uriIdentity/common/uriIdentity.js';
|
|
||||||
import { IOpenWindowOptions, IWindowOpenable } from '../../../platform/window/common/window.js';
|
import { IOpenWindowOptions, IWindowOpenable } from '../../../platform/window/common/window.js';
|
||||||
import { IWorkbenchEnvironmentService } from '../../services/environment/common/environmentService.js';
|
import { IWorkbenchEnvironmentService } from '../../services/environment/common/environmentService.js';
|
||||||
import { IExtensionManagementServerService } from '../../services/extensionManagement/common/extensionManagement.js';
|
import { IExtensionManagementServerService } from '../../services/extensionManagement/common/extensionManagement.js';
|
||||||
|
@ -104,12 +103,11 @@ class RemoteExtensionManagementCLI extends ExtensionManagementCLI {
|
||||||
logger: ILogger,
|
logger: ILogger,
|
||||||
@IExtensionManagementService extensionManagementService: IExtensionManagementService,
|
@IExtensionManagementService extensionManagementService: IExtensionManagementService,
|
||||||
@IExtensionGalleryService extensionGalleryService: IExtensionGalleryService,
|
@IExtensionGalleryService extensionGalleryService: IExtensionGalleryService,
|
||||||
@IUriIdentityService uriIdentityService: IUriIdentityService,
|
|
||||||
@ILabelService labelService: ILabelService,
|
@ILabelService labelService: ILabelService,
|
||||||
@IWorkbenchEnvironmentService envService: IWorkbenchEnvironmentService,
|
@IWorkbenchEnvironmentService envService: IWorkbenchEnvironmentService,
|
||||||
@IExtensionManifestPropertiesService private readonly _extensionManifestPropertiesService: IExtensionManifestPropertiesService,
|
@IExtensionManifestPropertiesService private readonly _extensionManifestPropertiesService: IExtensionManifestPropertiesService,
|
||||||
) {
|
) {
|
||||||
super(logger, extensionManagementService, extensionGalleryService, uriIdentityService);
|
super(logger, extensionManagementService, extensionGalleryService);
|
||||||
|
|
||||||
const remoteAuthority = envService.remoteAuthority;
|
const remoteAuthority = envService.remoteAuthority;
|
||||||
this._location = remoteAuthority ? labelService.getHostLabel(Schemas.vscodeRemote, remoteAuthority) : undefined;
|
this._location = remoteAuthority ? labelService.getHostLabel(Schemas.vscodeRemote, remoteAuthority) : undefined;
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { KeyMod, KeyCode } from '../../../../base/common/keyCodes.js';
|
||||||
import { Registry } from '../../../../platform/registry/common/platform.js';
|
import { Registry } from '../../../../platform/registry/common/platform.js';
|
||||||
import { MenuRegistry, MenuId, registerAction2, Action2, IMenuItem, IAction2Options } from '../../../../platform/actions/common/actions.js';
|
import { MenuRegistry, MenuId, registerAction2, Action2, IMenuItem, IAction2Options } from '../../../../platform/actions/common/actions.js';
|
||||||
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
|
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
|
||||||
import { ExtensionsLocalizedLabel, IExtensionManagementService, IExtensionGalleryService, PreferencesLocalizedLabel, EXTENSION_INSTALL_SOURCE_CONTEXT, ExtensionInstallSource, UseUnpkgResourceApi } from '../../../../platform/extensionManagement/common/extensionManagement.js';
|
import { ExtensionsLocalizedLabel, IExtensionManagementService, IExtensionGalleryService, PreferencesLocalizedLabel, EXTENSION_INSTALL_SOURCE_CONTEXT, ExtensionInstallSource, UseUnpkgResourceApi, InstallOperation } from '../../../../platform/extensionManagement/common/extensionManagement.js';
|
||||||
import { EnablementState, IExtensionManagementServerService, IWorkbenchExtensionEnablementService, IWorkbenchExtensionManagementService, extensionsConfigurationNodeBase } from '../../../services/extensionManagement/common/extensionManagement.js';
|
import { EnablementState, IExtensionManagementServerService, IWorkbenchExtensionEnablementService, IWorkbenchExtensionManagementService, extensionsConfigurationNodeBase } from '../../../services/extensionManagement/common/extensionManagement.js';
|
||||||
import { IExtensionIgnoredRecommendationsService, IExtensionRecommendationsService } from '../../../services/extensionRecommendations/common/extensionRecommendations.js';
|
import { IExtensionIgnoredRecommendationsService, IExtensionRecommendationsService } from '../../../services/extensionRecommendations/common/extensionRecommendations.js';
|
||||||
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from '../../../common/contributions.js';
|
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from '../../../common/contributions.js';
|
||||||
|
@ -77,6 +77,7 @@ import { CONTEXT_KEYBINDINGS_EDITOR } from '../../preferences/common/preferences
|
||||||
import { ProgressLocation } from '../../../../platform/progress/common/progress.js';
|
import { ProgressLocation } from '../../../../platform/progress/common/progress.js';
|
||||||
import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js';
|
import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js';
|
||||||
import { IConfigurationMigrationRegistry, Extensions as ConfigurationMigrationExtensions } from '../../../common/configuration.js';
|
import { IConfigurationMigrationRegistry, Extensions as ConfigurationMigrationExtensions } from '../../../common/configuration.js';
|
||||||
|
import { IProductService } from '../../../../platform/product/common/productService.js';
|
||||||
|
|
||||||
// Singletons
|
// Singletons
|
||||||
registerSingleton(IExtensionsWorkbenchService, ExtensionsWorkbenchService, InstantiationType.Eager /* Auto updates extensions */);
|
registerSingleton(IExtensionsWorkbenchService, ExtensionsWorkbenchService, InstantiationType.Eager /* Auto updates extensions */);
|
||||||
|
@ -491,7 +492,7 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
|
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
|
||||||
@IExtensionGalleryService extensionGalleryService: IExtensionGalleryService,
|
@IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService,
|
||||||
@IContextKeyService contextKeyService: IContextKeyService,
|
@IContextKeyService contextKeyService: IContextKeyService,
|
||||||
@IViewsService private readonly viewsService: IViewsService,
|
@IViewsService private readonly viewsService: IViewsService,
|
||||||
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
|
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||||
|
@ -499,6 +500,10 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi
|
||||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||||
@IDialogService private readonly dialogService: IDialogService,
|
@IDialogService private readonly dialogService: IDialogService,
|
||||||
@ICommandService private readonly commandService: ICommandService,
|
@ICommandService private readonly commandService: ICommandService,
|
||||||
|
@IFileDialogService private readonly fileDialogService: IFileDialogService,
|
||||||
|
@IProductService private readonly productService: IProductService,
|
||||||
|
@IUriIdentityService private readonly uriIdentityService: IUriIdentityService,
|
||||||
|
@INotificationService private readonly notificationService: INotificationService,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
const hasGalleryContext = CONTEXT_HAS_GALLERY.bindTo(contextKeyService);
|
const hasGalleryContext = CONTEXT_HAS_GALLERY.bindTo(contextKeyService);
|
||||||
|
@ -1582,6 +1587,53 @@ class ExtensionsContributions extends Disposable implements IWorkbenchContributi
|
||||||
run: async (accessor: ServicesAccessor, id: string) => accessor.get(IPreferencesService).openSettings({ jsonEditor: false, query: `@ext:${id}` })
|
run: async (accessor: ServicesAccessor, id: string) => accessor.get(IPreferencesService).openSettings({ jsonEditor: false, query: `@ext:${id}` })
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const downloadVSIX = async (extensionId: string, preRelease: boolean) => {
|
||||||
|
const result = await this.fileDialogService.showOpenDialog({
|
||||||
|
title: localize('download title', "Select folder to download the VSIX"),
|
||||||
|
canSelectFiles: false,
|
||||||
|
canSelectFolders: true,
|
||||||
|
canSelectMany: false,
|
||||||
|
openLabel: localize('download', "Download"),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result?.[0]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [galleryExtension] = await this.extensionGalleryService.getExtensions([{ id: extensionId, preRelease: true }], { compatible: true }, CancellationToken.None);
|
||||||
|
if (!galleryExtension) {
|
||||||
|
throw new Error(localize('not found', "Extension '{0}' not found.", extensionId));
|
||||||
|
}
|
||||||
|
await this.extensionGalleryService.download(galleryExtension, this.uriIdentityService.extUri.joinPath(result[0], `${galleryExtension.identifier.id}-${galleryExtension.version}.vsix`), InstallOperation.None);
|
||||||
|
this.notificationService.info(localize('download.completed', "Successfully downloaded the VSIX"));
|
||||||
|
};
|
||||||
|
|
||||||
|
this.registerExtensionAction({
|
||||||
|
id: 'workbench.extensions.action.download',
|
||||||
|
title: localize('download VSIX', "Download VSIX"),
|
||||||
|
menu: {
|
||||||
|
id: MenuId.ExtensionContext,
|
||||||
|
when: ContextKeyExpr.and(ContextKeyExpr.equals('extensionStatus', 'uninstalled'), ContextKeyExpr.has('isGalleryExtension')),
|
||||||
|
order: this.productService.quality === 'stable' ? 0 : 1
|
||||||
|
},
|
||||||
|
run: async (accessor: ServicesAccessor, extensionId: string) => {
|
||||||
|
downloadVSIX(extensionId, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.registerExtensionAction({
|
||||||
|
id: 'workbench.extensions.action.downloadPreRelease',
|
||||||
|
title: localize('download pre-release', "Download Pre-Release VSIX"),
|
||||||
|
menu: {
|
||||||
|
id: MenuId.ExtensionContext,
|
||||||
|
when: ContextKeyExpr.and(ContextKeyExpr.equals('extensionStatus', 'uninstalled'), ContextKeyExpr.has('isGalleryExtension'), ContextKeyExpr.has('extensionHasPreReleaseVersion')),
|
||||||
|
order: this.productService.quality === 'stable' ? 1 : 0
|
||||||
|
},
|
||||||
|
run: async (accessor: ServicesAccessor, extensionId: string) => {
|
||||||
|
downloadVSIX(extensionId, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.registerExtensionAction({
|
this.registerExtensionAction({
|
||||||
id: 'workbench.extensions.action.manageAccountPreferences',
|
id: 'workbench.extensions.action.manageAccountPreferences',
|
||||||
title: localize2('workbench.extensions.action.changeAccountPreference', "Account Preferences"),
|
title: localize2('workbench.extensions.action.changeAccountPreference', "Account Preferences"),
|
||||||
|
|
Загрузка…
Ссылка в новой задаче