diff --git a/src/extension.ts b/src/extension.ts index eac8181..1c9aa12 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,6 +3,7 @@ import SettingsHelper from "./settingsHelper"; import ContributedCommands from "./commands"; import Config from "./services/config"; import ExtensionHelper from "./services/extensions"; +import logger from './services/logger'; function selectProfile( config: Config, @@ -33,8 +34,8 @@ function selectProfile( await settingsHelper.updateUserSettings(profileSettings); let extensions = config.getProfileExtensions(profile); - await extensionsHelper.installExtensions(extensions); - await extensionsHelper.removeExtensions(extensions); + await extensionsHelper.installExtensions(extensions, logger); + await extensionsHelper.removeExtensions(extensions, logger); msg.dispose(); diff --git a/src/services/extensions.ts b/src/services/extensions.ts index 323483b..93e584c 100755 --- a/src/services/extensions.ts +++ b/src/services/extensions.ts @@ -6,6 +6,7 @@ import SettingsHelper, { OsType } from "../settingsHelper"; import Config from "./config"; import { promisify } from "util"; import * as child_process from "child_process"; +import { Logger } from "./logger"; const exec = promisify(child_process.exec); @@ -53,7 +54,7 @@ class ExtensionHelper { ); } - private async removeExtension(ext: ExtensionInfo) { + private async removeExtension(ext: ExtensionInfo, logger: Logger) { const name = `${ext.publisherName}.${ext.name}-${ext.version}`; let extPath = join(this.settings.ExtensionFolder, name); @@ -69,6 +70,8 @@ class ExtensionHelper { if (!(await fs.pathExists(join(this.context.globalStoragePath, name)))) { await fs.copy(extPath, backupPath); } + logger.appendLine(`Extension ${ext.name} has been backed up.`); + logger.appendLine(""); } catch (e) { console.log(`Profile Switcher: Error backing up exstension ${name}`); console.log(e); @@ -76,13 +79,15 @@ class ExtensionHelper { try { await fs.remove(extPath); + logger.appendLine(`Extension ${ext.name} has been removed from VS Code.`); + logger.appendLine(""); } catch (e) { console.log(`Profile Switcher: Error removing exstension ${name}`); console.log(e); } } - public async removeExtensions(extensions: ExtensionInfo[]) { + public async removeExtensions(extensions: ExtensionInfo[], logger: Logger) { let installedExtensions = this.getInstalled(); let extensionsToRemove = installedExtensions.filter( @@ -93,42 +98,29 @@ class ExtensionHelper { await fs.mkdir(this.context.globalStoragePath); } - let removes = extensionsToRemove.map(ext => this.removeExtension(ext)); + logger.show(); + logger.appendLine( + `Preparing to remove ${extensionsToRemove.length} extensions.` + ); + logger.appendLine(""); + logger.appendLine(""); - await Promise.all(removes); - } + let removes = extensionsToRemove.map((ext, i) => { + logger.appendLine( + `Removing ${ext.name} (${i} of ${extensionsToRemove.length})` + ); + logger.appendLine(""); + this.removeExtension(ext, logger); + }); - private getCodeBinary() { - let binaryFullPath: string = process.argv0; - let codeInstallSuffix = ""; - let codeCliPath = ""; - if (this.settings.OsType === OsType.Windows) { - if (this.settings.isInsiders) { - codeInstallSuffix = "Code - Insiders"; - codeCliPath = "bin/code-insiders"; - } else { - codeInstallSuffix = "Code"; - codeCliPath = "bin/code"; - } - } else if (this.settings.OsType === OsType.Linux) { - if (this.settings.isInsiders) { - codeInstallSuffix = "code-insiders"; - codeCliPath = "bin/code-insiders"; - } else { - codeInstallSuffix = "code"; - codeCliPath = "bin/code"; - } - } else if (this.settings.OsType === OsType.Mac) { - codeInstallSuffix = "Frameworks"; - codeCliPath = "Resources/app/bin/code"; - } - return `"${binaryFullPath.substr( - 0, - binaryFullPath.lastIndexOf(codeInstallSuffix) - )}${codeCliPath}"`; + await Promise.all(removes); } - private async installExtension(ext: ExtensionInfo, binaryFullPath: string) { + private async installExtension( + ext: ExtensionInfo, + binaryFullPath: string, + logger: Logger + ) { const name = `${ext.publisherName}.${ext.name}-${ext.version}`; const backupPath = join(this.context.globalStoragePath, name); @@ -137,6 +129,8 @@ class ExtensionHelper { try { await fs.copy(backupPath, join(this.settings.ExtensionFolder, name)); installed = true; + logger.appendLine(`Extension ${ext.name} was restored from backup.`); + logger.appendLine(""); } catch (e) { console.log( `Profile Switcher: Error copying ${name} from backup path, will try to force install.` @@ -149,8 +143,12 @@ class ExtensionHelper { try { const cli = `${binaryFullPath} --install-extension ${ext.publisherId}`; await exec(cli); - console.log(`Profile Switcher: Installed ${name}.`); + logger.appendLine( + `Extension ${name} was installed from the marketplace.` + ); + logger.appendLine(""); } catch (e) { + logger.appendLine(`Extension ${name} failed to install.`); console.log( `Profile Switcher: Error installing ${name} from marketplace.` ); @@ -159,7 +157,7 @@ class ExtensionHelper { } } - public async installExtensions(extensions: ExtensionInfo[]) { + public async installExtensions(extensions: ExtensionInfo[], logger: Logger) { let installedExtensions = this.getInstalled(); let newExtensions = extensions.filter( @@ -170,9 +168,20 @@ class ExtensionHelper { await fs.mkdir(this.context.globalStoragePath); } - let installs = newExtensions.map(ext => - this.installExtension(ext, this.getCodeBinary()) + logger.show(); + logger.appendLine( + `Preparing to install ${newExtensions.length} extensions.` ); + logger.appendLine(""); + logger.appendLine(""); + + let installs = newExtensions.map((ext, i) => { + logger.appendLine( + `Installing ${ext.name} (${i} of ${newExtensions.length})` + ); + logger.appendLine(""); + return this.installExtension(ext, this.settings.getCodeBinary(), logger); + }); await Promise.all(installs); } diff --git a/src/services/logger.ts b/src/services/logger.ts new file mode 100755 index 0000000..4c82c22 --- /dev/null +++ b/src/services/logger.ts @@ -0,0 +1,32 @@ +import * as vscode from "vscode"; + +export interface Logger { + appendLine(value: string): void; + show(preserveFocus?: boolean): void; +} + +class OutputChannelLogger implements Logger { + show(preserveFocus?: boolean | undefined): void { + let oc = this.getChannel(); + oc.show(preserveFocus); + } + appendLine(value: string): void { + let oc = this.getChannel(); + + oc.appendLine(value); + } + + private outputChannel: vscode.OutputChannel | null = null; + + private getChannel() { + if (!this.outputChannel) { + this.outputChannel = vscode.window.createOutputChannel( + "Profile Switcher" + ); + } + + return this.outputChannel; + } +} + +export default new OutputChannelLogger(); diff --git a/src/settingsHelper.ts b/src/settingsHelper.ts index ac81702..0dc5983 100755 --- a/src/settingsHelper.ts +++ b/src/settingsHelper.ts @@ -126,4 +126,34 @@ export default class SettingsHelper { spaces: 4 }); } + + public getCodeBinary() { + let binaryFullPath: string = process.argv0; + let codeInstallSuffix = ""; + let codeCliPath = ""; + if (this.OsType === OsType.Windows) { + if (this.isInsiders) { + codeInstallSuffix = "Code - Insiders"; + codeCliPath = "bin/code-insiders"; + } else { + codeInstallSuffix = "Code"; + codeCliPath = "bin/code"; + } + } else if (this.OsType === OsType.Linux) { + if (this.isInsiders) { + codeInstallSuffix = "code-insiders"; + codeCliPath = "bin/code-insiders"; + } else { + codeInstallSuffix = "code"; + codeCliPath = "bin/code"; + } + } else if (this.OsType === OsType.Mac) { + codeInstallSuffix = "Frameworks"; + codeCliPath = "Resources/app/bin/code"; + } + return `"${binaryFullPath.substr( + 0, + binaryFullPath.lastIndexOf(codeInstallSuffix) + )}${codeCliPath}"`; + } }