Skip to content

Commit

Permalink
fix: run debugger in terminal shell when shellType is terminal
Browse files Browse the repository at this point in the history
Fixes #571
  • Loading branch information
sheremet-va committed Jan 22, 2025
1 parent 91c485f commit 5caefd6
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 14 deletions.
38 changes: 38 additions & 0 deletions debug-shims.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* eslint-disable ts/method-signature-style */
// https://github.com/microsoft/vscode-js-debug/blob/main/src/typings/vscode-js-debug.d.ts

declare module '@vscode/js-debug' {
import type * as vscode from 'vscode'

/** @see {IExports.registerDebugTerminalOptionsProvider} */
export interface IDebugTerminalOptionsProvider {
/**
* Called when the user creates a JavaScript Debug Terminal. It's called
* with the options js-debug wants to use to create the terminal. It should
* modify and return the options to use in the terminal.
*
* In order to avoid conflicting with existing logic, participants should
* try to modify options in a additive way. For example prefer appending
* to rather than reading and overwriting `options.env.PATH`.
*/
provideTerminalOptions(options: vscode.TerminalOptions): vscode.ProviderResult<vscode.TerminalOptions>
}

/**
* Defines the exports of the `js-debug` extension. Once you have this typings
* file, these can be acquired in your extension using the following code:
*
* ```
* const jsDebugExt = vscode.extensions.getExtension('ms-vscode.js-debug-nightly')
* || vscode.extensions.getExtension('ms-vscode.js-debug');
* await jsDebugExt.activate()
* const jsDebug: import('@vscode/js-debug').IExports = jsDebug.exports;
* ```
*/
export interface IExports {
/**
* Registers a participant used when the user creates a JavaScript Debug Terminal.
*/
registerDebugTerminalOptionsProvider(provider: IDebugTerminalOptionsProvider): vscode.Disposable
}
}
27 changes: 18 additions & 9 deletions src/api/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,24 @@ export async function createVitestTerminalProcess(pkg: VitestPackage): Promise<R
}

export class VitestTerminalProcess implements VitestProcess {
private stopped: Promise<void>

constructor(
public readonly id: number,
private wsProcess: VitestWebSocketProcess,
private readonly terminal: vscode.Terminal,
) {
const disposer = vscode.window.onDidCloseTerminal(async (e) => {
if (e === terminal) {
const exitCode = e.exitStatus?.code
// TODO: have a single emitter, don't reuse ws one
// this event is required for api.dispose() and onUnexpectedExit
wsProcess.ws.emit('exit', exitCode)
disposer.dispose()
}
this.stopped = new Promise((resolve) => {
const disposer = vscode.window.onDidCloseTerminal(async (e) => {
if (e === terminal) {
const exitCode = e.exitStatus?.code
// TODO: have a single emitter, don't reuse ws one
// this event is required for api.dispose() and onUnexpectedExit
wsProcess.ws.emit('exit', exitCode)
disposer.dispose()
resolve()
}
})
})
}

Expand All @@ -82,7 +87,11 @@ export class VitestTerminalProcess implements VitestProcess {

close() {
this.wsProcess.close()
this.terminal.dispose()
// send ctrl+c to sigint any running processs (vscode/#108289)
this.terminal.sendText('\x03')
// and then destroy it on the next event loop tick
setTimeout(() => this.terminal.dispose(), 1)
return this.stopped
}

on(event: string, listener: (...args: any[]) => void) {
Expand Down
14 changes: 10 additions & 4 deletions src/debug/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,21 @@ export async function debugTests(

const debugConfig = {
__name: 'Vitest',
type: 'pwa-node',
type: config.shellType === 'terminal' ? 'node-terminal' : 'pwa-node',
request: 'launch',
name: 'Debug Tests',
autoAttachChildProcesses: true,
skipFiles: config.debugExclude,
smartStep: true,
runtimeArgs,
runtimeExecutable,
program: workerPath,
...(config.shellType === 'terminal'
? {
command: `${runtimeExecutable} ${workerPath}`,
}
: {
program: workerPath,
runtimeArgs,
runtimeExecutable,
}),
cwd: pkg.cwd,
env: {
...process.env,
Expand Down
37 changes: 37 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ class VitestExtension {

private disposables: vscode.Disposable[] = []

/** @internal */
_debugDisposable: vscode.Disposable | undefined

constructor() {
log.info(`[v${version}] Vitest extension is activated because Vitest is installed or there is a Vite/Vitest config file in the workspace.`)

Expand Down Expand Up @@ -206,6 +209,8 @@ class VitestExtension {
}
debugProfile.tag = api.tag
debugProfile.runHandler = async (request, token) => {
await this.registerDebugOptions()

await debugTests(
this.testController,
this.testTree,
Expand Down Expand Up @@ -400,6 +405,38 @@ class VitestExtension {
}
}

async registerDebugOptions() {
if (this._debugDisposable) {
return
}
const config = getConfig()
if (config.shellType !== 'terminal') {
return
}
try {
const jsDebugExt = vscode.extensions.getExtension('ms-vscode.js-debug-nightly') || vscode.extensions.getExtension('ms-vscode.js-debug')
await jsDebugExt?.activate()
const jsDebug: import('@vscode/js-debug').IExports = jsDebugExt?.exports

if (jsDebug) {
this._debugDisposable = jsDebug.registerDebugTerminalOptionsProvider({
provideTerminalOptions(options) {
options.shellArgs = getConfig().terminalShellArgs
options.shellPath = getConfig().terminalShellPath
return options
},
})
this.disposables.push(this._debugDisposable)
}
else {
log.error('Failed to connect to the debug extension. Debugger will open a terminal window.')
}
}
catch (err) {
log.error('Cannot create debug options provider.', err)
}
}

async dispose() {
this.api?.dispose()
this.testTree.dispose()
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"extends": ["./tsconfig.base.json"],
"include": ["src"]
"include": ["src", "./debug-shims.d.ts"]
}

0 comments on commit 5caefd6

Please sign in to comment.