提交 a744e4e1 编写于 作者: B Benjamin Pasero

debt - workspace settings only supports specific files

上级 9f1f36cb
......@@ -27,4 +27,9 @@ export interface IWorkspaceConfigurationService extends IConfigurationService {
export interface IWorkspaceConfigurationValue<T> extends IConfigurationValue<T> {
workspace: T;
}
\ No newline at end of file
}
export const WORKSPACE_STANDALONE_CONFIGURATIONS = {
'tasks': '.vscode/tasks.json',
'launch': '.vscode/launch.json'
};
\ No newline at end of file
......@@ -51,7 +51,7 @@ export function merge(base: any, add: any, overwrite: boolean): void {
export function consolidate(configMap: { [key: string]: IConfigFile; }): { contents: any; parseErrors: string[]; } {
const finalConfig: any = Object.create(null);
const parseErrors: string[] = [];
const regexp = /\/(team\.)?([^\.]*)*\.json/;
const regexp = /\/([^\.]*)*\.json/;
// We want to use the default settings file as base and let all other config
// files overwrite the base one
......@@ -69,15 +69,12 @@ export function consolidate(configMap: { [key: string]: IConfigFile; }): { conte
return;
}
// If a file is team.foo.json, it indicates team settings, strip this away
const isTeamSetting = !!matches[1];
// Extract the config key from the file name (except for settings.json which is the default)
let configElement: any = finalConfig;
if (matches && matches[2] && matches[2] !== CONFIG_DEFAULT_NAME) {
if (matches && matches[1] && matches[1] !== CONFIG_DEFAULT_NAME) {
// Use the name of the file as top level config section for all settings inside
const configSection = matches[2];
const configSection = matches[1];
let element = configElement[configSection];
if (!element) {
element = Object.create(null);
......@@ -86,7 +83,7 @@ export function consolidate(configMap: { [key: string]: IConfigFile; }): { conte
configElement = element;
}
merge(configElement, config.contents, !isTeamSetting /* user settings overrule team settings */);
merge(configElement, config.contents, false);
if (config.parseError) {
parseErrors.push(configFileName);
}
......
......@@ -19,15 +19,10 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { WORKSPACE_CONFIG_DEFAULT_PATH } from 'vs/workbench/services/configuration/common/configuration';
import { WORKSPACE_CONFIG_DEFAULT_PATH, WORKSPACE_STANDALONE_CONFIGURATIONS } from 'vs/workbench/services/configuration/common/configuration';
import { IFileService } from 'vs/platform/files/common/files';
import { IConfigurationEditingService, ConfigurationEditingErrorCode, IConfigurationEditingError, ConfigurationTarget, IConfigurationValue } from 'vs/workbench/services/configuration/common/configurationEditing';
export const WORKSPACE_STANDALONE_CONFIGURATIONS = {
'tasks': '.vscode/tasks.json',
'launch': '.vscode/launch.json'
};
interface IConfigurationEditOperation extends IConfigurationValue {
target: URI;
isWorkspaceStandalone?: boolean;
......
......@@ -21,7 +21,7 @@ import errors = require('vs/base/common/errors');
import { IConfigFile, consolidate, newConfigFile } from 'vs/workbench/services/configuration/common/model';
import { IConfigurationServiceEvent, getConfigurationValue } from 'vs/platform/configuration/common/configuration';
import { ConfigurationService as BaseConfigurationService } from 'vs/platform/configuration/node/configurationService';
import { IWorkspaceConfigurationService, IWorkspaceConfigurationValue, CONFIG_DEFAULT_NAME, WORKSPACE_CONFIG_FOLDER_DEFAULT_NAME } from 'vs/workbench/services/configuration/common/configuration';
import { IWorkspaceConfigurationService, IWorkspaceConfigurationValue, CONFIG_DEFAULT_NAME, WORKSPACE_CONFIG_FOLDER_DEFAULT_NAME, WORKSPACE_STANDALONE_CONFIGURATIONS, WORKSPACE_CONFIG_DEFAULT_PATH } from 'vs/workbench/services/configuration/common/configuration';
import { EventType as FileEventType, FileChangeType, FileChangesEvent } from 'vs/platform/files/common/files';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import Event, { Emitter } from 'vs/base/common/event';
......@@ -172,14 +172,21 @@ export class WorkspaceConfigurationService implements IWorkspaceConfigurationSer
return TPromise.as(Object.create(null));
}
// once: when invoked for the first time we fetch *all* json files using the bulk stats and content routes
// once: when invoked for the first time we fetch json files that contribute settings
if (!this.bulkFetchFromWorkspacePromise) {
this.bulkFetchFromWorkspacePromise = resolveStat(this.contextService.toResource(this.workspaceSettingsRootFolder)).then(stat => {
if (!stat.isDirectory) {
return TPromise.as([]);
}
return resolveContents(stat.children.filter(stat => paths.extname(stat.resource.fsPath) === '.json').map(stat => stat.resource));
return resolveContents(stat.children.filter(stat => {
const isJson = paths.extname(stat.resource.fsPath) === '.json';
if (!isJson) {
return false; // only JSON files
}
return this.isWorkspaceConfigurationFile(this.contextService.toWorkspaceRelativePath(stat.resource)); // only workspace config files
}).map(stat => stat.resource));
}, (err) => {
if (err) {
return []; // never fail this call
......@@ -200,7 +207,13 @@ export class WorkspaceConfigurationService implements IWorkspaceConfigurationSer
// Find changes that affect workspace configuration files
for (let i = 0, len = events.length; i < len; i++) {
const workspacePath = this.contextService.toWorkspaceRelativePath(events[i].resource);
const resource = events[i].resource;
const isJson = paths.extname(resource.fsPath) === '.json';
if (!isJson) {
continue; // only JSON files
}
const workspacePath = this.contextService.toWorkspaceRelativePath(resource);
if (!workspacePath) {
continue; // event is not inside workspace
}
......@@ -211,11 +224,8 @@ export class WorkspaceConfigurationService implements IWorkspaceConfigurationSer
affectedByChanges = true;
}
// outside my folder or not a *.json file
if (
paths.extname(workspacePath) !== '.json' || // we only care about *.json files
paths.dirname(workspacePath) !== this.workspaceSettingsRootFolder // which are top level in .vscode
) {
// only valid workspace config files
if (!this.isWorkspaceConfigurationFile(workspacePath)) {
continue;
}
......@@ -227,7 +237,7 @@ export class WorkspaceConfigurationService implements IWorkspaceConfigurationSer
break;
case FileChangeType.UPDATED:
case FileChangeType.ADDED:
this.workspaceFilePathToConfiguration[workspacePath] = resolveContent(events[i].resource).then(content => newConfigFile(content.value), errors.onUnexpectedError);
this.workspaceFilePathToConfiguration[workspacePath] = resolveContent(resource).then(content => newConfigFile(content.value), errors.onUnexpectedError);
affectedByChanges = true;
}
}
......@@ -238,6 +248,10 @@ export class WorkspaceConfigurationService implements IWorkspaceConfigurationSer
}
}
private isWorkspaceConfigurationFile(workspaceRelativePath: string): boolean {
return [WORKSPACE_CONFIG_DEFAULT_PATH, WORKSPACE_STANDALONE_CONFIGURATIONS.launch, WORKSPACE_STANDALONE_CONFIGURATIONS.tasks].some(p => p === workspaceRelativePath);
}
public set telemetryService(value: ITelemetryService) {
this.baseConfigurationService.telemetryService = value;
}
......
......@@ -24,28 +24,6 @@ suite('ConfigurationService - Model', () => {
assert.deepEqual(base, { 'a': { 'b': 2 } });
});
test('Test consolidate (settings)', () => {
const config1: model.IConfigFile = {
contents: {
awesome: true
}
};
const config2: model.IConfigFile = {
contents: {
awesome: false
}
};
const expected = {
awesome: false
};
assert.deepEqual(model.consolidate({ '.vscode/team.settings.json': config1, '.vscode/settings.json': config2 }).contents, expected);
assert.deepEqual(model.consolidate({ 'settings.json': config2, 'team.settings.json': config1 }).contents, {});
assert.deepEqual(model.consolidate({ '.vscode/team.settings.json': config1, '.vscode/settings.json': config2, '.vscode/team2.settings.json': config1 }).contents, expected);
});
test('Test consolidate (settings and tasks)', () => {
const settingsConfig: model.IConfigFile = {
contents: {
......
......@@ -23,12 +23,13 @@ import { WorkspaceConfigurationService } from 'vs/workbench/services/configurati
import URI from 'vs/base/common/uri';
import utils = require('vs/workbench/services/files/test/node/utils');
import { FileService } from 'vs/workbench/services/files/node/fileService';
import { ConfigurationEditingService, WORKSPACE_STANDALONE_CONFIGURATIONS } from 'vs/workbench/services/configuration/node/configurationEditingService';
import { ConfigurationEditingService } from 'vs/workbench/services/configuration/node/configurationEditingService';
import { ConfigurationTarget, IConfigurationEditingError, ConfigurationEditingErrorCode } from 'vs/workbench/services/configuration/common/configurationEditing';
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
import { IFileService } from 'vs/platform/files/common/files';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { WORKSPACE_STANDALONE_CONFIGURATIONS } from 'vs/workbench/services/configuration/common/configuration';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册