mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-04 17:23:45 -05:00
Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)
* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 * disable strict null check
This commit is contained in:
@@ -21,7 +21,7 @@ import {
|
||||
INSTALL_ERROR_MALICIOUS,
|
||||
INSTALL_ERROR_INCOMPATIBLE
|
||||
} from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { areSameExtensions, getGalleryExtensionId, groupByExtension, getMaliciousExtensionsSet, getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { areSameExtensions, getGalleryExtensionId, groupByExtension, getMaliciousExtensionsSet, getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, ExtensionIdentifierWithVersion } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { localizeManifest } from '../common/extensionNls';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { Limiter, createCancelablePromise, CancelablePromise, Queue } from 'vs/base/common/async';
|
||||
@@ -35,7 +35,7 @@ import { ExtensionsManifestCache } from 'vs/platform/extensionManagement/node/ex
|
||||
import { ExtensionsLifecycle } from 'vs/platform/extensionManagement/node/extensionLifecycle';
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { isEngineValid } from 'vs/platform/extensions/node/extensionValidator';
|
||||
import { isEngineValid } from 'vs/platform/extensions/common/extensionValidator';
|
||||
import { tmpdir } from 'os';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { IDownloadService } from 'vs/platform/download/common/download';
|
||||
@@ -44,7 +44,7 @@ import { Schemas } from 'vs/base/common/network';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { getPathFromAmdModule } from 'vs/base/common/amd';
|
||||
import { getManifest } from 'vs/platform/extensionManagement/node/extensionManagementUtil';
|
||||
import { IExtensionManifest, ExtensionType, ExtensionIdentifierWithVersion } from 'vs/platform/extensions/common/extensions';
|
||||
import { IExtensionManifest, ExtensionType } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
// {{SQL CARBON EDIT}
|
||||
import product from 'vs/platform/product/node/product';
|
||||
@@ -112,21 +112,21 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
private uninstalledFileLimiter: Queue<any>;
|
||||
private reportedExtensions: Promise<IReportedExtension[]> | undefined;
|
||||
private lastReportTimestamp = 0;
|
||||
private readonly installingExtensions: Map<string, CancelablePromise<void>> = new Map<string, CancelablePromise<void>>();
|
||||
private readonly installingExtensions: Map<string, CancelablePromise<ILocalExtension>> = new Map<string, CancelablePromise<ILocalExtension>>();
|
||||
private readonly uninstallingExtensions: Map<string, CancelablePromise<void>> = new Map<string, CancelablePromise<void>>();
|
||||
private readonly manifestCache: ExtensionsManifestCache;
|
||||
private readonly extensionLifecycle: ExtensionsLifecycle;
|
||||
|
||||
private readonly _onInstallExtension = new Emitter<InstallExtensionEvent>();
|
||||
private readonly _onInstallExtension = this._register(new Emitter<InstallExtensionEvent>());
|
||||
readonly onInstallExtension: Event<InstallExtensionEvent> = this._onInstallExtension.event;
|
||||
|
||||
private readonly _onDidInstallExtension = new Emitter<DidInstallExtensionEvent>();
|
||||
private readonly _onDidInstallExtension = this._register(new Emitter<DidInstallExtensionEvent>());
|
||||
readonly onDidInstallExtension: Event<DidInstallExtensionEvent> = this._onDidInstallExtension.event;
|
||||
|
||||
private readonly _onUninstallExtension = new Emitter<IExtensionIdentifier>();
|
||||
private readonly _onUninstallExtension = this._register(new Emitter<IExtensionIdentifier>());
|
||||
readonly onUninstallExtension: Event<IExtensionIdentifier> = this._onUninstallExtension.event;
|
||||
|
||||
private _onDidUninstallExtension = new Emitter<DidUninstallExtensionEvent>();
|
||||
private _onDidUninstallExtension = this._register(new Emitter<DidUninstallExtensionEvent>());
|
||||
onDidUninstallExtension: Event<DidUninstallExtensionEvent> = this._onDidUninstallExtension.event;
|
||||
|
||||
constructor(
|
||||
@@ -161,7 +161,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
|
||||
unzip(zipLocation: URI, type: ExtensionType): Promise<IExtensionIdentifier> {
|
||||
this.logService.trace('ExtensionManagementService#unzip', zipLocation.toString());
|
||||
return this.install(zipLocation, type);
|
||||
return this.install(zipLocation, type).then(local => local.identifier);
|
||||
}
|
||||
|
||||
private collectFiles(extension: ILocalExtension): Promise<IFile[]> {
|
||||
@@ -190,7 +190,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
|
||||
}
|
||||
|
||||
install(vsix: URI, type: ExtensionType = ExtensionType.User): Promise<IExtensionIdentifier> {
|
||||
install(vsix: URI, type: ExtensionType = ExtensionType.User): Promise<ILocalExtension> {
|
||||
// {{SQL CARBON EDIT}}
|
||||
let startTime = new Date().getTime();
|
||||
|
||||
@@ -232,20 +232,20 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
local => {
|
||||
this.reportTelemetry(this.getTelemetryEvent(InstallOperation.Install), getLocalExtensionTelemetryData(local), new Date().getTime() - startTime, void 0);
|
||||
this._onDidInstallExtension.fire({ identifier, zipPath, local, operation: InstallOperation.Install });
|
||||
return identifier;
|
||||
return local;
|
||||
},
|
||||
error => { this._onDidInstallExtension.fire({ identifier, zipPath, error, operation: InstallOperation.Install }); return Promise.reject(error); }
|
||||
);
|
||||
// return this.getMetadata(getGalleryExtensionId(manifest.publisher, manifest.name))
|
||||
// .then(
|
||||
// metadata => this.installFromZipPath(identifierWithVersion, zipPath, metadata, type, operation, token),
|
||||
// () => this.installFromZipPath(identifierWithVersion, zipPath, null, type, operation, token))
|
||||
// .then(
|
||||
// () => { this.logService.info('Successfully installed the extension:', identifier.id); return identifier; },
|
||||
// e => {
|
||||
// this.logService.error('Failed to install the extension:', identifier.id, e.message);
|
||||
// return Promise.reject(e);
|
||||
// });
|
||||
// () => this.installFromZipPath(identifierWithVersion, zipPath, null, type, operation, token))
|
||||
// .then(
|
||||
// local => { this.logService.info('Successfully installed the extension:', identifier.id); return local; },
|
||||
// e => {
|
||||
// this.logService.error('Failed to install the extension:', identifier.id, e.message);
|
||||
// return Promise.reject(e);
|
||||
// });
|
||||
// {{SQL CARBON EDIT}} - End
|
||||
});
|
||||
});
|
||||
@@ -284,12 +284,12 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
));
|
||||
}
|
||||
|
||||
async installFromGallery(extension: IGalleryExtension): Promise<void> {
|
||||
async installFromGallery(extension: IGalleryExtension): Promise<ILocalExtension> {
|
||||
if (!this.galleryService.isEnabled()) {
|
||||
return Promise.reject(new Error(nls.localize('MarketPlaceDisabled', "Marketplace is not enabled")));
|
||||
}
|
||||
const startTime = new Date().getTime();
|
||||
|
||||
this.logService.info('Installing extension:', extension.identifier.id);
|
||||
this._onInstallExtension.fire({ identifier: extension.identifier, gallery: extension });
|
||||
|
||||
const onDidInstallExtensionSuccess = (extension: IGalleryExtension, operation: InstallOperation, local: ILocalExtension) => {
|
||||
this.logService.info(`Extensions installed successfully:`, extension.identifier.id);
|
||||
this._onDidInstallExtension.fire({ identifier: extension.identifier, gallery: extension, local, operation });
|
||||
@@ -317,8 +317,11 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
let cancellablePromise = this.installingExtensions.get(key);
|
||||
if (!cancellablePromise) {
|
||||
|
||||
this.logService.info('Installing extension:', extension.identifier.id);
|
||||
this._onInstallExtension.fire({ identifier: extension.identifier, gallery: extension });
|
||||
|
||||
let operation: InstallOperation = InstallOperation.Install;
|
||||
let cancellationToken: CancellationToken, successCallback: (a?: any) => void, errorCallback: (e?: any) => any | null;
|
||||
let cancellationToken: CancellationToken, successCallback: (local: ILocalExtension) => void, errorCallback: (e?: any) => any | null;
|
||||
cancellablePromise = createCancelablePromise(token => { cancellationToken = token; return new Promise((c, e) => { successCallback = c; errorCallback = e; }); });
|
||||
this.installingExtensions.set(key, cancellablePromise);
|
||||
try {
|
||||
@@ -340,7 +343,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
}
|
||||
this.installingExtensions.delete(key);
|
||||
onDidInstallExtensionSuccess(extension, operation, local);
|
||||
successCallback(null);
|
||||
successCallback(local);
|
||||
},
|
||||
error => {
|
||||
this.installingExtensions.delete(key);
|
||||
@@ -367,7 +370,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
const compatibleExtension = await this.galleryService.getCompatibleExtension(extension);
|
||||
|
||||
if (!compatibleExtension) {
|
||||
return Promise.reject(new ExtensionManagementError(nls.localize('notFoundCompatibleDependency', "Unable to install because, the extension '{0}' compatible with current version '{1}' of VS Code is not found.", extension.identifier.id, pkg.version), INSTALL_ERROR_INCOMPATIBLE));
|
||||
return Promise.reject(new ExtensionManagementError(nls.localize('notFoundCompatibleDependency', "Unable to install '{0}' extension because it is not compatible with the current version of VS Code (version {1}).", extension.identifier.id, pkg.version), INSTALL_ERROR_INCOMPATIBLE));
|
||||
}
|
||||
|
||||
return compatibleExtension;
|
||||
@@ -408,9 +411,10 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
};
|
||||
|
||||
this.logService.trace('Started downloading extension:', extension.identifier.id);
|
||||
return this.galleryService.download(extension, operation)
|
||||
return this.galleryService.download(extension, URI.file(tmpdir()), operation)
|
||||
.then(
|
||||
zipPath => {
|
||||
zip => {
|
||||
const zipPath = zip.fsPath;
|
||||
this.logService.info('Downloaded extension:', extension.identifier.id, zipPath);
|
||||
return getManifest(zipPath)
|
||||
.then(
|
||||
@@ -470,7 +474,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
}
|
||||
this.logService.info('Installation completed.', identifier.id);
|
||||
if (metadata) {
|
||||
local.metadata = metadata;
|
||||
this.setMetadata(local, metadata);
|
||||
return this.saveMetadataForLocalExtension(local);
|
||||
}
|
||||
return local;
|
||||
@@ -500,12 +504,12 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
e => Promise.reject(new ExtensionManagementError(this.joinErrors(e).message, INSTALL_ERROR_DELETING)));
|
||||
}
|
||||
|
||||
private rename(identfier: IExtensionIdentifier, extractPath: string, renamePath: string, retryUntil: number): Promise<void> {
|
||||
private rename(identifier: IExtensionIdentifier, extractPath: string, renamePath: string, retryUntil: number): Promise<void> {
|
||||
return pfs.rename(extractPath, renamePath)
|
||||
.then(undefined, error => {
|
||||
if (isWindows && error && error.code === 'EPERM' && Date.now() < retryUntil) {
|
||||
this.logService.info(`Failed renaming ${extractPath} to ${renamePath} with 'EPERM' error. Trying again...`, identfier.id);
|
||||
return this.rename(identfier, extractPath, renamePath, retryUntil);
|
||||
this.logService.info(`Failed renaming ${extractPath} to ${renamePath} with 'EPERM' error. Trying again...`, identifier.id);
|
||||
return this.rename(identifier, extractPath, renamePath, retryUntil);
|
||||
}
|
||||
return Promise.reject(new ExtensionManagementError(error.message || nls.localize('renameError', "Unknown error while renaming {0} to {1}", extractPath, renamePath), error.code || INSTALL_ERROR_RENAMING));
|
||||
});
|
||||
@@ -743,7 +747,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
this.logService.trace('Started scanning system extensions');
|
||||
const systemExtensionsPromise = this.scanExtensions(this.systemExtensionsPath, ExtensionType.System)
|
||||
.then(result => {
|
||||
this.logService.info('Scanned system extensions:', result.length);
|
||||
this.logService.trace('Scanned system extensions:', result.length);
|
||||
return result;
|
||||
});
|
||||
if (this.environmentService.isBuilt) {
|
||||
@@ -756,7 +760,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
if (devSystemExtensionsList.length) {
|
||||
return this.scanExtensions(this.devSystemExtensionsPath, ExtensionType.System)
|
||||
.then(result => {
|
||||
this.logService.info('Scanned dev system extensions:', result.length);
|
||||
this.logService.trace('Scanned dev system extensions:', result.length);
|
||||
return result.filter(r => devSystemExtensionsList.some(id => areSameExtensions(r.identifier, { id })));
|
||||
});
|
||||
} else {
|
||||
@@ -776,7 +780,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
const byExtension: ILocalExtension[][] = groupByExtension(extensions, e => e.identifier);
|
||||
extensions = byExtension.map(p => p.sort((a, b) => semver.rcompare(a.manifest.version, b.manifest.version))[0]);
|
||||
}
|
||||
this.logService.info('Scanned user extensions:', extensions.length);
|
||||
this.logService.trace('Scanned user extensions:', extensions.length);
|
||||
return extensions;
|
||||
});
|
||||
}
|
||||
@@ -800,25 +804,44 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
const readmeUrl = readme ? URI.file(path.join(extensionPath, readme)) : null;
|
||||
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), uuid: metadata ? metadata.id : null };
|
||||
return <ILocalExtension>{ type, identifier, manifest, metadata, location: URI.file(extensionPath), readmeUrl, changelogUrl };
|
||||
const identifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name) };
|
||||
const local = <ILocalExtension>{ type, identifier, manifest, metadata, location: URI.file(extensionPath), readmeUrl, changelogUrl };
|
||||
if (metadata) {
|
||||
this.setMetadata(local, metadata);
|
||||
}
|
||||
return local;
|
||||
}))
|
||||
.then(undefined, () => null);
|
||||
}
|
||||
|
||||
removeDeprecatedExtensions(): Promise<any> {
|
||||
return this.removeUninstalledExtensions()
|
||||
.then(() => this.removeOutdatedExtensions());
|
||||
private setMetadata(local: ILocalExtension, metadata: IGalleryMetadata): void {
|
||||
local.metadata = metadata;
|
||||
local.identifier.uuid = metadata.id;
|
||||
}
|
||||
|
||||
private removeUninstalledExtensions(): Promise<void> {
|
||||
return this.getUninstalledExtensions()
|
||||
.then(uninstalled => this.scanExtensions(this.extensionsPath, ExtensionType.User) // All user extensions
|
||||
.then(extensions => {
|
||||
const toRemove: ILocalExtension[] = extensions.filter(e => uninstalled[new ExtensionIdentifierWithVersion(e.identifier, e.manifest.version).key()]);
|
||||
return Promise.all(toRemove.map(e => this.extensionLifecycle.postUninstall(e).then(() => this.removeUninstalledExtension(e))));
|
||||
})
|
||||
).then(() => undefined);
|
||||
async removeDeprecatedExtensions(): Promise<void> {
|
||||
await this.removeUninstalledExtensions();
|
||||
await this.removeOutdatedExtensions();
|
||||
}
|
||||
|
||||
private async removeUninstalledExtensions(): Promise<void> {
|
||||
const uninstalled = await this.getUninstalledExtensions();
|
||||
const extensions = await this.scanExtensions(this.extensionsPath, ExtensionType.User); // All user extensions
|
||||
const installed: Set<string> = new Set<string>();
|
||||
for (const e of extensions) {
|
||||
if (!uninstalled[new ExtensionIdentifierWithVersion(e.identifier, e.manifest.version).key()]) {
|
||||
installed.add(e.identifier.id.toLowerCase());
|
||||
}
|
||||
}
|
||||
const byExtension: ILocalExtension[][] = groupByExtension(extensions, e => e.identifier);
|
||||
await Promise.all(byExtension.map(async e => {
|
||||
const latest = e.sort((a, b) => semver.rcompare(a.manifest.version, b.manifest.version))[0];
|
||||
if (!installed.has(latest.identifier.id.toLowerCase())) {
|
||||
await this.extensionLifecycle.postUninstall(latest);
|
||||
}
|
||||
}));
|
||||
const toRemove: ILocalExtension[] = extensions.filter(e => uninstalled[new ExtensionIdentifierWithVersion(e.identifier, e.manifest.version).key()]);
|
||||
await Promise.all(toRemove.map(e => this.removeUninstalledExtension(e)));
|
||||
}
|
||||
|
||||
private removeOutdatedExtensions(): Promise<void> {
|
||||
@@ -845,8 +868,8 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
||||
return pfs.rimraf(extension.location.fsPath).then(() => this.logService.info('Deleted from disk', extension.identifier.id, extension.location.fsPath));
|
||||
}
|
||||
|
||||
private isUninstalled(identfier: ExtensionIdentifierWithVersion): Promise<boolean> {
|
||||
return this.filterUninstalled(identfier).then(uninstalled => uninstalled.length === 1);
|
||||
private isUninstalled(identifier: ExtensionIdentifierWithVersion): Promise<boolean> {
|
||||
return this.filterUninstalled(identifier).then(uninstalled => uninstalled.length === 1);
|
||||
}
|
||||
|
||||
private filterUninstalled(...identifiers: ExtensionIdentifierWithVersion[]): Promise<string[]> {
|
||||
|
||||
Reference in New Issue
Block a user