diff options
Diffstat (limited to 'src/vs/platform')
6 files changed, 60 insertions, 32 deletions
diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index 5bd1488b472..c9c362f066e 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -72,7 +72,7 @@ export interface ParsedArgs { remote?: string; 'disable-user-env-probe'?: boolean; 'force'?: boolean; - 'default'?: boolean; + 'donot-sync'?: boolean; 'force-user-env'?: boolean; 'sync'?: 'on' | 'off'; @@ -188,7 +188,7 @@ export const OPTIONS: OptionDescriptions<Required<ParsedArgs>> = { 'file-chmod': { type: 'boolean' }, 'driver-verbose': { type: 'boolean' }, 'force': { type: 'boolean' }, - 'default': { type: 'boolean' }, + 'donot-sync': { type: 'boolean' }, 'trace': { type: 'boolean' }, 'trace-category-filter': { type: 'string' }, 'trace-options': { type: 'string' }, diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index 36735a9b105..d5bbcec2963 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -92,7 +92,7 @@ export interface IGalleryMetadata { export interface ILocalExtension extends IExtension { readonly manifest: IExtensionManifest; - isDefault: boolean | undefined; + isMachineScoped: boolean; publisherId: string | null; publisherDisplayName: string | null; readmeUrl: URI | null; @@ -206,8 +206,8 @@ export interface IExtensionManagementService { zip(extension: ILocalExtension): Promise<URI>; unzip(zipLocation: URI): Promise<IExtensionIdentifier>; getManifest(vsix: URI): Promise<IExtensionManifest>; - install(vsix: URI, isDefault?: boolean): Promise<ILocalExtension>; - installFromGallery(extension: IGalleryExtension, isDefault?: boolean): Promise<ILocalExtension>; + install(vsix: URI, isMachineScoped?: boolean): Promise<ILocalExtension>; + installFromGallery(extension: IGalleryExtension, isMachineScoped?: boolean): Promise<ILocalExtension>; uninstall(extension: ILocalExtension, force?: boolean): Promise<void>; reinstallFromGallery(extension: ILocalExtension): Promise<void>; getInstalled(type?: ExtensionType): Promise<ILocalExtension[]>; diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 5fffb8f48e5..28da448838d 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -152,7 +152,7 @@ export class ExtensionManagementService extends Disposable implements IExtension } - install(vsix: URI, isDefault?: boolean): Promise<ILocalExtension> { + install(vsix: URI, isMachineScoped?: boolean): Promise<ILocalExtension> { this.logService.trace('ExtensionManagementService#install', vsix.toString()); return createCancelablePromise(token => { return this.downloadVsix(vsix).then(downloadLocation => { @@ -170,6 +170,7 @@ export class ExtensionManagementService extends Disposable implements IExtension .then(installedExtensions => { const existing = installedExtensions.filter(i => areSameExtensions(identifier, i.identifier))[0]; if (existing) { + isMachineScoped = isMachineScoped || existing.isMachineScoped; operation = InstallOperation.Update; if (identifierWithVersion.equals(new ExtensionIdentifierWithVersion(existing.identifier, existing.manifest.version))) { return this.extensionsScanner.removeExtension(existing, 'existing').then(null, e => Promise.reject(new Error(nls.localize('restartCode', "Please restart VS Code before reinstalling {0}.", manifest.displayName || manifest.name)))); @@ -194,8 +195,8 @@ export class ExtensionManagementService extends Disposable implements IExtension this._onInstallExtension.fire({ identifier, zipPath }); return this.getGalleryMetadata(getGalleryExtensionId(manifest.publisher, manifest.name)) .then( - metadata => this.installFromZipPath(identifierWithVersion, zipPath, { ...metadata, isDefault }, operation, token), - () => this.installFromZipPath(identifierWithVersion, zipPath, isDefault ? { isDefault } : undefined, operation, token)) + metadata => this.installFromZipPath(identifierWithVersion, zipPath, { ...metadata, isMachineScoped }, operation, token), + () => this.installFromZipPath(identifierWithVersion, zipPath, isMachineScoped ? { isMachineScoped } : undefined, operation, token)) .then( local => { this.logService.info('Successfully installed the extension:', identifier.id); return local; }, e => { @@ -239,7 +240,7 @@ export class ExtensionManagementService extends Disposable implements IExtension )); } - async installFromGallery(extension: IGalleryExtension, isDefault?: boolean): Promise<ILocalExtension> { + async installFromGallery(extension: IGalleryExtension, isMachineScoped?: boolean): Promise<ILocalExtension> { if (!this.galleryService.isEnabled()) { return Promise.reject(new Error(nls.localize('MarketPlaceDisabled', "Marketplace is not enabled"))); } @@ -288,7 +289,7 @@ export class ExtensionManagementService extends Disposable implements IExtension this.downloadInstallableExtension(extension, operation) .then(installableExtension => { - installableExtension.metadata.isDefault = isDefault !== undefined ? isDefault : existingExtension?.isDefault; + installableExtension.metadata.isMachineScoped = isMachineScoped || existingExtension?.isMachineScoped; return this.installExtension(installableExtension, cancellationToken) .then(local => this.extensionsDownloader.delete(URI.file(installableExtension.zipPath)).finally(() => { }).then(() => local)); }) @@ -483,7 +484,7 @@ export class ExtensionManagementService extends Disposable implements IExtension async updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): Promise<ILocalExtension> { this.logService.trace('ExtensionManagementService#updateMetadata', local.identifier.id); - local = await this.extensionsScanner.saveMetadataForLocalExtension(local, { ...metadata, isDefault: local.isDefault }); + local = await this.extensionsScanner.saveMetadataForLocalExtension(local, { ...metadata, isMachineScoped: local.isMachineScoped }); this.manifestCache.invalidate(); return local; } diff --git a/src/vs/platform/extensionManagement/node/extensionsScanner.ts b/src/vs/platform/extensionManagement/node/extensionsScanner.ts index 63c85181cc1..8c9d4ce94dd 100644 --- a/src/vs/platform/extensionManagement/node/extensionsScanner.ts +++ b/src/vs/platform/extensionManagement/node/extensionsScanner.ts @@ -32,7 +32,7 @@ const INSTALL_ERROR_EXTRACTING = 'extracting'; const INSTALL_ERROR_DELETING = 'deleting'; const INSTALL_ERROR_RENAMING = 'renaming'; -export type IMetadata = Partial<IGalleryMetadata & { isDefault: boolean; }>; +export type IMetadata = Partial<IGalleryMetadata & { isMachineScoped: boolean; }>; export class ExtensionsScanner extends Disposable { @@ -131,6 +131,9 @@ export class ExtensionsScanner extends Disposable { async saveMetadataForLocalExtension(local: ILocalExtension, metadata: IMetadata): Promise<ILocalExtension> { this.setMetadata(local, metadata); + + // unset if false + metadata.isMachineScoped = metadata.isMachineScoped || undefined; const manifestPath = path.join(local.location.fsPath, 'package.json'); const raw = await pfs.readFile(manifestPath, 'utf8'); const { manifest } = await this.parseManifest(raw); @@ -229,7 +232,7 @@ export class ExtensionsScanner extends Disposable { const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0]; const changelogUrl = changelog ? URI.file(path.join(extensionPath, changelog)) : null; const identifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name) }; - const local = <ILocalExtension>{ type, identifier, manifest, location: URI.file(extensionPath), readmeUrl, changelogUrl, publisherDisplayName: null, publisherId: null, isDefault: undefined }; + const local = <ILocalExtension>{ type, identifier, manifest, location: URI.file(extensionPath), readmeUrl, changelogUrl, publisherDisplayName: null, publisherId: null, isMachineScoped: false }; if (metadata) { this.setMetadata(local, metadata); } @@ -261,7 +264,7 @@ export class ExtensionsScanner extends Disposable { local.publisherDisplayName = metadata.publisherDisplayName || null; local.publisherId = metadata.publisherId || null; local.identifier.uuid = metadata.id; - local.isDefault = metadata.isDefault; + local.isMachineScoped = !!metadata.isMachineScoped; } private async removeUninstalledExtensions(): Promise<void> { diff --git a/src/vs/platform/userDataSync/common/extensionsMerge.ts b/src/vs/platform/userDataSync/common/extensionsMerge.ts index 7b6a48834fc..07c8a7bd733 100644 --- a/src/vs/platform/userDataSync/common/extensionsMerge.ts +++ b/src/vs/platform/userDataSync/common/extensionsMerge.ts @@ -8,6 +8,9 @@ import { ISyncExtension } from 'vs/platform/userDataSync/common/userDataSync'; import { IExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { startsWith } from 'vs/base/common/strings'; import { deepClone } from 'vs/base/common/objects'; +import { ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { distinct } from 'vs/base/common/arrays'; export interface IMergeResult { added: ISyncExtension[]; @@ -201,3 +204,19 @@ function massageOutgoingExtension(extension: ISyncExtension, key: string): ISync } return massagedExtension; } + +export function getIgnoredExtensions(installed: ILocalExtension[], configurationService: IConfigurationService): string[] { + const defaultIgnoredExtensions = installed.filter(i => i.isMachineScoped).map(i => i.identifier.id.toLowerCase()); + const value = (configurationService.getValue<string[]>('sync.ignoredExtensions') || []).map(id => id.toLowerCase()); + const added: string[] = [], removed: string[] = []; + if (Array.isArray(value)) { + for (const key of value) { + if (startsWith(key, '-')) { + removed.push(key.substring(1)); + } else { + added.push(key); + } + } + } + return distinct([...defaultIgnoredExtensions, ...added,].filter(setting => removed.indexOf(setting) === -1)); +} diff --git a/src/vs/platform/userDataSync/common/extensionsSync.ts b/src/vs/platform/userDataSync/common/extensionsSync.ts index af62cda98db..1741086e3db 100644 --- a/src/vs/platform/userDataSync/common/extensionsSync.ts +++ b/src/vs/platform/userDataSync/common/extensionsSync.ts @@ -6,12 +6,12 @@ import { SyncStatus, IUserDataSyncStoreService, ISyncExtension, IUserDataSyncLogService, IUserDataSynchroniser, SyncResource, IUserDataSyncEnablementService, IUserDataSyncBackupStoreService, ISyncResourceHandle, ISyncPreviewResult, USER_DATA_SYNC_SCHEME } from 'vs/platform/userDataSync/common/userDataSync'; import { Event } from 'vs/base/common/event'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IExtensionManagementService, IExtensionGalleryService, IGlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionManagementService, IExtensionGalleryService, IGlobalExtensionEnablementService, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionType, IExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IFileService } from 'vs/platform/files/common/files'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { merge } from 'vs/platform/userDataSync/common/extensionsMerge'; +import { merge, getIgnoredExtensions } from 'vs/platform/userDataSync/common/extensionsMerge'; import { isNonEmptyArray } from 'vs/base/common/arrays'; import { AbstractSynchroniser, IRemoteUserData, ISyncData } from 'vs/platform/userDataSync/common/abstractSynchronizer'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; @@ -87,9 +87,11 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse const remoteUserData = await this.getRemoteUserData(lastSyncUserData); if (remoteUserData.syncData !== null) { - const localExtensions = await this.getLocalExtensions(); + const installedExtensions = await this.extensionManagementService.getInstalled(); + const localExtensions = this.getLocalExtensions(installedExtensions); const remoteExtensions = await this.parseAndMigrateExtensions(remoteUserData.syncData); - const { added, updated, remote, removed } = merge(localExtensions, remoteExtensions, localExtensions, [], this.getIgnoredExtensions()); + const ignoredExtensions = getIgnoredExtensions(installedExtensions, this.configurationService); + const { added, updated, remote, removed } = merge(localExtensions, remoteExtensions, localExtensions, [], ignoredExtensions); await this.apply({ added, removed, updated, remote, remoteUserData, localExtensions, skippedExtensions: [], lastSyncUserData, hasLocalChanged: added.length > 0 || removed.length > 0 || updated.length > 0, @@ -120,8 +122,10 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse this.logService.info(`${this.syncResourceLogLabel}: Started pushing extensions...`); this.setStatus(SyncStatus.Syncing); - const localExtensions = await this.getLocalExtensions(); - const { added, removed, updated, remote } = merge(localExtensions, null, null, [], this.getIgnoredExtensions()); + const installedExtensions = await this.extensionManagementService.getInstalled(); + const localExtensions = this.getLocalExtensions(installedExtensions); + const ignoredExtensions = getIgnoredExtensions(installedExtensions, this.configurationService); + const { added, removed, updated, remote } = merge(localExtensions, null, null, [], ignoredExtensions); const lastSyncUserData = await this.getLastSyncUserData<ILastSyncUserData>(); const remoteUserData = await this.getRemoteUserData(lastSyncUserData); await this.apply({ @@ -145,7 +149,8 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse async resolveContent(uri: URI): Promise<string | null> { if (isEqual(uri, ExtensionsSynchroniser.EXTENSIONS_DATA_URI)) { - const localExtensions = await this.getLocalExtensions(); + const installedExtensions = await this.extensionManagementService.getInstalled(); + const localExtensions = this.getLocalExtensions(installedExtensions); return this.format(localExtensions); } @@ -189,7 +194,8 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse async hasLocalData(): Promise<boolean> { try { - const localExtensions = await this.getLocalExtensions(); + const installedExtensions = await this.extensionManagementService.getInstalled(); + const localExtensions = this.getLocalExtensions(installedExtensions); if (isNonEmptyArray(localExtensions)) { return true; } @@ -206,9 +212,11 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse } protected async performReplace(syncData: ISyncData, remoteUserData: IRemoteUserData, lastSyncUserData: ILastSyncUserData | null): Promise<void> { - const localExtensions = await this.getLocalExtensions(); + const installedExtensions = await this.extensionManagementService.getInstalled(); + const localExtensions = this.getLocalExtensions(installedExtensions); const syncExtensions = await this.parseAndMigrateExtensions(syncData); - const { added, updated, removed } = merge(localExtensions, syncExtensions, localExtensions, [], this.getIgnoredExtensions()); + const ignoredExtensions = getIgnoredExtensions(installedExtensions, this.configurationService); + const { added, updated, removed } = merge(localExtensions, syncExtensions, localExtensions, [], ignoredExtensions); await this.apply({ added, removed, updated, remote: syncExtensions, remoteUserData, localExtensions, skippedExtensions: [], lastSyncUserData, @@ -222,7 +230,9 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse const lastSyncExtensions: ISyncExtension[] | null = lastSyncUserData ? await this.parseAndMigrateExtensions(lastSyncUserData.syncData!) : null; const skippedExtensions: ISyncExtension[] = lastSyncUserData ? lastSyncUserData.skippedExtensions || [] : []; - const localExtensions = await this.getLocalExtensions(); + const installedExtensions = await this.extensionManagementService.getInstalled(); + const localExtensions = this.getLocalExtensions(installedExtensions); + const ignoredExtensions = getIgnoredExtensions(installedExtensions, this.configurationService); if (remoteExtensions) { this.logService.trace(`${this.syncResourceLogLabel}: Merging remote extensions with local extensions...`); @@ -230,7 +240,7 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse this.logService.trace(`${this.syncResourceLogLabel}: Remote extensions does not exist. Synchronizing extensions for the first time.`); } - const { added, removed, updated, remote } = merge(localExtensions, remoteExtensions, lastSyncExtensions, skippedExtensions, this.getIgnoredExtensions()); + const { added, removed, updated, remote } = merge(localExtensions, remoteExtensions, lastSyncExtensions, skippedExtensions, ignoredExtensions); return { added, @@ -246,10 +256,6 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse }; } - private getIgnoredExtensions() { - return this.configurationService.getValue<string[]>('sync.ignoredExtensions') || []; - } - private async apply({ added, removed, updated, remote, remoteUserData, skippedExtensions, lastSyncUserData, localExtensions, hasLocalChanged, hasRemoteChanged }: IExtensionsSyncPreviewResult, forcePush?: boolean): Promise<void> { if (!hasLocalChanged && !hasRemoteChanged) { @@ -388,8 +394,7 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse return JSON.parse(syncData.content); } - private async getLocalExtensions(): Promise<ISyncExtension[]> { - const installedExtensions = await this.extensionManagementService.getInstalled(); + private getLocalExtensions(installedExtensions: ILocalExtension[]): ISyncExtension[] { const disabledExtensions = this.extensionEnablementService.getDisabledExtensions(); return installedExtensions .map(({ identifier, type }) => { |