Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify debugging the agent and the extension at the same time (full-stack) #2516

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"mode": "auto",
"program": "${workspaceFolder}/cmd/publisher/main.go",
"args": ["ui", "--listen=localhost:9001", "-vv"],
"cwd": "${workspaceFolder}"
"cwd": "${workspaceFolder}/test/sample-content"
}
]
}
14 changes: 13 additions & 1 deletion extensions/vscode/.vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,19 @@
"request": "launch",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
"preLaunchTask": "${defaultBuildTask}"
"preLaunchTask": "${defaultBuildTask}",
"env": { "POSIT_PUBLISHER_USE_EXTERNAL_AGENT": "FALSE" },
"cwd": "${workspaceFolder}/../../test/sample-content"
sagerb marked this conversation as resolved.
Show resolved Hide resolved
},
{
"name": "Run Extension using external API agent on 9001",
"type": "extensionHost",
"request": "launch",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
"preLaunchTask": "${defaultBuildTask}",
"env": { "POSIT_PUBLISHER_USE_EXTERNAL_AGENT": "TRUE" },
"cwd": "${workspaceFolder}/../../test/sample-content"
},
{
"name": "Extension Tests",
Expand Down
41 changes: 35 additions & 6 deletions extensions/vscode/CONTRIBUTING.md
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding the notes for how to accomplish simultaneous debugging 🎉

Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,46 @@ just test

Utilize VSCode's built-in debugger to troubleshoot and diagnose issues.

Launch the debugger by pressing `F5` or go to `Run > Start Debugging`.
Switch to the debugger extension view within VSCode and select one of the two
debug configurations (specified within `extensions/vscode/.vscode/launch.json`):

- `Run Extension`
- `Run Extension using external API agent on 9001`

The first target (`Run Extension`) is very helpful when you are simply wanting to debug
functionality within the extension. It's configuration will cause the extension under test to
automatically launch the agent (unlike the second option).

The second target (`Run Extension using external API agent on 9001`) is helpful for when you want to debug
both the extension UX and the agent at the same time. To do this, you will need to:

1. First launch a debug session from a VSCode window which has opened the repo's base directory
(see [API Debugging](./../../CONTRIBUTING.md#debugging-in-vs-code))
2. Then launch another debug session (using the `Run Extension using external API agent on 9001` configuration)
from a separate VSCode window which has opened the `extensions/vscode` folder.

Notes when using `Run Extension using external API agent on 9001`:

- Both the agent's and extension's `launch.json` files are setup using the same working
subdirectory of `test/sample-content`. If you change it in one, you will need to change it in the other.
sagerb marked this conversation as resolved.
Show resolved Hide resolved
(This mimics the production runtime functionality where they both are initialized with the same working
subdirectory.) This location must also be different than the root of the repository (which the VSCode
window for agent development must open) and the extension location `extensions/vscode` (which the VSCode
window for UX development must open).
- If you stop the debugging of the agent, you'll need to relaunch debugging of the extension after
the agent is back up.

If you use `F5` or use the menu option `Run > Start Debugging` to launch the debugger,
be sure to pre-select the configuration.

Either invocation will launch a new window named `Extension Host Development` with the extension installed and enabled.

When testing, utilize the sample projects in `../../test/sample-content`. Open these projects as a workspace within the `Extension Host Development` window.

#### Connecting to API Debug Session

To connect to the API debug session change the `Service` class in
`extensions/vscode/src/services.ts` to a hardcoded `port = 9001;` and remove
the code inside of the `start` and `stop` methods.
Debugging the home view is done with browser development tools. Activate the publisher extension within the
extension under test, and then use the palette command `Developer:Open Webview Developer Tools` to
launch the browser debugging window. Note: This command will appear to do nothing if there is no webview
visible within the extension at the time, so be sure to switch to the publisher extension view before issuing the command.

### Re-building the Webview(s)

Expand Down
25 changes: 22 additions & 3 deletions extensions/vscode/src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// Copyright (C) 2024 by Posit Software, PBC.

import { ExtensionContext, Uri, commands, workspace } from "vscode";
import {
ExtensionContext,
ExtensionMode,
Uri,
commands,
workspace,
} from "vscode";

import * as ports from "src/ports";
import { Service } from "src/services";
Expand Down Expand Up @@ -43,11 +49,24 @@ export async function activate(context: ExtensionContext) {
setStateContext(PositPublishState.uninitialized);
setInitializationInProgressContext(InitializationInProgress.false);

const port = await ports.acquire();
const useExternalAgent =
context.extensionMode === ExtensionMode.Development &&
process.env.POSIT_PUBLISHER_USE_EXTERNAL_AGENT === "TRUE";
console.log(
"Starting Context in extension mode: %s, with useExternalAgent set to %s",
context.extensionMode,
useExternalAgent,
);

let port = 9001;
if (!useExternalAgent) {
port = await ports.acquire();
}

const stream = new EventStream(port);
context.subscriptions.push(stream);

service = new Service(context, port);
service = new Service(context, port, useExternalAgent);
service.start();

const watchers = new WatcherManager();
Expand Down
19 changes: 15 additions & 4 deletions extensions/vscode/src/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,36 @@ export class Service implements Disposable {
private context: ExtensionContext;
private server: Server;
private agentURL: string;
private useExternalAgent: boolean;

constructor(context: ExtensionContext, port: number) {
constructor(
context: ExtensionContext,
port: number,
useExternalAgent: boolean,
) {
this.context = context;
this.useExternalAgent = useExternalAgent;

this.agentURL = `http://${HOST}:${port}/api`;
this.server = new Server(port);
initApi(this.isUp(), this.agentURL);
}

start = async () => {
await this.server.start(this.context);
if (!this.useExternalAgent) {
await this.server.start(this.context);
}
};

isUp = () => {
return this.server.isUp();
};

stop = async () => {
await this.server.stop();
this.server.dispose();
if (!this.useExternalAgent) {
await this.server.stop();
this.server.dispose();
}
};

dispose() {
Expand Down
Loading