Skip to content

Commit

Permalink
Add initialisation logging and test coverage (#42)
Browse files Browse the repository at this point in the history
* add logging and test coverage

* update after rebase

* change compile source
  • Loading branch information
christian-bromann authored Nov 1, 2022
1 parent d6f11bb commit 105c34e
Show file tree
Hide file tree
Showing 14 changed files with 263 additions and 126 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ node_modules
*.vsix
wasm
.DS_Store
coverage
47 changes: 47 additions & 0 deletions __mocks__/vscode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { vi } from 'vitest'

export const notebooks = {
createNotebookController: vi.fn().mockReturnValue({
createNotebookCellExecution: vi.fn().mockReturnValue({ start: vi.fn(), end: vi.fn() })
}),
registerNotebookCellStatusBarItemProvider: vi.fn(),
createRendererMessaging: vi.fn().mockReturnValue({
postMessage: vi.fn(),
onDidReceiveMessage: vi.fn().mockReturnValue({ dispose: vi.fn() })
})
}

export const Uri = {
joinPath: vi.fn().mockReturnValue('/foo/bar'),
parse: vi.fn()
}

export const workspace = {
openTextDocument: vi.fn(),
registerNotebookSerializer: vi.fn(),
fs: {
readFile: vi.fn().mockResolvedValue(Buffer.from('some wasm file'))
}
}

export const terminal = {
show: vi.fn(),
sendText: vi.fn()
}

export const window = {
showWarningMessage: vi.fn(),
showInformationMessage: vi.fn(),
createTerminal: vi.fn().mockReturnValue(terminal)
}

export const commands = {
registerCommand: vi.fn()
}

export const env = {
clipboard: {
writeText: vi.fn()
},
openExternal: vi.fn()
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
"postinstall": "npm run download:wasm",
"test": "run-s test:*",
"test:lint": "eslint src --ext ts",
"test:unit": "vitest",
"test:unit": "vitest --coverage",
"watch": "npm run build:dev -- --watch"
},
"devDependencies": {
Expand Down
34 changes: 34 additions & 0 deletions src/extension/commands/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import path from 'node:path'

import { NotebookCell, Uri, window, env } from 'vscode'

import { CliProvider } from '../provider/cli'
import { getTerminalByCell } from '../utils'

export function openTerminal (cell: NotebookCell) {
const terminal = getTerminalByCell(cell)
if (!terminal) {
return window.showWarningMessage('Couldn\'t find terminal! Was it already closed?')
}
return terminal.show()
}

export function copyCellToClipboard (cell: NotebookCell) {
env.clipboard.writeText(cell.document.getText())
return window.showInformationMessage('Copied cell to clipboard!')
}

export async function runCLICommand (cell: NotebookCell) {
if (!await CliProvider.isCliInstalled()) {
return window.showInformationMessage(
'Runme CLI is not installed. Do you want to download it?',
'Download now'
).then((openBrowser) => openBrowser && env.openExternal(
Uri.parse('https://github.com/stateful/runme/releases')
))
}
const cliName: string = (cell.metadata?.['cliName'] || '').trim()
const term = window.createTerminal(`CLI: ${cliName}`)
term.show(false)
term.sendText(`runme run ${cliName} --chdir="${path.dirname(cell.document.uri.fsPath)}"`)
}
9 changes: 6 additions & 3 deletions src/extension/executors/script/utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import fs from 'node:fs'
import path from 'node:path'
import { workspace, Uri } from 'vscode'

const tw = fs.readFileSync(path.resolve(__dirname, '..', 'assets', 'tw.min.css')).toString()
let tw: string

export function getHTMLTemplate (htmlSection: string, codeSection = '', attributes: Record<string, string>) {
if (!tw) {
tw = workspace.fs.readFile(Uri.joinPath(Uri.parse(__dirname), '..', 'assets', 'tw.min.css')).toString()
}

return /*html*/`
<html>
<head>
Expand Down
93 changes: 31 additions & 62 deletions src/extension/extension.ts
Original file line number Diff line number Diff line change
@@ -1,72 +1,41 @@
import path from 'node:path'

import vscode from 'vscode'
import { workspace, notebooks, commands, ExtensionContext } from 'vscode'

import { Serializer } from './notebook'
import { Kernel } from './kernel'
// import { ViteServerProcess } from './server'
import { ShowTerminalProvider, BackgroundTaskProvider } from './provider/background'
import { PidStatusProvider } from './provider/pid'
import { CopyProvider } from './provider/copy'
import { getTerminalByCell, resetEnv } from './utils'
import { resetEnv } from './utils'
import { CliProvider } from './provider/cli'

// const viteProcess = new ViteServerProcess()

export async function activate (context: vscode.ExtensionContext) {
console.log('[Runme] Activating Extension')
const kernel = new Kernel(context)

// await viteProcess.start()
context.subscriptions.push(
kernel,
// viteProcess,
vscode.workspace.registerNotebookSerializer('runme', new Serializer(context), {
transientOutputs: true,
transientCellMetadata: {
inputCollapsed: true,
outputCollapsed: true,
},
}),
vscode.notebooks.registerNotebookCellStatusBarItemProvider('runme', new ShowTerminalProvider()),
vscode.notebooks.registerNotebookCellStatusBarItemProvider('runme', new PidStatusProvider()),
vscode.notebooks.registerNotebookCellStatusBarItemProvider('runme', new CliProvider()),
vscode.notebooks.registerNotebookCellStatusBarItemProvider('runme', new BackgroundTaskProvider()),
vscode.notebooks.registerNotebookCellStatusBarItemProvider('runme', new CopyProvider()),
vscode.commands.registerCommand('runme.openTerminal', (cell: vscode.NotebookCell) => {
const terminal = getTerminalByCell(cell)
if (!terminal) {
return vscode.window.showWarningMessage('Couldn\'t find terminal! Was it already closed?')
}
return terminal.show()
}),
vscode.commands.registerCommand('runme.copyCellToClipboard', (cell: vscode.NotebookCell) => {
vscode.env.clipboard.writeText(cell.document.getText())
return vscode.window.showInformationMessage('Copied cell to clipboard!')
}),

vscode.commands.registerCommand('runme.runCliCommand', async (cell: vscode.NotebookCell) => {
if (!await CliProvider.isCliInstalled()) {
return vscode.window.showInformationMessage(
'Runme CLI is not installed. Do you want to download it?',
'Download now'
).then((openBrowser) => openBrowser && vscode.env.openExternal(
vscode.Uri.parse('https://github.com/stateful/runme/releases')
))
}
const cliName: string = (cell.metadata?.['cliName'] || '').trim()
const term = vscode.window.createTerminal(`CLI: ${cliName}`)
term.show(false)
term.sendText(`runme run ${cliName} --chdir="${path.dirname(cell.document.uri.fsPath)}"`)
}),

vscode.commands.registerCommand('runme.resetEnv', resetEnv)
)

console.log('[Runme] Extension successfully activated')
}

// This method is called when your extension is deactivated
export function deactivate () {
// viteProcess.stop()
import { openTerminal, runCLICommand, copyCellToClipboard } from './commands'

export class RunmeExtension {
async initialise (context: ExtensionContext) {
const kernel = new Kernel(context)
// const viteProcess = new ViteServerProcess()
// await viteProcess.start()

context.subscriptions.push(
kernel,
// viteProcess,
workspace.registerNotebookSerializer('runme', new Serializer(context), {
transientOutputs: true,
transientCellMetadata: {
inputCollapsed: true,
outputCollapsed: true,
},
}),
notebooks.registerNotebookCellStatusBarItemProvider('runme', new ShowTerminalProvider()),
notebooks.registerNotebookCellStatusBarItemProvider('runme', new PidStatusProvider()),
notebooks.registerNotebookCellStatusBarItemProvider('runme', new CliProvider()),
notebooks.registerNotebookCellStatusBarItemProvider('runme', new BackgroundTaskProvider()),
notebooks.registerNotebookCellStatusBarItemProvider('runme', new CopyProvider()),
commands.registerCommand('runme.resetEnv', resetEnv),
commands.registerCommand('runme.openTerminal', openTerminal),
commands.registerCommand('runme.runCliCommand', runCLICommand),
commands.registerCommand('runme.copyCellToClipboard', copyCellToClipboard)
)
}
}
19 changes: 19 additions & 0 deletions src/extension/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { ExtensionContext } from 'vscode'

import { RunmeExtension } from './extension'

const ext = new RunmeExtension()

export async function activate (context: ExtensionContext) {
console.log('[Runme] Activating Extension')
try {
await ext.initialise(context)
console.log('[Runme] Extension successfully activated')
} catch (err: any) {
console.log(`[Runme] Failed to initialise the extension ${err.message}`)
}
}

export function deactivate () {
console.log('[Runme] Deactivating Extension')
}
20 changes: 10 additions & 10 deletions src/extension/kernel.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import vscode, { ExtensionContext, NotebookEditor } from 'vscode'
import { Disposable, notebooks, window, workspace, ExtensionContext, NotebookEditor, NotebookCell } from 'vscode'

import type { ClientMessage } from '../types'
import { ClientMessages } from '../constants'
Expand All @@ -10,14 +10,14 @@ import { resetEnv, getKey } from './utils'

import './wasm/wasm_exec.js'

export class Kernel implements vscode.Disposable {
#disposables: vscode.Disposable[] = []
#controller = vscode.notebooks.createNotebookController(
export class Kernel implements Disposable {
#disposables: Disposable[] = []
#controller = notebooks.createNotebookController(
'runme',
'runme',
'RUNME'
)
protected messaging = vscode.notebooks.createRendererMessaging('runme-renderer')
protected messaging = notebooks.createRendererMessaging('runme-renderer')

constructor(protected context: ExtensionContext) {
this.#controller.supportedLanguages = Object.keys(executor)
Expand Down Expand Up @@ -60,22 +60,22 @@ export class Kernel implements vscode.Disposable {
return this._doExecuteCell(cell)
}
} else if (message.type === ClientMessages.infoMessage) {
return vscode.window.showInformationMessage(message.output as string)
return window.showInformationMessage(message.output as string)
} else if (message.type === ClientMessages.errorMessage) {
return vscode.window.showInformationMessage(message.output as string)
return window.showInformationMessage(message.output as string)
}

console.error(`[Runme] Unknown event type: ${message.type}`)
}

private async _executeAll(cells: vscode.NotebookCell[]) {
private async _executeAll(cells: NotebookCell[]) {
for (const cell of cells) {
await this._doExecuteCell(cell)
}
}

private async _doExecuteCell(cell: vscode.NotebookCell): Promise<void> {
const runningCell = await vscode.workspace.openTextDocument(cell.document.uri)
private async _doExecuteCell(cell: NotebookCell): Promise<void> {
const runningCell = await workspace.openTextDocument(cell.document.uri)
const exec = this.#controller.createNotebookCellExecution(cell)

exec.start(Date.now())
Expand Down
Loading

0 comments on commit 105c34e

Please sign in to comment.