make the outputchannel singleton (#67)

This commit is contained in:
Sheng Chen 2018-01-29 17:25:19 +08:00 коммит произвёл GitHub
Родитель 74c8f33764
Коммит 6b2c9160c2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 74 добавлений и 62 удалений

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

@ -1,12 +1,11 @@
"use strict";
import * as vscode from "vscode";
import { terraformChannel } from "./terraformChannel";
export abstract class BaseShell {
protected outputChannel: vscode.OutputChannel;
constructor(outputChannel: vscode.OutputChannel) {
this.outputChannel = outputChannel;
constructor() {
this.initShellInternal();
}
@ -14,7 +13,7 @@ export abstract class BaseShell {
// We keep the TFConfiguration for the moment - will need to be updated to sync folders
const tfActiveFile = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.document.fileName : null;
this.outputChannel.appendLine(`Running - ${tfCommand}, Active File: ${tfActiveFile}`);
terraformChannel.appendLine(`Running - ${tfCommand}, Active File: ${tfActiveFile}`);
// Run Terraform command
this.runTerraformInternal(tfCommand, workingDir);
@ -23,8 +22,8 @@ export abstract class BaseShell {
public async runTerraformCmdAsync(tfCommand: string): Promise<any> {
const tfActiveFile = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.document.fileName : null;
this.outputChannel.appendLine(`Running - ${tfCommand}`);
this.outputChannel.show();
terraformChannel.appendLine(`Running - ${tfCommand}`);
terraformChannel.show();
return this.runTerraformAsyncInternal(tfActiveFile, tfCommand);
}
@ -37,11 +36,11 @@ export abstract class BaseShell {
}
protected output(label: string, message: string): void {
this.outputChannel.append(`[${label}] ${message}`);
terraformChannel.appendLine(`[${label}] ${message}`);
}
protected outputLine(label: string, message: string): void {
this.outputChannel.appendLine(`[${label}] ${message}`);
terraformChannel.appendLine(`[${label}] ${message}`);
}
protected isWindows(): boolean {

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

@ -2,13 +2,14 @@
import * as path from "path";
import { clearInterval, setInterval, setTimeout } from "timers";
import { commands, OutputChannel, window } from "vscode";
import { commands, window } from "vscode";
import * as nls from "vscode-nls";
import { AzureAccount, AzureSession, AzureSubscription } from "./azure-account.api";
import {
delay, Errors, getStorageAccountKey, getUserSettings,
provisionConsole, resetConsole, runInTerminal,
} from "./cloudConsoleLauncher";
import { terraformChannel } from "./terraformChannel";
import { isNodeVersionValid } from "./utils/nodeUtils";
import { DialogOption, openUrlHint } from "./utils/uiUtils";
@ -37,14 +38,13 @@ export function openCloudConsole(
api: AzureAccount,
subscription: AzureSubscription,
os: IOS,
outputChannel: OutputChannel,
tempFile: string) {
return (async function retry(): Promise<any> {
outputChannel.show();
outputChannel.appendLine("Attempting to open CloudConsole - Connecting to cloudshell");
terraformChannel.show();
terraformChannel.appendLine("Attempting to open CloudConsole - Connecting to cloudshell");
/* tslint:disable:semicolon */
const progress = delayedInterval(() => { outputChannel.append("..") }, 500);
const progress = delayedInterval(() => { terraformChannel.append("..") }, 500);
/* tslint:enable:semicolon */
const isWindows = process.platform === "win32";
@ -69,7 +69,7 @@ export function openCloudConsole(
return;
}
outputChannel.append("\nUsersettings obtained from Tokens - proceeding\n");
terraformChannel.appendLine("Usersettings obtained from Tokens - proceeding");
// Finding the storage account
const storageProfile = result.userSettings.storageProfile;
@ -92,7 +92,7 @@ export function openCloudConsole(
storageAccount.subscriptionId,
result.token.accessToken,
storageAccount.storageAccountName).then((keys) => {
outputChannel.appendLine("Storage key obtained ");
terraformChannel.appendLine("Storage key obtained ");
storageAccountKey = keys.body.keys[0].value;
});
@ -157,8 +157,8 @@ export function openCloudConsole(
return [terminal, response, storageAccount.storageAccountName, storageAccountKey, fileShareName, storageAccount.resourceGroup];
})().catch((err) => {
outputChannel.append("\nConnecting to CloudShell failed with error: \n" + err);
outputChannel.show();
terraformChannel.appendLine("Connecting to CloudShell failed with error: " + err);
terraformChannel.show();
throw err;
});
}

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

@ -12,6 +12,7 @@ import { openCloudConsole, OSes } from "./cloudConsole";
import { delay } from "./cloudConsoleLauncher";
import { aciConfig, Constants, exportContainerCmd, exportTestScript } from "./constants";
import { azFileDelete, azFilePush, escapeFile, TerminalType, TestOption, TFTerminal } from "./shared";
import { terraformChannel } from "./terraformChannel";
import { DialogOption } from "./utils/uiUtils";
const tempFile = path.join(os.tmpdir(), "cloudshell" + vscode.env.sessionId + ".log");
@ -23,7 +24,7 @@ export class CloudShell extends BaseShell {
Constants.TerraformTerminalName);
public async pushFiles(files: vscode.Uri[], syncAllFiles: boolean): Promise<void> {
this.outputChannel.appendLine("Attempting to upload files to CloudShell");
terraformChannel.appendLine("Attempting to upload files to CloudShell");
const RETRY_INTERVAL = 500;
const RETRY_TIMES = 30;
@ -40,13 +41,13 @@ export class CloudShell extends BaseShell {
for (const file of files.map((a) => a.fsPath)) {
try {
if (await fsExtra.pathExists(file)) {
this.outputChannel.appendLine(`Uploading file ${file} to cloud shell`);
terraformChannel.appendLine(`Uploading file ${file} to cloud shell`);
await azFilePush(this.csTerm.storageAccountName,
this.csTerm.storageAccountKey,
this.csTerm.fileShareName, file);
}
} catch (err) {
this.outputChannel.appendLine(err);
terraformChannel.appendLine(err);
}
}
@ -75,12 +76,12 @@ export class CloudShell extends BaseShell {
} else {
for (const file of files.map((a) => a.fsPath)) {
try {
this.outputChannel.appendLine(`Deleting file ${file} from cloud shell`);
terraformChannel.appendLine(`Deleting file ${file} from cloud shell`);
await azFileDelete(this.csTerm.storageAccountName,
this.csTerm.storageAccountKey,
this.csTerm.fileShareName, file);
} catch (err) {
this.outputChannel.appendLine(err);
terraformChannel.appendLine(err);
}
}
}
@ -109,7 +110,7 @@ export class CloudShell extends BaseShell {
protected initShellInternal() {
vscode.window.onDidCloseTerminal(async (terminal) => {
if (terminal === this.csTerm.terminal) {
this.outputChannel.appendLine("CloudShell terminal was closed");
terraformChannel.appendLine("CloudShell terminal was closed");
await fsExtra.remove(tempFile);
this.csTerm.terminal = null;
}
@ -117,7 +118,7 @@ export class CloudShell extends BaseShell {
}
protected async syncWorkspaceInternal(file): Promise<void> {
this.outputChannel.appendLine(`Deleting ${path.basename(file)} in CloudShell`);
terraformChannel.appendLine(`Deleting ${path.basename(file)} in CloudShell`);
const retryInterval = 500;
const retryTimes = 30;
@ -131,14 +132,14 @@ export class CloudShell extends BaseShell {
this.csTerm.ws.send("rm " + path.relative(vscode.workspace.rootPath, file) + " \n");
// TODO: Add directory management
} catch (err) {
this.outputChannel.appendLine(err);
terraformChannel.appendLine(err);
}
break;
}
}
} else {
vscode.window.showErrorMessage("Open a terminal first");
this.outputChannel.appendLine("Terminal not opened when trying to transfer files");
terraformChannel.appendLine("Terminal not opened when trying to transfer files");
}
}
@ -200,7 +201,7 @@ export class CloudShell extends BaseShell {
.getExtension<AzureSubscription>("ms-vscode.azure-account")!.exports;
const operationSystem = process.platform === "win32" ? OSes.Windows : OSes.Linux;
return await openCloudConsole(accountAPI, azureSubscription, operationSystem, this.outputChannel, tempFile);
return await openCloudConsole(accountAPI, azureSubscription, operationSystem, tempFile);
}
protected async runTFCommand(command: string, workdir: string, terminal: Terminal): Promise<void> {
@ -235,7 +236,7 @@ export class CloudShell extends BaseShell {
this.csTerm.storageAccountKey = terminal[3];
this.csTerm.fileShareName = terminal[4];
this.csTerm.ResourceGroup = terminal[5];
this.outputChannel.appendLine("Obtained cloudshell terminal, retrying push files.");
terraformChannel.appendLine("Obtained cloudshell terminal, retrying push files.");
resolve(true);
} else {
console.log("Open CloudShell cancelled by user.");

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

@ -25,12 +25,8 @@ function getShell(): BaseShell {
}
export function activate(ctx: vscode.ExtensionContext) {
const outputChannel: vscode.OutputChannel = vscode.window.createOutputChannel("VSCode extension for Azure Terraform");
outputChannel.appendLine("Loading extension");
cs = new CloudShell(outputChannel);
is = new IntegratedShell(outputChannel);
cs = new CloudShell();
is = new IntegratedShell();
initFileWatcher(ctx);
ctx.subscriptions.push(vscode.workspace.onDidChangeConfiguration((e) => {
@ -67,7 +63,7 @@ export function activate(ctx: vscode.ExtensionContext) {
ctx.subscriptions.push(vscode.commands.registerCommand("vscode-terraform-azure.visualize", async () => {
if (await isDotInstalled()) {
await is.visualize(outputChannel);
await is.visualize();
}
}));

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

@ -8,6 +8,7 @@ import { commands, Uri, ViewColumn, workspace } from "vscode";
import { BaseShell } from "./baseShell";
import { Constants } from "./constants";
import { TerminalType, TestOption, TFTerminal } from "./shared";
import { terraformChannel } from "./terraformChannel";
import { isServicePrincipalSetInEnv } from "./utils/azureUtils";
import { executeCommand } from "./utils/cpUtils";
import { isDockerInstalled, runE2EInDocker, runLintInDocker } from "./utils/dockerUtils";
@ -24,7 +25,7 @@ export class IntegratedShell extends BaseShell {
private graphUri: Uri;
// Creates a png of terraform resource graph to visualize the resources under management.
public async visualize(outputChannel: vscode.OutputChannel): Promise<void> {
public async visualize(): Promise<void> {
await this.deletePng();
await executeCommand(
@ -34,7 +35,6 @@ export class IntegratedShell extends BaseShell {
shell: true,
cwd: vscode.workspace.workspaceFolders[0].uri.fsPath,
},
outputChannel,
);
const output: string = await executeCommand(
"terraform",
@ -43,11 +43,10 @@ export class IntegratedShell extends BaseShell {
shell: true,
cwd: vscode.workspace.workspaceFolders[0].uri.fsPath,
},
outputChannel,
);
const tmpFile: string = path.join(os.tmpdir(), "terraformgraph.output");
await fse.writeFile(tmpFile, output);
await drawGraph(outputChannel, vscode.workspace.workspaceFolders[0].uri.fsPath, tmpFile);
await drawGraph(vscode.workspace.workspaceFolders[0].uri.fsPath, tmpFile);
await commands.executeCommand("vscode.open", this.graphUri, ViewColumn.Two);
}
@ -93,7 +92,7 @@ export class IntegratedShell extends BaseShell {
}
const containerName: string = vscode.workspace.getConfiguration("tf-azure").get("test-container");
this.outputChannel.appendLine("Checking Azure Service Principal environment variables...");
terraformChannel.appendLine("Checking Azure Service Principal environment variables...");
if (!isServicePrincipalSetInEnv()) {
return;
}
@ -101,7 +100,6 @@ export class IntegratedShell extends BaseShell {
switch (TestType) {
case TestOption.lint: {
await runLintInDocker(
this.outputChannel,
vscode.workspace.workspaceFolders[0].uri.fsPath + ":/tf-test/module",
containerName,
);
@ -110,7 +108,6 @@ export class IntegratedShell extends BaseShell {
case TestOption.e2enossh: {
console.log("Running e2e test in " + process.env["ARM_TEST_LOCATION"]);
await runE2EInDocker(
this.outputChannel,
[
vscode.workspace.workspaceFolders[0].uri.fsPath + "/logs:/tf-test/module.kitchen",
vscode.workspace.workspaceFolders[0].uri.fsPath + ":/tf-test/module",
@ -122,7 +119,6 @@ export class IntegratedShell extends BaseShell {
case TestOption.e2ewithssh: {
console.log("Running e2e test in " + process.env["ARM_TEST_LOCATION"]);
await runE2EInDocker(
this.outputChannel,
[
`${path.join(os.homedir(), ".ssh")}:/root/.ssh/`,
vscode.workspace.workspaceFolders[0].uri.fsPath + "/logs:/tf-test/module.kitchen",
@ -143,7 +139,6 @@ export class IntegratedShell extends BaseShell {
"docker",
cmd.split(" "),
{ shell: true },
this.outputChannel,
);
}
break;

32
src/terraformChannel.ts Normal file
Просмотреть файл

@ -0,0 +1,32 @@
"use strict";
import * as vscode from "vscode";
export interface ITerraformChannel {
appendLine(message: any, title?: string): void;
append(message: any): void;
show(): void;
}
class TerraformChannel implements ITerraformChannel {
private readonly channel: vscode.OutputChannel = vscode.window.createOutputChannel("Azure Terraform");
public appendLine(message: any, title?: string): void {
if (title) {
const simplifiedTime = (new Date()).toISOString().replace(/z|t/gi, " ").trim(); // YYYY-MM-DD HH:mm:ss.sss
const hightlightingTitle = `[${title} ${simplifiedTime}]`;
this.channel.appendLine(hightlightingTitle);
}
this.channel.appendLine(message);
}
public append(message: any): void {
this.channel.append(message);
}
public show(): void {
this.channel.show();
}
}
export const terraformChannel: ITerraformChannel = new TerraformChannel();

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

@ -1,9 +1,9 @@
"use strict";
import * as cp from "child_process";
import * as vscode from "vscode";
import { terraformChannel } from "../terraformChannel";
export async function executeCommand(command: string, args: string[], options: cp.SpawnOptions, outputChannel?: vscode.OutputChannel): Promise<string> {
export async function executeCommand(command: string, args: string[], options: cp.SpawnOptions): Promise<string> {
return new Promise((resolve: (res: string) => void, reject: (e: Error) => void): void => {
let result: string = "";
const childProc: cp.ChildProcess = cp.spawn(command, args, options);
@ -11,16 +11,10 @@ export async function executeCommand(command: string, args: string[], options: c
childProc.stdout.on("data", (data: string | Buffer) => {
data = data.toString();
result = result.concat(data);
if (outputChannel) {
outputChannel.append(data);
}
terraformChannel.append(data);
});
childProc.stderr.on("data", (data: string | Buffer) => {
if (outputChannel) {
outputChannel.append(data.toString());
}
});
childProc.stderr.on("data", (data: string | Buffer) => terraformChannel.append(data.toString()));
childProc.on("error", reject);
childProc.on("close", (code: number) => {

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

@ -1,6 +1,5 @@
"use strict";
import * as vscode from "vscode";
import { executeCommand } from "./cpUtils";
import { openUrlHint } from "./uiUtils";
@ -14,7 +13,7 @@ export async function isDockerInstalled(): Promise<boolean> {
}
}
export async function runLintInDocker(outputChannel: vscode.OutputChannel, volumn: string, containerName: string): Promise<void> {
export async function runLintInDocker(volumn: string, containerName: string): Promise<void> {
try {
await executeCommand(
"docker",
@ -30,14 +29,13 @@ export async function runLintInDocker(outputChannel: vscode.OutputChannel, volum
"build",
],
{ shell: true },
outputChannel,
);
} catch (error) {
throw new Error("Run lint task in Docker failed, Please switch to output channel for more details.");
}
}
export async function runE2EInDocker(outputChannel: vscode.OutputChannel, volumn: string[], containerName: string): Promise<void> {
export async function runE2EInDocker(volumn: string[], containerName: string): Promise<void> {
try {
await executeCommand(
"docker",
@ -64,7 +62,6 @@ export async function runE2EInDocker(outputChannel: vscode.OutputChannel, volumn
"e2e",
],
{ shell: true },
outputChannel,
);
} catch (error) {
throw new Error("Run E2E test in Docker failed, Please switch to output channel for more details.");

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

@ -1,6 +1,5 @@
"use strict";
import * as vscode from "vscode";
import { executeCommand } from "./cpUtils";
import { openUrlHint } from "./uiUtils";
@ -14,7 +13,7 @@ export async function isDotInstalled(): Promise<boolean> {
}
}
export async function drawGraph(outputChannel: vscode.OutputChannel, workingDirectory: string, inputFile: string): Promise<void> {
export async function drawGraph(workingDirectory: string, inputFile: string): Promise<void> {
await executeCommand(
"dot",
["-Tpng", "-o", "graph.png", inputFile],
@ -22,6 +21,5 @@ export async function drawGraph(outputChannel: vscode.OutputChannel, workingDire
cwd: workingDirectory,
shell: true,
},
outputChannel,
);
}