Merge from vscode e0762af258c0b20320ed03f3871a41967acc4421 (#7404)

* Merge from vscode e0762af258c0b20320ed03f3871a41967acc4421

* readd svgs
This commit is contained in:
Anthony Dresser
2019-09-27 11:13:19 -07:00
committed by GitHub
parent 6385443a4c
commit 07109617b5
348 changed files with 4219 additions and 4307 deletions

View File

@@ -44,7 +44,7 @@ import Constants from 'vs/workbench/contrib/markers/browser/constants';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceContextService, WorkbenchState, IWorkspaceFolder, IWorkspace } from 'vs/platform/workspace/common/workspace';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { IOutputService, IOutputChannel } from 'vs/workbench/contrib/output/common/output';
@@ -178,6 +178,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
private _schemaVersion: JsonSchemaVersion | undefined;
private _executionEngine: ExecutionEngine | undefined;
private _workspaceFolders: IWorkspaceFolder[] | undefined;
private _workspace: IWorkspace | undefined;
private _ignoredWorkspaceFolders: IWorkspaceFolder[] | undefined;
private _showIgnoreMessage?: boolean;
private _providers: Map<number, ITaskProvider>;
@@ -425,7 +426,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
return this._showIgnoreMessage;
}
private updateSetup(setup?: [IWorkspaceFolder[], IWorkspaceFolder[], ExecutionEngine, JsonSchemaVersion]): void {
private updateSetup(setup?: [IWorkspaceFolder[], IWorkspaceFolder[], ExecutionEngine, JsonSchemaVersion, IWorkspace | undefined]): void {
if (!setup) {
setup = this.computeWorkspaceFolderSetup();
}
@@ -447,6 +448,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
this._ignoredWorkspaceFolders = setup[1];
this._executionEngine = setup[2];
this._schemaVersion = setup[3];
this._workspace = setup[4];
}
protected showOutput(runSource: TaskRunSource = TaskRunSource.User): void {
@@ -1402,13 +1404,21 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
for (let folder of this.workspaceFolders) {
promises.push(this.computeWorkspaceFolderTasks(folder, runSource).then((value) => value, () => undefined));
}
return Promise.all(promises).then((values) => {
return Promise.all(promises).then(async (values) => {
let result = new Map<string, WorkspaceFolderTaskResult>();
for (let value of values) {
if (value) {
result.set(value.workspaceFolder.uri.toString(), value);
}
}
const userTasks = await this.computeUserTasks(this.workspaceFolders[0], runSource).then((value) => value, () => undefined);
if (userTasks) {
result.set('settings', userTasks);
}
const workspaceFileTasks = await this.computeWorkspaceFileTasks(this.workspaceFolders[0], runSource).then((value) => value, () => undefined);
if (workspaceFileTasks && this._workspace && this._workspace.configuration) {
result.set(this._workspace.configuration.toString(), workspaceFileTasks);
}
return result;
});
}
@@ -1429,7 +1439,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
return ProblemMatcherRegistry.onReady().then(async (): Promise<WorkspaceFolderTaskResult> => {
let taskSystemInfo: TaskSystemInfo | undefined = this._taskSystemInfos.get(workspaceFolder.uri.scheme);
let problemReporter = new ProblemReporter(this._outputChannel);
let parseResult = TaskConfig.parse(workspaceFolder, taskSystemInfo ? taskSystemInfo.platform : Platform.platform, workspaceFolderConfiguration.config!, problemReporter);
let parseResult = TaskConfig.parse(workspaceFolder, this._workspace, taskSystemInfo ? taskSystemInfo.platform : Platform.platform, workspaceFolderConfiguration.config!, problemReporter, TaskConfig.TaskConfigSource.TasksJson);
let hasErrors = false;
if (!parseResult.validationStatus.isOK()) {
hasErrors = true;
@@ -1456,6 +1466,101 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
});
}
private testParseExternalConfig(config: TaskConfig.ExternalTaskRunnerConfiguration | undefined, location: string): { config: TaskConfig.ExternalTaskRunnerConfiguration | undefined, hasParseErrors: boolean } {
if (!config) {
return { config: undefined, hasParseErrors: false };
}
let parseErrors: string[] = (config as any).$parseErrors;
if (parseErrors) {
let isAffected = false;
for (const parseError of parseErrors) {
if (/tasks\.json$/.test(parseError)) {
isAffected = true;
break;
}
}
if (isAffected) {
this._outputChannel.append(nls.localize('TaskSystem.invalidTaskJsonOther', 'Error: The content of the tasks json in {0} has syntax errors. Please correct them before executing a task.\n', location));
this.showOutput();
return { config, hasParseErrors: true };
}
}
return { config, hasParseErrors: false };
}
private async computeWorkspaceFileTasks(workspaceFolder: IWorkspaceFolder, runSource: TaskRunSource = TaskRunSource.User): Promise<WorkspaceFolderTaskResult> {
if (this.executionEngine === ExecutionEngine.Process) {
return this.emptyWorkspaceTaskResults(workspaceFolder);
}
const configuration = this.testParseExternalConfig(this.configurationService.inspect<TaskConfig.ExternalTaskRunnerConfiguration>('tasks').workspace, nls.localize('TasksSystem.locationWorkspaceConfig', 'workspace file'));
let customizedTasks: { byIdentifier: IStringDictionary<ConfiguringTask>; } = {
byIdentifier: Object.create(null)
};
const custom: CustomTask[] = [];
await this.computeTasksForSingleConfig(workspaceFolder, configuration.config, runSource, custom, customizedTasks.byIdentifier, TaskConfig.TaskConfigSource.WorkspaceFile);
const engine = configuration.config ? TaskConfig.ExecutionEngine.from(configuration.config) : ExecutionEngine.Terminal;
if (engine === ExecutionEngine.Process) {
this.notificationService.warn(nls.localize('TaskSystem.versionWorkspaceFile', 'Only tasks version 2.0.0 permitted in .codeworkspace.'));
return this.emptyWorkspaceTaskResults(workspaceFolder);
}
return { workspaceFolder, set: { tasks: custom }, configurations: customizedTasks, hasErrors: configuration.hasParseErrors };
}
private async computeUserTasks(workspaceFolder: IWorkspaceFolder, runSource: TaskRunSource = TaskRunSource.User): Promise<WorkspaceFolderTaskResult> {
if (this.executionEngine === ExecutionEngine.Process) {
return this.emptyWorkspaceTaskResults(workspaceFolder);
}
const configuration = this.testParseExternalConfig(this.configurationService.inspect<TaskConfig.ExternalTaskRunnerConfiguration>('tasks').user, nls.localize('TasksSystem.locationUserConfig', 'user settings'));
let customizedTasks: { byIdentifier: IStringDictionary<ConfiguringTask>; } = {
byIdentifier: Object.create(null)
};
const custom: CustomTask[] = [];
await this.computeTasksForSingleConfig(workspaceFolder, configuration.config, runSource, custom, customizedTasks.byIdentifier, TaskConfig.TaskConfigSource.User);
const engine = configuration.config ? TaskConfig.ExecutionEngine.from(configuration.config) : ExecutionEngine.Terminal;
if (engine === ExecutionEngine.Process) {
this.notificationService.warn(nls.localize('TaskSystem.versionSettings', 'Only tasks version 2.0.0 permitted in user settings.'));
return this.emptyWorkspaceTaskResults(workspaceFolder);
}
return { workspaceFolder, set: { tasks: custom }, configurations: customizedTasks, hasErrors: configuration.hasParseErrors };
}
private emptyWorkspaceTaskResults(workspaceFolder: IWorkspaceFolder): WorkspaceFolderTaskResult {
return { workspaceFolder, set: undefined, configurations: undefined, hasErrors: false };
}
private async computeTasksForSingleConfig(workspaceFolder: IWorkspaceFolder, config: TaskConfig.ExternalTaskRunnerConfiguration | undefined, runSource: TaskRunSource, custom: CustomTask[], customized: IStringDictionary<ConfiguringTask>, source: TaskConfig.TaskConfigSource): Promise<boolean> {
if (!config) {
return false;
}
let taskSystemInfo: TaskSystemInfo | undefined = workspaceFolder ? this._taskSystemInfos.get(workspaceFolder.uri.scheme) : undefined;
let problemReporter = new ProblemReporter(this._outputChannel);
let parseResult = TaskConfig.parse(workspaceFolder, this._workspace, taskSystemInfo ? taskSystemInfo.platform : Platform.platform, config, problemReporter, source);
let hasErrors = false;
if (!parseResult.validationStatus.isOK()) {
this.showOutput(runSource);
hasErrors = true;
}
if (problemReporter.status.isFatal()) {
problemReporter.fatal(nls.localize('TaskSystem.configurationErrors', 'Error: the provided task configuration has validation errors and can\'t not be used. Please correct the errors first.'));
return hasErrors;
}
if (parseResult.configured && parseResult.configured.length > 0) {
for (let task of parseResult.configured) {
customized[task.configures._key] = task;
}
}
if (!(await this._areJsonTasksSupportedPromise) && (parseResult.custom.length > 0)) {
console.warn('Custom workspace tasks are not supported.');
} else {
for (let task of parseResult.custom) {
custom.push(task);
}
}
return hasErrors;
}
private computeConfiguration(workspaceFolder: IWorkspaceFolder): Promise<WorkspaceFolderConfigurationResult> {
let { config, hasParseErrors } = this.getConfiguration(workspaceFolder);
return Promise.resolve<WorkspaceFolderConfigurationResult>({ workspaceFolder, config, hasErrors: hasParseErrors });
@@ -1463,18 +1568,19 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
protected abstract computeLegacyConfiguration(workspaceFolder: IWorkspaceFolder): Promise<WorkspaceFolderConfigurationResult>;
private computeWorkspaceFolderSetup(): [IWorkspaceFolder[], IWorkspaceFolder[], ExecutionEngine, JsonSchemaVersion] {
private computeWorkspaceFolderSetup(): [IWorkspaceFolder[], IWorkspaceFolder[], ExecutionEngine, JsonSchemaVersion, IWorkspace | undefined] {
let workspaceFolders: IWorkspaceFolder[] = [];
let ignoredWorkspaceFolders: IWorkspaceFolder[] = [];
let executionEngine = ExecutionEngine.Terminal;
let schemaVersion = JsonSchemaVersion.V2_0_0;
let workspace: IWorkspace | undefined;
if (this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) {
let workspaceFolder: IWorkspaceFolder = this.contextService.getWorkspace().folders[0];
workspaceFolders.push(workspaceFolder);
executionEngine = this.computeExecutionEngine(workspaceFolder);
schemaVersion = this.computeJsonSchemaVersion(workspaceFolder);
} else if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
workspace = this.contextService.getWorkspace();
for (let workspaceFolder of this.contextService.getWorkspace().folders) {
if (schemaVersion === this.computeJsonSchemaVersion(workspaceFolder)) {
workspaceFolders.push(workspaceFolder);
@@ -1487,7 +1593,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
}
}
}
return [workspaceFolders, ignoredWorkspaceFolders, executionEngine, schemaVersion];
return [workspaceFolders, ignoredWorkspaceFolders, executionEngine, schemaVersion, workspace];
}
private computeExecutionEngine(workspaceFolder: IWorkspaceFolder): ExecutionEngine {
@@ -1508,7 +1614,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
protected getConfiguration(workspaceFolder: IWorkspaceFolder): { config: TaskConfig.ExternalTaskRunnerConfiguration | undefined; hasParseErrors: boolean } {
let result = this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY
? Objects.deepClone(this.configurationService.getValue<TaskConfig.ExternalTaskRunnerConfiguration>('tasks', { resource: workspaceFolder.uri }))
? Objects.deepClone(this.configurationService.inspect<TaskConfig.ExternalTaskRunnerConfiguration>('tasks', { resource: workspaceFolder.uri }).workspaceFolder)
: undefined;
if (!result) {
return { config: undefined, hasParseErrors: false };
@@ -1660,7 +1766,11 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
}
const TaskQuickPickEntry = (task: Task): TaskQuickPickEntry => {
let description: string | undefined;
if (this.needsFolderQualification()) {
if (task._source.kind === TaskSourceKind.User) {
description = nls.localize('taskQuickPick.userSettings', 'User Settings');
} else if (task._source.kind === TaskSourceKind.WorkspaceFile) {
description = task.getWorkspaceFileName();
} else if (this.needsFolderQualification()) {
let workspaceFolder = task.getWorkspaceFolder();
if (workspaceFolder) {
description = workspaceFolder.name;