Added task provider example

This commit is contained in:
Dirk Baeumer
2017-07-05 17:21:28 +02:00
parent 4155e0e0cc
commit ad39f8c2dd
8 changed files with 288 additions and 0 deletions

2
task-provider-sample/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
out
node_modules

View File

@ -0,0 +1,38 @@
// A launch configuration that compiles the extension and then opens it inside a new window
{
"version": "0.1.0",
"configurations": [
{
"name": "Launch Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceRoot}"],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": ["${workspaceRoot}/out/src/**/*.js"],
"preLaunchTask": "npm: run compile"
},
{
"name": "Launch Tests",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ],
"stopOnEntry": false,
"sourceMaps": true,
"outFiles": ["${workspaceRoot}/out/test/**/*.js"],
"preLaunchTask": "npm: run compile"
},
{
"type": "node",
"request": "attach",
"name": "Attach to Extension Host",
"protocol": "legacy",
"port": 5870,
"sourceMaps": true,
"restart": true,
"outDir": "${workspaceRoot}/out/src"
}
]
}

15
task-provider-sample/.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,15 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "compile",
"isBackground": true,
"problemMatcher": [
"$tsc-watch"
]
}
]
}

View File

@ -0,0 +1,9 @@
.vscode/**
.vscode-test/**
out/test/**
test/**
src/**
**/*.map
.gitignore
tsconfig.json
vsc-extension-quickstart.md

View File

@ -0,0 +1,10 @@
# Task Provider Example
- Detects tasks in Rakefiles
## Running the example
- Open this example in VS Code
- `npm install`
- `npm run compile`
- `F5` to start debugging

View File

@ -0,0 +1,45 @@
{
"name": "task-provider-samples",
"displayName": "Task Provider Samples",
"description": "Samples for VSCode's view API",
"version": "0.0.1",
"publisher": "ms-vscode",
"engines": {
"vscode": "^1.13.0"
},
"categories": [
"Other"
],
"activationEvents": [
"onCommand:workbench.action.tasks.runTask"
],
"main": "./out/src/extension",
"contributes": {
"taskDefinitions": [
{
"type": "rake",
"required": ["task"],
"properties": {
"task": {
"type": "string",
"description": "The Rake task to customize"
},
"file": {
"type": "string",
"description": "The Rake file that provides the task. Can be omitted."
}
}
}
]
},
"scripts": {
"vscode:prepublish": "tsc -p ./",
"compile": "tsc -watch -p ./",
"postinstall": "node ./node_modules/vscode/bin/install"
},
"devDependencies": {
"typescript": "^2.4.1",
"vscode": "^1.1.2",
"@types/node": "*"
}
}

View File

@ -0,0 +1,153 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as path from 'path';
import * as fs from 'fs';
import * as cp from 'child_process';
import * as vscode from 'vscode';
let taskProvider: vscode.Disposable | undefined;
export function activate(_context: vscode.ExtensionContext): void {
let workspaceRoot = vscode.workspace.rootPath;
if (!workspaceRoot) {
return;
}
let pattern = path.join(workspaceRoot, 'Rakefile');
let rakePromise: Thenable<vscode.Task[]> | undefined = undefined;
let fileWatcher = vscode.workspace.createFileSystemWatcher(pattern);
fileWatcher.onDidChange(() => rakePromise = undefined);
fileWatcher.onDidCreate(() => rakePromise = undefined);
fileWatcher.onDidDelete(() => rakePromise = undefined);
taskProvider = vscode.workspace.registerTaskProvider('grunt', {
provideTasks: () => {
if (!rakePromise) {
rakePromise = getRakeTasks();
}
return rakePromise;
},
resolveTask(_task: vscode.Task): vscode.Task | undefined {
return undefined;
}
});
}
export function deactivate(): void {
if (taskProvider) {
taskProvider.dispose();
}
}
function exists(file: string): Promise<boolean> {
return new Promise<boolean>((resolve, _reject) => {
fs.exists(file, (value) => {
resolve(value);
});
});
}
function exec(command: string, options: cp.ExecOptions): Promise<{ stdout: string; stderr: string }> {
return new Promise<{ stdout: string; stderr: string }>((resolve, reject) => {
cp.exec(command, options, (error, stdout, stderr) => {
if (error) {
reject({ error, stdout, stderr });
}
resolve({ stdout, stderr });
});
});
}
let _channel: vscode.OutputChannel;
function getOutputChannel(): vscode.OutputChannel {
if (!_channel) {
_channel = vscode.window.createOutputChannel('Rake Auto Detection');
}
return _channel;
}
interface RakeTaskDefinition extends vscode.TaskDefinition {
task: string;
file?: string;
}
const buildNames: string[] = ['build', 'compile', 'watch'];
function isBuildTask(name: string): boolean {
for (let buildName of buildNames) {
if (name.indexOf(buildName) !== -1) {
return true;
}
}
return false;
}
const testNames: string[] = ['test'];
function isTestTask(name: string): boolean {
for (let testName of testNames) {
if (name.indexOf(testName) !== -1) {
return true;
}
}
return false;
}
async function getRakeTasks(): Promise<vscode.Task[]> {
let workspaceRoot = vscode.workspace.rootPath;
let emptyTasks: vscode.Task[] = [];
if (!workspaceRoot) {
return emptyTasks;
}
let rakeFile = path.join(workspaceRoot, 'Rakefile');
if (!await exists(rakeFile)) {
return emptyTasks;
}
let commandLine = 'rake -AT -f Rakefile';
try {
let { stdout, stderr } = await exec(commandLine, { cwd: workspaceRoot });
if (stderr && stderr.length > 0) {
getOutputChannel().appendLine(stderr);
getOutputChannel().show(true);
}
let result: vscode.Task[] = [];
if (stdout) {
let lines = stdout.split(/\r{0,1}\n/);
for (let line of lines) {
if (line.length === 0) {
continue;
}
let regExp = /rake\s(.*)#/;
let matches = regExp.exec(line);
if (matches && matches.length === 2) {
let taskName = matches[1].trim();
let kind: RakeTaskDefinition = {
type: 'rake',
task: taskName
};
let task = new vscode.Task(kind, taskName, 'rake', new vscode.ShellExecution(`rake ${taskName}`));
result.push(task);
let lowerCaseLine = line.toLowerCase();
if (isBuildTask(lowerCaseLine)) {
task.group = vscode.TaskGroup.Build;
} else if (isTestTask(lowerCaseLine)) {
task.group = vscode.TaskGroup.Test;
}
}
}
}
return result;
} catch (err) {
let channel = getOutputChannel();
if (err.stderr) {
channel.appendLine(err.stderr);
}
if (err.stdout) {
channel.appendLine(err.stdout);
}
channel.appendLine('Auto detecting rake tasts failed.');
channel.show(true);
return emptyTasks;
}
}

View File

@ -0,0 +1,16 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"outDir": "out",
"lib": [
"es6"
],
"sourceMap": true,
"rootDir": "."
},
"exclude": [
"node_modules",
".vscode-test"
]
}