Skip to content

Commit

Permalink
microsoft#108793 check casing and use proper extUri
Browse files Browse the repository at this point in the history
  • Loading branch information
sandy081 committed Dec 9, 2020
1 parent 8b9b8df commit 52cc4e6
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 52 deletions.
5 changes: 3 additions & 2 deletions src/vs/platform/configuration/common/configurationModels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { Registry } from 'vs/platform/registry/common/platform';
import { Disposable } from 'vs/base/common/lifecycle';
import { Emitter, Event } from 'vs/base/common/event';
import { IFileService } from 'vs/platform/files/common/files';
import { dirname } from 'vs/base/common/resources';
import { IExtUri } from 'vs/base/common/resources';

export class ConfigurationModel implements IConfigurationModel {

Expand Down Expand Up @@ -348,11 +348,12 @@ export class UserSettings extends Disposable {
constructor(
private readonly userSettingsResource: URI,
private readonly scopes: ConfigurationScope[] | undefined,
extUri: IExtUri,
private readonly fileService: IFileService
) {
super();
this.parser = new ConfigurationModelParser(this.userSettingsResource.toString(), this.scopes);
this._register(this.fileService.watch(dirname(this.userSettingsResource)));
this._register(this.fileService.watch(extUri.dirname(this.userSettingsResource)));
this._register(Event.filter(this.fileService.onDidFilesChange, e => e.contains(this.userSettingsResource))(() => this._onDidChange.fire()));
}

Expand Down
3 changes: 2 additions & 1 deletion src/vs/platform/configuration/common/configurationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Event, Emitter } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import { IFileService } from 'vs/platform/files/common/files';
import { RunOnceScheduler } from 'vs/base/common/async';
import { extUriBiasedIgnorePathCase } from 'vs/base/common/resources';

export class ConfigurationService extends Disposable implements IConfigurationService, IDisposable {

Expand All @@ -29,7 +30,7 @@ export class ConfigurationService extends Disposable implements IConfigurationSe
fileService: IFileService
) {
super();
this.userConfiguration = this._register(new UserSettings(this.settingsResource, undefined, fileService));
this.userConfiguration = this._register(new UserSettings(this.settingsResource, undefined, extUriBiasedIgnorePathCase, fileService));
this.configuration = new Configuration(new DefaultConfigurationModel(), new ConfigurationModel());

this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reloadConfiguration(), 50));
Expand Down
36 changes: 18 additions & 18 deletions src/vs/workbench/api/common/extHostWorkspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Emitter, Event } from 'vs/base/common/event';
import { TernarySearchTree } from 'vs/base/common/map';
import { Schemas } from 'vs/base/common/network';
import { Counter } from 'vs/base/common/numbers';
import { basename, basenameOrAuthority, dirname, isEqual, relativePath } from 'vs/base/common/resources';
import { basename, basenameOrAuthority, dirname, ExtUri, relativePath } from 'vs/base/common/resources';
import { compare } from 'vs/base/common/strings';
import { withUndefinedAsNull } from 'vs/base/common/types';
import { URI } from 'vs/base/common/uri';
Expand All @@ -37,27 +37,27 @@ export interface IExtHostWorkspaceProvider {
resolveProxy(url: string): Promise<string | undefined>;
}

function isFolderEqual(folderA: URI, folderB: URI): boolean {
return isEqual(folderA, folderB);
function isFolderEqual(folderA: URI, folderB: URI, extHostFileSystemInfo: IExtHostFileSystemInfo): boolean {
return new ExtUri(uri => ignorePathCasing(uri, extHostFileSystemInfo)).isEqual(folderA, folderB);
}

function compareWorkspaceFolderByUri(a: vscode.WorkspaceFolder, b: vscode.WorkspaceFolder): number {
return isFolderEqual(a.uri, b.uri) ? 0 : compare(a.uri.toString(), b.uri.toString());
function compareWorkspaceFolderByUri(a: vscode.WorkspaceFolder, b: vscode.WorkspaceFolder, extHostFileSystemInfo: IExtHostFileSystemInfo): number {
return isFolderEqual(a.uri, b.uri, extHostFileSystemInfo) ? 0 : compare(a.uri.toString(), b.uri.toString());
}

function compareWorkspaceFolderByUriAndNameAndIndex(a: vscode.WorkspaceFolder, b: vscode.WorkspaceFolder): number {
function compareWorkspaceFolderByUriAndNameAndIndex(a: vscode.WorkspaceFolder, b: vscode.WorkspaceFolder, extHostFileSystemInfo: IExtHostFileSystemInfo): number {
if (a.index !== b.index) {
return a.index < b.index ? -1 : 1;
}

return isFolderEqual(a.uri, b.uri) ? compare(a.name, b.name) : compare(a.uri.toString(), b.uri.toString());
return isFolderEqual(a.uri, b.uri, extHostFileSystemInfo) ? compare(a.name, b.name) : compare(a.uri.toString(), b.uri.toString());
}

function delta(oldFolders: vscode.WorkspaceFolder[], newFolders: vscode.WorkspaceFolder[], compare: (a: vscode.WorkspaceFolder, b: vscode.WorkspaceFolder) => number): { removed: vscode.WorkspaceFolder[], added: vscode.WorkspaceFolder[] } {
const oldSortedFolders = oldFolders.slice(0).sort(compare);
const newSortedFolders = newFolders.slice(0).sort(compare);
function delta(oldFolders: vscode.WorkspaceFolder[], newFolders: vscode.WorkspaceFolder[], compare: (a: vscode.WorkspaceFolder, b: vscode.WorkspaceFolder, extHostFileSystemInfo: IExtHostFileSystemInfo) => number, extHostFileSystemInfo: IExtHostFileSystemInfo): { removed: vscode.WorkspaceFolder[], added: vscode.WorkspaceFolder[] } {
const oldSortedFolders = oldFolders.slice(0).sort((a, b) => compare(a, b, extHostFileSystemInfo));
const newSortedFolders = newFolders.slice(0).sort((a, b) => compare(a, b, extHostFileSystemInfo));

return arrayDelta(oldSortedFolders, newSortedFolders, compare);
return arrayDelta(oldSortedFolders, newSortedFolders, (a, b) => compare(a, b, extHostFileSystemInfo));
}

function ignorePathCasing(uri: URI, extHostFileSystemInfo: IExtHostFileSystemInfo): boolean {
Expand Down Expand Up @@ -87,7 +87,7 @@ class ExtHostWorkspaceImpl extends Workspace {
if (previousConfirmedWorkspace) {
folders.forEach((folderData, index) => {
const folderUri = URI.revive(folderData.uri);
const existingFolder = ExtHostWorkspaceImpl._findFolder(previousUnconfirmedWorkspace || previousConfirmedWorkspace, folderUri);
const existingFolder = ExtHostWorkspaceImpl._findFolder(previousUnconfirmedWorkspace || previousConfirmedWorkspace, folderUri, extHostFileSystemInfo);

if (existingFolder) {
existingFolder.name = folderData.name;
Expand All @@ -106,15 +106,15 @@ class ExtHostWorkspaceImpl extends Workspace {
newWorkspaceFolders.sort((f1, f2) => f1.index < f2.index ? -1 : 1);

const workspace = new ExtHostWorkspaceImpl(id, name, newWorkspaceFolders, configuration ? URI.revive(configuration) : null, !!isUntitled, uri => ignorePathCasing(uri, extHostFileSystemInfo));
const { added, removed } = delta(oldWorkspace ? oldWorkspace.workspaceFolders : [], workspace.workspaceFolders, compareWorkspaceFolderByUri);
const { added, removed } = delta(oldWorkspace ? oldWorkspace.workspaceFolders : [], workspace.workspaceFolders, compareWorkspaceFolderByUri, extHostFileSystemInfo);

return { workspace, added, removed };
}

private static _findFolder(workspace: ExtHostWorkspaceImpl, folderUriToFind: URI): MutableWorkspaceFolder | undefined {
private static _findFolder(workspace: ExtHostWorkspaceImpl, folderUriToFind: URI, extHostFileSystemInfo: IExtHostFileSystemInfo): MutableWorkspaceFolder | undefined {
for (let i = 0; i < workspace.folders.length; i++) {
const folder = workspace.workspaceFolders[i];
if (isFolderEqual(folder.uri, folderUriToFind)) {
if (isFolderEqual(folder.uri, folderUriToFind, extHostFileSystemInfo)) {
return folder;
}
}
Expand Down Expand Up @@ -254,7 +254,7 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac
const validatedDistinctWorkspaceFoldersToAdd: { uri: vscode.Uri, name?: string }[] = [];
if (Array.isArray(workspaceFoldersToAdd)) {
workspaceFoldersToAdd.forEach(folderToAdd => {
if (URI.isUri(folderToAdd.uri) && !validatedDistinctWorkspaceFoldersToAdd.some(f => isFolderEqual(f.uri, folderToAdd.uri))) {
if (URI.isUri(folderToAdd.uri) && !validatedDistinctWorkspaceFoldersToAdd.some(f => isFolderEqual(f.uri, folderToAdd.uri, this._extHostFileSystemInfo))) {
validatedDistinctWorkspaceFoldersToAdd.push({ uri: folderToAdd.uri, name: folderToAdd.name || basenameOrAuthority(folderToAdd.uri) });
}
});
Expand Down Expand Up @@ -283,13 +283,13 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac

for (let i = 0; i < newWorkspaceFolders.length; i++) {
const folder = newWorkspaceFolders[i];
if (newWorkspaceFolders.some((otherFolder, index) => index !== i && isFolderEqual(folder.uri, otherFolder.uri))) {
if (newWorkspaceFolders.some((otherFolder, index) => index !== i && isFolderEqual(folder.uri, otherFolder.uri, this._extHostFileSystemInfo))) {
return false; // cannot add the same folder multiple times
}
}

newWorkspaceFolders.forEach((f, index) => f.index = index); // fix index
const { added, removed } = delta(currentWorkspaceFolders, newWorkspaceFolders, compareWorkspaceFolderByUriAndNameAndIndex);
const { added, removed } = delta(currentWorkspaceFolders, newWorkspaceFolders, compareWorkspaceFolderByUriAndNameAndIndex, this._extHostFileSystemInfo);
if (added.length === 0 && removed.length === 0) {
return false; // nothing actually changed
}
Expand Down
43 changes: 24 additions & 19 deletions src/vs/workbench/services/configuration/browser/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/

import { URI } from 'vs/base/common/uri';
import * as resources from 'vs/base/common/resources';
import { Event, Emitter } from 'vs/base/common/event';
import * as errors from 'vs/base/common/errors';
import { Disposable, IDisposable, dispose, toDisposable, MutableDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
Expand All @@ -22,6 +21,7 @@ import { equals } from 'vs/base/common/objects';
import { IConfigurationModel } from 'vs/platform/configuration/common/configuration';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { hash } from 'vs/base/common/hash';
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';

export class UserConfiguration extends Disposable {

Expand All @@ -36,10 +36,11 @@ export class UserConfiguration extends Disposable {
constructor(
private readonly userSettingsResource: URI,
private readonly scopes: ConfigurationScope[] | undefined,
private readonly fileService: IFileService
private readonly fileService: IFileService,
private readonly uriIdentityService: IUriIdentityService,
) {
super();
this.userConfiguration.value = new UserSettings(this.userSettingsResource, this.scopes, this.fileService);
this.userConfiguration.value = new UserSettings(this.userSettingsResource, this.scopes, uriIdentityService.extUri, this.fileService);
this._register(this.userConfiguration.value.onDidChange(() => this.reloadConfigurationScheduler.schedule()));
this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reload().then(configurationModel => this._onDidChangeConfiguration.fire(configurationModel)), 50));
}
Expand All @@ -53,9 +54,9 @@ export class UserConfiguration extends Disposable {
return this.userConfiguration.value!.loadConfiguration();
}

const folder = resources.dirname(this.userSettingsResource);
const standAloneConfigurationResources: [string, URI][] = [TASKS_CONFIGURATION_KEY].map(name => ([name, resources.joinPath(folder, `${name}.json`)]));
const fileServiceBasedConfiguration = new FileServiceBasedConfiguration(folder.toString(), [this.userSettingsResource], standAloneConfigurationResources, this.scopes, this.fileService);
const folder = this.uriIdentityService.extUri.dirname(this.userSettingsResource);
const standAloneConfigurationResources: [string, URI][] = [TASKS_CONFIGURATION_KEY].map(name => ([name, this.uriIdentityService.extUri.joinPath(folder, `${name}.json`)]));
const fileServiceBasedConfiguration = new FileServiceBasedConfiguration(folder.toString(), [this.userSettingsResource], standAloneConfigurationResources, this.scopes, this.fileService, this.uriIdentityService);
const configurationModel = await fileServiceBasedConfiguration.loadConfiguration();
this.userConfiguration.value = fileServiceBasedConfiguration;

Expand Down Expand Up @@ -88,11 +89,12 @@ class FileServiceBasedConfiguration extends Disposable {
private readonly settingsResources: URI[],
private readonly standAloneConfigurationResources: [string, URI][],
private readonly scopes: ConfigurationScope[] | undefined,
private fileService: IFileService
private fileService: IFileService,
private uriIdentityService: IUriIdentityService
) {
super();
this.allResources = [...this.settingsResources, ...this.standAloneConfigurationResources.map(([, resource]) => resource)];
this._register(combinedDisposable(...this.allResources.map(resource => this.fileService.watch(resources.dirname(resource)))));
this._register(combinedDisposable(...this.allResources.map(resource => this.fileService.watch(uriIdentityService.extUri.dirname(resource)))));
this._folderSettingsModelParser = new ConfigurationModelParser(name, this.scopes);
this._standAloneConfigurations = [];
this._cache = new ConfigurationModel();
Expand Down Expand Up @@ -165,7 +167,7 @@ class FileServiceBasedConfiguration extends Disposable {
return true;
}
// One of the resource's parent got deleted
if (this.allResources.some(resource => event.contains(resources.dirname(resource), FileChangeType.DELETED))) {
if (this.allResources.some(resource => event.contains(this.uriIdentityService.extUri.dirname(resource), FileChangeType.DELETED))) {
return true;
}
return false;
Expand Down Expand Up @@ -194,14 +196,15 @@ export class RemoteUserConfiguration extends Disposable {
remoteAuthority: string,
configurationCache: IConfigurationCache,
fileService: IFileService,
uriIdentityService: IUriIdentityService,
remoteAgentService: IRemoteAgentService
) {
super();
this._fileService = fileService;
this._userConfiguration = this._cachedConfiguration = new CachedRemoteUserConfiguration(remoteAuthority, configurationCache);
remoteAgentService.getEnvironment().then(async environment => {
if (environment) {
const userConfiguration = this._register(new FileServiceBasedRemoteUserConfiguration(environment.settingsPath, REMOTE_MACHINE_SCOPES, this._fileService));
const userConfiguration = this._register(new FileServiceBasedRemoteUserConfiguration(environment.settingsPath, REMOTE_MACHINE_SCOPES, this._fileService, uriIdentityService));
this._register(userConfiguration.onDidChangeConfiguration(configurationModel => this.onDidUserConfigurationChange(configurationModel)));
this._userConfigurationInitializationPromise = userConfiguration.initialize();
const configurationModel = await this._userConfigurationInitializationPromise;
Expand Down Expand Up @@ -260,7 +263,8 @@ class FileServiceBasedRemoteUserConfiguration extends Disposable {
constructor(
private readonly configurationResource: URI,
private readonly scopes: ConfigurationScope[] | undefined,
private readonly fileService: IFileService
private readonly fileService: IFileService,
private readonly uriIdentityService: IUriIdentityService,
) {
super();

Expand All @@ -283,7 +287,7 @@ class FileServiceBasedRemoteUserConfiguration extends Disposable {
}

private watchDirectory(): void {
const directory = resources.dirname(this.configurationResource);
const directory = this.uriIdentityService.extUri.dirname(this.configurationResource);
this.directoryWatcherDisposable = this.fileService.watch(directory);
}

Expand Down Expand Up @@ -713,24 +717,25 @@ export class FolderConfiguration extends Disposable implements IFolderConfigurat
configFolderRelativePath: string,
private readonly workbenchState: WorkbenchState,
fileService: IFileService,
uriIdentityService: IUriIdentityService,
private readonly configurationCache: IConfigurationCache
) {
super();

this.configurationFolder = resources.joinPath(workspaceFolder.uri, configFolderRelativePath);
this.configurationFolder = uriIdentityService.extUri.joinPath(workspaceFolder.uri, configFolderRelativePath);
this.cachedFolderConfiguration = new CachedFolderConfiguration(workspaceFolder.uri, configFolderRelativePath, configurationCache);
if (this.configurationCache.needsCaching(workspaceFolder.uri)) {
this.folderConfiguration = this.cachedFolderConfiguration;
whenProviderRegistered(workspaceFolder.uri, fileService)
.then(() => {
this.folderConfiguration.dispose();
this.folderConfigurationDisposable.dispose();
this.folderConfiguration = this.createFileServiceBasedConfiguration(fileService);
this.folderConfiguration = this.createFileServiceBasedConfiguration(fileService, uriIdentityService);
this._register(this.folderConfiguration.onDidChange(e => this.onDidFolderConfigurationChange()));
this.onDidFolderConfigurationChange();
});
} else {
this.folderConfiguration = this.createFileServiceBasedConfiguration(fileService);
this.folderConfiguration = this.createFileServiceBasedConfiguration(fileService, uriIdentityService);
this.folderConfigurationDisposable = this._register(this.folderConfiguration.onDidChange(e => this.onDidFolderConfigurationChange()));
}
}
Expand All @@ -748,10 +753,10 @@ export class FolderConfiguration extends Disposable implements IFolderConfigurat
this._onDidChange.fire();
}

private createFileServiceBasedConfiguration(fileService: IFileService) {
const settingsResources = [resources.joinPath(this.configurationFolder, `${FOLDER_SETTINGS_NAME}.json`)];
const standAloneConfigurationResources: [string, URI][] = [TASKS_CONFIGURATION_KEY, LAUNCH_CONFIGURATION_KEY].map(name => ([name, resources.joinPath(this.configurationFolder, `${name}.json`)]));
return new FileServiceBasedConfiguration(this.configurationFolder.toString(), settingsResources, standAloneConfigurationResources, WorkbenchState.WORKSPACE === this.workbenchState ? FOLDER_SCOPES : WORKSPACE_SCOPES, fileService);
private createFileServiceBasedConfiguration(fileService: IFileService, uriIdentityService: IUriIdentityService) {
const settingsResources = [uriIdentityService.extUri.joinPath(this.configurationFolder, `${FOLDER_SETTINGS_NAME}.json`)];
const standAloneConfigurationResources: [string, URI][] = [TASKS_CONFIGURATION_KEY, LAUNCH_CONFIGURATION_KEY].map(name => ([name, uriIdentityService.extUri.joinPath(this.configurationFolder, `${name}.json`)]));
return new FileServiceBasedConfiguration(this.configurationFolder.toString(), settingsResources, standAloneConfigurationResources, WorkbenchState.WORKSPACE === this.workbenchState ? FOLDER_SCOPES : WORKSPACE_SCOPES, fileService, uriIdentityService);
}

private updateCache(): Promise<void> {
Expand Down
Loading

0 comments on commit 52cc4e6

Please sign in to comment.