Skip to content

Commit

Permalink
Revert "debt: clean up obsolete file usage (#236379)"
Browse files Browse the repository at this point in the history
This reverts commit 625bae2.
  • Loading branch information
bpasero authored Dec 18, 2024
1 parent 3e86f1e commit 8b67830
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -456,8 +456,8 @@ export const enum ExtensionManagementErrorCode {
Extract = 'Extract',
Scanning = 'Scanning',
ScanningExtension = 'ScanningExtension',
ReadRemoved = 'ReadRemoved',
UnsetRemoved = 'UnsetRemoved',
ReadUninstalled = 'ReadUninstalled',
UnsetUninstalled = 'UnsetUninstalled',
Delete = 'Delete',
Rename = 'Rename',
IntializeDefaultProfile = 'IntializeDefaultProfile',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { coalesce } from '../../../base/common/arrays.js';
import { ThrottledDelayer } from '../../../base/common/async.js';
import * as objects from '../../../base/common/objects.js';
import { VSBuffer } from '../../../base/common/buffer.js';
import { IStringDictionary } from '../../../base/common/collections.js';
import { getErrorMessage } from '../../../base/common/errors.js';
import { getNodeType, parse, ParseError } from '../../../base/common/json.js';
import { getParseErrorMessage } from '../../../base/common/jsonErrorMessages.js';
Expand All @@ -17,11 +18,12 @@ import * as platform from '../../../base/common/platform.js';
import { basename, isEqual, joinPath } from '../../../base/common/resources.js';
import * as semver from '../../../base/common/semver/semver.js';
import Severity from '../../../base/common/severity.js';
import { isEmptyObject } from '../../../base/common/types.js';
import { URI } from '../../../base/common/uri.js';
import { localize } from '../../../nls.js';
import { IEnvironmentService } from '../../environment/common/environment.js';
import { IProductVersion, Metadata } from './extensionManagement.js';
import { areSameExtensions, computeTargetPlatform, getExtensionId, getGalleryExtensionId } from './extensionManagementUtil.js';
import { areSameExtensions, computeTargetPlatform, ExtensionKey, getExtensionId, getGalleryExtensionId } from './extensionManagementUtil.js';
import { ExtensionType, ExtensionIdentifier, IExtensionManifest, TargetPlatform, IExtensionIdentifier, IRelaxedExtensionManifest, UNDEFINED_PUBLISHER, IExtensionDescription, BUILTIN_MANIFEST_CACHE_FILE, USER_MANIFEST_CACHE_FILE, ExtensionIdentifierMap, parseEnabledApiProposalNames } from '../../extensions/common/extensions.js';
import { validateExtensionManifest } from '../../extensions/common/extensionValidator.js';
import { FileOperationResult, IFileService, toFileOperationResult } from '../../files/common/files.js';
Expand Down Expand Up @@ -104,6 +106,7 @@ export type ScanOptions = {
readonly profileLocation?: URI;
readonly includeInvalid?: boolean;
readonly includeAllVersions?: boolean;
readonly includeUninstalled?: boolean;
readonly checkControlFile?: boolean;
readonly language?: string;
readonly useCache?: boolean;
Expand Down Expand Up @@ -142,9 +145,10 @@ export abstract class AbstractExtensionsScannerService extends Disposable implem
private readonly _onDidChangeCache = this._register(new Emitter<ExtensionType>());
readonly onDidChangeCache = this._onDidChangeCache.event;

private readonly systemExtensionsCachedScanner = this._register(this.instantiationService.createInstance(CachedExtensionsScanner, this.currentProfile));
private readonly userExtensionsCachedScanner = this._register(this.instantiationService.createInstance(CachedExtensionsScanner, this.currentProfile));
private readonly extensionsScanner = this._register(this.instantiationService.createInstance(ExtensionsScanner));
private readonly obsoleteFile = joinPath(this.userExtensionsLocation, '.obsolete');
private readonly systemExtensionsCachedScanner = this._register(this.instantiationService.createInstance(CachedExtensionsScanner, this.currentProfile, this.obsoleteFile));
private readonly userExtensionsCachedScanner = this._register(this.instantiationService.createInstance(CachedExtensionsScanner, this.currentProfile, this.obsoleteFile));
private readonly extensionsScanner = this._register(this.instantiationService.createInstance(ExtensionsScanner, this.obsoleteFile));

constructor(
readonly systemExtensionsLocation: URI,
Expand Down Expand Up @@ -195,8 +199,8 @@ export abstract class AbstractExtensionsScannerService extends Disposable implem
const location = scanOptions.profileLocation ?? this.userExtensionsLocation;
this.logService.trace('Started scanning user extensions', location);
const profileScanOptions: IProfileExtensionsScanOptions | undefined = this.uriIdentityService.extUri.isEqual(scanOptions.profileLocation, this.userDataProfilesService.defaultProfile.extensionsResource) ? { bailOutWhenFileNotFound: true } : undefined;
const extensionsScannerInput = await this.createExtensionScannerInput(location, !!scanOptions.profileLocation, ExtensionType.User, scanOptions.language, true, profileScanOptions, scanOptions.productVersion ?? this.getProductVersion());
const extensionsScanner = scanOptions.useCache && !extensionsScannerInput.devMode ? this.userExtensionsCachedScanner : this.extensionsScanner;
const extensionsScannerInput = await this.createExtensionScannerInput(location, !!scanOptions.profileLocation, ExtensionType.User, !scanOptions.includeUninstalled, scanOptions.language, true, profileScanOptions, scanOptions.productVersion ?? this.getProductVersion());
const extensionsScanner = scanOptions.useCache && !extensionsScannerInput.devMode && extensionsScannerInput.excludeObsolete ? this.userExtensionsCachedScanner : this.extensionsScanner;
let extensions: IRelaxedScannedExtension[];
try {
extensions = await extensionsScanner.scanExtensions(extensionsScannerInput);
Expand All @@ -217,7 +221,7 @@ export abstract class AbstractExtensionsScannerService extends Disposable implem
if (this.environmentService.isExtensionDevelopment && this.environmentService.extensionDevelopmentLocationURI) {
const extensions = (await Promise.all(this.environmentService.extensionDevelopmentLocationURI.filter(extLoc => extLoc.scheme === Schemas.file)
.map(async extensionDevelopmentLocationURI => {
const input = await this.createExtensionScannerInput(extensionDevelopmentLocationURI, false, ExtensionType.User, scanOptions.language, false /* do not validate */, undefined, scanOptions.productVersion ?? this.getProductVersion());
const input = await this.createExtensionScannerInput(extensionDevelopmentLocationURI, false, ExtensionType.User, true, scanOptions.language, false /* do not validate */, undefined, scanOptions.productVersion ?? this.getProductVersion());
const extensions = await this.extensionsScanner.scanOneOrMultipleExtensions(input);
return extensions.map(extension => {
// Override the extension type from the existing extensions
Expand All @@ -233,7 +237,7 @@ export abstract class AbstractExtensionsScannerService extends Disposable implem
}

async scanExistingExtension(extensionLocation: URI, extensionType: ExtensionType, scanOptions: ScanOptions): Promise<IScannedExtension | null> {
const extensionsScannerInput = await this.createExtensionScannerInput(extensionLocation, false, extensionType, scanOptions.language, true, undefined, scanOptions.productVersion ?? this.getProductVersion());
const extensionsScannerInput = await this.createExtensionScannerInput(extensionLocation, false, extensionType, true, scanOptions.language, true, undefined, scanOptions.productVersion ?? this.getProductVersion());
const extension = await this.extensionsScanner.scanExtension(extensionsScannerInput);
if (!extension) {
return null;
Expand All @@ -245,7 +249,7 @@ export abstract class AbstractExtensionsScannerService extends Disposable implem
}

async scanOneOrMultipleExtensions(extensionLocation: URI, extensionType: ExtensionType, scanOptions: ScanOptions): Promise<IScannedExtension[]> {
const extensionsScannerInput = await this.createExtensionScannerInput(extensionLocation, false, extensionType, scanOptions.language, true, undefined, scanOptions.productVersion ?? this.getProductVersion());
const extensionsScannerInput = await this.createExtensionScannerInput(extensionLocation, false, extensionType, true, scanOptions.language, true, undefined, scanOptions.productVersion ?? this.getProductVersion());
const extensions = await this.extensionsScanner.scanOneOrMultipleExtensions(extensionsScannerInput);
return this.applyScanOptions(extensions, extensionType, scanOptions, true);
}
Expand Down Expand Up @@ -401,7 +405,7 @@ export abstract class AbstractExtensionsScannerService extends Disposable implem

private async scanDefaultSystemExtensions(useCache: boolean, language: string | undefined): Promise<IRelaxedScannedExtension[]> {
this.logService.trace('Started scanning system extensions');
const extensionsScannerInput = await this.createExtensionScannerInput(this.systemExtensionsLocation, false, ExtensionType.System, language, true, undefined, this.getProductVersion());
const extensionsScannerInput = await this.createExtensionScannerInput(this.systemExtensionsLocation, false, ExtensionType.System, true, language, true, undefined, this.getProductVersion());
const extensionsScanner = useCache && !extensionsScannerInput.devMode ? this.systemExtensionsCachedScanner : this.extensionsScanner;
const result = await extensionsScanner.scanExtensions(extensionsScannerInput);
this.logService.trace('Scanned system extensions:', result.length);
Expand Down Expand Up @@ -431,7 +435,7 @@ export abstract class AbstractExtensionsScannerService extends Disposable implem
break;
}
}
const result = await Promise.all(devSystemExtensionsLocations.map(async location => this.extensionsScanner.scanExtension((await this.createExtensionScannerInput(location, false, ExtensionType.System, language, true, undefined, this.getProductVersion())))));
const result = await Promise.all(devSystemExtensionsLocations.map(async location => this.extensionsScanner.scanExtension((await this.createExtensionScannerInput(location, false, ExtensionType.System, true, language, true, undefined, this.getProductVersion())))));
this.logService.trace('Scanned dev system extensions:', result.length);
return coalesce(result);
}
Expand All @@ -445,7 +449,7 @@ export abstract class AbstractExtensionsScannerService extends Disposable implem
}
}

private async createExtensionScannerInput(location: URI, profile: boolean, type: ExtensionType, language: string | undefined, validate: boolean, profileScanOptions: IProfileExtensionsScanOptions | undefined, productVersion: IProductVersion): Promise<ExtensionScannerInput> {
private async createExtensionScannerInput(location: URI, profile: boolean, type: ExtensionType, excludeObsolete: boolean, language: string | undefined, validate: boolean, profileScanOptions: IProfileExtensionsScanOptions | undefined, productVersion: IProductVersion): Promise<ExtensionScannerInput> {
const translations = await this.getTranslations(language ?? platform.language);
const mtime = await this.getMtime(location);
const applicationExtensionsLocation = profile && !this.uriIdentityService.extUri.isEqual(location, this.userDataProfilesService.defaultProfile.extensionsResource) ? this.userDataProfilesService.defaultProfile.extensionsResource : undefined;
Expand All @@ -458,6 +462,7 @@ export abstract class AbstractExtensionsScannerService extends Disposable implem
profile,
profileScanOptions,
type,
excludeObsolete,
validate,
productVersion.version,
productVersion.date,
Expand Down Expand Up @@ -499,6 +504,7 @@ export class ExtensionScannerInput {
public readonly profile: boolean,
public readonly profileScanOptions: IProfileExtensionsScanOptions | undefined,
public readonly type: ExtensionType,
public readonly excludeObsolete: boolean,
public readonly validate: boolean,
public readonly productVersion: string,
public readonly productDate: string | undefined,
Expand Down Expand Up @@ -528,6 +534,7 @@ export class ExtensionScannerInput {
&& a.profile === b.profile
&& objects.equals(a.profileScanOptions, b.profileScanOptions)
&& a.type === b.type
&& a.excludeObsolete === b.excludeObsolete
&& a.validate === b.validate
&& a.productVersion === b.productVersion
&& a.productDate === b.productDate
Expand All @@ -551,6 +558,7 @@ class ExtensionsScanner extends Disposable {
private readonly extensionsEnabledWithApiProposalVersion: string[];

constructor(
private readonly obsoleteFile: URI,
@IExtensionsProfileScannerService protected readonly extensionsProfileScannerService: IExtensionsProfileScannerService,
@IUriIdentityService protected readonly uriIdentityService: IUriIdentityService,
@IFileService protected readonly fileService: IFileService,
Expand All @@ -563,9 +571,15 @@ class ExtensionsScanner extends Disposable {
}

async scanExtensions(input: ExtensionScannerInput): Promise<IRelaxedScannedExtension[]> {
return input.profile
? this.scanExtensionsFromProfile(input)
: this.scanExtensionsFromLocation(input);
const extensions = input.profile ? await this.scanExtensionsFromProfile(input) : await this.scanExtensionsFromLocation(input);
let obsolete: IStringDictionary<boolean> = {};
if (input.excludeObsolete && input.type === ExtensionType.User) {
try {
const raw = (await this.fileService.readFile(this.obsoleteFile)).value.toString();
obsolete = JSON.parse(raw);
} catch (error) { /* ignore */ }
}
return isEmptyObject(obsolete) ? extensions : extensions.filter(e => !obsolete[ExtensionKey.create(e).toString()]);
}

private async scanExtensionsFromLocation(input: ExtensionScannerInput): Promise<IRelaxedScannedExtension[]> {
Expand All @@ -582,7 +596,7 @@ class ExtensionsScanner extends Disposable {
if (input.type === ExtensionType.User && basename(c.resource).indexOf('.') === 0) {
return null;
}
const extensionScannerInput = new ExtensionScannerInput(c.resource, input.mtime, input.applicationExtensionslocation, input.applicationExtensionslocationMtime, input.profile, input.profileScanOptions, input.type, input.validate, input.productVersion, input.productDate, input.productCommit, input.devMode, input.language, input.translations);
const extensionScannerInput = new ExtensionScannerInput(c.resource, input.mtime, input.applicationExtensionslocation, input.applicationExtensionslocationMtime, input.profile, input.profileScanOptions, input.type, input.excludeObsolete, input.validate, input.productVersion, input.productDate, input.productCommit, input.devMode, input.language, input.translations);
return this.scanExtension(extensionScannerInput);
}));
return coalesce(extensions)
Expand All @@ -608,7 +622,7 @@ class ExtensionsScanner extends Disposable {
const extensions = await Promise.all<IRelaxedScannedExtension | null>(
scannedProfileExtensions.map(async extensionInfo => {
if (filter(extensionInfo)) {
const extensionScannerInput = new ExtensionScannerInput(extensionInfo.location, input.mtime, input.applicationExtensionslocation, input.applicationExtensionslocationMtime, input.profile, input.profileScanOptions, input.type, input.validate, input.productVersion, input.productDate, input.productCommit, input.devMode, input.language, input.translations);
const extensionScannerInput = new ExtensionScannerInput(extensionInfo.location, input.mtime, input.applicationExtensionslocation, input.applicationExtensionslocationMtime, input.profile, input.profileScanOptions, input.type, input.excludeObsolete, input.validate, input.productVersion, input.productDate, input.productCommit, input.devMode, input.language, input.translations);
return this.scanExtension(extensionScannerInput, extensionInfo.metadata);
}
return null;
Expand Down Expand Up @@ -877,6 +891,7 @@ class CachedExtensionsScanner extends ExtensionsScanner {

constructor(
private readonly currentProfile: IUserDataProfile,
obsoleteFile: URI,
@IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService,
@IExtensionsProfileScannerService extensionsProfileScannerService: IExtensionsProfileScannerService,
@IUriIdentityService uriIdentityService: IUriIdentityService,
Expand All @@ -885,7 +900,7 @@ class CachedExtensionsScanner extends ExtensionsScanner {
@IEnvironmentService environmentService: IEnvironmentService,
@ILogService logService: ILogService
) {
super(extensionsProfileScannerService, uriIdentityService, fileService, productService, environmentService, logService);
super(obsoleteFile, extensionsProfileScannerService, uriIdentityService, fileService, productService, environmentService, logService);
}

override async scanExtensions(input: ExtensionScannerInput): Promise<IRelaxedScannedExtension[]> {
Expand Down
Loading

0 comments on commit 8b67830

Please sign in to comment.