Add static logger class for azdata extension (#11939)

* Add static logger class for arc extension

* Fix compile errors

* Fix test
This commit is contained in:
Charles Gagnon
2020-08-24 12:32:45 -07:00
committed by GitHub
parent d96e83c3f0
commit 0e4e8c304c
8 changed files with 109 additions and 109 deletions

View File

@@ -7,6 +7,7 @@ import * as vscode from 'vscode';
import * as cp from 'child_process';
import * as sudo from 'sudo-prompt';
import * as loc from '../localizedConstants';
import Logger from './logger';
/**
* Wrapper error for when an unexpected exit code was received
@@ -46,11 +47,10 @@ export type ProcessOutput = { stdout: string, stderr: string };
* @param command The command to execute
* @param args Optional args to pass, every arg and arg value must be a separate item in the array
* @param additionalEnvVars Additional environment variables to add to the process environment
* @param outputChannel Channel used to display diagnostic information
*/
export async function executeCommand(command: string, args: string[], outputChannel: vscode.OutputChannel, additionalEnvVars?: { [key: string]: string },): Promise<ProcessOutput> {
export async function executeCommand(command: string, args: string[], additionalEnvVars?: { [key: string]: string },): Promise<ProcessOutput> {
return new Promise((resolve, reject) => {
outputChannel.appendLine(loc.executingCommand(command, args));
Logger.log(loc.executingCommand(command, args));
const stdoutBuffers: Buffer[] = [];
const stderrBuffers: Buffer[] = [];
const env = Object.assign({}, process.env, additionalEnvVars);
@@ -62,14 +62,14 @@ export async function executeCommand(command: string, args: string[], outputChan
const stdout = Buffer.concat(stdoutBuffers).toString('utf8').trim();
const stderr = Buffer.concat(stderrBuffers).toString('utf8').trim();
if (stdout) {
outputChannel.appendLine(loc.stdoutOutput(stdout));
Logger.log(loc.stdoutOutput(stdout));
}
if (stderr) {
outputChannel.appendLine(loc.stdoutOutput(stderr));
Logger.log(loc.stdoutOutput(stderr));
}
if (code) {
const err = new ExitCodeError(code, stderr);
outputChannel.appendLine(err.message);
Logger.log(err.message);
reject(err);
} else {
resolve({ stdout: stdout, stderr: stderr });
@@ -83,22 +83,21 @@ export async function executeCommand(command: string, args: string[], outputChan
* this function. The exact prompt is platform-dependent.
* @param command The command to execute
* @param args The additional args
* @param outputChannel Channel used to display diagnostic information
*/
export async function executeSudoCommand(command: string, outputChannel: vscode.OutputChannel): Promise<ProcessOutput> {
export async function executeSudoCommand(command: string): Promise<ProcessOutput> {
return new Promise((resolve, reject) => {
outputChannel.appendLine(loc.executingCommand(`sudo ${command}`, []));
Logger.log(loc.executingCommand(`sudo ${command}`, []));
sudo.exec(command, { name: vscode.env.appName }, (error, stdout, stderr) => {
stdout = stdout?.toString() ?? '';
stderr = stderr?.toString() ?? '';
if (stdout) {
outputChannel.appendLine(loc.stdoutOutput(stdout));
Logger.log(loc.stdoutOutput(stdout));
}
if (stderr) {
outputChannel.appendLine(loc.stdoutOutput(stderr));
Logger.log(loc.stdoutOutput(stderr));
}
if (error) {
outputChannel.appendLine(loc.unexpectedCommandError(error.message));
Logger.log(loc.unexpectedCommandError(error.message));
reject(error);
} else {
resolve({ stdout: stdout, stderr: stderr });

View File

@@ -3,11 +3,11 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as fs from 'fs';
import * as request from 'request';
import * as path from 'path';
import * as loc from '../localizedConstants';
import Logger from './logger';
const DownloadTimeout = 20000;
@@ -17,34 +17,33 @@ export namespace HttpClient {
* Downloads a file from the given URL, resolving to the full path of the downloaded file when complete
* @param downloadUrl The URL to download the file from
* @param targetFolder The folder to download the file to
* @param outputChannel Channel used to display diagnostic information
* @returns Full path to the downloaded file
*/
export function download(downloadUrl: string, targetFolder: string, outputChannel: vscode.OutputChannel): Promise<string> {
export function download(downloadUrl: string, targetFolder: string): Promise<string> {
return new Promise((resolve, reject) => {
let totalMegaBytes: number | undefined = undefined;
let receivedBytes = 0;
let printThreshold = 0.1;
let downloadRequest = request.get(downloadUrl, { timeout: DownloadTimeout })
.on('error', downloadError => {
outputChannel.appendLine(loc.downloadError);
outputChannel.appendLine(downloadError?.message ?? downloadError);
Logger.log(loc.downloadError);
Logger.log(downloadError?.message ?? downloadError);
reject(downloadError);
})
.on('response', (response) => {
if (response.statusCode !== 200) {
outputChannel.appendLine(loc.downloadError);
outputChannel.appendLine(response.statusMessage);
Logger.log(loc.downloadError);
Logger.log(response.statusMessage);
return reject(response.statusMessage);
}
const filename = path.basename(response.request.path);
const targetPath = path.join(targetFolder, filename);
outputChannel.appendLine(loc.downloadingTo(filename, targetPath));
Logger.log(loc.downloadingTo(filename, targetPath));
// Wait to create the WriteStream until here so we can use the actual
// filename based off of the URI.
downloadRequest.pipe(fs.createWriteStream(targetPath))
.on('close', async () => {
outputChannel.appendLine(loc.downloadFinished);
Logger.log(loc.downloadFinished);
resolve(targetPath);
})
.on('error', (downloadError) => {
@@ -54,7 +53,7 @@ export namespace HttpClient {
let contentLength = response.headers['content-length'];
let totalBytes = parseInt(contentLength || '0');
totalMegaBytes = totalBytes / (1024 * 1024);
outputChannel.appendLine(loc.downloadingProgressMb('0', totalMegaBytes.toFixed(2)));
Logger.log(loc.downloadingProgressMb('0', totalMegaBytes.toFixed(2)));
})
.on('data', (data) => {
receivedBytes += data.length;
@@ -62,7 +61,7 @@ export namespace HttpClient {
let receivedMegaBytes = receivedBytes / (1024 * 1024);
let percentage = receivedMegaBytes / totalMegaBytes;
if (percentage >= printThreshold) {
outputChannel.appendLine(loc.downloadingProgressMb(receivedMegaBytes.toFixed(2), totalMegaBytes.toFixed(2)));
Logger.log(loc.downloadingProgressMb(receivedMegaBytes.toFixed(2), totalMegaBytes.toFixed(2)));
printThreshold += 0.1;
}
}
@@ -74,8 +73,8 @@ export namespace HttpClient {
* Gets the filename for the specified URL - following redirects as needed
* @param url The URL to get the filename of
*/
export async function getFilename(url: string, outputChannel: vscode.OutputChannel): Promise<string> {
outputChannel.appendLine(loc.gettingFilenameOfUrl(url));
export async function getFilename(url: string): Promise<string> {
Logger.log(loc.gettingFilenameOfUrl(url));
return new Promise((resolve, reject) => {
let httpRequest = request.get(url, { timeout: DownloadTimeout })
.on('error', downloadError => {
@@ -88,7 +87,7 @@ export namespace HttpClient {
// We don't want to actually download the file so abort the request now
httpRequest.abort();
const filename = path.basename(response.request.path);
outputChannel.appendLine(loc.gotFilenameOfUrl(response.request.path, filename));
Logger.log(loc.gotFilenameOfUrl(response.request.path, filename));
resolve(filename);
});
});

View File

@@ -0,0 +1,24 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
export class Log {
private _output: vscode.OutputChannel;
constructor() {
this._output = vscode.window.createOutputChannel('azdata');
}
log(msg: string): void {
this._output.appendLine(msg);
}
show(): void {
this._output.show(true);
}
}
const Logger = new Log();
export default Logger;