Feature: Tasks (core) (#12184)

* initial

* string sanitize

* hygiene

* build task

* added build task

* hygiene

* initial tasks view

* finished tasks

* add sql carbon tags and undo changes

* remove task message

* fix tasks tests

* removed extension stuff

* add problem matcher

* remove extra space

* undo extension changes

* add problem matcher to mssql
This commit is contained in:
Aditya Bist
2020-11-04 13:07:20 -08:00
committed by GitHub
parent 4af67c9734
commit 6b2c409cff
11 changed files with 90 additions and 36 deletions

View File

@@ -20,6 +20,11 @@
"postinstall": "node ./build/postinstall.js"
},
"contributes": {
"problemMatchers": [
{
"name": "tasks"
}
],
"commands": [
{
"command": "mssql.exportSqlAsNotebook",

View File

@@ -11,4 +11,4 @@
]
}
]
}
}

View File

@@ -59,7 +59,7 @@ import './mainThreadWebviewManager';
import './mainThreadWorkspace';
import './mainThreadComments';
import './mainThreadNotebook';
// import './mainThreadTask'; {{SQL CARBON EDIT}} @anthonydresser comment out task
import './mainThreadTask';
import './mainThreadLabelService';
import './mainThreadTunnelService';
import './mainThreadAuthentication';

View File

@@ -60,7 +60,7 @@ import { ExtHostLabelService } from 'vs/workbench/api/common/extHostLabelService
import { getRemoteName } from 'vs/platform/remote/common/remoteHosts';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations';
// import { IExtHostTask } from 'vs/workbench/api/common/extHostTask';
import { IExtHostTask } from 'vs/workbench/api/common/extHostTask';
// import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService';
import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch';
import { ILogService } from 'vs/platform/log/common/log';
@@ -124,7 +124,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
const extHostTerminalService = rpcProtocol.set(ExtHostContext.ExtHostTerminalService, accessor.get(IExtHostTerminalService));
// const extHostDebugService = rpcProtocol.set(ExtHostContext.ExtHostDebugService, accessor.get(IExtHostDebugService)); {{SQL CARBON EDIT}} remove debug service
const extHostSearch = rpcProtocol.set(ExtHostContext.ExtHostSearch, accessor.get(IExtHostSearch));
// const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, accessor.get(IExtHostTask)); {{SQL CARBON EDIT}} remove tasks service
const extHostTask = rpcProtocol.set(ExtHostContext.ExtHostTask, accessor.get(IExtHostTask));
const extHostOutputService = rpcProtocol.set(ExtHostContext.ExtHostOutputService, accessor.get(IExtHostOutputService));
// manually create and register addressable instances
@@ -155,8 +155,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
// Check that no named customers are missing
// {{SQL CARBON EDIT}} filter out the services we don't expose
const filtered: ProxyIdentifier<any>[] = [ExtHostContext.ExtHostDebugService, ExtHostContext.ExtHostTask];
const filtered: ProxyIdentifier<any>[] = [ExtHostContext.ExtHostDebugService];
const expected: ProxyIdentifier<any>[] = values(ExtHostContext).filter(v => !filtered.find(x => x === v));
rpcProtocol.assertRegistered(expected);
// Other instances
@@ -755,7 +756,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostDocumentContentProviders.registerTextDocumentContentProvider(scheme, provider);
},
registerTaskProvider: (type: string, provider: vscode.TaskProvider) => {
throw new Error('Tasks api is not allowed in Azure Data Studio'); // {{SQL CARBON EDIT}} disable task
extHostApiDeprecation.report('window.registerTaskProvider', extension,
`Use the corresponding function on the 'tasks' namespace instead`);
return extHostTask.registerTaskProvider(extension, type, provider);
},
registerFileSystemProvider(scheme, provider, options) {
return extHostFileSystem.registerFileSystemProvider(scheme, provider, options);
@@ -911,38 +915,30 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
}
};
const tasks: typeof vscode.tasks = { // {{SQL CARBON EDIT}} disable tasks api
const tasks: typeof vscode.tasks = {
registerTaskProvider: (type: string, provider: vscode.TaskProvider) => {
extHostLogService.warn('Tasks API is disabled in Azure Data Studio');
return undefined!;
return extHostTask.registerTaskProvider(extension, type, provider);
},
fetchTasks: (filter?: vscode.TaskFilter): Thenable<vscode.Task[]> => {
extHostLogService.warn('Tasks API is disabled in Azure Data Studio');
return undefined!;
return extHostTask.fetchTasks(filter);
},
executeTask: (task: vscode.Task): Thenable<vscode.TaskExecution> => {
extHostLogService.warn('Tasks API is disabled in Azure Data Studio');
return undefined!;
return extHostTask.executeTask(extension, task);
},
get taskExecutions(): vscode.TaskExecution[] {
extHostLogService.warn('Tasks API is disabled in Azure Data Studio');
return undefined!;
return extHostTask.taskExecutions;
},
onDidStartTask: (listeners, thisArgs?, disposables?) => {
extHostLogService.warn('Tasks API is disabled in Azure Data Studio');
return undefined!;
return extHostTask.onDidStartTask(listeners, thisArgs, disposables);
},
onDidEndTask: (listeners, thisArgs?, disposables?) => {
extHostLogService.warn('Tasks API is disabled in Azure Data Studio');
return undefined!;
return extHostTask.onDidEndTask(listeners, thisArgs, disposables);
},
onDidStartTaskProcess: (listeners, thisArgs?, disposables?) => {
extHostLogService.warn('Tasks API is disabled in Azure Data Studio');
return undefined!;
return extHostTask.onDidStartTaskProcess(listeners, thisArgs, disposables);
},
onDidEndTaskProcess: (listeners, thisArgs?, disposables?) => {
extHostLogService.warn('Tasks API is disabled in Azure Data Studio');
return undefined!;
return extHostTask.onDidEndTaskProcess(listeners, thisArgs, disposables);
}
};

View File

@@ -11,7 +11,7 @@ import { IExtHostConfiguration, ExtHostConfiguration } from 'vs/workbench/api/co
import { IExtHostCommands, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
import { IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import { IExtHostTerminalService, WorkerExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService';
// import { IExtHostTask, WorkerExtHostTask } from 'vs/workbench/api/common/extHostTask';
import { IExtHostTask, WorkerExtHostTask } from 'vs/workbench/api/common/extHostTask';
// import { IExtHostDebugService, WorkerExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService';
import { IExtHostSearch, ExtHostSearch } from 'vs/workbench/api/common/extHostSearch';
import { IExtensionStoragePaths, ExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
@@ -34,7 +34,7 @@ registerSingleton(IExtHostFileSystemInfo, ExtHostFileSystemInfo);
registerSingleton(IExtHostOutputService, ExtHostOutputService);
registerSingleton(IExtHostSearch, ExtHostSearch);
registerSingleton(IExtHostStorage, ExtHostStorage);
// registerSingleton(IExtHostTask, WorkerExtHostTask);
registerSingleton(IExtHostTask, WorkerExtHostTask);
registerSingleton(IExtHostTerminalService, WorkerExtHostTerminalService);
registerSingleton(IExtHostTunnelService, ExtHostTunnelService);
registerSingleton(IExtHostWindow, ExtHostWindow);

View File

@@ -6,7 +6,7 @@
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ExtHostOutputService2 } from 'vs/workbench/api/node/extHostOutputService';
import { ExtHostTerminalService } from 'vs/workbench/api/node/extHostTerminalService';
// import { ExtHostTask } from 'vs/workbench/api/node/extHostTask';
import { ExtHostTask } from 'vs/workbench/api/node/extHostTask';
// import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService';
import { NativeExtHostSearch } from 'vs/workbench/api/node/extHostSearch';
import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService';
@@ -16,7 +16,7 @@ import { ExtHostTunnelService } from 'vs/workbench/api/node/extHostTunnelService
import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService';
import { IExtHostOutputService } from 'vs/workbench/api/common/extHostOutput';
import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch';
// import { IExtHostTask } from 'vs/workbench/api/common/extHostTask';
import { IExtHostTask } from 'vs/workbench/api/common/extHostTask';
import { IExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService';
import { IExtHostTunnelService } from 'vs/workbench/api/common/extHostTunnelService';
import { ILogService } from 'vs/platform/log/common/log';
@@ -33,6 +33,6 @@ registerSingleton(ILogService, ExtHostLogService);
// registerSingleton(IExtHostDebugService, ExtHostDebugService);
registerSingleton(IExtHostOutputService, ExtHostOutputService2);
registerSingleton(IExtHostSearch, NativeExtHostSearch);
// registerSingleton(IExtHostTask, ExtHostTask);
registerSingleton(IExtHostTask, ExtHostTask);
registerSingleton(IExtHostTerminalService, ExtHostTerminalService);
registerSingleton(IExtHostTunnelService, ExtHostTunnelService);

View File

@@ -82,6 +82,12 @@ import { isWorkspaceFolder, TaskQuickPickEntry, QUICKOPEN_DETAIL_CONFIG, TaskQui
import { ILogService } from 'vs/platform/log/common/log';
import { once } from 'vs/base/common/functional';
// {{ SQL CARBON EDIT }}
// integration with tasks view panel
import { ITaskService as ISqlTaskService, TaskStatusChangeArgs } from 'sql/workbench/services/tasks/common/tasksService';
import { TaskStatus } from 'sql/workbench/api/common/extHostBackgroundTaskManagement';
import { TaskInfo } from 'azdata';
const QUICKOPEN_HISTORY_LIMIT_CONFIG = 'task.quickOpen.history';
const PROBLEM_MATCHER_NEVER_CONFIG = 'task.problemMatchers.neverPrompt';
const USE_SLOW_PICKER = 'task.quickOpen.showAll';
@@ -227,6 +233,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
private _waitForSupportedExecutions: Promise<void>;
private _onDidRegisterSupportedExecutions: Emitter<void> = new Emitter();
// {{SQL CARBON EDIT}}
private lastRunTasksViewTask: TaskInfo;
constructor(
@IConfigurationService private readonly configurationService: IConfigurationService,
@IMarkerService protected readonly markerService: IMarkerService,
@@ -258,7 +267,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
@ITextModelService private readonly textModelResolverService: ITextModelService,
@IPreferencesService private readonly preferencesService: IPreferencesService,
@IViewDescriptorService private readonly viewDescriptorService: IViewDescriptorService,
@ILogService private readonly logService: ILogService
@ILogService private readonly logService: ILogService,
@ISqlTaskService private readonly sqlTaskService: ISqlTaskService
) {
super();
@@ -882,7 +892,6 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
if (!task) {
throw new TaskError(Severity.Info, nls.localize('TaskServer.noTask', 'Task to execute is undefined'), TaskErrors.TaskNotFound);
}
return new Promise<ITaskSummary | undefined>(async (resolve) => {
let resolver = this.createResolver();
if (options && options.attachProblemMatcher && this.shouldAttachProblemMatcher(task) && !InMemoryTask.is(task)) {
@@ -1473,8 +1482,25 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
const execTask = async (task: Task, resolver: ITaskResolver): Promise<ITaskSummary> => {
return ProblemMatcherRegistry.onReady().then(() => {
// {{ SQL CARBON EDIT }}
const taskNodeId = UUID.generateUuid();
let taskInfo: TaskInfo = {
databaseName: undefined,
serverName: undefined,
description: undefined,
isCancelable: false,
name: task._label,
providerName: undefined,
taskExecutionMode: 0,
taskId: taskNodeId,
status: TaskStatus.NotStarted
};
this.sqlTaskService.createNewTask(taskInfo);
this.lastRunTasksViewTask = taskInfo;
let executeResult = this.getTaskSystem().run(task, resolver);
return this.handleExecuteResult(executeResult, runSource);
// {{ SQL CARBON EDIT }}
return this.handleExecuteResult(executeResult, runSource, taskNodeId);
});
};
@@ -1511,7 +1537,8 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
}
}
private async handleExecuteResult(executeResult: ITaskExecuteResult, runSource?: TaskRunSource): Promise<ITaskSummary> {
// {{SQL CARBON EDIT}}
private async handleExecuteResult(executeResult: ITaskExecuteResult, runSource?: TaskRunSource, taskNodeId?: string): Promise<ITaskSummary> {
if (executeResult.task.taskLoadMessages && executeResult.task.taskLoadMessages.length > 0) {
executeResult.task.taskLoadMessages.forEach(loadMessage => {
this._outputChannel.append(loadMessage + '\n');
@@ -1546,6 +1573,19 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
throw new TaskError(Severity.Warning, nls.localize('TaskSystem.active', 'There is already a task running. Terminate it first before executing another task.'), TaskErrors.RunningTask);
}
}
// {{ SQL CARBON EDIT }}
executeResult.promise.then((summary: ITaskSummary) => {
let args: TaskStatusChangeArgs = {
taskId: taskNodeId ? taskNodeId : executeResult.task._id,
status: undefined
};
if (summary.exitCode === 0) {
args.status = TaskStatus.Succeeded;
} else if (summary.exitCode === 1) {
args.status = TaskStatus.Failed;
}
this.sqlTaskService.handleTaskComplete(args);
});
return executeResult.promise;
}
@@ -2555,9 +2595,16 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
ProblemMatcherRegistry.onReady().then(() => {
return this.editorService.saveAll({ reason: SaveReason.AUTO }).then(() => { // make sure all dirty editors are saved
// {{SQL CARBON EDIT}}
let lastRunTasksViewTask = this.lastRunTasksViewTask;
lastRunTasksViewTask.taskId = UUID.generateUuid();
this.sqlTaskService.createNewTask(lastRunTasksViewTask);
this.lastRunTasksViewTask = lastRunTasksViewTask;
let executeResult = this.getTaskSystem().rerun();
if (executeResult) {
return this.handleExecuteResult(executeResult);
// {{SQL CARBON EDIT}}
return this.handleExecuteResult(executeResult, undefined, lastRunTasksViewTask.taskId);
} else {
this.doRunTaskCommand();
return Promise.resolve(undefined);

View File

@@ -5,7 +5,9 @@
import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
// {{SQL CARBON EDIT}}
export const FOLDER_CONFIG_FOLDER_NAME = '.azuredatastudio';
export const TASKS_FOLDER_CONFIG_FOLDER_NAME = '.vscode';
export const FOLDER_SETTINGS_NAME = 'settings';
export const FOLDER_SETTINGS_PATH = `${FOLDER_CONFIG_FOLDER_NAME}/${FOLDER_SETTINGS_NAME}.json`;
@@ -26,7 +28,7 @@ export const TASKS_CONFIGURATION_KEY = 'tasks';
export const LAUNCH_CONFIGURATION_KEY = 'launch';
export const WORKSPACE_STANDALONE_CONFIGURATIONS = Object.create(null);
WORKSPACE_STANDALONE_CONFIGURATIONS[TASKS_CONFIGURATION_KEY] = `${FOLDER_CONFIG_FOLDER_NAME}/${TASKS_CONFIGURATION_KEY}.json`;
WORKSPACE_STANDALONE_CONFIGURATIONS[TASKS_CONFIGURATION_KEY] = `${TASKS_FOLDER_CONFIG_FOLDER_NAME}/${TASKS_CONFIGURATION_KEY}.json`;
WORKSPACE_STANDALONE_CONFIGURATIONS[LAUNCH_CONFIGURATION_KEY] = `${FOLDER_CONFIG_FOLDER_NAME}/${LAUNCH_CONFIGURATION_KEY}.json`;
export const USER_STANDALONE_CONFIGURATIONS = Object.create(null);
USER_STANDALONE_CONFIGURATIONS[TASKS_CONFIGURATION_KEY] = `${TASKS_CONFIGURATION_KEY}.json`;

View File

@@ -96,6 +96,10 @@ suite('ConfigurationEditingService', () => {
globalTasksFile = path.join(workspaceDir, 'tasks.json');
workspaceSettingsDir = path.join(workspaceDir, '.azuredatastudio'); // {{SQL CARBON EDIT}} .vscode to .azuredatastudio
// {{SQL CARBON EDIT}} add .vscode folder for tasks tests
const tasksSettingsDir = path.join(workspaceDir, '.vscode');
await mkdirp(tasksSettingsDir, 493);
return await mkdirp(workspaceSettingsDir, 493);
}

View File

@@ -206,7 +206,7 @@ export class ExtensionHostManager extends Disposable {
// Check that no named customers are missing
// {{SQL CARBON EDIT}} filter out services we don't expose
const filtered: ProxyIdentifier<any>[] = [MainContext.MainThreadDebugService, MainContext.MainThreadTask];
const filtered: ProxyIdentifier<any>[] = [MainContext.MainThreadDebugService];
const expected: ProxyIdentifier<any>[] = Object.keys(MainContext).map((key) => (<any>MainContext)[key]).filter(v => !filtered.some(x => x === v));
this._rpcProtocol.assertRegistered(expected);

View File

@@ -331,7 +331,7 @@ import 'vs/workbench/contrib/terminal/browser/terminalView';
import 'vs/workbench/contrib/relauncher/browser/relauncher.contribution';
// Tasks
// import 'vs/workbench/contrib/tasks/browser/task.contribution'; {{SQL CARBON EDIT}}
import 'vs/workbench/contrib/tasks/browser/task.contribution';
// Remote
import 'vs/workbench/contrib/remote/common/remote.contribution';