Skip to content
This repository has been archived by the owner on Mar 11, 2024. It is now read-only.

Temporarily continue logging to the Truffle for VS Code output channel #237

Merged
merged 4 commits into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions src/Output.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Consensys Software Inc. All rights reserved.
// Licensed under the MIT license.

import {commands} from 'vscode';
import {commands, ExtensionContext, window} from 'vscode';
import {LogView} from './views/LogView';

export enum OutputLabel {
Expand All @@ -16,6 +16,8 @@ export enum OutputLabel {
}

export class Output {
private static readonly _outputChannel = window.createOutputChannel(OutputLabel.truffleForVSCode);

/**
* Append the given value and a line feed character
* to the log panel
Expand All @@ -26,6 +28,9 @@ export class Output {
*/
public static outputLine(label: OutputLabel, message: string, description?: string): void {
commands.executeCommand(`${LogView.viewType}.create.log`, label, this.formatMessage(label, message), description);

// INFO: THIS IS THE OLD VERSION OF LOGGER USING OUTPUT CHANNELS
this._outputChannel.appendLine(this.formatMessage(label, message));
}

/**
Expand All @@ -34,7 +39,7 @@ export class Output {
* @param label - represents the log type
* @param description - represents the log description
*/
public static dispose(label: OutputLabel, description?: string): void {
public static async dispose(label: OutputLabel, description?: string): Promise<void> {
commands.executeCommand(`${LogView.viewType}.dispose.tab`, label, description);
}

Expand All @@ -47,4 +52,20 @@ export class Output {
private static formatMessage(label = '', message = ''): string {
return `${label ? `[${label}] ` : ''}${message}`;
}

/**
* INFO: THIS IS THE OLD VERSION OF LOGGER USING OUTPUT CHANNELS
* Call this only once to push the outputChannel into the list of subscriptions.
*/
public static init(context: ExtensionContext) {
context.subscriptions.push(this._outputChannel);
}

public static show(): void {
this._outputChannel.show();
}

public static hide(): void {
this._outputChannel.hide();
}
}
6 changes: 6 additions & 0 deletions src/commands/TruffleCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ export namespace TruffleCommands {
}

await showIgnorableNotification(Constants.statusBarMessages.buildingContracts, async () => {
// INFO: THIS IS THE OLD VERSION OF LOGGER USING OUTPUT CHANNELS
Output.show();

await outputCommandHelper.executeCommand(contractDirectory, 'npx', args.join(' '));
commands.executeCommand('truffle-vscode.views.deployments.refresh');

Expand Down Expand Up @@ -509,6 +512,9 @@ async function deployToNetwork(networkName: string, truffleConfigPath: string):
const truffleConfigName = path.basename(truffleConfigPath);
await fs.ensureDir(workspaceRoot);

// INFO: THIS IS THE OLD VERSION OF LOGGER USING OUTPUT CHANNELS
Output.show();

try {
await installRequiredDependencies();
await outputCommandHelper.executeCommand(
Expand Down
4 changes: 4 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {registerGanacheDetails} from './pages/GanacheDetails';
import {registerLogView} from './views/LogView';
import {saveTextDocument} from './helpers/workspace';
import {StatusBarItems} from './Models/StatusBarItems/Contract';
import {Output} from './Output';

export async function activate(context: ExtensionContext) {
/**
Expand All @@ -58,6 +59,9 @@ export async function activate(context: ExtensionContext) {

Constants.initialize(context); // still do this first.

// INFO: THIS IS THE OLD VERSION OF LOGGER USING OUTPUT CHANNELS
Output.init(context);

DebuggerConfiguration.initialize(context);

// Registering the log view as first because it needs to print the requirement log
Expand Down
32 changes: 27 additions & 5 deletions src/services/dashboard/DashboardService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import {Output, OutputLabel} from '@/Output';
import {ChildProcess} from 'child_process';
import {OutputChannel, window} from 'vscode';
import {Constants, RequiredApps} from '../../Constants';
import {shell, spawnProcess} from '../../helpers';
import {findPid, killPid} from '../../helpers/shell';
Expand All @@ -12,6 +13,8 @@ import {isDashboardRunning, waitDashboardStarted} from './DashboardServiceClient

export namespace DashboardService {
export interface IDashboardProcess {
// INFO: THIS IS THE OLD VERSION OF LOGGER USING OUTPUT CHANNELS
output?: OutputChannel;
pid?: number;
port: number | string;
process?: ChildProcess;
Expand Down Expand Up @@ -64,6 +67,10 @@ export namespace DashboardService {
dashboardProcesses[port] = await spawnDashboardServer(port);
}

// INFO: THIS IS THE OLD VERSION OF LOGGER USING OUTPUT CHANNELS
// open the channel to show the output.
dashboardProcesses[port]?.output?.show(false);

Telemetry.sendEvent('DashboardService.waitDashboardStarted.serverStarted');

return dashboardProcesses[port];
Expand All @@ -87,15 +94,23 @@ export namespace DashboardService {

async function spawnDashboardServer(port: number | string): Promise<IDashboardProcess> {
const process = spawnProcess(undefined, `${RequiredApps.truffle} ${RequiredApps.dashboard}`, []);
const dashboardProcess = {port, process} as IDashboardProcess;

// INFO: THIS IS THE OLD VERSION OF LOGGER USING OUTPUT CHANNELS
const output = window.createOutputChannel(`${OutputLabel.dashboardCommands}:${port}`);

const dashboardProcess = {port, process, output} as IDashboardProcess;

// INFO: THIS IS THE OLD VERSION OF LOGGER USING OUTPUT CHANNELS
output.show(true);

try {
addAllListeners(port, process);
addAllListeners(output, port, process);
await waitDashboardStarted(port, Constants.dashboardRetryAttempts);
dashboardProcess.pid = await findPid(port);
} catch (error) {
Telemetry.sendException(error as Error);
await stopDashboardProcess(dashboardProcess, true);
await Output.dispose(OutputLabel.dashboardCommands, port.toString());
throw error;
}

Expand All @@ -107,27 +122,34 @@ export namespace DashboardService {
return;
}

const {pid, port, process} = dashboardProcess;
const {output, pid, port, process} = dashboardProcess;
delete dashboardProcesses[port];
Output.dispose(OutputLabel.dashboardCommands, port.toString());
await Output.dispose(OutputLabel.dashboardCommands, port.toString());

if (process) {
removeAllListeners(process);
process.kill('SIGINT');
}

// INFO: THIS IS THE OLD VERSION OF LOGGER USING OUTPUT CHANNELS
if (output) {
output.dispose();
}

if (pid && (killOutOfBand ? true : !!process)) {
return killPid(pid);
}
}

function addAllListeners(port: number | string, process: ChildProcess): void {
function addAllListeners(output: OutputChannel, port: number | string, process: ChildProcess): void {
process.stdout!.on('data', (data: string | Buffer) => {
Output.outputLine(OutputLabel.dashboardCommands, data.toString(), port.toString());
output.appendLine(data.toString());
});

process.stderr!.on('data', (data: string | Buffer) => {
Output.outputLine(OutputLabel.dashboardCommands, data.toString(), port.toString());
output.appendLine(data.toString());
});

process.on('exit', () => {
Expand Down
34 changes: 28 additions & 6 deletions src/services/ganache/GanacheService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import {Output, OutputLabel} from '@/Output';
import {ChildProcess} from 'child_process';
import {OutputChannel, window} from 'vscode';
import {Constants, RequiredApps} from '../../Constants';
import {shell, spawnProcess} from '../../helpers';
import {findPid, killPid} from '../../helpers/shell';
Expand All @@ -13,6 +14,8 @@ import {isGanacheServer, waitGanacheStarted} from './GanacheServiceClient';

export namespace GanacheService {
export interface IGanacheProcess {
// INFO: THIS IS THE OLD VERSION OF LOGGER USING OUTPUT CHANNELS
output?: OutputChannel;
pid?: number;
port: number | string;
process?: ChildProcess;
Expand Down Expand Up @@ -59,13 +62,17 @@ export namespace GanacheService {

if (portStatus === PortStatus.GANACHE) {
const pid = await findPid(port);
ganacheProcesses[port] = {pid, port};
ganacheProcesses[port] = ganacheProcesses[port] ? ganacheProcesses[port] : {pid, port};
}

if (portStatus === PortStatus.FREE) {
ganacheProcesses[port] = await spawnGanacheServer(port, options);
}

// INFO: THIS IS THE OLD VERSION OF LOGGER USING OUTPUT CHANNELS
// open the channel to show the output.
ganacheProcesses[port]?.output?.show(false);

Telemetry.sendEvent('GanacheServiceClient.waitGanacheStarted.serverStarted');
return ganacheProcesses[port];
}
Expand Down Expand Up @@ -99,15 +106,23 @@ export namespace GanacheService {
}

const process = spawnProcess(undefined, 'npx', args);
const ganacheProcess = {port, process} as IGanacheProcess;

// INFO: THIS IS THE OLD VERSION OF LOGGER USING OUTPUT CHANNELS
const output = window.createOutputChannel(`${OutputLabel.ganacheCommands}:${port}`);

const ganacheProcess = {port, process, output} as IGanacheProcess;

// INFO: THIS IS THE OLD VERSION OF LOGGER USING OUTPUT CHANNELS
output.show(true);

try {
addAllListeners(port, process);
addAllListeners(output, port, process);
await waitGanacheStarted(port, Constants.ganacheRetryAttempts);
ganacheProcess.pid = await findPid(port);
} catch (error) {
Telemetry.sendException(error as Error);
await stopGanacheProcess(ganacheProcess, true);
await Output.dispose(OutputLabel.ganacheCommands, port.toString());
throw error;
}

Expand All @@ -119,27 +134,34 @@ export namespace GanacheService {
return;
}

const {pid, port, process} = ganacheProcess;
const {output, pid, port, process} = ganacheProcess;
delete ganacheProcesses[port];
Output.dispose(OutputLabel.ganacheCommands, port.toString());
await Output.dispose(OutputLabel.ganacheCommands, port.toString());

if (process) {
removeAllListeners(process);
process.kill('SIGINT');
}

// INFO: THIS IS THE OLD VERSION OF LOGGER USING OUTPUT CHANNELS
if (output) {
output.dispose();
}

if (pid && (killOutOfBand ? true : !!process)) {
return killPid(pid);
}
}

function addAllListeners(port: number | string, process: ChildProcess): void {
function addAllListeners(output: OutputChannel, port: number | string, process: ChildProcess): void {
process.stdout!.on('data', (data: string | Buffer) => {
Output.outputLine(OutputLabel.ganacheCommands, data.toString(), port.toString());
output.appendLine(data.toString());
});

process.stderr!.on('data', (data: string | Buffer) => {
Output.outputLine(OutputLabel.ganacheCommands, data.toString(), port.toString());
output.appendLine(data.toString());
});

process.on('exit', () => {
Expand Down
5 changes: 4 additions & 1 deletion src/views/LogView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ export class LogView implements WebviewViewProvider {
* @param description - represents the log description
*/
public async createLog(label: OutputLabel, message: string, description?: string): Promise<void> {
// Displays the log panel. Unfortunately it doesn't load immediately so we have to wait for the html to load
// this._view?.show?.(true); // `show` is not implemented in 1.49 but is for 1.50 insiders

// Checks if the log panel has already been loaded and is visible
if (this._view == null || this._view?.visible === false) {
// If it has not yet been loaded, save the log to be executed after loading the log panel
Expand All @@ -96,7 +99,7 @@ export class LogView implements WebviewViewProvider {
*/
public async disposeTab(label: OutputLabel, description?: string): Promise<void> {
// Displays the log panel. Unfortunately it doesn't load immediately so we have to wait for the html to load
this._view?.show?.(true); // `show` is not implemented in 1.49 but is for 1.50 insiders
// this._view?.show?.(true); // `show` is not implemented in 1.49 but is for 1.50 insiders

// Checks if the log panel has already been loaded and is visible
if (this._view?.visible === false) {
Expand Down
2 changes: 1 addition & 1 deletion test/commands/GanacheService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ describe('Unit tests GanacheService', () => {
});
});

['1', '65535', '8454', 8000, 8454].forEach((port) => {
['1', '65535', 8000, 8454].forEach((port) => {
it(`startGanacheServer should pass validation if port is ${port}`, async () => {
// Arrange
const urlValidatorSpy = sinon.spy(UrlValidator, 'validatePort');
Expand Down