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
2 changes: 1 addition & 1 deletion extension/schemas/aspire-global-settings.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,4 @@
}
},
"additionalProperties": false
}
}
2 changes: 1 addition & 1 deletion extension/schemas/aspire-settings.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -262,4 +262,4 @@
}
},
"additionalProperties": false
}
}
7 changes: 5 additions & 2 deletions extension/src/commands/add.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { AspireEditorCommandProvider } from '../editor/AspireEditorCommandProvider';
import { AspireTerminalProvider } from '../utils/AspireTerminalProvider';
import { getAppHostArgs } from '../utils/appHostArgs';

export async function addCommand(terminalProvider: AspireTerminalProvider) {
await terminalProvider.sendAspireCommandToAspireTerminal('add');
export async function addCommand(terminalProvider: AspireTerminalProvider, editorCommandProvider: AspireEditorCommandProvider) {
const appHostArgs = await getAppHostArgs(editorCommandProvider);
await terminalProvider.sendAspireCommandToAspireTerminal('add', true, appHostArgs);
}
7 changes: 5 additions & 2 deletions extension/src/commands/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { AspireEditorCommandProvider } from '../editor/AspireEditorCommandProvider';
import { AspireTerminalProvider } from '../utils/AspireTerminalProvider';
import { getAppHostArgs } from '../utils/appHostArgs';

export async function deployCommand(terminalProvider: AspireTerminalProvider) {
await terminalProvider.sendAspireCommandToAspireTerminal('deploy');
export async function deployCommand(terminalProvider: AspireTerminalProvider, editorCommandProvider: AspireEditorCommandProvider) {
const appHostArgs = await getAppHostArgs(editorCommandProvider);
await terminalProvider.sendAspireCommandToAspireTerminal('deploy', true, appHostArgs);
}
7 changes: 5 additions & 2 deletions extension/src/commands/publish.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { AspireEditorCommandProvider } from '../editor/AspireEditorCommandProvider';
import { AspireTerminalProvider } from '../utils/AspireTerminalProvider';
import { getAppHostArgs } from '../utils/appHostArgs';

export async function publishCommand(terminalProvider: AspireTerminalProvider) {
await terminalProvider.sendAspireCommandToAspireTerminal('publish');
export async function publishCommand(terminalProvider: AspireTerminalProvider, editorCommandProvider: AspireEditorCommandProvider) {
const appHostArgs = await getAppHostArgs(editorCommandProvider);
await terminalProvider.sendAspireCommandToAspireTerminal('publish', true, appHostArgs);
}
7 changes: 5 additions & 2 deletions extension/src/commands/update.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { AspireEditorCommandProvider } from '../editor/AspireEditorCommandProvider';
import { AspireTerminalProvider } from '../utils/AspireTerminalProvider';
import { getAppHostArgs } from '../utils/appHostArgs';

export async function updateCommand(terminalProvider: AspireTerminalProvider) {
await terminalProvider.sendAspireCommandToAspireTerminal('update');
export async function updateCommand(terminalProvider: AspireTerminalProvider, editorCommandProvider: AspireEditorCommandProvider) {
const appHostArgs = await getAppHostArgs(editorCommandProvider);
await terminalProvider.sendAspireCommandToAspireTerminal('update', true, appHostArgs);
}
26 changes: 18 additions & 8 deletions extension/src/editor/AspireEditorCommandProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ export class AspireEditorCommandProvider implements vscode.Disposable {
const fileText = await vscode.workspace.fs.readFile(vscode.Uri.file(filePath)).then(buffer => buffer.toString());
const lines = fileText.split(/\r?\n/);

return lines.some(line => line.startsWith('#:sdk Aspire.AppHost.Sdk'));
if (lines.some(line => line.startsWith('#:sdk Aspire.AppHost.Sdk'))) {
return true;
}

const firstNonEmptyLine = lines.find(line => line.trim().length > 0)?.trim();
return firstNonEmptyLine === 'var builder = DistributedApplication.CreateBuilder(args);';
}

private onChangeAppHostPath(newPath: string | null) {
Expand Down Expand Up @@ -113,15 +118,20 @@ export class AspireEditorCommandProvider implements vscode.Disposable {
}
}

public async tryExecuteRunAppHost(noDebug: boolean): Promise<void> {
let appHostToRun: string;
/**
* Returns the resolved AppHost path from the active editor or workspace settings, or null if none is available.
*/
public async getAppHostPath(): Promise<string | null> {
if (vscode.window.activeTextEditor && await this.isAppHostCsFile(vscode.window.activeTextEditor.document.uri.fsPath)) {
appHostToRun = vscode.window.activeTextEditor.document.uri.fsPath;
return vscode.window.activeTextEditor.document.uri.fsPath;
}
else if (this._workspaceAppHostPath) {
appHostToRun = this._workspaceAppHostPath;
}
else {

return this._workspaceAppHostPath;
}

public async tryExecuteRunAppHost(noDebug: boolean): Promise<void> {
const appHostToRun = await this.getAppHostPath();
if (!appHostToRun) {
vscode.window.showErrorMessage(noAppHostInWorkspace);
return;
}
Expand Down
8 changes: 4 additions & 4 deletions extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ export async function activate(context: vscode.ExtensionContext) {

const editorCommandProvider = new AspireEditorCommandProvider();

const cliAddCommandRegistration = vscode.commands.registerCommand('aspire-vscode.add', () => tryExecuteCommand('aspire-vscode.add', terminalProvider, addCommand));
const cliAddCommandRegistration = vscode.commands.registerCommand('aspire-vscode.add', () => tryExecuteCommand('aspire-vscode.add', terminalProvider, (tp) => addCommand(tp, editorCommandProvider)));
const cliNewCommandRegistration = vscode.commands.registerCommand('aspire-vscode.new', () => tryExecuteCommand('aspire-vscode.new', terminalProvider, newCommand));
const cliInitCommandRegistration = vscode.commands.registerCommand('aspire-vscode.init', () => tryExecuteCommand('aspire-vscode.init', terminalProvider, initCommand));
const cliDeployCommandRegistration = vscode.commands.registerCommand('aspire-vscode.deploy', () => tryExecuteCommand('aspire-vscode.deploy', terminalProvider, deployCommand));
const cliPublishCommandRegistration = vscode.commands.registerCommand('aspire-vscode.publish', () => tryExecuteCommand('aspire-vscode.publish', terminalProvider, publishCommand));
const cliUpdateCommandRegistration = vscode.commands.registerCommand('aspire-vscode.update', () => tryExecuteCommand('aspire-vscode.update', terminalProvider, updateCommand));
const cliDeployCommandRegistration = vscode.commands.registerCommand('aspire-vscode.deploy', () => tryExecuteCommand('aspire-vscode.deploy', terminalProvider, (tp) => deployCommand(tp, editorCommandProvider)));
const cliPublishCommandRegistration = vscode.commands.registerCommand('aspire-vscode.publish', () => tryExecuteCommand('aspire-vscode.publish', terminalProvider, (tp) => publishCommand(tp, editorCommandProvider)));
const cliUpdateCommandRegistration = vscode.commands.registerCommand('aspire-vscode.update', () => tryExecuteCommand('aspire-vscode.update', terminalProvider, (tp) => updateCommand(tp, editorCommandProvider)));
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));
Expand Down
15 changes: 14 additions & 1 deletion extension/src/utils/AspireTerminalProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export class AspireTerminalProvider implements vscode.Disposable {
this._dcpServerConnectionInfo = value;
}

async sendAspireCommandToAspireTerminal(subcommand: string, showTerminal: boolean = true) {
async sendAspireCommandToAspireTerminal(subcommand: string, showTerminal: boolean = true, additionalArgs?: string[]) {
const cliPath = await this.getAspireCliExecutablePath();

// On Windows, use & to execute paths, especially those with special characters
Expand All @@ -73,6 +73,19 @@ export class AspireTerminalProvider implements vscode.Disposable {
command = `${quotedPath} ${subcommand}`;
}

if (additionalArgs && additionalArgs.length > 0) {
const quotedArgs = additionalArgs.map(arg => {
if (process.platform === 'win32') {
// On Windows PowerShell, wrap in double quotes and escape inner double quotes
return `"${arg.replace(/"/g, '`"')}"`;
} else {
// On Unix, wrap in single quotes and escape inner single quotes
return `'${arg.replace(/'/g, "'\"'\"'")}'`;
}
});
command += ' ' + quotedArgs.join(' ');
}

if (this.isCliDebugLoggingEnabled()) {
command += ' --debug';
}
Expand Down
14 changes: 14 additions & 0 deletions extension/src/utils/appHostArgs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { AspireEditorCommandProvider } from '../editor/AspireEditorCommandProvider';

/**
* Returns CLI arguments to pass the resolved AppHost project path via --apphost,
* or undefined if no AppHost is currently available.
*/
export async function getAppHostArgs(editorCommandProvider: AspireEditorCommandProvider): Promise<string[] | undefined> {
const appHostPath = await editorCommandProvider.getAppHostPath();
if (!appHostPath) {
return undefined;
}

return ['--apphost', appHostPath];
}
Loading