Skip to content
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
35 changes: 35 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Aspire VS Code extension launch configurations
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}/extension"
],
"outFiles": [
"${workspaceFolder}/extension/dist/**/*.js"
],
"preLaunchTask": "npm: watch extension",
"cwd": "${workspaceFolder}/extension"
},
{
"name": "Run Extension (cli stop on entry)",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}/extension"
],
"outFiles": [
"${workspaceFolder}/extension/dist/**/*.js"
],
"preLaunchTask": "npm: watch extension",
"env": {
"ASPIRE_CLI_STOP_ON_ENTRY": "true"
},
"cwd": "${workspaceFolder}/extension"
}
]
}
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
"dotnet.previewSolution-freeWorkspaceMode": true,
"dotnet.testWindow.useTestingPlatformProtocol": true,
"dotnet.defaultSolution": "./Aspire.slnx",
"dotnet.preview.enableSupportForSlnx": true
"dotnet.preview.enableSupportForSlnx": true,
"aspire.enableSettingsFileCreationPromptOnStartup": false
}
45 changes: 45 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch",
"problemMatcher": "$ts-webpack-watch",
"isBackground": true,
"presentation": {
"reveal": "never",
"group": "watchers"
},
"group": {
"kind": "build",
"isDefault": true
},
"label": "npm: watch extension",
"path": "extension",
},
{
"type": "npm",
"script": "watch-tests",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never",
"group": "watchers"
},
"group": "build",
"label": "npm: watch-tests extension",
"path": "extension",
},
{
"label": "tasks: watch-tests extension",
"dependsOn": [
"npm: watch",
"npm: watch-tests"
],
"problemMatcher": [],
"path": "extension"
}
]
}
9 changes: 3 additions & 6 deletions extension/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
// A launch configuration that compiles the extension and then opens it inside a new window
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
// Aspire VS Code extension launch configurations
{
"version": "0.2.0",
"configurations": [
Expand All @@ -15,7 +12,7 @@
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}"
"preLaunchTask": "npm: watch extension"
},
{
"name": "Run Extension (cli stop on entry)",
Expand All @@ -27,7 +24,7 @@
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}",
"preLaunchTask": "npm: watch extension",
"env": {
"ASPIRE_CLI_STOP_ON_ENTRY": "true"
}
Expand Down
10 changes: 6 additions & 4 deletions extension/.vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"group": {
"kind": "build",
"isDefault": true
}
},
"label": "npm: watch extension"
},
{
"type": "npm",
Expand All @@ -26,15 +27,16 @@
"reveal": "never",
"group": "watchers"
},
"group": "build"
"group": "build",
"label": "npm: watch-tests extension"
},
{
"label": "tasks: watch-tests",
"label": "tasks: watch-tests extension",
"dependsOn": [
"npm: watch",
"npm: watch-tests"
],
"problemMatcher": []
"problemMatcher": [],
}
]
}
21 changes: 16 additions & 5 deletions extension/CONTRIBUTING.MD
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,23 @@
## Install Prerequisites

- Node.js (LTS version)
- Visual Studio Code (latest)
- .NET Aspire CLI must be installed and available in your PATH.
- NPM and yarn accessible in the PATH
- Visual Studio Code (latest) or Visual Studio Code Insiders
- .NET Aspire CLI must be installed and available in the PATH

## Build CLI

Run `build.ps1` (Windows) or `build.sh` (Mac/Linux) to compile the Aspire CLI, install dependencies, and localize.

## Run extension locally

- Open the extension folder in Visual Studio Code.
- Run `yarn install` to install dependencies and then `yarn compile` to generate loc files.
- Press `F5` to start a new Extension Development Host instance of VS Code with the extension loaded.
- Open the Command Palette (`Cmd+Shift+P` or `Ctrl+Shift+P`) and run the desired Aspire command.
- Launch either the `Run Extension` or `Run Extension (cli stop on entry)` launch configuration. The latter will set an environment variable that causes the CLI to wait until a debugger is attached to execute its logic.

### Optional: set the CLI path

If you want to effectively debug the Aspire CLI together with the Aspire VS Code extension, you must set the `Aspire Cli Executable Path` setting to the Aspire CLI output path. The output path, relative to the Aspire repository root directory, is `artifacts/bin/Aspire.Cli/Debug/net8.0/aspire`.

You may also want to use the `Run Extension (cli stop on entry)` launch configuration, as `Run Extension` does not prevent the Aspire CLI from executing immediately.

You can use the `Aspire: Extension settings` command to open VS Code settings directly to the Aspire extension category.
11 changes: 7 additions & 4 deletions extension/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ if (-not (Get-Command yarn -ErrorAction SilentlyContinue)) {
exit 1
}

# Check for VS Code
if (-not (Get-Command code -ErrorAction SilentlyContinue)) {
Write-Error "Error: VS Code is not installed or 'code' command is not in PATH."
Write-Host "Please install VS Code and ensure it's added to your PATH."
# Check for VS Code or VS Code Insiders
$hasVSCode = Get-Command code -ErrorAction SilentlyContinue
$hasVSCodeInsiders = Get-Command code-insiders -ErrorAction SilentlyContinue

if (-not $hasVSCode -and -not $hasVSCodeInsiders) {
Write-Error "Error: VS Code or VS Code Insiders is not installed or not in PATH."
Write-Host "Please install VS Code or VS Code Insiders and ensure it's added to your PATH."
exit 1
}

Expand Down
8 changes: 4 additions & 4 deletions extension/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ if ! command -v yarn &> /dev/null; then
exit 1
fi

# Check for VS Code
if ! command -v code &> /dev/null; then
echo "Error: VS Code is not installed or 'code' command is not in PATH."
echo "Please install VS Code and ensure it's added to your PATH."
# Check for VS Code or VS Code Insiders
if ! command -v code &> /dev/null && ! command -v code-insiders &> /dev/null; then
echo "Error: VS Code or VS Code Insiders is not installed or not in PATH."
echo "Please install VS Code or VS Code Insiders and ensure it's added to your PATH."
exit 1
fi

Expand Down
3 changes: 3 additions & 0 deletions extension/loc/xlf/aspire-vscode.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@
"title": "%command.configureLaunchJson%",
"category": "Aspire"
},
{
"command": "aspire-vscode.settings",
"title": "%command.settings%",
"category": "Aspire"
},
{
"command": "aspire-vscode.runAppHost",
"title": "%command.runAppHost%",
Expand Down
1 change: 1 addition & 0 deletions extension/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"command.config": "Manage configuration settings",
"command.deploy": "Deploy app",
"command.configureLaunchJson": "Configure launch.json file",
"command.settings": "Extension settings",
"configuration.aspire.enableSettingsFileCreationPromptOnStartup": "Enable apphost discovery on extension activation and prompt to setup .aspire/settings.json.appHostPath if it does not exist in the workspace.",
"configuration.aspire.aspireCliExecutablePath": "The path to the Aspire CLI executable. If not set, the extension will attempt to use 'aspire' from the system PATH.",
"configuration.aspire.enableAspireCliDebugLogging": "Enable console debug logging for Aspire CLI commands executed by the extension.",
Expand Down
6 changes: 6 additions & 0 deletions extension/src/commands/settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as vscode from 'vscode';

export async function settingsCommand(): Promise<void> {
// Open the settings UI filtered to Aspire extension settings
await vscode.commands.executeCommand('workbench.action.openSettings', '@ext:microsoft-aspire.aspire-vscode');
}
3 changes: 2 additions & 1 deletion extension/src/debugger/AspireDebugSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { createDebugSessionConfiguration } from "./debuggerExtensions";
import { AspireTerminalProvider } from "../utils/AspireTerminalProvider";
import { ICliRpcClient } from "../server/rpcClient";
import path from "path";
import { EnvironmentVariables } from "../utils/environment";

export class AspireDebugSession implements vscode.DebugAdapter {
private readonly _onDidSendMessage = new EventEmitter<any>();
Expand Down Expand Up @@ -77,7 +78,7 @@ export class AspireDebugSession implements vscode.DebugAdapter {
if (!noDebug) {
args.push('--start-debug-session');
}
if (process.env.ASPIRE_CLI_STOP_ON_ENTRY === 'true') {
if (process.env[EnvironmentVariables.ASPIRE_CLI_STOP_ON_ENTRY] === 'true') {
args.push('--cli-wait-for-debugger');
}

Expand Down
4 changes: 3 additions & 1 deletion extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { AspireTerminalProvider } from './utils/AspireTerminalProvider';
import { MessageConnection } from 'vscode-jsonrpc';
import { openTerminalCommand } from './commands/openTerminal';
import { updateCommand } from './commands/update';
import { settingsCommand } from './commands/settings';
import { checkForExistingAppHostPathInWorkspace } from './utils/workspace';
import { AspireEditorCommandProvider } from './editor/AspireEditorCommandProvider';

Expand Down Expand Up @@ -58,11 +59,12 @@ export async function activate(context: vscode.ExtensionContext) {
const cliUpdateCommandRegistration = vscode.commands.registerCommand('aspire-vscode.update', () => tryExecuteCommand('aspire-vscode.update', terminalProvider, updateCommand));
const openTerminalCommandRegistration = vscode.commands.registerCommand('aspire-vscode.openTerminal', () => tryExecuteCommand('aspire-vscode.openTerminal', terminalProvider, openTerminalCommand));
const configureLaunchJsonCommandRegistration = vscode.commands.registerCommand('aspire-vscode.configureLaunchJson', () => tryExecuteCommand('aspire-vscode.configureLaunchJson', terminalProvider, configureLaunchJsonCommand));
const settingsCommandRegistration = vscode.commands.registerCommand('aspire-vscode.settings', () => tryExecuteCommand('aspire-vscode.settings', terminalProvider, settingsCommand));
const runAppHostCommandRegistration = vscode.commands.registerCommand('aspire-vscode.runAppHost', () => editorCommandProvider.tryExecuteRunAppHost(true));
const debugAppHostCommandRegistration = vscode.commands.registerCommand('aspire-vscode.debugAppHost', () => editorCommandProvider.tryExecuteRunAppHost(false));

context.subscriptions.push(cliAddCommandRegistration, cliNewCommandRegistration, cliInitCommandRegistration, cliConfigCommandRegistration, cliDeployCommandRegistration, cliPublishCommandRegistration, openTerminalCommandRegistration, configureLaunchJsonCommandRegistration);
context.subscriptions.push(cliUpdateCommandRegistration, runAppHostCommandRegistration, debugAppHostCommandRegistration);
context.subscriptions.push(cliUpdateCommandRegistration, settingsCommandRegistration, runAppHostCommandRegistration, debugAppHostCommandRegistration);

const debugConfigProvider = new AspireDebugConfigurationProvider();
context.subscriptions.push(
Expand Down
7 changes: 4 additions & 3 deletions extension/src/utils/AspireTerminalProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { extensionLogOutputChannel } from './logging';
import { RpcServerConnectionInfo } from '../server/AspireRpcServer';
import { DcpServerConnectionInfo } from '../dcp/types';
import { getRunSessionInfo, getSupportedCapabilities } from '../capabilities';
import { EnvironmentVariables } from './environment';

export const enum AnsiColors {
Green = '\x1b[32m'
Expand Down Expand Up @@ -60,7 +61,7 @@ export class AspireTerminalProvider implements vscode.Disposable {
command += ' --debug';
}

if (process.env.ASPIRE_CLI_STOP_ON_ENTRY === 'true') {
if (process.env[EnvironmentVariables.ASPIRE_CLI_STOP_ON_ENTRY] === 'true') {
command += ' --cli-wait-for-debugger';
}

Expand Down Expand Up @@ -178,12 +179,12 @@ export class AspireTerminalProvider implements vscode.Disposable {
getAspireCliExecutablePath(surroundWithQuotes: boolean = true): string {
const aspireCliPath = vscode.workspace.getConfiguration('aspire').get<string>('aspireCliExecutablePath', '');
if (aspireCliPath && aspireCliPath.trim().length > 0) {
extensionLogOutputChannel.info(`Using user-configured Aspire CLI path: ${aspireCliPath}`);
extensionLogOutputChannel.debug(`Using user-configured Aspire CLI path: ${aspireCliPath}`);
const path = shellEscapeSingleQuotes(aspireCliPath.trim());
return surroundWithQuotes ? `'${path}'` : path;
}

extensionLogOutputChannel.info('No user-configured Aspire CLI path found');
extensionLogOutputChannel.debug('No user-configured Aspire CLI path found');
return "aspire";

function shellEscapeSingleQuotes(str: string): string {
Expand Down
6 changes: 5 additions & 1 deletion extension/src/utils/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ export function mergeEnvs(base: NodeJS.ProcessEnv, envVars?: EnvVar[]): Record<s
}
}
return merged;
}
}

export const enum EnvironmentVariables {
ASPIRE_CLI_STOP_ON_ENTRY = "ASPIRE_CLI_STOP_ON_ENTRY"
}
Loading