Skip to content

Commit

Permalink
Debugger
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdriscoll committed Oct 13, 2023
1 parent d9900e2 commit 6a53f4b
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 34 deletions.
24 changes: 10 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
"command": "powershell-universal.walkthrough",
"title": "PowerShell Universal: Getting Started Walkthrough"
},
{
"command": "powershell-universal.attachRunspace",
"title": "Attach Runspace",
"icon": "$(debug-alt)"
},
{
"command": "powershell-universal.addConnection",
"title": "Add Connection",
Expand Down Expand Up @@ -131,21 +136,11 @@
"title": "Open App Page File",
"icon": "$(go-to-file)"
},
{
"command": "powershell-universal.debugEndpoint",
"title": "Debug",
"icon": "$(debug-alt)"
},
{
"command": "powershell-universal.downloadUniversal",
"title": "PowerShell Universal: Download",
"icon": "$(desktop-download)"
},
{
"command": "powershell-universal.connectToDashboard",
"title": "Debug App Process",
"icon": "$(debug-alt)"
},
{
"command": "powershell-universal.viewDashboardLog",
"title": "View Log",
Expand Down Expand Up @@ -486,6 +481,11 @@
}
],
"view/item/context": [
{
"command": "powershell-universal.attachRunspace",
"when": "view == universalPlatformProviderView && viewItem == runspace",
"group": "inline"
},
{
"command": "powershell-universal.connection",
"when": "view == universalConnectionProviderView && viewItem == connection",
Expand Down Expand Up @@ -525,10 +525,6 @@
"command": "powershell-universal.viewDashboardLog",
"when": "view == universalDashboardProviderView && viewItem == dashboard"
},
{
"command": "powershell-universal.connectToDashboard",
"when": "view == universalDashboardProviderView && viewItem == dashboard"
},
{
"command": "powershell-universal.openDashboardTerminal",
"when": "view == universalDashboardProviderView && viewItem == dashboardSessionPage",
Expand Down
11 changes: 0 additions & 11 deletions src/commands/debugEndpoint.ts

This file was deleted.

17 changes: 15 additions & 2 deletions src/commands/debugger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import * as vscode from 'vscode';
import { load } from '../settings';
import { HubConnectionBuilder, LogLevel, HubConnection } from '@microsoft/signalr';
import { DebugProtocol } from '@vscode/debugprotocol';
import { RunspaceTreeItem } from '../platform-treeview';

let adapter: UniversalDebugAdapter;

export const registerDebuggerCommands = (context: vscode.ExtensionContext) => {
vscode.commands.registerCommand('powershell-universal.attachRunspace', (item) => attachRunspace(item, context));

adapter = new UniversalDebugAdapter(context);

vscode.debug.registerDebugAdapterDescriptorFactory('powershelluniversal', {
Expand All @@ -15,6 +18,17 @@ export const registerDebuggerCommands = (context: vscode.ExtensionContext) => {
});
}


export const attachRunspace = async (runspace: RunspaceTreeItem, context: vscode.ExtensionContext) => {
await vscode.debug.startDebugging(undefined, {
name: "PowerShell Universal",
type: "powershelluniversal",
request: "attach",
processId: runspace.runspace.processId,
runspaceId: runspace.runspace.id
});
};

export class UniversalDebugAdapter implements vscode.DebugAdapter {

constructor(context: vscode.ExtensionContext) {
Expand All @@ -41,8 +55,7 @@ export class UniversalDebugAdapter implements vscode.DebugAdapter {
.build();

this.hubConnection.on("message", (message: string) => {
var json = message.split('\r\n')[2];
const protocolMessage = JSON.parse(json) as DebugProtocol.ProtocolMessage;
const protocolMessage = JSON.parse(message) as DebugProtocol.ProtocolMessage;
this.handleMessage(protocolMessage);
});

Expand Down
64 changes: 62 additions & 2 deletions src/platform-treeview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as vscode from 'vscode';
import { IConnection, load } from './settings';
import ParentTreeItem from './parentTreeItem';
import { Container } from './container';
import { Module } from './types';
import { Module, Process, Runspace } from './types';

export class PlatformTreeViewProvider implements vscode.TreeDataProvider<vscode.TreeItem> {

Expand All @@ -16,7 +16,8 @@ export class PlatformTreeViewProvider implements vscode.TreeDataProvider<vscode.
async getChildren(element?: vscode.TreeItem | undefined) {
if (element == null) {
return [
new ModulesTreeItem()
new ModulesTreeItem(),
new ProcessesTreeItem()
]
}

Expand All @@ -31,6 +32,65 @@ export class PlatformTreeViewProvider implements vscode.TreeDataProvider<vscode.
}
}

export class ProcessesTreeItem extends ParentTreeItem {
async getChildren(): Promise<vscode.TreeItem[]> {
try {
const processes = await Container.universal.getProcesses();
return processes.map(x => new ProcessTreeItem(x));
}
catch (err) {
Container.universal.showConnectionError("Failed to query modules. " + err);
return [];
}
}
constructor() {
super("Processes", vscode.TreeItemCollapsibleState.Collapsed);

const themeIcon = new vscode.ThemeIcon("server-process");
this.iconPath = themeIcon;
}
}

export class ProcessTreeItem extends ParentTreeItem {
public process: Process;
async getChildren(): Promise<vscode.TreeItem[]> {
try {
const runspaces = await Container.universal.getRunspaces(this.process.processId);
return runspaces.map(x => new RunspaceTreeItem(x));
}
catch (err) {
Container.universal.showConnectionError("Failed to query modules. " + err);
return [];
}
}
constructor(process: Process) {
super(process.description, vscode.TreeItemCollapsibleState.Collapsed);

this.process = process;

const themeIcon = new vscode.ThemeIcon("server-process");
this.iconPath = themeIcon;
}
}


export class RunspaceTreeItem extends vscode.TreeItem {
public runspace: Runspace;
constructor(runspace: Runspace) {
super(`Runspace ${runspace.id.toString()}`, vscode.TreeItemCollapsibleState.None);

this.description = runspace.availability;
this.tooltip = runspace.state;

this.runspace = runspace;

const themeIcon = new vscode.ThemeIcon("circuit-board");
this.iconPath = themeIcon;
}

contextValue = 'runspace';
}

export class ModulesTreeItem extends ParentTreeItem {
async getChildren(): Promise<vscode.TreeItem[]> {
return [
Expand Down
19 changes: 19 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,23 @@ export type FileSystemItem = {
items: Array<FileSystemItem>;
isLeaf: boolean;
content: string;
}

export type Process = {
processName: string;
description: string;
processId: number;
environment: Environment
};

export type Environment = {
name: string;
description: string;
};

export type Runspace = {
id: number;
state: string;
availability: string;
processId: number;
}
18 changes: 13 additions & 5 deletions src/universal.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as vscode from 'vscode';
import { Dashboard, DashboardDiagnostics, Settings, Endpoint, Script, Job, ScriptParameter, JobPagedViewModel, JobLog, FileSystemItem, DashboardPage, Terminal, TerminalInstance, Module } from './types';
import { Dashboard, DashboardDiagnostics, Settings, Endpoint, Script, Job, ScriptParameter, JobPagedViewModel, JobLog, FileSystemItem, DashboardPage, Terminal, TerminalInstance, Module, Process, Runspace } from './types';
import axios, { AxiosPromise } from 'axios';
import { load, SetAppToken, SetUrl } from './settings';
import { Container } from './container';
Expand Down Expand Up @@ -622,12 +622,20 @@ export class Universal {
terminal?.sendText(command, true);
}

connectDashboard(id: number) {
this.sendTerminalCommand(`Debug-PSUDashboard -Id ${id}`);
getProcesses(): Promise<Array<Process>> {
return new Promise((resolve, reject) => {
this.request(`/api/v1/diagnostics/processes`, 'GET')?.then(x => resolve(x.data)).catch(x => {
reject(x);
});
});
}

debugDashboardEndpoint(id: string) {
this.sendTerminalCommand(`Get-PSUDashboardEndpointRunspace -Id ${id} | Debug-Runspace`);
getRunspaces(processId: number): Promise<Array<Runspace>> {
return new Promise((resolve, reject) => {
this.request(`/api/v1/diagnostics/processes/${processId}/runspaces`, 'GET')?.then(x => resolve(x.data.map((y: any) => { return { ...y, processId }; }))).catch(x => {
reject(x);
});
});
}

connectUniversal(url: string) {
Expand Down

0 comments on commit 6a53f4b

Please sign in to comment.