Skip to content

Commit

Permalink
[💡 Feature]: Extract logging as global object (#212)
Browse files Browse the repository at this point in the history
* type change handler of git provider

* remove unused store

* Implement logger singleton to handle logging across the whole extension

* add unit tests

* make logger package work for web

* add IS_WEB_BUNDLE as global in tests

* set globals more dynamically

* remove enablement for todo.toggle

* remove enablement for other tree item commands as well
  • Loading branch information
christian-bromann authored Sep 6, 2022
1 parent 7e24cd0 commit f868927
Show file tree
Hide file tree
Showing 44 changed files with 2,528 additions and 1,911 deletions.
2 changes: 2 additions & 0 deletions jest-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ global.BACKEND_BASE_URL = 'http://BACKEND_BASE_URL.com'
global.BACKEND_GEO_URL = 'http://BACKEND_GEO_URL.com'
// @ts-expect-error
global.BACKEND_FWDGEO_URL = 'http://BACKEND_FWDGEO_URL.com'
// @ts-expect-error
global.IS_WEB_BUNDLE = false

// @ts-expect-error
global.TextDecoder = TextDecoder
Expand Down
9 changes: 3 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@
"command": "marquee.link",
"title": "Jump to origin",
"category": "Marquee",
"enablement": "listFocus",
"icon": {
"light": "assets/link-dark.svg",
"dark": "assets/link-light.svg"
Expand Down Expand Up @@ -151,14 +150,12 @@
{
"command": "marquee.edit",
"category": "Marquee",
"enablement": "listFocus",
"title": "Edit"
},
{
"command": "marquee.todo.toggle",
"title": "Toggle Todo",
"category": "Marquee",
"enablement": "listFocus"
"category": "Marquee"
},
{
"command": "marquee.todo.addEditor",
Expand Down Expand Up @@ -236,8 +233,7 @@
{
"command": "marquee.snippet.insert",
"title": "Insert",
"category": "Marquee",
"enablement": "listFocus"
"category": "Marquee"
},
{
"command": "marquee.snippet.delete",
Expand Down Expand Up @@ -3476,6 +3472,7 @@
"@mui/icons-material": "5.8.4",
"@mui/material": "5.10.1",
"@types/vscode": "^1.70.0",
"@vscode/test-web": "^0.0.30",
"material-ui-popup-state": "^4.0.2",
"react": "18.2.0",
"react-dom": "18.2.0",
Expand Down
12 changes: 6 additions & 6 deletions packages/extension/src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fs from 'fs/promises'
import vscode from 'vscode'
import path from 'path'
import { WorkspaceType } from '@vscode-marquee/utils/extension'
import { WorkspaceType, Logger } from '@vscode-marquee/utils/extension'
import type { MarqueeEvents } from '@vscode-marquee/utils'
import type { Snippet } from '@vscode-marquee/widget-snippets/extension'

Expand All @@ -15,7 +15,6 @@ import { config, THIRD_PARTY_EXTENSION_DIR } from './constants'
import type { ExtensionConfiguration } from './types'

export class MarqueeExtension {
private readonly _channel = vscode.window.createOutputChannel('Marquee')
private readonly _stateMgr: StateManager

private readonly gui: MarqueeGui
Expand All @@ -25,8 +24,8 @@ export class MarqueeExtension {
constructor (private readonly context: vscode.ExtensionContext) {
this.context.subscriptions.push(...this.setupCommands())

this._stateMgr = new StateManager(this.context, this._channel)
this.gui = new MarqueeGui(this.context, this._stateMgr, this._channel)
this._stateMgr = new StateManager(this.context)
this.gui = new MarqueeGui(this.context, this._stateMgr)
this.treeView = new TreeView(this.context, this._stateMgr)
this.view = vscode.window.createTreeView('marquee', {
treeDataProvider: this.treeView,
Expand All @@ -52,10 +51,10 @@ export class MarqueeExtension {
fs.rm(thirdPartyDir, { force: true, recursive: true }).then(
() => fs.mkdir(thirdPartyDir)
).then(() => (
this._channel.appendLine(`Regenerated widget extension dir ${thirdPartyDir}`)
Logger.info(`Regenerated widget extension dir ${thirdPartyDir}`)
)).then(
() => this.openMarqueeOnStartup(config.get('configuration')),
(err) => this._channel.appendLine(`[Error]: ${(err as Error).message}`)
(err) => Logger.error(`[Error]: ${(err as Error).message}`)
)
} else {
this.openMarqueeOnStartup(config.get('configuration'))
Expand Down Expand Up @@ -89,6 +88,7 @@ export class MarqueeExtension {
return
}

Logger.info('Open Marquee on start up enabled, opening GUI')
return this.openGui()
}

Expand Down
6 changes: 3 additions & 3 deletions packages/extension/src/gui.view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Channel from 'tangle/webviews'
import { v4 as uuidv4 } from 'uuid'
import { EventEmitter } from 'events'
import { render } from 'eta'
import { getExtProps } from '@vscode-marquee/utils/extension'
import { getExtProps, Logger } from '@vscode-marquee/utils/extension'
import type { Client } from 'tangle'
import type { MarqueeEvents } from '@vscode-marquee/utils'

Expand Down Expand Up @@ -39,7 +39,6 @@ export class MarqueeGui extends EventEmitter {
constructor (
private readonly context: vscode.ExtensionContext,
private readonly stateMgr: StateManager,
private readonly channel: vscode.OutputChannel
) {
super()
this._template = vscode.workspace.fs.readFile(vscode.Uri.joinPath(this._baseUri, 'dist', 'extension.html'))
Expand Down Expand Up @@ -88,7 +87,7 @@ export class MarqueeGui extends EventEmitter {
* mode if so
*/
if (this.stateMgr.gui.state.modeName && !this.stateMgr.gui.configuration.modes[this.stateMgr.gui.state.modeName]) {
this.channel.appendLine(`Couldn't find selected mode "${this.stateMgr.gui.state.modeName}", switching to default`)
Logger.warn(`Couldn't find selected mode "${this.stateMgr.gui.state.modeName}", switching to default`)
await this.stateMgr.gui.updateState('modeName', DEFAULT_STATE.modeName)
}
}
Expand Down Expand Up @@ -294,6 +293,7 @@ export class MarqueeGui extends EventEmitter {
}

private _executeCommand ({ command, args, options }: { command: string, args: any[], options: any }) {
Logger.info(`Execute command "${command}" with args: ${(args || []).map((arg) => JSON.stringify(arg)).join(', ')}`)
telemetry.sendTelemetryEvent('executeCommand', { command })
if (args && args.length > 0 && command === 'vscode.openFolder') {
return vscode.commands.executeCommand(command, vscode.Uri.parse(args[0].toString()), options)
Expand Down
4 changes: 3 additions & 1 deletion packages/extension/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import type { Client } from 'tangle'

import telemetry from './telemetry'
import { MarqueeExtension } from './extension'
import { getExtProps, GitProvider } from '@vscode-marquee/utils/extension'
import { getExtProps, GitProvider, Logger } from '@vscode-marquee/utils/extension'

export async function activate (context: vscode.ExtensionContext) {
telemetry.sendTelemetryEvent('extensionActivate', getExtProps())
Logger.configure(context)

const gitProvider = new GitProvider(context)
await gitProvider.init()
context.subscriptions.push(gitProvider)
Expand Down
20 changes: 11 additions & 9 deletions packages/extension/src/stateManager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import vscode from 'vscode'

import ExtensionManager, {
Logger,
pkg as packageJson,
activate as activateUtils,
State as GlobalState,
Expand Down Expand Up @@ -54,7 +55,7 @@ export default class StateManager implements vscode.Disposable {
*/
([id, activate]) => ({
id,
exports: activate(this._context, this._channel),
exports: activate(this._context),
isActive: true,
packageJSON: { marquee: { widget: true } }
}) as Pick<vscode.Extension<ExtensionExport>, 'id' | 'exports' | 'isActive' | 'packageJSON'>
Expand All @@ -66,10 +67,7 @@ export default class StateManager implements vscode.Disposable {
private _subscriptions: vscode.Disposable[] = this.widgetExtensions.map(
(ex) => ex.exports.marquee.disposable)

constructor (
private readonly _context: vscode.ExtensionContext,
private readonly _channel: vscode.OutputChannel
) {
constructor (private readonly _context: vscode.ExtensionContext) {
this._subscriptions.push(
vscode.commands.registerCommand('marquee.jsonImport', this._import.bind(this)),
vscode.commands.registerCommand('marquee.jsonExport', this._export.bind(this))
Expand Down Expand Up @@ -105,6 +103,7 @@ export default class StateManager implements vscode.Disposable {
}

try {
Logger.info(`Import configuration from ${filePath}`)
const dec = new TextDecoder('utf-8')
const importJSON = await vscode.workspace.fs.readFile(filePath)
const obj = JSON.parse(dec.decode(importJSON))
Expand Down Expand Up @@ -157,7 +156,9 @@ export default class StateManager implements vscode.Disposable {
this.global.emit('gui.close')
return this.global.emit('gui.open', true)
} catch (err) {
vscode.window.showErrorMessage(`Error importing file: ${(err as Error).message}`)
const message = `Error importing file: ${(err as Error).message}`
Logger.error(message)
vscode.window.showErrorMessage(message)
} finally {
/**
* re-enable config change listener again
Expand Down Expand Up @@ -191,6 +192,7 @@ export default class StateManager implements vscode.Disposable {
return
}

Logger.info(`Export configuration and state to ${exportPath}`)
const jsonExport: ExportFormat = {
type: CONFIG_FILE_TYPE,
version: packageJson.version,
Expand All @@ -204,9 +206,9 @@ export default class StateManager implements vscode.Disposable {
`Successfully exported Marquee state to ${exportPath.fsPath}`
)
} catch (err) {
vscode.window.showErrorMessage(
`Error writing export file: ${(err as Error).message}`
)
const message = `Error writing export file: ${(err as Error).message}`
Logger.error(message)
vscode.window.showErrorMessage(message)
}
}

Expand Down
16 changes: 6 additions & 10 deletions packages/extension/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import vscode from 'vscode'
import ExtensionManager, { defaultConfigurations } from '@vscode-marquee/utils/extension'
import ExtensionManager, { defaultConfigurations, Logger } from '@vscode-marquee/utils/extension'

import { MODES_UPDATE_TIMEOUT } from './constants'

Expand Down Expand Up @@ -42,12 +42,11 @@ export class GUIExtensionManager extends ExtensionManager<State, Configuration>

constructor (
context: vscode.ExtensionContext,
channel: vscode.OutputChannel,
key: string,
defaultConfiguration: Configuration,
defaultState: State
) {
super(context, channel, key, defaultConfiguration, defaultState)
super(context, key, defaultConfiguration, defaultState)
this._disposables.push(vscode.workspace.onDidChangeConfiguration(this._onModeChange.bind(this)))
}

Expand Down Expand Up @@ -98,16 +97,13 @@ export class GUIExtensionManager extends ExtensionManager<State, Configuration>

const config = vscode.workspace.getConfiguration('marquee')
const val = config.get('configuration.modes') as Configuration[keyof Configuration]
this._channel.appendLine('Update configuration.modes via configuration listener')
Logger.info('Update configuration.modes via configuration listener')
this.broadcast({ modes: JSON.parse(JSON.stringify(val)) })
}
}

export function activateGUI (
context: vscode.ExtensionContext,
channel: vscode.OutputChannel
) {
const stateManager = new GUIExtensionManager(context, channel, 'configuration', DEFAULT_CONFIGURATION, DEFAULT_STATE)
export function activateGUI (context: vscode.ExtensionContext) {
const stateManager = new GUIExtensionManager(context, 'configuration', DEFAULT_CONFIGURATION, DEFAULT_STATE)

return {
marquee: {
Expand Down Expand Up @@ -151,6 +147,6 @@ export const linkMarquee = async (item: any) => {
editor.revealRange(r, vscode.TextEditorRevealType.InCenter)
editor.selection = new vscode.Selection(r.start, r.end)
} catch (err: any) {
console.warn(`Marquee: ${(err as Error).message}`)
Logger.warn(`Marquee: ${(err as Error).message}`)
}
}
7 changes: 5 additions & 2 deletions packages/extension/tests/__mocks__/vscode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ const vscode: any = {
UIKind: {
Desktop: 1,
Web: 2
},
ExtensionMode: {
Development: 'development'
}
}
vscode.TreeItemCollapsibleState = {
Expand All @@ -45,12 +48,12 @@ vscode.commands = {
const lineAtMock = jest.fn().mockReturnValue({ range: 'some range'})

vscode.TreeItem = jest.fn()
vscode.EventEmitter = jest.fn()
vscode.EventEmitter = jest.fn().mockReturnValue({ event: {}, fire: jest.fn() })
vscode.workspace = {
name: 'foobarWorkspace',
workspaceFile: { path: '/foo/bar' },
workspaceFolders: [{ uri: '/some/uri' }],
getConfiguration: jest.fn().mockReturnValue({ get: jest.fn(), update: jest.fn() }),
getConfiguration: jest.fn().mockReturnValue({ get: jest.fn(), update: jest.fn(), set: jest.fn() }),
onDidCloseTextDocument: jest.fn(),
onDidChangeTextDocument: jest.fn(),
onDidChangeConfiguration: jest.fn(),
Expand Down
Loading

0 comments on commit f868927

Please sign in to comment.