Skip to content
This repository has been archived by the owner on Jul 31, 2023. It is now read-only.

Commit

Permalink
Fix #192. Rake task autodetection.
Browse files Browse the repository at this point in the history
  • Loading branch information
rebornix committed Aug 10, 2017
1 parent 80b6dbc commit f2080e6
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 3 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
}
],
"engines": {
"vscode": "^1.12.0"
"vscode": "^1.14.0"
},
"license": "MIT",
"icon": "images/ruby.png",
Expand Down Expand Up @@ -77,7 +77,8 @@
},
"activationEvents": [
"onLanguage:ruby",
"onLanguage:erb"
"onLanguage:erb",
"onCommand:workbench.action.tasks.runTask"
],
"main": "./out/ruby.js",
"contributes": {
Expand Down
2 changes: 2 additions & 0 deletions src/ruby.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as cp from 'child_process';
import { LintCollection } from './lint/lintCollection';
import { RubyDocumentFormattingEditProvider } from './format/rubyFormat';
import * as utils from './utils';
import { registerTaskProvider } from './task/rake';

export function activate(context: ExtensionContext) {
const subs = context.subscriptions;
Expand All @@ -25,6 +26,7 @@ export function activate(context: ExtensionContext) {
registerCompletionProvider(context);
registerFormatter(context);
registerIntellisenseProvider(context);
registerTaskProvider(context);
utils.loadEnv();
}

Expand Down
140 changes: 140 additions & 0 deletions src/task/rake.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
'use strict';

import * as path from 'path';
import * as fs from 'fs';
import * as vscode from 'vscode';
import { getOutputChannel, exec } from '../utils';

let rakeFiles: Set<vscode.Uri> = new Set<vscode.Uri>();

export async function registerTaskProvider(ctx: vscode.ExtensionContext) {
let workspaceRoot = vscode.workspace.rootPath;
if (!workspaceRoot) {
return;
}
let rakePromise: Thenable<vscode.Task[]> | undefined = undefined;
let files = await vscode.workspace.findFiles("**/[rR]akefile{,.rb}");
for (let i = 0; i < files.length; i++) {
rakeFiles.add(files[i]);
}

let fileWatcher = vscode.workspace.createFileSystemWatcher("**/[rR]akefile{,.rb}");
fileWatcher.onDidChange(() => rakePromise = undefined);
fileWatcher.onDidCreate((uri) => {
rakeFiles.add(uri);
rakePromise = undefined
});
fileWatcher.onDidDelete((uri) => {
rakeFiles.delete(uri);
rakePromise = undefined
});

let taskProvider = vscode.workspace.registerTaskProvider('rake', {
provideTasks: () => {
if (!rakePromise) {
rakePromise = getRakeTasks();
}
return rakePromise;
},
resolveTask(_task: vscode.Task): vscode.Task | undefined {
return undefined;
}
});
}

function exists(file: string): Promise<boolean> {
return new Promise<boolean>((resolve, _reject) => {
fs.exists(file, (value) => {
resolve(value);
});
});
}

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;
}

if (rakeFiles.size < 1) {
return emptyTasks;
}

for (let key in rakeFiles.keys) {
if (!await exists(rakeFiles[key])) {
return emptyTasks;
}
}

let commandLine = 'rake -AT';
try {
let { stdout, stderr } = await exec(commandLine, { cwd: workspaceRoot });
if (stderr && stderr.length > 0) {
getOutputChannel().appendLine(stderr);
}
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;
}
}
1 change: 0 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export function getOutputChannel(): vscode.OutputChannel {
}

export async function loadEnv() {
getOutputChannel().appendLine(process.env.SHELL);
let { stdout, stderr } = await exec(process.env.SHELL + " -lc export", { cwd: vscode.workspace.rootPath });
let envs = stdout.trim().split('\n');
for (let i = 0; i < envs.length; i++) {
Expand Down

0 comments on commit f2080e6

Please sign in to comment.