Refactor stateless classes into modules
This commit is contained in:
Родитель
647685a5f2
Коммит
1304997de1
|
@ -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, " ");
|
||||
}
|
Загрузка…
Ссылка в новой задаче