Refactor stateless classes into modules

This commit is contained in:
Eric Jizba 2017-10-02 09:07:02 -07:00
Родитель 647685a5f2
Коммит 1304997de1
4 изменённых файлов: 96 добавлений и 108 удалений

Просмотреть файл

@ -10,9 +10,9 @@ import * as util from './util';
import * as vscode from 'vscode';
import { INode, FunctionAppNode } from './nodes';
import { FunctionsCli } from './functions-cli';
import * as FunctionsCli from './functions-cli';
import { QuickPickItemWithData } from './util';
import { TemplateFiles } from './template-files';
import * as TemplateFiles from './template-files';
const _expectedFunctionAppFiles = [
"host.json",
@ -28,7 +28,7 @@ export function openInPortal(node?: INode) {
}
}
export async function createFunction(outputChannel: vscode.OutputChannel, functionsCli: FunctionsCli) {
export async function createFunction(outputChannel: vscode.OutputChannel) {
let functionAppPath: string;
const folders = vscode.workspace.workspaceFolders;
if (!folders || folders.length === 0) {
@ -45,7 +45,7 @@ export async function createFunction(outputChannel: vscode.OutputChannel, functi
if (missingFiles.length !== 0) {
const result = await vscode.window.showWarningMessage(`The current folder is missing the following function app files: '${missingFiles.join("', '")}'. Add the missing files?`, _yes, _no);
if (result === _yes) {
await functionsCli.createFunctionApp(outputChannel, functionAppPath);
await FunctionsCli.createFunctionApp(outputChannel, functionAppPath);
} else {
throw new util.UserCancelledError();
}
@ -63,12 +63,12 @@ export async function createFunction(outputChannel: vscode.OutputChannel, functi
const name = await util.showInputBox("Function Name", "Provide a function name", false, (s) => validateTemplateName(functionAppPath, s));
await functionsCli.createFunction(outputChannel, functionAppPath, template.label, name);
await FunctionsCli.createFunction(outputChannel, functionAppPath, template.label, name);
const newFileUri = vscode.Uri.file(path.join(functionAppPath, name, "index.js"));
vscode.window.showTextDocument(await vscode.workspace.openTextDocument(newFileUri));
}
export async function createFunctionApp(outputChannel: vscode.OutputChannel, functionsCli: FunctionsCli) {
export async function createFunctionApp(outputChannel: vscode.OutputChannel) {
const newFolderId = "newFolder";
let folderPicks = [new QuickPickItemWithData("$(plus) New Folder", undefined, newFolderId)];
const folders = vscode.workspace.workspaceFolders;
@ -86,11 +86,11 @@ export async function createFunctionApp(outputChannel: vscode.OutputChannel, fun
const launchJsonExists = await fs.existsSync(launchJsonPath);
// TODO: Handle folders that are already initialized
await functionsCli.createFunctionApp(outputChannel, functionAppPath);
await FunctionsCli.createFunctionApp(outputChannel, functionAppPath);
if (!tasksJsonExists && !launchJsonExists) {
await util.writeToFile(tasksJsonPath, TemplateFiles.tasksJson);
await util.writeToFile(launchJsonPath, TemplateFiles.launchJson);
await util.writeToFile(tasksJsonPath, TemplateFiles.getTasksJson());
await util.writeToFile(launchJsonPath, TemplateFiles.getLaunchJson());
}
if (createNewFolder) {

Просмотреть файл

@ -13,7 +13,6 @@ import { AzureAccount } from './azure-account.api';
import { AzureFunctionsExplorer } from './explorer';
import { INode, FunctionAppNode } from './nodes'
import { Reporter } from './telemetry';
import { FunctionsCli } from './functions-cli'
export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(new Reporter(context));
@ -26,17 +25,13 @@ export function activate(context: vscode.ExtensionContext) {
const explorer = new AzureFunctionsExplorer(azureAccount);
context.subscriptions.push(vscode.window.registerTreeDataProvider('azureFunctionsExplorer', explorer));
const terminal: vscode.Terminal = vscode.window.createTerminal('Azure Functions');
context.subscriptions.push(terminal);
const functionsCli = new FunctionsCli(terminal);
const outputChannel = vscode.window.createOutputChannel("Azure Functions");
context.subscriptions.push(outputChannel);
initCommand(context, 'azureFunctions.refresh', (node?: INode) => explorer.refresh(node));
initCommand(context, 'azureFunctions.openInPortal', (node?: INode) => commands.openInPortal(node));
initAsyncCommand(context, 'azureFunctions.createFunction', (node?: INode) => commands.createFunction(outputChannel, functionsCli));
initAsyncCommand(context, 'azureFunctions.createFunctionApp', (node?: INode) => commands.createFunctionApp(outputChannel, functionsCli));
initAsyncCommand(context, 'azureFunctions.createFunction', (node?: INode) => commands.createFunction(outputChannel));
initAsyncCommand(context, 'azureFunctions.createFunctionApp', (node?: INode) => commands.createFunctionApp(outputChannel));
initAsyncCommand(context, 'azureFunctions.startFunctionApp', (node?: FunctionAppNode) => commands.startFunctionApp(outputChannel, node));
initAsyncCommand(context, 'azureFunctions.stopFunctionApp', (node?: FunctionAppNode) => commands.stopFunctionApp(outputChannel, node));
initAsyncCommand(context, 'azureFunctions.restartFunctionApp', (node?: FunctionAppNode) => commands.restartFunctionApp(outputChannel, node));

Просмотреть файл

@ -6,42 +6,37 @@
import * as cp from 'child_process';
import * as vscode from 'vscode';
export class FunctionsCli {
constructor(private readonly _terminal: vscode.Terminal) {
}
export async function createFunction(outputChannel: vscode.OutputChannel, workingDirectory: string, templateName: string, name: string) {
await executeCommand(outputChannel, workingDirectory, 'new', '--language', 'JavaScript', '--template', templateName, '--name', name);
}
async createFunction(outputChannel: vscode.OutputChannel, workingDirectory: string, templateName: string, name: string) {
await this.executeCommand(outputChannel, workingDirectory, 'new', '--language', 'JavaScript', '--template', templateName, '--name', name);
}
export async function createFunctionApp(outputChannel: vscode.OutputChannel, workingDirectory: string) {
await executeCommand(outputChannel, workingDirectory, 'init');
}
async createFunctionApp(outputChannel: vscode.OutputChannel, workingDirectory: string) {
await this.executeCommand(outputChannel, workingDirectory, 'init');
}
private executeCommand(outputChannel: vscode.OutputChannel, workingDirectory: string, ...args: string[]): Promise<void> {
return new Promise((resolve, reject) => {
const options: cp.SpawnOptions = {
cwd: workingDirectory,
shell: true
};
const childProc = cp.spawn('func', args, options);
let stderr: string = '';
childProc.stdout.on('data', (data) => outputChannel.append(data.toString()));
childProc.stderr.on('data', (data) => stderr = stderr.concat(data.toString()));
childProc.on('error', error => reject(error));
childProc.on('close', code => {
const errorMessage = stderr.trim();
if (errorMessage) {
// 'func' commands always seem to return exit code 0. For now,
// we will use stderr to detect if an error occurs (even though stderr
// doesn't necessarily mean there's an error)
reject(errorMessage);
} else if (code !== 0) {
reject(new Error(`Command failed with exit code '${code}'.`));
} else {
resolve();
}
});
function executeCommand(outputChannel: vscode.OutputChannel, workingDirectory: string, ...args: string[]): Promise<void> {
return new Promise((resolve, reject) => {
const options: cp.SpawnOptions = {
cwd: workingDirectory,
shell: true
};
const childProc = cp.spawn('func', args, options);
let stderr: string = '';
childProc.stdout.on('data', (data) => outputChannel.append(data.toString()));
childProc.stderr.on('data', (data) => stderr = stderr.concat(data.toString()));
childProc.on('error', error => reject(error));
childProc.on('close', code => {
const errorMessage = stderr.trim();
if (errorMessage) {
// 'func' commands always seem to return exit code 0. For now,
// we will use stderr to detect if an error occurs (even though stderr
// doesn't necessarily mean there's an error)
reject(errorMessage);
} else if (code !== 0) {
reject(new Error(`Command failed with exit code '${code}'.`));
} else {
resolve();
}
});
}
});
}

Просмотреть файл

@ -3,65 +3,63 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export class TemplateFiles {
private static readonly _taskId = "launchFunctionApp";
private static readonly _tasksJson = {
"version": "2.0.0",
"tasks": [
{
"taskName": "Launch Function App",
"identifier": TemplateFiles._taskId,
"type": "shell",
"command": "func host start",
"isBackground": true,
"presentation": {
"reveal": "silent"
},
"problemMatcher": [
{
"owner": "azureFunctions",
"pattern": [
{
"regexp": "\\b\\B",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
"beginsPattern": "^.*Stopping host.*",
"endsPattern": "^.*Job host started.*"
export function getTasksJson() {
return stringifyJSON(tasksJson);
}
export function getLaunchJson() {
return stringifyJSON(launchJson);
}
const taskId = "launchFunctionApp";
const tasksJson = {
"version": "2.0.0",
"tasks": [
{
"taskName": "Launch Function App",
"identifier": taskId,
"type": "shell",
"command": "func host start",
"isBackground": true,
"presentation": {
"reveal": "silent"
},
"problemMatcher": [
{
"owner": "azureFunctions",
"pattern": [
{
"regexp": "\\b\\B",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
"beginsPattern": "^.*Stopping host.*",
"endsPattern": "^.*Job host started.*"
}
]
}
]
};
}
]
}
]
};
private static readonly _launchJson = {
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Azure Functions",
"type": "node",
"request": "attach",
"port": 5858,
"protocol": "inspector", // TODO: Verify behavior on older versions of node
"preLaunchTask": TemplateFiles._taskId
}
]
};
const launchJson = {
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Azure Functions",
"type": "node",
"request": "attach",
"port": 5858,
"protocol": "inspector", // TODO: Verify behavior on older versions of node
"preLaunchTask": taskId
}
]
};
static get tasksJson() {
return TemplateFiles.stringifyJSON(TemplateFiles._tasksJson);
}
static get launchJson() {
return TemplateFiles.stringifyJSON(TemplateFiles._launchJson);
}
private static stringifyJSON(data: any): string {
return JSON.stringify(data, null, " ");
}
function stringifyJSON(data: any): string {
return JSON.stringify(data, null, " ");
}