diff --git a/.vscode/launch.json b/.vscode/launch.json index 647127315..451731d4b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -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" } ] } diff --git a/extensions/vscode/.vscode/launch.json b/extensions/vscode/.vscode/launch.json index 3e59a6afa..e27741ea6 100644 --- a/extensions/vscode/.vscode/launch.json +++ b/extensions/vscode/.vscode/launch.json @@ -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" + }, + { + "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", diff --git a/extensions/vscode/CONTRIBUTING.md b/extensions/vscode/CONTRIBUTING.md index c27174287..779cf6047 100644 --- a/extensions/vscode/CONTRIBUTING.md +++ b/extensions/vscode/CONTRIBUTING.md @@ -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. + (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) diff --git a/extensions/vscode/src/extension.ts b/extensions/vscode/src/extension.ts index 1f4de70e4..412d444a7 100644 --- a/extensions/vscode/src/extension.ts +++ b/extensions/vscode/src/extension.ts @@ -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"; @@ -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(); diff --git a/extensions/vscode/src/services.ts b/extensions/vscode/src/services.ts index 14ed1c992..2942a0140 100644 --- a/extensions/vscode/src/services.ts +++ b/extensions/vscode/src/services.ts @@ -10,16 +10,25 @@ 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 = () => { @@ -27,8 +36,10 @@ export class Service implements Disposable { }; stop = async () => { - await this.server.stop(); - this.server.dispose(); + if (!this.useExternalAgent) { + await this.server.stop(); + this.server.dispose(); + } }; dispose() {