make the outputchannel singleton (#67)
This commit is contained in:
Родитель
74c8f33764
Коммит
6b2c9160c2
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче