diff --git a/src/commands.ts b/src/commands.ts index dc26bd4c..367f2212 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -36,8 +36,7 @@ export async function createFunction(outputChannel: vscode.OutputChannel, functi if (missingFiles.length !== 0) { const result = await vscode.window.showWarningMessage(`The current folder is not initialized as a function app. Add missing files: '${missingFiles.join("', '")}'?`, _yes, _no); if (result === _yes) { - const output = await functionsCli.initFunctionApp(rootPath); - outputChannel.append(output); + await functionsCli.initFunctionApp(outputChannel, rootPath); } else { throw new util.UserCancelledError(); } @@ -54,8 +53,7 @@ export async function createFunction(outputChannel: vscode.OutputChannel, functi const name = await util.showInputBox("Function Name", "Provide a function name", (s) => validateTemplateName(rootPath, s)); - const output = await functionsCli.createFunction(rootPath, template.label, name); - outputChannel.append(output); + await functionsCli.createFunction(outputChannel, rootPath, template.label, name); } } @@ -92,8 +90,7 @@ export async function initFunctionApp(outputChannel: vscode.OutputChannel, funct } // TODO: Handle folders that are already initialized - const output = await functionsCli.initFunctionApp(functionAppPath); - outputChannel.append(output); + await functionsCli.initFunctionApp(outputChannel, functionAppPath); } export async function startFunctionApp(outputChannel: vscode.OutputChannel, node?: FunctionAppNode) { diff --git a/src/functions-cli.ts b/src/functions-cli.ts index 714bdeaa..f4b19bd2 100644 --- a/src/functions-cli.ts +++ b/src/functions-cli.ts @@ -10,28 +10,25 @@ export class FunctionsCli { constructor(private readonly _terminal: vscode.Terminal) { } - createFunction(workingDirectory: string, templateName: string, name: string): Promise { - return this.executeCommand(workingDirectory, `func new --language JavaScript --template ${templateName} --name ${name}`); + async createFunction(outputChannel: vscode.OutputChannel, workingDirectory: string, templateName: string, name: string) { + return this.executeCommand(outputChannel, workingDirectory, 'new', '--language', 'JavaScript', '--template', templateName, '--name', name); } - initFunctionApp(workingDirectory: string): Promise { - return this.executeCommand(workingDirectory, `func init`); + async initFunctionApp(outputChannel: vscode.OutputChannel, workingDirectory: string) { + return this.executeCommand(outputChannel, workingDirectory, 'init'); } - private executeCommand(workingDirectory: string, command: string): Promise { - return new Promise((resolve, reject) => { + private executeCommand(outputChannel: vscode.OutputChannel, workingDirectory: string, ...args: string[]): Promise { + return new Promise((resolve, reject) => { const options: cp.ExecOptions = { cwd: workingDirectory }; - // TODO: Verify special characters are escaped properly - cp.exec(command, options, (error, stdout, stderr) => { - if (stderr) { - reject(new Error(stderr)); - } else if (error) { - reject(error); - } else { - resolve(stdout); - } + const childProc = cp.spawn('func', args, options); + childProc.stdout.on('data', (data) => outputChannel.append(data.toString())); + childProc.stderr.on('data', (data) => reject(new Error(data.toString()))); + childProc.on('error', error => reject(error)); + childProc.on('close', code => { + code === 0 ? resolve() : reject(new Error(`Command failed with exit code '${code}'.`)) }); }); }