Skip to content

Commit 37c72e7

Browse files
committed
Add ability to not to sync an extension while installing using cli
1 parent 9de4326 commit 37c72e7

11 files changed

Lines changed: 117 additions & 58 deletions

File tree

src/vs/code/node/cliProcessMain.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export class Main {
8686
} else if (argv['list-extensions']) {
8787
await this.listExtensions(!!argv['show-versions'], argv['category']);
8888
} else if (argv['install-extension']) {
89-
await this.installExtensions(argv['install-extension'], !!argv['force'], !!argv['default']);
89+
await this.installExtensions(argv['install-extension'], !!argv['force'], !!argv['donot-sync']);
9090
} else if (argv['uninstall-extension']) {
9191
await this.uninstallExtension(argv['uninstall-extension']);
9292
} else if (argv['locate-extension']) {
@@ -126,7 +126,7 @@ export class Main {
126126
extensions.forEach(e => console.log(getId(e.manifest, showVersions)));
127127
}
128128

129-
private async installExtensions(extensions: string[], force: boolean, isDefault: boolean): Promise<void> {
129+
private async installExtensions(extensions: string[], force: boolean, donotSync: boolean): Promise<void> {
130130
const failed: string[] = [];
131131
const installedExtensionsManifests: IExtensionManifest[] = [];
132132
if (extensions.length) {
@@ -135,7 +135,7 @@ export class Main {
135135

136136
for (const extension of extensions) {
137137
try {
138-
const manifest = await this.installExtension(extension, force, isDefault);
138+
const manifest = await this.installExtension(extension, force, donotSync);
139139
if (manifest) {
140140
installedExtensionsManifests.push(manifest);
141141
}
@@ -150,15 +150,15 @@ export class Main {
150150
return failed.length ? Promise.reject(localize('installation failed', "Failed Installing Extensions: {0}", failed.join(', '))) : Promise.resolve();
151151
}
152152

153-
private async installExtension(extension: string, force: boolean, isDefault: boolean): Promise<IExtensionManifest | null> {
153+
private async installExtension(extension: string, force: boolean, donotSync: boolean): Promise<IExtensionManifest | null> {
154154
if (/\.vsix$/i.test(extension)) {
155155
extension = path.isAbsolute(extension) ? extension : path.join(process.cwd(), extension);
156156

157157
const manifest = await getManifest(extension);
158158
const valid = await this.validate(manifest, force);
159159

160160
if (valid) {
161-
return this.extensionManagementService.install(URI.file(extension)).then(id => {
161+
return this.extensionManagementService.install(URI.file(extension), donotSync).then(id => {
162162
console.log(localize('successVsixInstall', "Extension '{0}' was successfully installed.", getBaseLabel(extension)));
163163
return manifest;
164164
}, error => {
@@ -205,7 +205,7 @@ export class Main {
205205
}
206206
console.log(localize('updateMessage', "Updating the extension '{0}' to the version {1}", id, extension.version));
207207
}
208-
await this.installFromGallery(id, extension, isDefault);
208+
await this.installFromGallery(id, extension, donotSync);
209209
return manifest;
210210
}));
211211
}
@@ -227,11 +227,11 @@ export class Main {
227227
return true;
228228
}
229229

230-
private async installFromGallery(id: string, extension: IGalleryExtension, isDefault: boolean): Promise<void> {
230+
private async installFromGallery(id: string, extension: IGalleryExtension, donotSync: boolean): Promise<void> {
231231
console.log(localize('installing', "Installing extension '{0}' v{1}...", id, extension.version));
232232

233233
try {
234-
await this.extensionManagementService.installFromGallery(extension, isDefault);
234+
await this.extensionManagementService.installFromGallery(extension, donotSync);
235235
console.log(localize('successInstall', "Extension '{0}' v{1} was successfully installed.", id, extension.version));
236236
} catch (error) {
237237
if (isPromiseCanceledError(error)) {

src/vs/platform/environment/node/argv.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export interface ParsedArgs {
7272
remote?: string;
7373
'disable-user-env-probe'?: boolean;
7474
'force'?: boolean;
75-
'default'?: boolean;
75+
'donot-sync'?: boolean;
7676
'force-user-env'?: boolean;
7777
'sync'?: 'on' | 'off';
7878

@@ -188,7 +188,7 @@ export const OPTIONS: OptionDescriptions<Required<ParsedArgs>> = {
188188
'file-chmod': { type: 'boolean' },
189189
'driver-verbose': { type: 'boolean' },
190190
'force': { type: 'boolean' },
191-
'default': { type: 'boolean' },
191+
'donot-sync': { type: 'boolean' },
192192
'trace': { type: 'boolean' },
193193
'trace-category-filter': { type: 'string' },
194194
'trace-options': { type: 'string' },

src/vs/platform/extensionManagement/common/extensionManagement.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export interface IGalleryMetadata {
9292

9393
export interface ILocalExtension extends IExtension {
9494
readonly manifest: IExtensionManifest;
95-
isDefault: boolean | undefined;
95+
isMachineScoped: boolean;
9696
publisherId: string | null;
9797
publisherDisplayName: string | null;
9898
readmeUrl: URI | null;
@@ -206,8 +206,8 @@ export interface IExtensionManagementService {
206206
zip(extension: ILocalExtension): Promise<URI>;
207207
unzip(zipLocation: URI): Promise<IExtensionIdentifier>;
208208
getManifest(vsix: URI): Promise<IExtensionManifest>;
209-
install(vsix: URI, isDefault?: boolean): Promise<ILocalExtension>;
210-
installFromGallery(extension: IGalleryExtension, isDefault?: boolean): Promise<ILocalExtension>;
209+
install(vsix: URI, isMachineScoped?: boolean): Promise<ILocalExtension>;
210+
installFromGallery(extension: IGalleryExtension, isMachineScoped?: boolean): Promise<ILocalExtension>;
211211
uninstall(extension: ILocalExtension, force?: boolean): Promise<void>;
212212
reinstallFromGallery(extension: ILocalExtension): Promise<void>;
213213
getInstalled(type?: ExtensionType): Promise<ILocalExtension[]>;

src/vs/platform/extensionManagement/node/extensionManagementService.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
152152

153153
}
154154

155-
install(vsix: URI, isDefault?: boolean): Promise<ILocalExtension> {
155+
install(vsix: URI, isMachineScoped?: boolean): Promise<ILocalExtension> {
156156
this.logService.trace('ExtensionManagementService#install', vsix.toString());
157157
return createCancelablePromise(token => {
158158
return this.downloadVsix(vsix).then(downloadLocation => {
@@ -170,6 +170,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
170170
.then(installedExtensions => {
171171
const existing = installedExtensions.filter(i => areSameExtensions(identifier, i.identifier))[0];
172172
if (existing) {
173+
isMachineScoped = isMachineScoped || existing.isMachineScoped;
173174
operation = InstallOperation.Update;
174175
if (identifierWithVersion.equals(new ExtensionIdentifierWithVersion(existing.identifier, existing.manifest.version))) {
175176
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
194195
this._onInstallExtension.fire({ identifier, zipPath });
195196
return this.getGalleryMetadata(getGalleryExtensionId(manifest.publisher, manifest.name))
196197
.then(
197-
metadata => this.installFromZipPath(identifierWithVersion, zipPath, { ...metadata, isDefault }, operation, token),
198-
() => this.installFromZipPath(identifierWithVersion, zipPath, isDefault ? { isDefault } : undefined, operation, token))
198+
metadata => this.installFromZipPath(identifierWithVersion, zipPath, { ...metadata, isMachineScoped }, operation, token),
199+
() => this.installFromZipPath(identifierWithVersion, zipPath, isMachineScoped ? { isMachineScoped } : undefined, operation, token))
199200
.then(
200201
local => { this.logService.info('Successfully installed the extension:', identifier.id); return local; },
201202
e => {
@@ -239,7 +240,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
239240
));
240241
}
241242

242-
async installFromGallery(extension: IGalleryExtension, isDefault?: boolean): Promise<ILocalExtension> {
243+
async installFromGallery(extension: IGalleryExtension, isMachineScoped?: boolean): Promise<ILocalExtension> {
243244
if (!this.galleryService.isEnabled()) {
244245
return Promise.reject(new Error(nls.localize('MarketPlaceDisabled', "Marketplace is not enabled")));
245246
}
@@ -288,7 +289,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
288289

289290
this.downloadInstallableExtension(extension, operation)
290291
.then(installableExtension => {
291-
installableExtension.metadata.isDefault = isDefault !== undefined ? isDefault : existingExtension?.isDefault;
292+
installableExtension.metadata.isMachineScoped = isMachineScoped || existingExtension?.isMachineScoped;
292293
return this.installExtension(installableExtension, cancellationToken)
293294
.then(local => this.extensionsDownloader.delete(URI.file(installableExtension.zipPath)).finally(() => { }).then(() => local));
294295
})
@@ -483,7 +484,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
483484

484485
async updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): Promise<ILocalExtension> {
485486
this.logService.trace('ExtensionManagementService#updateMetadata', local.identifier.id);
486-
local = await this.extensionsScanner.saveMetadataForLocalExtension(local, { ...metadata, isDefault: local.isDefault });
487+
local = await this.extensionsScanner.saveMetadataForLocalExtension(local, { ...metadata, isMachineScoped: local.isMachineScoped });
487488
this.manifestCache.invalidate();
488489
return local;
489490
}

src/vs/platform/extensionManagement/node/extensionsScanner.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const INSTALL_ERROR_EXTRACTING = 'extracting';
3232
const INSTALL_ERROR_DELETING = 'deleting';
3333
const INSTALL_ERROR_RENAMING = 'renaming';
3434

35-
export type IMetadata = Partial<IGalleryMetadata & { isDefault: boolean; }>;
35+
export type IMetadata = Partial<IGalleryMetadata & { isMachineScoped: boolean; }>;
3636

3737
export class ExtensionsScanner extends Disposable {
3838

@@ -131,6 +131,9 @@ export class ExtensionsScanner extends Disposable {
131131

132132
async saveMetadataForLocalExtension(local: ILocalExtension, metadata: IMetadata): Promise<ILocalExtension> {
133133
this.setMetadata(local, metadata);
134+
135+
// unset if false
136+
metadata.isMachineScoped = metadata.isMachineScoped || undefined;
134137
const manifestPath = path.join(local.location.fsPath, 'package.json');
135138
const raw = await pfs.readFile(manifestPath, 'utf8');
136139
const { manifest } = await this.parseManifest(raw);
@@ -229,7 +232,7 @@ export class ExtensionsScanner extends Disposable {
229232
const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0];
230233
const changelogUrl = changelog ? URI.file(path.join(extensionPath, changelog)) : null;
231234
const identifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name) };
232-
const local = <ILocalExtension>{ type, identifier, manifest, location: URI.file(extensionPath), readmeUrl, changelogUrl, publisherDisplayName: null, publisherId: null, isDefault: undefined };
235+
const local = <ILocalExtension>{ type, identifier, manifest, location: URI.file(extensionPath), readmeUrl, changelogUrl, publisherDisplayName: null, publisherId: null, isMachineScoped: false };
233236
if (metadata) {
234237
this.setMetadata(local, metadata);
235238
}
@@ -261,7 +264,7 @@ export class ExtensionsScanner extends Disposable {
261264
local.publisherDisplayName = metadata.publisherDisplayName || null;
262265
local.publisherId = metadata.publisherId || null;
263266
local.identifier.uuid = metadata.id;
264-
local.isDefault = metadata.isDefault;
267+
local.isMachineScoped = !!metadata.isMachineScoped;
265268
}
266269

267270
private async removeUninstalledExtensions(): Promise<void> {

src/vs/platform/userDataSync/common/extensionsMerge.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import { ISyncExtension } from 'vs/platform/userDataSync/common/userDataSync';
88
import { IExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
99
import { startsWith } from 'vs/base/common/strings';
1010
import { deepClone } from 'vs/base/common/objects';
11+
import { ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement';
12+
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
13+
import { distinct } from 'vs/base/common/arrays';
1114

1215
export interface IMergeResult {
1316
added: ISyncExtension[];
@@ -201,3 +204,19 @@ function massageOutgoingExtension(extension: ISyncExtension, key: string): ISync
201204
}
202205
return massagedExtension;
203206
}
207+
208+
export function getIgnoredExtensions(installed: ILocalExtension[], configurationService: IConfigurationService): string[] {
209+
const defaultIgnoredExtensions = installed.filter(i => i.isMachineScoped).map(i => i.identifier.id.toLowerCase());
210+
const value = (configurationService.getValue<string[]>('sync.ignoredExtensions') || []).map(id => id.toLowerCase());
211+
const added: string[] = [], removed: string[] = [];
212+
if (Array.isArray(value)) {
213+
for (const key of value) {
214+
if (startsWith(key, '-')) {
215+
removed.push(key.substring(1));
216+
} else {
217+
added.push(key);
218+
}
219+
}
220+
}
221+
return distinct([...defaultIgnoredExtensions, ...added,].filter(setting => removed.indexOf(setting) === -1));
222+
}

0 commit comments

Comments
 (0)