CLI update extension review fixes
parent
3ff7d4545b
commit
c210448601
|
@ -21,7 +21,7 @@ arguments=(
|
|||
'--show-versions[show versions of installed extensions, when using --list-extensions]'
|
||||
'--install-extension[install an extension]:id or path:_files -g "*.vsix(-.)"'
|
||||
'--uninstall-extension[uninstall an extension]:id or path:_files -g "*.vsix(-.)"'
|
||||
'--update-extensions[update the marketplace-installed extensions]'
|
||||
'--update-extensions[update the installed extensions]'
|
||||
'--enable-proposed-api[enables proposed API features for extensions]::extension id: '
|
||||
'--verbose[print verbose output (implies --wait)]'
|
||||
'--log[log level to use]:level [info]:(critical error warn info debug trace off)'
|
||||
|
|
|
@ -100,7 +100,7 @@ export const OPTIONS: OptionDescriptions<Required<NativeParsedArgs>> = {
|
|||
'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") },
|
||||
'uninstall-extension': { type: 'string[]', cat: 'e', args: 'ext-id', description: localize('uninstallExtension', "Uninstalls an extension.") },
|
||||
'update-extensions': { type: 'boolean', cat: 'e', description: localize('updateExtensions', "Update the marketplace-installed extensions.") },
|
||||
'update-extensions': { type: 'boolean', cat: 'e', description: localize('updateExtensions', "Update the installed extensions.") },
|
||||
'enable-proposed-api': { type: 'string[]', allowEmptyValue: true, cat: 'e', args: 'ext-id', description: localize('experimentalApis', "Enables proposed API features for extensions. Can receive one or more extension IDs to enable individually.") },
|
||||
|
||||
'version': { type: 'boolean', cat: 't', alias: 'v', description: localize('version', "Print version.") },
|
||||
|
|
|
@ -10,7 +10,7 @@ import { basename } from 'vs/base/common/resources';
|
|||
import { gt } from 'vs/base/common/semver/semver';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { localize } from 'vs/nls';
|
||||
import { EXTENSION_IDENTIFIER_REGEX, IExtensionGalleryService, IExtensionInfo, IExtensionManagementService, IGalleryExtension, ILocalExtension, InstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { EXTENSION_IDENTIFIER_REGEX, IExtensionGalleryService, IExtensionInfo, IExtensionManagementService, IGalleryExtension, ILocalExtension, InstallOptions, InstallExtensionInfo, InstallOperation } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { areSameExtensions, getGalleryExtensionId, getIdAndVersion } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { ExtensionType, EXTENSION_CATEGORIES, IExtensionManifest } from 'vs/platform/extensions/common/extensions';
|
||||
import { ILogger } from 'vs/platform/log/common/log';
|
||||
|
@ -29,7 +29,7 @@ function getId(manifest: IExtensionManifest, withVersion?: boolean): string {
|
|||
}
|
||||
|
||||
type InstallVSIXInfo = { vsix: URI; installOptions: InstallOptions };
|
||||
type InstallExtensionInfo = { id: string; version?: string; installOptions: InstallOptions };
|
||||
type CLIInstallExtensionInfo = { id: string; version?: string; installOptions: InstallOptions };
|
||||
|
||||
export class ExtensionManagementCLI {
|
||||
|
||||
|
@ -89,7 +89,7 @@ export class ExtensionManagementCLI {
|
|||
}
|
||||
|
||||
const installVSIXInfos: InstallVSIXInfo[] = [];
|
||||
let installExtensionInfos: InstallExtensionInfo[] = [];
|
||||
let installExtensionInfos: CLIInstallExtensionInfo[] = [];
|
||||
const addInstallExtensionInfo = (id: string, version: string | undefined, isBuiltin: boolean) => {
|
||||
installExtensionInfos.push({ id, version: version !== 'prerelease' ? version : undefined, installOptions: { ...installOptions, isBuiltin, installPreReleaseVersion: version === 'prerelease' || installOptions.installPreReleaseVersion } });
|
||||
};
|
||||
|
@ -178,45 +178,29 @@ export class ExtensionManagementCLI {
|
|||
const installedExtensionsQuery: IExtensionInfo[] = [];
|
||||
for (const extension of installedExtensions) {
|
||||
if (!!extension.identifier.uuid) { // No need to check new version for an unpublished extension
|
||||
installedExtensionsQuery.push({
|
||||
id: `${extension.manifest.publisher}.${extension.manifest.name}`,
|
||||
preRelease: extension.isPreReleaseVersion
|
||||
});
|
||||
installedExtensionsQuery.push({ ...extension.identifier, preRelease: extension.preRelease });
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.info(localize('updateExtensionsQuery', "Update extensions: querying version for {0} extensions", installedExtensionsQuery.length));
|
||||
this.logger.trace(localize('updateExtensionsQuery', "Fetching latest versions for {0} extensions", installedExtensionsQuery.length));
|
||||
const availableVersions = await this.extensionGalleryService.getExtensions(installedExtensionsQuery, { compatible: true }, CancellationToken.None);
|
||||
|
||||
const newVersionAvailable: [IGalleryExtension, boolean, string][] = [];
|
||||
const extensionsToUpdate: InstallExtensionInfo[] = [];
|
||||
for (const newVersion of availableVersions) {
|
||||
for (const oldVersion of installedExtensions) {
|
||||
if (areSameExtensions(oldVersion.identifier, newVersion.identifier) && gt(newVersion.version, oldVersion.manifest.version)) {
|
||||
newVersionAvailable.push([newVersion, oldVersion.isPreReleaseVersion, oldVersion.manifest.version]);
|
||||
extensionsToUpdate.push({
|
||||
extension: newVersion,
|
||||
options: { operation: InstallOperation.Update, installPreReleaseVersion: oldVersion.isPreReleaseVersion }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newVersionAvailable.length) {
|
||||
this.logger.info(localize('updateExtensionsNewVersionsAvailable', "Update extensions: {0} extensions have new version available", newVersionAvailable.length));
|
||||
const failed: string[] = [];
|
||||
await Promise.all(newVersionAvailable.map(async extensionInfo => {
|
||||
try {
|
||||
if (extensionInfo[1]) {
|
||||
this.logger.info(localize('updateExtensionsPrereleaseVersion', "Updating extension '{0}' from prerelease version {1} to version {2}", extensionInfo[0].identifier.id, extensionInfo[2], extensionInfo[0].version));
|
||||
}
|
||||
else {
|
||||
this.logger.info(localize('updateExtensionsStandardVersion', "Updating extension '{0}' from version {1} to version {2}", extensionInfo[0].identifier.id, extensionInfo[2], extensionInfo[0].version));
|
||||
}
|
||||
await this.extensionManagementService.installFromGallery(extensionInfo[0]);
|
||||
} catch (err) {
|
||||
this.logger.error(err.message || err.stack || err);
|
||||
failed.push(extensionInfo[0].identifier.id);
|
||||
}
|
||||
}));
|
||||
if (failed.length) {
|
||||
throw new Error(localize('installation failed', "Failed Installing Extensions: {0}", failed.join(', ')));
|
||||
}
|
||||
if (extensionsToUpdate.length) {
|
||||
this.logger.info(localize('updateExtensionsNewVersionsAvailable', "Updating extensions: {0}", extensionsToUpdate.map(ext => ext.extension.identifier.id).join(', ')));
|
||||
await this.extensionManagementService.installGalleryExtensions(extensionsToUpdate);
|
||||
this.logger.info(localize('updateExtensionsDone', "Updated {0} extensions", extensionsToUpdate.length));
|
||||
}
|
||||
else {
|
||||
this.logger.info(localize('updateExtensionsNoExtensions', "No extension to update"));
|
||||
|
@ -248,7 +232,7 @@ export class ExtensionManagementCLI {
|
|||
return null;
|
||||
}
|
||||
|
||||
private async getGalleryExtensions(extensions: InstallExtensionInfo[]): Promise<Map<string, IGalleryExtension>> {
|
||||
private async getGalleryExtensions(extensions: CLIInstallExtensionInfo[]): Promise<Map<string, IGalleryExtension>> {
|
||||
const galleryExtensions = new Map<string, IGalleryExtension>();
|
||||
const preRelease = extensions.some(e => e.installOptions.installPreReleaseVersion);
|
||||
const targetPlatform = await this.extensionManagementService.getTargetPlatform();
|
||||
|
@ -267,7 +251,7 @@ export class ExtensionManagementCLI {
|
|||
return galleryExtensions;
|
||||
}
|
||||
|
||||
private async installFromGallery({ id, version, installOptions }: InstallExtensionInfo, galleryExtension: IGalleryExtension, installed: ILocalExtension[]): Promise<IExtensionManifest | null> {
|
||||
private async installFromGallery({ id, version, installOptions }: CLIInstallExtensionInfo, galleryExtension: IGalleryExtension, installed: ILocalExtension[]): Promise<IExtensionManifest | null> {
|
||||
const manifest = await this.extensionGalleryService.getManifest(galleryExtension, CancellationToken.None);
|
||||
if (manifest && !this.validateExtensionKind(manifest)) {
|
||||
return null;
|
||||
|
|
|
@ -159,7 +159,7 @@ class CliMain extends Disposable {
|
|||
return extensionManagementCLI.uninstallExtensions(this.asExtensionIdOrVSIX(this.args['uninstall-extension']), !!this.args['force']);
|
||||
}
|
||||
|
||||
// Update the marketplace-installed extensions
|
||||
// Update the installed extensions
|
||||
else if (this.args['update-extensions']) {
|
||||
return extensionManagementCLI.updateExtensions();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue