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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ tests/PolyglotAppHosts/**/Go/apphost.exe

#Aspire CLI
.aspire/
.modules/

# Release notes automation output
tools/ReleaseNotes/analysis-output/
Expand Down
5 changes: 3 additions & 2 deletions extension/gulpfile.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { execSync } = require('child_process');
const { execFileSync } = require('child_process');
const gulp = require('gulp');
const path = require('path');
const fs = require('fs');
Expand Down Expand Up @@ -40,7 +40,8 @@ const exportL10n = (done) => {

// Step 1: Export strings from source files to bundle.l10n.json
console.log('Exporting l10n strings from source files...');
execSync(`npx @vscode/l10n-dev export --outDir ${l10nDir} ./src`, {
const l10nDevCli = path.join(path.dirname(require.resolve('@vscode/l10n-dev/package.json')), 'dist', 'cli.js');
execFileSync(process.execPath, [l10nDevCli, 'export', '--outDir', l10nDir, './src'], {
cwd: rootDir,
stdio: 'inherit'
});
Expand Down
9 changes: 9 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.

7 changes: 7 additions & 0 deletions extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,13 @@
"description": "%configuration.aspire.globalAppHostsPollingInterval%",
"scope": "window"
},
"aspire.appHostDiscoveryTimeoutMs": {
"type": "number",
"default": 30000,
"minimum": 1000,
"description": "%configuration.aspire.appHostDiscoveryTimeoutMs%",
"scope": "window"
},
"aspire.enableCodeLens": {
"type": "boolean",
"default": true,
Expand Down
1 change: 1 addition & 0 deletions extension/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"configuration.aspire.enableDebugConfigEnvironmentLogging": "Include environment variables when logging debug session configurations. This can help diagnose environment-related issues but may expose sensitive information in logs.",
"configuration.aspire.registerMcpServerInWorkspace": "Whether to register the Aspire MCP server when a workspace is open.",
"configuration.aspire.globalAppHostsPollingInterval": "Polling interval in milliseconds for fetching all running AppHosts (used in global view). Minimum: 1000.",
"configuration.aspire.appHostDiscoveryTimeoutMs": "Timeout in milliseconds for Aspire CLI commands that discover AppHost projects. Minimum: 1000.",
"configuration.aspire.enableCodeLens": "Show CodeLens actions (state, restart, stop, logs) inline above resource declarations in AppHost files.",
"configuration.aspire.enableGutterDecorations": "Show colored status dots in the editor gutter next to resource declarations in AppHost files.",
"configuration.aspire.enableAutoRestore": "Automatically run 'aspire restore' when the workspace opens and whenever aspire.config.json changes (e.g. after switching git branches). Keeps integration packages in sync and prevents editor errors.",
Expand Down
67 changes: 61 additions & 6 deletions extension/src/debugger/AspireDebugConfigurationProvider.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,40 @@
import * as vscode from 'vscode';
import { defaultConfigurationName } from '../loc/strings';
import { AppHostDiscoveryService, getDebugTargetForCandidate } from '../utils/appHostDiscovery';
import type { CandidateAppHostDisplayInfo } from '../utils/appHostDiscovery';
import { checkCliAvailableOrRedirect } from '../utils/workspace';
import { extensionLogOutputChannel } from '../utils/logging';

export class AspireDebugConfigurationProvider implements vscode.DebugConfigurationProvider {
constructor(private readonly _appHostDiscoveryService: AppHostDiscoveryService) {
}

async provideDebugConfigurations(folder: vscode.WorkspaceFolder | undefined, token?: vscode.CancellationToken): Promise<vscode.DebugConfiguration[]> {
if (folder === undefined) {
return [];
}

const configurations: vscode.DebugConfiguration[] = [];
configurations.push({
const activeEditor = vscode.window.activeTextEditor;
if (!activeEditor) {
return [this.createDefaultConfiguration(folder)];
}

const activeEditorFolder = vscode.workspace.getWorkspaceFolder(activeEditor.document.uri);
if (activeEditorFolder?.uri.toString() !== folder.uri.toString()) {
return [this.createDefaultConfiguration(folder)];
}

const candidate = await this.tryFindCandidateForEditorFile(activeEditor.document.uri.fsPath, folder);
if (!candidate) {
return [this.createDefaultConfiguration(folder)];
}

return [{
type: 'aspire',
request: 'launch',
name: defaultConfigurationName,
program: '${workspaceFolder}'
});

return configurations;
program: getDebugTargetForCandidate(candidate)
}];
}

async resolveDebugConfiguration(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, token?: vscode.CancellationToken): Promise<vscode.DebugConfiguration | null | undefined> {
Expand Down Expand Up @@ -44,4 +62,41 @@ export class AspireDebugConfigurationProvider implements vscode.DebugConfigurati

return config;
}

async resolveDebugConfigurationWithSubstitutedVariables(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, token?: vscode.CancellationToken): Promise<vscode.DebugConfiguration | null | undefined> {
if (typeof config.program === 'string') {
config.program = await this.resolveDebugTarget(config.program, folder);
}

return config;
}

private async tryFindCandidateForEditorFile(filePath: string, folder: vscode.WorkspaceFolder): Promise<CandidateAppHostDisplayInfo | undefined> {
try {
return await this._appHostDiscoveryService.tryFindCandidateForEditorFile(filePath, folder);
}
catch (error) {
extensionLogOutputChannel.warn(`Failed to discover AppHost for debug configuration file ${filePath}: ${error}`);
return undefined;
}
}

private async resolveDebugTarget(filePath: string, folder: vscode.WorkspaceFolder | undefined): Promise<string> {
try {
return await this._appHostDiscoveryService.resolveDebugTarget(filePath, folder);
}
catch (error) {
extensionLogOutputChannel.warn(`Failed to resolve AppHost debug target ${filePath}: ${error}`);
return filePath;
}
}

private createDefaultConfiguration(folder: vscode.WorkspaceFolder): vscode.DebugConfiguration {
return {
type: 'aspire',
request: 'launch',
name: defaultConfigurationName,
program: folder.uri.fsPath
};
}
}
Loading
Loading