From 98c68a831983608cc224e944694f28d463bd0147 Mon Sep 17 00:00:00 2001 From: alexyaang <59073590+alexyaang@users.noreply.github.com> Date: Fri, 30 Jun 2023 14:52:49 -0400 Subject: [PATCH 01/15] use image name property supported by preview 5 instead of 6 --- src/tasks/netSdk/netSdkTaskUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tasks/netSdk/netSdkTaskUtils.ts b/src/tasks/netSdk/netSdkTaskUtils.ts index a087f677cf..0c9c021347 100644 --- a/src/tasks/netSdk/netSdkTaskUtils.ts +++ b/src/tasks/netSdk/netSdkTaskUtils.ts @@ -43,7 +43,7 @@ export async function getNetSdkBuildCommand(isProjectWebApp: boolean, projectFol withNamedArg('--arch', await normalizeArchitectureToRidArchitecture()), withArg(publishFlag), withNamedArg('--configuration', configuration), - withNamedArg('-p:ContainerRepository', getValidImageName(projectFolderName), { assignValue: true }), + withNamedArg('-p:ContainerImageName', getValidImageName(projectFolderName), { assignValue: true }), withNamedArg('-p:ContainerImageTag', NetSdkDefaultImageTag, { assignValue: true }) )(); From a0af03c32cc5af3611f92bf971c3ac5acd0580c6 Mon Sep 17 00:00:00 2001 From: alexyaang <59073590+alexyaang@users.noreply.github.com> Date: Fri, 30 Jun 2023 16:59:41 -0400 Subject: [PATCH 02/15] no more static variables --- src/debugging/netSdk/NetSdkDebugHelper.ts | 40 +++++++++-------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/src/debugging/netSdk/NetSdkDebugHelper.ts b/src/debugging/netSdk/NetSdkDebugHelper.ts index 67f9dfb42c..fb871fef8c 100644 --- a/src/debugging/netSdk/NetSdkDebugHelper.ts +++ b/src/debugging/netSdk/NetSdkDebugHelper.ts @@ -3,9 +3,8 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IActionContext } from "@microsoft/vscode-azext-utils"; import * as path from "path"; -import { Uri, WorkspaceFolder, commands, l10n, tasks } from "vscode"; +import { Uri, commands, l10n, tasks } from "vscode"; import { ext } from "../../extensionVariables"; import { NetChooseBuildTypeContext, netContainerBuild } from "../../scaffolding/wizard/net/NetContainerBuild"; import { AllNetContainerBuildOptions, NetContainerBuildOptionsKey } from "../../scaffolding/wizard/net/NetSdkChooseBuildStep"; @@ -23,8 +22,6 @@ import { NetCoreDebugHelper, NetCoreDebugScaffoldingOptions } from "../netcore/N export class NetSdkDebugHelper extends NetCoreDebugHelper { - private static projPath: string | undefined; - public async provideDebugConfigurations(context: DockerDebugScaffoldContext, options?: NetCoreDebugScaffoldingOptions): Promise { const configurations: DockerDebugConfiguration[] = []; @@ -37,7 +34,7 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { await netContainerBuild(netCoreBuildContext); if (netCoreBuildContext?.containerBuildOptions === AllNetContainerBuildOptions[1]) { - const appProjectAbsolutePath = await this.inferProjPath(context.actionContext, context.folder); + const appProjectAbsolutePath = await this.inferProjPath(context, options); configurations.push({ name: 'Docker .NET Container SDK Launch', @@ -59,7 +56,7 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { const { task, promise } = netSdkRunTaskProvider.createNetSdkRunTask( { netCore: { - appProject: await this.inferProjPath(context.actionContext, context.folder), + appProject: await this.inferProjPath(undefined, debugConfiguration.netCore), } } ); @@ -69,17 +66,11 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { try { await promise; } catch (error) { - await NetSdkDebugHelper.clearWorkspaceState(); + await ext.context.workspaceState.update(NetContainerBuildOptionsKey, ''); throw error; } } - public static async clearWorkspaceState(): Promise { - await ext.context.workspaceState.update(NetContainerBuildOptionsKey, ''); // clear the workspace state - NetSdkDebugHelper.projPath = undefined; // clear the static projPath variable - return Promise.resolve(); - } - protected override async inferAppOutput(debugConfiguration: DockerDebugConfiguration): Promise { const ridOS = await normalizeOsToRidOs(); const ridArchitecture = await normalizeArchitectureToRidArchitecture(); @@ -89,7 +80,7 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { try { projectInfo = await getNetCoreProjectInfo('GetProjectProperties', debugConfiguration.netCore?.appProject, additionalProperties); } catch (error) { - await NetSdkDebugHelper.clearWorkspaceState(); + await ext.context.workspaceState.update(NetContainerBuildOptionsKey, ''); throw error; } @@ -100,18 +91,16 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { ? path.win32.normalize(projectInfo[3]) : path.posix.normalize(projectInfo[3]); } else { - await NetSdkDebugHelper.clearWorkspaceState(); + await ext.context.workspaceState.update(NetContainerBuildOptionsKey, ''); throw new Error(l10n.t("Your current project configuration or .NET SDK version doesn't support SDK Container build. Please choose a compatible project or update .NET SDK.")); } } - await NetSdkDebugHelper.clearWorkspaceState(); + await ext.context.workspaceState.update(NetContainerBuildOptionsKey, ''); throw new Error(l10n.t('Unable to determine assembly output path.')); } protected override async loadExternalInfo(context: DockerDebugContext, debugConfiguration: DockerDebugConfiguration): Promise<{ configureSsl: boolean, containerName: string, platformOS: PlatformOS }> { - NetSdkDebugHelper.projPath = debugConfiguration.netCore.appProject; - const associatedTask = context.runDefinition; return { configureSsl: !!(associatedTask?.netCore?.configureSsl), @@ -130,18 +119,19 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { } /** - * @returns the project path stored in the static variable projPath if it exists, + * @returns the project path stored in NetCoreDebugScaffoldingOptions, * otherwise prompts the user to select a .csproj file and stores the path * in the static variable projPath */ - private async inferProjPath(context: IActionContext, folder: WorkspaceFolder): Promise { - if (NetSdkDebugHelper.projPath) { - return NetSdkDebugHelper.projPath; + private async inferProjPath(context: DockerDebugScaffoldContext, options?: NetCoreDebugScaffoldingOptions): Promise { + options = options || {}; + if (options.appProject) { + return options.appProject; } - const projFileItem = await quickPickProjectFileItem(context, undefined, folder, 'No project file could be found.'); - NetSdkDebugHelper.projPath = projFileItem.absoluteFilePath; // save the path for future use - return projFileItem.absoluteFilePath; + const projFileItem = await quickPickProjectFileItem(context.actionContext, undefined, context.folder, 'No project file could be found.'); + options.appProject = projFileItem.absoluteFilePath; // save the path for future use + return options.appProject; } } From a23594850885ce13167e98546c5d2b5acd2a89e7 Mon Sep 17 00:00:00 2001 From: alexyaang <59073590+alexyaang@users.noreply.github.com> Date: Mon, 3 Jul 2023 11:01:43 -0400 Subject: [PATCH 03/15] Get container & image name from msbuild --- package.json | 12 ++++ .../netCore/GetProjectProperties.targets | 4 +- src/debugging/netSdk/NetSdkDebugHelper.ts | 63 +++++++++++-------- src/tasks/netSdk/NetSdkRunTaskProvider.ts | 9 ++- src/tasks/netSdk/netSdkTaskUtils.ts | 13 ++-- src/utils/execAsync.ts | 8 ++- src/utils/getValidImageName.ts | 8 +++ 7 files changed, 77 insertions(+), 40 deletions(-) diff --git a/package.json b/package.json index 41603c5b28..3a9e3b4120 100644 --- a/package.json +++ b/package.json @@ -1524,6 +1524,18 @@ "required": [ "appProject" ] + }, + "dockerRun": { + "description": "%vscode-docker.tasks.docker-run.dockerRun.description%", + "properties": { + "containerName": { + "type": "string", + "description": "%vscode-docker.tasks.docker-run.dockerRun.containerName%" + } + }, + "required": [ + "containerName" + ] } } } diff --git a/resources/netCore/GetProjectProperties.targets b/resources/netCore/GetProjectProperties.targets index 929dd3ae4e..e1d16df4f0 100644 --- a/resources/netCore/GetProjectProperties.targets +++ b/resources/netCore/GetProjectProperties.targets @@ -1,6 +1,7 @@ $(GetProjectPropertiesDependsOn);ComputeContainerConfig; + $(AssemblyName) @@ -10,7 +11,8 @@ $(TargetFramework)$(TargetFrameworks.Split(';')[0]) $(OutputPath)$(AssemblyName).dll $(ContainerWorkingDirectory)/$(AssemblyName).dll -$(SDKContainerSupportEnabled)" +$(SDKContainerSupportEnabled) +$(InferImageName)" Overwrite="True" /> diff --git a/src/debugging/netSdk/NetSdkDebugHelper.ts b/src/debugging/netSdk/NetSdkDebugHelper.ts index fb871fef8c..52ea490f00 100644 --- a/src/debugging/netSdk/NetSdkDebugHelper.ts +++ b/src/debugging/netSdk/NetSdkDebugHelper.ts @@ -4,13 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import * as path from "path"; -import { Uri, commands, l10n, tasks } from "vscode"; +import { commands, l10n, tasks } from "vscode"; import { ext } from "../../extensionVariables"; import { NetChooseBuildTypeContext, netContainerBuild } from "../../scaffolding/wizard/net/NetContainerBuild"; import { AllNetContainerBuildOptions, NetContainerBuildOptionsKey } from "../../scaffolding/wizard/net/NetSdkChooseBuildStep"; -import { getDefaultContainerName } from "../../tasks/TaskHelper"; -import { netSdkRunTaskProvider } from "../../tasks/netSdk/NetSdkRunTaskProvider"; +import { NetSdkRunTaskDefinition, netSdkRunTaskProvider } from "../../tasks/netSdk/NetSdkRunTaskProvider"; import { normalizeArchitectureToRidArchitecture, normalizeOsToRidOs } from "../../tasks/netSdk/netSdkTaskUtils"; +import { getContainerNameWithTag } from "../../utils/getValidImageName"; import { getNetCoreProjectInfo } from "../../utils/netCoreUtils"; import { getDockerOSType } from "../../utils/osUtils"; import { PlatformOS } from "../../utils/platform"; @@ -22,6 +22,8 @@ import { NetCoreDebugHelper, NetCoreDebugScaffoldingOptions } from "../netcore/N export class NetSdkDebugHelper extends NetCoreDebugHelper { + private projectInfo: string[] | undefined; + public async provideDebugConfigurations(context: DockerDebugScaffoldContext, options?: NetCoreDebugScaffoldingOptions): Promise { const configurations: DockerDebugConfiguration[] = []; @@ -53,13 +55,17 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { } public async afterResolveDebugConfiguration(context: DockerDebugContext, debugConfiguration: DockerDebugConfiguration): Promise { - const { task, promise } = netSdkRunTaskProvider.createNetSdkRunTask( - { - netCore: { - appProject: await this.inferProjPath(undefined, debugConfiguration.netCore), - } + const projectInfo = await this.getProjectInfo(debugConfiguration); + const runDefinition: Omit = { + netCore: { + appProject: await this.inferProjPath(undefined, debugConfiguration.netCore), + }, + dockerRun: { + containerName: projectInfo[5].toLowerCase() || 'dotnet' } - ); + }; + + const { task, promise } = netSdkRunTaskProvider.createNetSdkRunTask(runDefinition); await tasks.executeTask(task); @@ -72,22 +78,12 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { } protected override async inferAppOutput(debugConfiguration: DockerDebugConfiguration): Promise { - const ridOS = await normalizeOsToRidOs(); - const ridArchitecture = await normalizeArchitectureToRidArchitecture(); - const additionalProperties = `/p:ContainerRuntimeIdentifier="${ridOS}-${ridArchitecture}"`; - - let projectInfo: string[]; - try { - projectInfo = await getNetCoreProjectInfo('GetProjectProperties', debugConfiguration.netCore?.appProject, additionalProperties); - } catch (error) { - await ext.context.workspaceState.update(NetContainerBuildOptionsKey, ''); - throw error; - } + const projectInfo = await this.getProjectInfo(debugConfiguration); if (projectInfo.length >= 5) { // if .NET has support for SDK Build // fifth is whether .NET Web apps supports SDK Containers if (projectInfo[4] === 'true') { - return ridOS === 'win' // fourth is output path + return await getDockerOSType() === 'windows' // fourth is output path ? path.win32.normalize(projectInfo[3]) : path.posix.normalize(projectInfo[3]); } else { @@ -102,9 +98,10 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { protected override async loadExternalInfo(context: DockerDebugContext, debugConfiguration: DockerDebugConfiguration): Promise<{ configureSsl: boolean, containerName: string, platformOS: PlatformOS }> { const associatedTask = context.runDefinition; + const projectInfo = await this.getProjectInfo(debugConfiguration); return { configureSsl: !!(associatedTask?.netCore?.configureSsl), - containerName: this.inferDotNetSdkContainerName(debugConfiguration), + containerName: getContainerNameWithTag(projectInfo[5].toLowerCase(), "dev"), platformOS: await getDockerOSType() === "windows" ? 'Windows' : 'Linux', }; } @@ -113,9 +110,25 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { return appOutput; } - private inferDotNetSdkContainerName(debugConfiguration: DockerDebugConfiguration): string { - const projFileUri = Uri.file(path.dirname(debugConfiguration.netCore.appProject)); - return getDefaultContainerName(path.basename(projFileUri.fsPath), "dev"); + private async getProjectInfo(debugConfiguration: DockerDebugConfiguration): Promise { + if (this.projectInfo !== undefined && this.projectInfo.length > 0) { + return this.projectInfo; + } + + const ridOS = await normalizeOsToRidOs(); + const ridArchitecture = await normalizeArchitectureToRidArchitecture(); + const additionalProperties = `/p:ContainerRuntimeIdentifier="${ridOS}-${ridArchitecture}"`; + + let projectInfo: string[]; + try { + projectInfo = await getNetCoreProjectInfo('GetProjectProperties', debugConfiguration.netCore?.appProject, additionalProperties); + this.projectInfo = projectInfo; + } catch (error) { + await ext.context.workspaceState.update(NetContainerBuildOptionsKey, ''); + throw error; + } + + return projectInfo; } /** diff --git a/src/tasks/netSdk/NetSdkRunTaskProvider.ts b/src/tasks/netSdk/NetSdkRunTaskProvider.ts index a57e6ee0a4..6383a415ef 100644 --- a/src/tasks/netSdk/NetSdkRunTaskProvider.ts +++ b/src/tasks/netSdk/NetSdkRunTaskProvider.ts @@ -14,7 +14,7 @@ import { NetSdkRunTaskType, getNetSdkBuildCommand, getNetSdkRunCommand } from '. const NetSdkDebugTaskName = 'debug'; -export type NetSdkRunTask = NetCoreRunTaskDefinition; +export type NetSdkRunTaskDefinition = NetCoreRunTaskDefinition; export class NetSdkRunTaskProvider extends DockerTaskProvider { @@ -28,10 +28,9 @@ export class NetSdkRunTaskProvider extends DockerTaskProvider { const projectPath = task.definition.netCore?.appProject; const isProjectWebApp = await NetCoreTaskHelper.isWebApp(projectPath); const projectFolderPath = path.dirname(projectPath); - const projectFolderName = path.basename(projectFolderPath); // use dotnet to build the image - const buildCommand = await getNetSdkBuildCommand(isProjectWebApp, projectFolderName); + const buildCommand = await getNetSdkBuildCommand(isProjectWebApp, task.definition.dockerRun.containerName); await context.terminal.execAsyncInTerminal( buildCommand, { @@ -42,7 +41,7 @@ export class NetSdkRunTaskProvider extends DockerTaskProvider { ); // use docker run to run the image - const runCommand = await getNetSdkRunCommand(isProjectWebApp, projectFolderName); + const runCommand = await getNetSdkRunCommand(isProjectWebApp, task.definition.dockerRun.containerName); await context.terminal.execAsyncInTerminal( runCommand, { @@ -55,7 +54,7 @@ export class NetSdkRunTaskProvider extends DockerTaskProvider { return Promise.resolve(); } - public createNetSdkRunTask(options?: Omit): { task: Task, promise: Promise } { + public createNetSdkRunTask(options?: Omit): { task: Task, promise: Promise } { let task: Task; const definition = { ...options, diff --git a/src/tasks/netSdk/netSdkTaskUtils.ts b/src/tasks/netSdk/netSdkTaskUtils.ts index 0c9c021347..682552a549 100644 --- a/src/tasks/netSdk/netSdkTaskUtils.ts +++ b/src/tasks/netSdk/netSdkTaskUtils.ts @@ -7,10 +7,9 @@ import * as os from 'os'; import { vsDbgInstallBasePath } from "../../debugging/netcore/VsDbgHelper"; import { ext } from "../../extensionVariables"; import { RunContainerBindMount, RunContainerCommandOptions, Shell, composeArgs, withArg, withNamedArg } from "../../runtimes/docker"; -import { getValidImageName } from "../../utils/getValidImageName"; +import { getContainerNameWithTag, getImageNameWithTag } from '../../utils/getValidImageName'; import { getDockerOSType } from "../../utils/osUtils"; import { defaultVsCodeLabels } from "../TaskDefinitionBase"; -import { getDefaultContainerName, getDefaultImageName } from "../TaskHelper"; /** * Native architecture of the current machine in the RID format @@ -29,7 +28,7 @@ export type RidCpuArchitecture = export const NetSdkRunTaskType = 'dotnet-container-sdk'; const NetSdkDefaultImageTag = 'dev'; // intentionally default to dev tag for phase 1 of this feature -export async function getNetSdkBuildCommand(isProjectWebApp: boolean, projectFolderName: string): Promise { +export async function getNetSdkBuildCommand(isProjectWebApp: boolean, imageName: string): Promise { const configuration = 'Debug'; // intentionally default to Debug configuration for phase 1 of this feature // {@link https://github.com/dotnet/sdk-container-builds/issues/141} this could change in the future @@ -43,7 +42,7 @@ export async function getNetSdkBuildCommand(isProjectWebApp: boolean, projectFol withNamedArg('--arch', await normalizeArchitectureToRidArchitecture()), withArg(publishFlag), withNamedArg('--configuration', configuration), - withNamedArg('-p:ContainerImageName', getValidImageName(projectFolderName), { assignValue: true }), + withNamedArg('-p:ContainerImageName', imageName, { assignValue: true }), withNamedArg('-p:ContainerImageTag', NetSdkDefaultImageTag, { assignValue: true }) )(); @@ -51,16 +50,16 @@ export async function getNetSdkBuildCommand(isProjectWebApp: boolean, projectFol return quotedArgs.join(' '); } -export async function getNetSdkRunCommand(isProjectWebApp: boolean, projectFolderName: string): Promise { +export async function getNetSdkRunCommand(isProjectWebApp: boolean, imageName: string): Promise { const client = await ext.runtimeManager.getClient(); const options: RunContainerCommandOptions = { detached: true, publishAllPorts: true, - name: getDefaultContainerName(projectFolderName, NetSdkDefaultImageTag), + name: getContainerNameWithTag(imageName, NetSdkDefaultImageTag), environmentVariables: {}, removeOnExit: true, - imageRef: getDefaultImageName(projectFolderName, NetSdkDefaultImageTag), + imageRef: getImageNameWithTag(imageName, NetSdkDefaultImageTag), labels: defaultVsCodeLabels, mounts: await getRemoteDebuggerMount(), entrypoint: await getDockerOSType() === 'windows' ? 'cmd.exe' : '/bin/sh' diff --git a/src/utils/execAsync.ts b/src/utils/execAsync.ts index d78d3e132b..ea47abdf13 100644 --- a/src/utils/execAsync.ts +++ b/src/utils/execAsync.ts @@ -5,8 +5,8 @@ import * as cp from 'child_process'; import * as stream from 'stream'; -import { AccumulatorStream, Shell, spawnStreamAsync, StreamSpawnOptions } from '../runtimes/docker'; import { CancellationToken } from 'vscode'; +import { AccumulatorStream, Shell, spawnStreamAsync, StreamSpawnOptions } from '../runtimes/docker'; type Progress = (content: string, err: boolean) => void; @@ -57,7 +57,11 @@ export async function execAsync(command: string, options?: cp.ExecOptions & { st stdErrPipe: stderrIntermediate ?? stderrFinal, }; - await spawnStreamAsync(command, [], spawnOptions); + try { + await spawnStreamAsync(command, [], spawnOptions); + } catch (err) { + // best effort + } return { stdout: await stdoutFinal.getString(), diff --git a/src/utils/getValidImageName.ts b/src/utils/getValidImageName.ts index cc7fe93099..8b17387308 100644 --- a/src/utils/getValidImageName.ts +++ b/src/utils/getValidImageName.ts @@ -18,3 +18,11 @@ export function getValidImageNameFromPath(appPath: string, tag?: string): string export function getValidImageNameWithTag(nameHint: string, tag: string): string { return `${getValidImageName(nameHint)}:${tag}`; } + +export function getImageNameWithTag(nameHint: string, tag: string): string { + return `${nameHint}:${tag}`; +} + +export function getContainerNameWithTag(nameHint: string, tag: string): string { + return `${nameHint}-${tag}`; +} From 7965d0004bf3380576f55721a8a6d8d8d3825c63 Mon Sep 17 00:00:00 2001 From: alexyaang <59073590+alexyaang@users.noreply.github.com> Date: Mon, 3 Jul 2023 12:14:13 -0400 Subject: [PATCH 04/15] actually get image name from target file --- resources/netCore/GetProjectProperties.targets | 5 ++++- src/debugging/netSdk/NetSdkDebugHelper.ts | 13 +++++++++---- src/tasks/TaskHelper.ts | 6 +++++- src/utils/getValidImageName.ts | 6 +----- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/resources/netCore/GetProjectProperties.targets b/resources/netCore/GetProjectProperties.targets index e1d16df4f0..c0176c2126 100644 --- a/resources/netCore/GetProjectProperties.targets +++ b/resources/netCore/GetProjectProperties.targets @@ -1,10 +1,13 @@ $(GetProjectPropertiesDependsOn);ComputeContainerConfig; - $(AssemblyName) + + $(ContainerRepository) + $(ContainerImageName) + { diff --git a/src/utils/getValidImageName.ts b/src/utils/getValidImageName.ts index 8b17387308..bb1ad19619 100644 --- a/src/utils/getValidImageName.ts +++ b/src/utils/getValidImageName.ts @@ -16,13 +16,9 @@ export function getValidImageNameFromPath(appPath: string, tag?: string): string } export function getValidImageNameWithTag(nameHint: string, tag: string): string { - return `${getValidImageName(nameHint)}:${tag}`; + return getImageNameWithTag(getValidImageName(nameHint), tag); } export function getImageNameWithTag(nameHint: string, tag: string): string { return `${nameHint}:${tag}`; } - -export function getContainerNameWithTag(nameHint: string, tag: string): string { - return `${nameHint}-${tag}`; -} From 26946fd16291c7bc08cb78d8c27ac88f2f0083b7 Mon Sep 17 00:00:00 2001 From: alexyaang <59073590+alexyaang@users.noreply.github.com> Date: Mon, 3 Jul 2023 13:21:57 -0400 Subject: [PATCH 05/15] minor changes to clean up PR --- src/debugging/netSdk/NetSdkDebugHelper.ts | 2 +- src/tasks/netSdk/netSdkTaskUtils.ts | 3 ++- src/utils/execAsync.ts | 6 +----- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/debugging/netSdk/NetSdkDebugHelper.ts b/src/debugging/netSdk/NetSdkDebugHelper.ts index 8cf0bdf881..939d925824 100644 --- a/src/debugging/netSdk/NetSdkDebugHelper.ts +++ b/src/debugging/netSdk/NetSdkDebugHelper.ts @@ -111,7 +111,7 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { } private async getProjectInfo(debugConfiguration: DockerDebugConfiguration): Promise { - if (this.projectInfo !== undefined && this.projectInfo.length > 0) { + if (this.projectInfo !== undefined && this.projectInfo.length >= 6) { return this.projectInfo; } diff --git a/src/tasks/netSdk/netSdkTaskUtils.ts b/src/tasks/netSdk/netSdkTaskUtils.ts index 682552a549..b9001a7a62 100644 --- a/src/tasks/netSdk/netSdkTaskUtils.ts +++ b/src/tasks/netSdk/netSdkTaskUtils.ts @@ -7,9 +7,10 @@ import * as os from 'os'; import { vsDbgInstallBasePath } from "../../debugging/netcore/VsDbgHelper"; import { ext } from "../../extensionVariables"; import { RunContainerBindMount, RunContainerCommandOptions, Shell, composeArgs, withArg, withNamedArg } from "../../runtimes/docker"; -import { getContainerNameWithTag, getImageNameWithTag } from '../../utils/getValidImageName'; +import { getImageNameWithTag } from '../../utils/getValidImageName'; import { getDockerOSType } from "../../utils/osUtils"; import { defaultVsCodeLabels } from "../TaskDefinitionBase"; +import { getContainerNameWithTag } from '../TaskHelper'; /** * Native architecture of the current machine in the RID format diff --git a/src/utils/execAsync.ts b/src/utils/execAsync.ts index ea47abdf13..532f2b2f09 100644 --- a/src/utils/execAsync.ts +++ b/src/utils/execAsync.ts @@ -57,11 +57,7 @@ export async function execAsync(command: string, options?: cp.ExecOptions & { st stdErrPipe: stderrIntermediate ?? stderrFinal, }; - try { - await spawnStreamAsync(command, [], spawnOptions); - } catch (err) { - // best effort - } + await spawnStreamAsync(command, [], spawnOptions); return { stdout: await stdoutFinal.getString(), From 039513b4be61d894f1ef53ea785d34d2b4300dac Mon Sep 17 00:00:00 2001 From: alexyaang <59073590+alexyaang@users.noreply.github.com> Date: Mon, 3 Jul 2023 13:33:11 -0400 Subject: [PATCH 06/15] small tweak --- src/tasks/TaskHelper.ts | 4 ++-- src/utils/getValidImageName.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tasks/TaskHelper.ts b/src/tasks/TaskHelper.ts index ea2a743a44..bd60e1d2e7 100644 --- a/src/tasks/TaskHelper.ts +++ b/src/tasks/TaskHelper.ts @@ -213,8 +213,8 @@ export function getDefaultContainerName(nameHint: string, tag?: 'dev' | 'latest' return getContainerNameWithTag(getValidImageName(nameHint), tag); } -export function getContainerNameWithTag(nameHint: string, tag: string): string { - return `${nameHint}-${tag}`; +export function getContainerNameWithTag(name: string, tag: string): string { + return `${name}-${tag}`; } export async function recursiveFindTaskByType(allTasks: TaskDefinitionBase[], type: string, node: DebugConfigurationBase | TaskDefinitionBase): Promise { diff --git a/src/utils/getValidImageName.ts b/src/utils/getValidImageName.ts index bb1ad19619..0b21cfb2bb 100644 --- a/src/utils/getValidImageName.ts +++ b/src/utils/getValidImageName.ts @@ -19,6 +19,6 @@ export function getValidImageNameWithTag(nameHint: string, tag: string): string return getImageNameWithTag(getValidImageName(nameHint), tag); } -export function getImageNameWithTag(nameHint: string, tag: string): string { - return `${nameHint}:${tag}`; +export function getImageNameWithTag(name: string, tag: string): string { + return `${name}:${tag}`; } From 5fda3e00df3f33a18ccb431d7645c18508a80886 Mon Sep 17 00:00:00 2001 From: alexyaang <59073590+alexyaang@users.noreply.github.com> Date: Mon, 10 Jul 2023 11:18:59 -0400 Subject: [PATCH 07/15] simplified error handling --- src/debugging/netSdk/NetSdkDebugHelper.ts | 36 +++++++++-------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/src/debugging/netSdk/NetSdkDebugHelper.ts b/src/debugging/netSdk/NetSdkDebugHelper.ts index 939d925824..44f36b01a0 100644 --- a/src/debugging/netSdk/NetSdkDebugHelper.ts +++ b/src/debugging/netSdk/NetSdkDebugHelper.ts @@ -16,7 +16,7 @@ import { getDockerOSType } from "../../utils/osUtils"; import { PlatformOS } from "../../utils/platform"; import { quickPickProjectFileItem } from "../../utils/quickPickFile"; import { unresolveWorkspaceFolder } from "../../utils/resolveVariables"; -import { DockerDebugContext, DockerDebugScaffoldContext } from "../DebugHelper"; +import { DockerDebugContext, DockerDebugScaffoldContext, ResolvedDebugConfiguration } from "../DebugHelper"; import { DockerDebugConfiguration } from "../DockerDebugConfigurationProvider"; import { NetCoreDebugHelper, NetCoreDebugScaffoldingOptions } from "../netcore/NetCoreDebugHelper"; @@ -24,8 +24,7 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { private projectInfo: string[] | undefined; - public async provideDebugConfigurations(context: DockerDebugScaffoldContext, options?: NetCoreDebugScaffoldingOptions): Promise { - + public override async provideDebugConfigurations(context: DockerDebugScaffoldContext, options?: NetCoreDebugScaffoldingOptions): Promise { const configurations: DockerDebugConfiguration[] = []; const netCoreBuildContext: NetChooseBuildTypeContext = { @@ -54,6 +53,15 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { return configurations; } + public override async resolveDebugConfiguration(context: DockerDebugContext, debugConfiguration: DockerDebugConfiguration): Promise { + try { + return await super.resolveDebugConfiguration(context, debugConfiguration); + } catch (error) { + await ext.context.workspaceState.update(NetContainerBuildOptionsKey, ''); + throw error; + } + } + public async afterResolveDebugConfiguration(context: DockerDebugContext, debugConfiguration: DockerDebugConfiguration): Promise { const projectInfo = await this.getProjectInfo(debugConfiguration); const runDefinition: Omit = { @@ -66,15 +74,8 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { }; const { task, promise } = netSdkRunTaskProvider.createNetSdkRunTask(runDefinition); - await tasks.executeTask(task); - - try { - await promise; - } catch (error) { - await ext.context.workspaceState.update(NetContainerBuildOptionsKey, ''); - throw error; - } + await promise; } protected override async inferAppOutput(debugConfiguration: DockerDebugConfiguration): Promise { @@ -87,12 +88,10 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { ? path.win32.normalize(projectInfo[3]) : path.posix.normalize(projectInfo[3]); } else { - await ext.context.workspaceState.update(NetContainerBuildOptionsKey, ''); throw new Error(l10n.t("Your current project configuration or .NET SDK version doesn't support SDK Container build. Please choose a compatible project or update .NET SDK.")); } } - await ext.context.workspaceState.update(NetContainerBuildOptionsKey, ''); throw new Error(l10n.t('Unable to determine assembly output path.')); } @@ -111,7 +110,7 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { } private async getProjectInfo(debugConfiguration: DockerDebugConfiguration): Promise { - if (this.projectInfo !== undefined && this.projectInfo.length >= 6) { + if (this.projectInfo && this.projectInfo.length >= 6) { return this.projectInfo; } @@ -119,16 +118,9 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { const ridArchitecture = await normalizeArchitectureToRidArchitecture(); const additionalProperties = `/p:ContainerRuntimeIdentifier="${ridOS}-${ridArchitecture}"`; - let projectInfo: string[]; - try { - projectInfo = await getNetCoreProjectInfo('GetProjectProperties', debugConfiguration.netCore?.appProject, additionalProperties); - } catch (error) { - await ext.context.workspaceState.update(NetContainerBuildOptionsKey, ''); - throw error; - } + const projectInfo = await getNetCoreProjectInfo('GetProjectProperties', debugConfiguration.netCore?.appProject, additionalProperties); if (projectInfo.length < 6 || !projectInfo[5]) { - await ext.context.workspaceState.update(NetContainerBuildOptionsKey, ''); throw new Error(l10n.t("Your current project configuration or .NET SDK version doesn't support SDK Container build. Please choose a compatible project or update .NET SDK.")); } From eb824e3047487560be7b9d2459cb7e6e7d387de3 Mon Sep 17 00:00:00 2001 From: alexyaang <59073590+alexyaang@users.noreply.github.com> Date: Mon, 10 Jul 2023 11:39:18 -0400 Subject: [PATCH 08/15] simplified logic for getting app project --- src/debugging/netSdk/NetSdkDebugHelper.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/debugging/netSdk/NetSdkDebugHelper.ts b/src/debugging/netSdk/NetSdkDebugHelper.ts index 44f36b01a0..49d1c6e174 100644 --- a/src/debugging/netSdk/NetSdkDebugHelper.ts +++ b/src/debugging/netSdk/NetSdkDebugHelper.ts @@ -3,8 +3,9 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { IActionContext } from "@microsoft/vscode-azext-utils"; import * as path from "path"; -import { commands, l10n, tasks } from "vscode"; +import { WorkspaceFolder, commands, l10n, tasks } from "vscode"; import { ext } from "../../extensionVariables"; import { NetChooseBuildTypeContext, netContainerBuild } from "../../scaffolding/wizard/net/NetContainerBuild"; import { AllNetContainerBuildOptions, NetContainerBuildOptionsKey } from "../../scaffolding/wizard/net/NetSdkChooseBuildStep"; @@ -23,6 +24,7 @@ import { NetCoreDebugHelper, NetCoreDebugScaffoldingOptions } from "../netcore/N export class NetSdkDebugHelper extends NetCoreDebugHelper { private projectInfo: string[] | undefined; + private appProject: string | undefined; public override async provideDebugConfigurations(context: DockerDebugScaffoldContext, options?: NetCoreDebugScaffoldingOptions): Promise { const configurations: DockerDebugConfiguration[] = []; @@ -35,7 +37,7 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { await netContainerBuild(netCoreBuildContext); if (netCoreBuildContext?.containerBuildOptions === AllNetContainerBuildOptions[1]) { - const appProjectAbsolutePath = await this.inferProjPath(context, options); + const appProjectAbsolutePath = options?.appProject || await this.inferProjPath(context.actionContext, context.folder); configurations.push({ name: 'Docker .NET Container SDK Launch', @@ -66,7 +68,7 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { const projectInfo = await this.getProjectInfo(debugConfiguration); const runDefinition: Omit = { netCore: { - appProject: await this.inferProjPath(undefined, debugConfiguration.netCore), + appProject: debugConfiguration?.netCore?.appProject || await this.inferProjPath(context.actionContext, context.folder), }, dockerRun: { containerName: projectInfo[5] @@ -133,15 +135,14 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { * otherwise prompts the user to select a .csproj file and stores the path * in the static variable projPath */ - private async inferProjPath(context: DockerDebugScaffoldContext, options?: NetCoreDebugScaffoldingOptions): Promise { - options = options || {}; - if (options.appProject) { - return options.appProject; + private async inferProjPath(actionContext: IActionContext, folder: WorkspaceFolder): Promise { + if (this.appProject) { + return this.appProject; } - const projFileItem = await quickPickProjectFileItem(context.actionContext, undefined, context.folder, 'No project file could be found.'); - options.appProject = projFileItem.absoluteFilePath; // save the path for future use - return options.appProject; + const projFileItem = await quickPickProjectFileItem(actionContext, undefined, folder, 'No project file could be found.'); + this.appProject = projFileItem.absoluteFilePath; // save the path for future use + return this.appProject; } } From 01c18d9087ef340c2a224772a73391f3e826f4f2 Mon Sep 17 00:00:00 2001 From: alexyaang <59073590+alexyaang@users.noreply.github.com> Date: Mon, 10 Jul 2023 11:49:38 -0400 Subject: [PATCH 09/15] actually make ifer project file logic simpler --- src/debugging/netSdk/NetSdkDebugHelper.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/debugging/netSdk/NetSdkDebugHelper.ts b/src/debugging/netSdk/NetSdkDebugHelper.ts index 49d1c6e174..1cdc41c53a 100644 --- a/src/debugging/netSdk/NetSdkDebugHelper.ts +++ b/src/debugging/netSdk/NetSdkDebugHelper.ts @@ -24,7 +24,6 @@ import { NetCoreDebugHelper, NetCoreDebugScaffoldingOptions } from "../netcore/N export class NetSdkDebugHelper extends NetCoreDebugHelper { private projectInfo: string[] | undefined; - private appProject: string | undefined; public override async provideDebugConfigurations(context: DockerDebugScaffoldContext, options?: NetCoreDebugScaffoldingOptions): Promise { const configurations: DockerDebugConfiguration[] = []; @@ -136,13 +135,8 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { * in the static variable projPath */ private async inferProjPath(actionContext: IActionContext, folder: WorkspaceFolder): Promise { - if (this.appProject) { - return this.appProject; - } - const projFileItem = await quickPickProjectFileItem(actionContext, undefined, folder, 'No project file could be found.'); - this.appProject = projFileItem.absoluteFilePath; // save the path for future use - return this.appProject; + return projFileItem.absoluteFilePath; } } From ae8fc23f54930fcd56e64b87649e6f92309e7dd8 Mon Sep 17 00:00:00 2001 From: alexyaang <59073590+alexyaang@users.noreply.github.com> Date: Mon, 10 Jul 2023 13:23:57 -0400 Subject: [PATCH 10/15] convert project properties into interface for future expandibility --- src/debugging/netSdk/NetSdkDebugHelper.ts | 59 ++++++++++++--------- src/debugging/netcore/NetCoreDebugHelper.ts | 40 +++++++++++--- 2 files changed, 68 insertions(+), 31 deletions(-) diff --git a/src/debugging/netSdk/NetSdkDebugHelper.ts b/src/debugging/netSdk/NetSdkDebugHelper.ts index 1cdc41c53a..e1a840106f 100644 --- a/src/debugging/netSdk/NetSdkDebugHelper.ts +++ b/src/debugging/netSdk/NetSdkDebugHelper.ts @@ -19,11 +19,17 @@ import { quickPickProjectFileItem } from "../../utils/quickPickFile"; import { unresolveWorkspaceFolder } from "../../utils/resolveVariables"; import { DockerDebugContext, DockerDebugScaffoldContext, ResolvedDebugConfiguration } from "../DebugHelper"; import { DockerDebugConfiguration } from "../DockerDebugConfigurationProvider"; -import { NetCoreDebugHelper, NetCoreDebugScaffoldingOptions } from "../netcore/NetCoreDebugHelper"; +import { NetCoreDebugHelper, NetCoreDebugScaffoldingOptions, NetCoreProjectProperties } from "../netcore/NetCoreDebugHelper"; + +export interface NetSdkProjectProperties extends NetCoreProjectProperties { + containerWorkingDirectory: string; + isSdkContainerSupportEnabled: boolean; + containerName: string; +} export class NetSdkDebugHelper extends NetCoreDebugHelper { - private projectInfo: string[] | undefined; + protected projectProperties: NetSdkProjectProperties | undefined; public override async provideDebugConfigurations(context: DockerDebugScaffoldContext, options?: NetCoreDebugScaffoldingOptions): Promise { const configurations: DockerDebugConfiguration[] = []; @@ -64,13 +70,13 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { } public async afterResolveDebugConfiguration(context: DockerDebugContext, debugConfiguration: DockerDebugConfiguration): Promise { - const projectInfo = await this.getProjectInfo(debugConfiguration); + const projectInfo = await this.getProjectProperties(debugConfiguration); const runDefinition: Omit = { netCore: { appProject: debugConfiguration?.netCore?.appProject || await this.inferProjPath(context.actionContext, context.folder), }, dockerRun: { - containerName: projectInfo[5] + containerName: projectInfo.containerName } }; @@ -80,28 +86,24 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { } protected override async inferAppOutput(debugConfiguration: DockerDebugConfiguration): Promise { - const projectInfo = await this.getProjectInfo(debugConfiguration); - - if (projectInfo.length >= 5) { // if .NET has support for SDK Build - // fifth is whether .NET Web apps supports SDK Containers - if (projectInfo[4] === 'true') { - return await getDockerOSType() === 'windows' // fourth is output path - ? path.win32.normalize(projectInfo[3]) - : path.posix.normalize(projectInfo[3]); - } else { - throw new Error(l10n.t("Your current project configuration or .NET SDK version doesn't support SDK Container build. Please choose a compatible project or update .NET SDK.")); - } - } + const projectInfo = await this.getProjectProperties(debugConfiguration); - throw new Error(l10n.t('Unable to determine assembly output path.')); + // fifth is whether .NET Web apps supports SDK Containers + if (projectInfo.isSdkContainerSupportEnabled) { + return await getDockerOSType() === 'windows' // fourth is output path + ? path.win32.normalize(projectInfo.containerWorkingDirectory) + : path.posix.normalize(projectInfo.containerWorkingDirectory); + } else { + throw new Error(l10n.t("Your current project configuration or .NET SDK version doesn't support SDK Container build. Please choose a compatible project or update .NET SDK.")); + } } protected override async loadExternalInfo(context: DockerDebugContext, debugConfiguration: DockerDebugConfiguration): Promise<{ configureSsl: boolean, containerName: string, platformOS: PlatformOS }> { const associatedTask = context.runDefinition; - const projectInfo = await this.getProjectInfo(debugConfiguration); + const projectInfo = await this.getProjectProperties(debugConfiguration); return { configureSsl: !!(associatedTask?.netCore?.configureSsl), - containerName: getContainerNameWithTag(projectInfo[5], "dev"), + containerName: getContainerNameWithTag(projectInfo.containerName, "dev"), platformOS: await getDockerOSType() === "windows" ? 'Windows' : 'Linux', }; } @@ -110,9 +112,9 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { return appOutput; } - private async getProjectInfo(debugConfiguration: DockerDebugConfiguration): Promise { - if (this.projectInfo && this.projectInfo.length >= 6) { - return this.projectInfo; + protected override async getProjectProperties(debugConfiguration: DockerDebugConfiguration): Promise { + if (this.projectProperties) { + return this.projectProperties; } const ridOS = await normalizeOsToRidOs(); @@ -125,8 +127,17 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { throw new Error(l10n.t("Your current project configuration or .NET SDK version doesn't support SDK Container build. Please choose a compatible project or update .NET SDK.")); } - this.projectInfo = projectInfo; - return projectInfo; + const projectProperties: NetSdkProjectProperties = { + assemblyName: projectInfo[0], + targetFramework: projectInfo[1], + appOutput: projectInfo[2], + containerWorkingDirectory: projectInfo[3], + isSdkContainerSupportEnabled: projectInfo[4] === 'true', + containerName: projectInfo[5], + }; + + this.projectProperties = projectProperties; + return projectProperties; } /** diff --git a/src/debugging/netcore/NetCoreDebugHelper.ts b/src/debugging/netcore/NetCoreDebugHelper.ts index 6f92341c20..438f460052 100644 --- a/src/debugging/netcore/NetCoreDebugHelper.ts +++ b/src/debugging/netcore/NetCoreDebugHelper.ts @@ -35,7 +35,16 @@ export interface NetCoreDebugScaffoldingOptions { appProject?: string; } +export interface NetCoreProjectProperties { + assemblyName: string; + targetFramework: string; + appOutput: string; +} + export class NetCoreDebugHelper implements DebugHelper { + + protected projectProperties: NetCoreProjectProperties | undefined; + public async provideDebugConfigurations(context: DockerDebugScaffoldContext, options?: NetCoreDebugScaffoldingOptions): Promise { options = options || {}; options.appProject = options.appProject || await NetCoreTaskHelper.inferAppProject(context); // This method internally checks the user-defined input first @@ -178,13 +187,8 @@ export class NetCoreDebugHelper implements DebugHelper { } protected async inferAppOutput(debugConfiguration: DockerDebugConfiguration): Promise { - const projectInfo = await getNetCoreProjectInfo('GetProjectProperties', debugConfiguration.netCore?.appProject); - - if (projectInfo.length < 3) { - throw new Error(l10n.t('Unable to determine assembly output path.')); - } - - return projectInfo[2]; // First line is assembly name, second is target framework, third+ are output path(s) + const projectProperties = await this.getProjectProperties(debugConfiguration); + return projectProperties.appOutput; } protected inferAppContainerOutput(appOutput: string, platformOS: PlatformOS): string { @@ -205,6 +209,28 @@ export class NetCoreDebugHelper implements DebugHelper { }; } + protected async getProjectProperties(debugConfiguration: DockerDebugConfiguration): Promise { + if (this.projectProperties) { + return this.projectProperties; + } + + const projectInfo = await getNetCoreProjectInfo('GetProjectProperties', debugConfiguration.netCore?.appProject); + + if (projectInfo.length < 3) { + throw new Error(l10n.t('Unable to determine assembly output path.')); + } + + // First line is assembly name, second is target framework, third+ are output path(s) + const projectProperties: NetCoreProjectProperties = { + assemblyName: projectInfo[0], + targetFramework: projectInfo[1], + appOutput: projectInfo[2] + }; + + this.projectProperties = projectProperties; + return projectProperties; + } + private async acquireDebuggers(platformOS: PlatformOS): Promise { await window.withProgress( { From 6d0e6fc612086f5a04fc318f112ae2b5e5b59ecd Mon Sep 17 00:00:00 2001 From: alexyaang <59073590+alexyaang@users.noreply.github.com> Date: Mon, 10 Jul 2023 14:05:14 -0400 Subject: [PATCH 11/15] updated nls --- package.json | 4 ++-- package.nls.json | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 3a9e3b4120..27d68e1cfd 100644 --- a/package.json +++ b/package.json @@ -1526,11 +1526,11 @@ ] }, "dockerRun": { - "description": "%vscode-docker.tasks.docker-run.dockerRun.description%", + "description": "%vscode-docker.tasks.dotnet-container-sdk.dotnetContainerSdk.description%", "properties": { "containerName": { "type": "string", - "description": "%vscode-docker.tasks.docker-run.dockerRun.containerName%" + "description": "%vscode-docker.tasks.dotnet-container-sdk.dotnetContainerSdk.containerName%" } }, "required": [ diff --git a/package.nls.json b/package.nls.json index 3b943698f8..bb39017cca 100644 --- a/package.nls.json +++ b/package.nls.json @@ -123,6 +123,8 @@ "vscode-docker.tasks.docker-compose.dockerCompose.envFile.description": "File of environment variables read in and applied to the Docker containers.", "vscode-docker.tasks.docker-compose.dockerCompose.files.description": "The docker-compose files to include, in order.", "vscode-docker.tasks.docker-compose.dockerCompose.projectName.description": "Alternate project name to use when naming and labeling Docker objects. If using an alternate project name when composing up, the same project name must be specified when composing down.", + "vscode-docker.tasks.dotnet-container-sdk.dotnetContainerSdk.description": "Options for running the Docker container used for debugging. Learn more at https://aka.ms/vscode-docker-run-task", + "vscode-docker.tasks.dotnet-container-sdk.dotnetContainerSdk.containerName": "Name of the container used for debugging.", "vscode-docker.config.docker.promptForRegistryWhenPushingImages": "Prompt for registry selection if the image is not explicitly tagged.", "vscode-docker.config.template.build.template": "The command template.", "vscode-docker.config.template.build.label": "The label displayed to the user.", From cefc30ab3aaf7546977d107329fb826aa57651d3 Mon Sep 17 00:00:00 2001 From: alexyaang <59073590+alexyaang@users.noreply.github.com> Date: Mon, 10 Jul 2023 15:53:51 -0400 Subject: [PATCH 12/15] minor changes to naming inside package.json --- package.json | 4 ++-- package.nls.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 27d68e1cfd..dcc9cd2188 100644 --- a/package.json +++ b/package.json @@ -1526,11 +1526,11 @@ ] }, "dockerRun": { - "description": "%vscode-docker.tasks.dotnet-container-sdk.dotnetContainerSdk.description%", + "description": "%vscode-docker.tasks.dotnet-container-sdk.dockerRun.description%", "properties": { "containerName": { "type": "string", - "description": "%vscode-docker.tasks.dotnet-container-sdk.dotnetContainerSdk.containerName%" + "description": "%vscode-docker.tasks.dotnet-container-sdk.dockerRun.containerName%" } }, "required": [ diff --git a/package.nls.json b/package.nls.json index bb39017cca..51e38b7181 100644 --- a/package.nls.json +++ b/package.nls.json @@ -123,8 +123,8 @@ "vscode-docker.tasks.docker-compose.dockerCompose.envFile.description": "File of environment variables read in and applied to the Docker containers.", "vscode-docker.tasks.docker-compose.dockerCompose.files.description": "The docker-compose files to include, in order.", "vscode-docker.tasks.docker-compose.dockerCompose.projectName.description": "Alternate project name to use when naming and labeling Docker objects. If using an alternate project name when composing up, the same project name must be specified when composing down.", - "vscode-docker.tasks.dotnet-container-sdk.dotnetContainerSdk.description": "Options for running the Docker container used for debugging. Learn more at https://aka.ms/vscode-docker-run-task", - "vscode-docker.tasks.dotnet-container-sdk.dotnetContainerSdk.containerName": "Name of the container used for debugging.", + "vscode-docker.tasks.dotnet-container-sdk.dockerRun.description": "Options for running the Docker container used for debugging.", + "vscode-docker.tasks.dotnet-container-sdk.dockerRun.containerName": "Name of the container used for debugging.", "vscode-docker.config.docker.promptForRegistryWhenPushingImages": "Prompt for registry selection if the image is not explicitly tagged.", "vscode-docker.config.template.build.template": "The command template.", "vscode-docker.config.template.build.label": "The label displayed to the user.", From 3ada9097f9669265e60e286649bbb8dec5eedec9 Mon Sep 17 00:00:00 2001 From: alexyaang <59073590+alexyaang@users.noreply.github.com> Date: Tue, 11 Jul 2023 14:47:32 -0400 Subject: [PATCH 13/15] changed caching to stack variable --- src/debugging/netSdk/NetSdkDebugHelper.ts | 66 ++++++++++----------- src/debugging/netcore/NetCoreDebugHelper.ts | 7 --- src/tasks/TaskHelper.ts | 6 +- src/tasks/netSdk/NetSdkRunTaskProvider.ts | 4 +- src/tasks/netSdk/netSdkTaskUtils.ts | 4 +- 5 files changed, 38 insertions(+), 49 deletions(-) diff --git a/src/debugging/netSdk/NetSdkDebugHelper.ts b/src/debugging/netSdk/NetSdkDebugHelper.ts index e1a840106f..6132f39654 100644 --- a/src/debugging/netSdk/NetSdkDebugHelper.ts +++ b/src/debugging/netSdk/NetSdkDebugHelper.ts @@ -9,28 +9,25 @@ import { WorkspaceFolder, commands, l10n, tasks } from "vscode"; import { ext } from "../../extensionVariables"; import { NetChooseBuildTypeContext, netContainerBuild } from "../../scaffolding/wizard/net/NetContainerBuild"; import { AllNetContainerBuildOptions, NetContainerBuildOptionsKey } from "../../scaffolding/wizard/net/NetSdkChooseBuildStep"; -import { getContainerNameWithTag } from "../../tasks/TaskHelper"; import { NetSdkRunTaskDefinition, netSdkRunTaskProvider } from "../../tasks/netSdk/NetSdkRunTaskProvider"; import { normalizeArchitectureToRidArchitecture, normalizeOsToRidOs } from "../../tasks/netSdk/netSdkTaskUtils"; import { getNetCoreProjectInfo } from "../../utils/netCoreUtils"; import { getDockerOSType } from "../../utils/osUtils"; import { PlatformOS } from "../../utils/platform"; import { quickPickProjectFileItem } from "../../utils/quickPickFile"; -import { unresolveWorkspaceFolder } from "../../utils/resolveVariables"; -import { DockerDebugContext, DockerDebugScaffoldContext, ResolvedDebugConfiguration } from "../DebugHelper"; +import { resolveVariables, unresolveWorkspaceFolder } from "../../utils/resolveVariables"; +import { DockerDebugContext, DockerDebugScaffoldContext, ResolvedDebugConfiguration, inferContainerName } from "../DebugHelper"; import { DockerDebugConfiguration } from "../DockerDebugConfigurationProvider"; import { NetCoreDebugHelper, NetCoreDebugScaffoldingOptions, NetCoreProjectProperties } from "../netcore/NetCoreDebugHelper"; export interface NetSdkProjectProperties extends NetCoreProjectProperties { containerWorkingDirectory: string; isSdkContainerSupportEnabled: boolean; - containerName: string; + imageName: string; } export class NetSdkDebugHelper extends NetCoreDebugHelper { - protected projectProperties: NetSdkProjectProperties | undefined; - public override async provideDebugConfigurations(context: DockerDebugScaffoldContext, options?: NetCoreDebugScaffoldingOptions): Promise { const configurations: DockerDebugConfiguration[] = []; @@ -70,13 +67,12 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { } public async afterResolveDebugConfiguration(context: DockerDebugContext, debugConfiguration: DockerDebugConfiguration): Promise { - const projectInfo = await this.getProjectProperties(debugConfiguration); const runDefinition: Omit = { netCore: { appProject: debugConfiguration?.netCore?.appProject || await this.inferProjPath(context.actionContext, context.folder), }, dockerRun: { - containerName: projectInfo.containerName + image: context.runDefinition.dockerRun.image, } }; @@ -85,25 +81,23 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { await promise; } - protected override async inferAppOutput(debugConfiguration: DockerDebugConfiguration): Promise { - const projectInfo = await this.getProjectProperties(debugConfiguration); - - // fifth is whether .NET Web apps supports SDK Containers - if (projectInfo.isSdkContainerSupportEnabled) { - return await getDockerOSType() === 'windows' // fourth is output path - ? path.win32.normalize(projectInfo.containerWorkingDirectory) - : path.posix.normalize(projectInfo.containerWorkingDirectory); - } else { - throw new Error(l10n.t("Your current project configuration or .NET SDK version doesn't support SDK Container build. Please choose a compatible project or update .NET SDK.")); - } - } - protected override async loadExternalInfo(context: DockerDebugContext, debugConfiguration: DockerDebugConfiguration): Promise<{ configureSsl: boolean, containerName: string, platformOS: PlatformOS }> { - const associatedTask = context.runDefinition; - const projectInfo = await this.getProjectProperties(debugConfiguration); + const projectProperties = await this.getProjectProperties(debugConfiguration, context.folder); + debugConfiguration.netCore.appOutput = await this.normalizeAppOutput(projectProperties.containerWorkingDirectory, projectProperties.isSdkContainerSupportEnabled); + context.runDefinition = { + ...context.runDefinition, + dockerRun: { + containerName: inferContainerName(debugConfiguration, context, projectProperties.imageName, "dev"), + image: projectProperties.imageName, + }, + netCore: { + enableDebugging: true, + } + }; + return { - configureSsl: !!(associatedTask?.netCore?.configureSsl), - containerName: getContainerNameWithTag(projectInfo.containerName, "dev"), + configureSsl: false, + containerName: context.runDefinition.dockerRun.containerName, platformOS: await getDockerOSType() === "windows" ? 'Windows' : 'Linux', }; } @@ -112,16 +106,13 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { return appOutput; } - protected override async getProjectProperties(debugConfiguration: DockerDebugConfiguration): Promise { - if (this.projectProperties) { - return this.projectProperties; - } - + protected override async getProjectProperties(debugConfiguration: DockerDebugConfiguration, folder?: WorkspaceFolder): Promise { const ridOS = await normalizeOsToRidOs(); const ridArchitecture = await normalizeArchitectureToRidArchitecture(); const additionalProperties = `/p:ContainerRuntimeIdentifier="${ridOS}-${ridArchitecture}"`; + const resolvedAppProject = resolveVariables(debugConfiguration.netCore?.appProject, folder); - const projectInfo = await getNetCoreProjectInfo('GetProjectProperties', debugConfiguration.netCore?.appProject, additionalProperties); + const projectInfo = await getNetCoreProjectInfo('GetProjectProperties', resolvedAppProject, additionalProperties); if (projectInfo.length < 6 || !projectInfo[5]) { throw new Error(l10n.t("Your current project configuration or .NET SDK version doesn't support SDK Container build. Please choose a compatible project or update .NET SDK.")); @@ -133,13 +124,22 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { appOutput: projectInfo[2], containerWorkingDirectory: projectInfo[3], isSdkContainerSupportEnabled: projectInfo[4] === 'true', - containerName: projectInfo[5], + imageName: projectInfo[5], }; - this.projectProperties = projectProperties; return projectProperties; } + private async normalizeAppOutput(unnormalizedContainerWorkingDirectory: string, isSdkContainerSupportEnabled: boolean): Promise { + if (isSdkContainerSupportEnabled) { + return await getDockerOSType() === 'windows' // fourth is output path + ? path.win32.normalize(unnormalizedContainerWorkingDirectory) + : path.posix.normalize(unnormalizedContainerWorkingDirectory); + } else { + throw new Error(l10n.t("Your current project configuration or .NET SDK version doesn't support SDK Container build. Please choose a compatible project or update .NET SDK.")); + } + } + /** * @returns the project path stored in NetCoreDebugScaffoldingOptions, * otherwise prompts the user to select a .csproj file and stores the path diff --git a/src/debugging/netcore/NetCoreDebugHelper.ts b/src/debugging/netcore/NetCoreDebugHelper.ts index 438f460052..096de6d3dd 100644 --- a/src/debugging/netcore/NetCoreDebugHelper.ts +++ b/src/debugging/netcore/NetCoreDebugHelper.ts @@ -43,8 +43,6 @@ export interface NetCoreProjectProperties { export class NetCoreDebugHelper implements DebugHelper { - protected projectProperties: NetCoreProjectProperties | undefined; - public async provideDebugConfigurations(context: DockerDebugScaffoldContext, options?: NetCoreDebugScaffoldingOptions): Promise { options = options || {}; options.appProject = options.appProject || await NetCoreTaskHelper.inferAppProject(context); // This method internally checks the user-defined input first @@ -210,10 +208,6 @@ export class NetCoreDebugHelper implements DebugHelper { } protected async getProjectProperties(debugConfiguration: DockerDebugConfiguration): Promise { - if (this.projectProperties) { - return this.projectProperties; - } - const projectInfo = await getNetCoreProjectInfo('GetProjectProperties', debugConfiguration.netCore?.appProject); if (projectInfo.length < 3) { @@ -227,7 +221,6 @@ export class NetCoreDebugHelper implements DebugHelper { appOutput: projectInfo[2] }; - this.projectProperties = projectProperties; return projectProperties; } diff --git a/src/tasks/TaskHelper.ts b/src/tasks/TaskHelper.ts index bd60e1d2e7..b68d5d5998 100644 --- a/src/tasks/TaskHelper.ts +++ b/src/tasks/TaskHelper.ts @@ -210,11 +210,7 @@ export function getDefaultImageName(nameHint: string, tag?: 'dev' | 'latest'): s export function getDefaultContainerName(nameHint: string, tag?: 'dev' | 'latest'): string { tag = tag || 'dev'; - return getContainerNameWithTag(getValidImageName(nameHint), tag); -} - -export function getContainerNameWithTag(name: string, tag: string): string { - return `${name}-${tag}`; + return `${getValidImageName(nameHint)}-${tag}`; } export async function recursiveFindTaskByType(allTasks: TaskDefinitionBase[], type: string, node: DebugConfigurationBase | TaskDefinitionBase): Promise { diff --git a/src/tasks/netSdk/NetSdkRunTaskProvider.ts b/src/tasks/netSdk/NetSdkRunTaskProvider.ts index 6383a415ef..a65c488962 100644 --- a/src/tasks/netSdk/NetSdkRunTaskProvider.ts +++ b/src/tasks/netSdk/NetSdkRunTaskProvider.ts @@ -30,7 +30,7 @@ export class NetSdkRunTaskProvider extends DockerTaskProvider { const projectFolderPath = path.dirname(projectPath); // use dotnet to build the image - const buildCommand = await getNetSdkBuildCommand(isProjectWebApp, task.definition.dockerRun.containerName); + const buildCommand = await getNetSdkBuildCommand(isProjectWebApp, task.definition.dockerRun.image); await context.terminal.execAsyncInTerminal( buildCommand, { @@ -41,7 +41,7 @@ export class NetSdkRunTaskProvider extends DockerTaskProvider { ); // use docker run to run the image - const runCommand = await getNetSdkRunCommand(isProjectWebApp, task.definition.dockerRun.containerName); + const runCommand = await getNetSdkRunCommand(isProjectWebApp, task.definition.dockerRun.image); await context.terminal.execAsyncInTerminal( runCommand, { diff --git a/src/tasks/netSdk/netSdkTaskUtils.ts b/src/tasks/netSdk/netSdkTaskUtils.ts index b9001a7a62..f6bba49d90 100644 --- a/src/tasks/netSdk/netSdkTaskUtils.ts +++ b/src/tasks/netSdk/netSdkTaskUtils.ts @@ -10,7 +10,7 @@ import { RunContainerBindMount, RunContainerCommandOptions, Shell, composeArgs, import { getImageNameWithTag } from '../../utils/getValidImageName'; import { getDockerOSType } from "../../utils/osUtils"; import { defaultVsCodeLabels } from "../TaskDefinitionBase"; -import { getContainerNameWithTag } from '../TaskHelper'; +import { getDefaultContainerName } from '../TaskHelper'; /** * Native architecture of the current machine in the RID format @@ -57,7 +57,7 @@ export async function getNetSdkRunCommand(isProjectWebApp: boolean, imageName: s const options: RunContainerCommandOptions = { detached: true, publishAllPorts: true, - name: getContainerNameWithTag(imageName, NetSdkDefaultImageTag), + name: getDefaultContainerName(imageName, NetSdkDefaultImageTag), environmentVariables: {}, removeOnExit: true, imageRef: getImageNameWithTag(imageName, NetSdkDefaultImageTag), From 20d2c1e7abdf8117dc8abe68ea88e60ac65ea98e Mon Sep 17 00:00:00 2001 From: alexyaang <59073590+alexyaang@users.noreply.github.com> Date: Tue, 11 Jul 2023 15:01:25 -0400 Subject: [PATCH 14/15] remove ContainerImageName arg since we're relying on msbuild --- src/debugging/netcore/NetCoreDebugHelper.ts | 1 - src/tasks/netSdk/netSdkTaskUtils.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/src/debugging/netcore/NetCoreDebugHelper.ts b/src/debugging/netcore/NetCoreDebugHelper.ts index 096de6d3dd..e97ccf96c4 100644 --- a/src/debugging/netcore/NetCoreDebugHelper.ts +++ b/src/debugging/netcore/NetCoreDebugHelper.ts @@ -42,7 +42,6 @@ export interface NetCoreProjectProperties { } export class NetCoreDebugHelper implements DebugHelper { - public async provideDebugConfigurations(context: DockerDebugScaffoldContext, options?: NetCoreDebugScaffoldingOptions): Promise { options = options || {}; options.appProject = options.appProject || await NetCoreTaskHelper.inferAppProject(context); // This method internally checks the user-defined input first diff --git a/src/tasks/netSdk/netSdkTaskUtils.ts b/src/tasks/netSdk/netSdkTaskUtils.ts index f6bba49d90..55add09994 100644 --- a/src/tasks/netSdk/netSdkTaskUtils.ts +++ b/src/tasks/netSdk/netSdkTaskUtils.ts @@ -43,7 +43,6 @@ export async function getNetSdkBuildCommand(isProjectWebApp: boolean, imageName: withNamedArg('--arch', await normalizeArchitectureToRidArchitecture()), withArg(publishFlag), withNamedArg('--configuration', configuration), - withNamedArg('-p:ContainerImageName', imageName, { assignValue: true }), withNamedArg('-p:ContainerImageTag', NetSdkDefaultImageTag, { assignValue: true }) )(); From 7e4575072071a120e923ae8d2c087448fad28591 Mon Sep 17 00:00:00 2001 From: alexyaang <59073590+alexyaang@users.noreply.github.com> Date: Tue, 11 Jul 2023 15:14:52 -0400 Subject: [PATCH 15/15] removed inferProjPath as it's unnecessary --- src/debugging/netSdk/NetSdkDebugHelper.ts | 24 +++++++---------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/debugging/netSdk/NetSdkDebugHelper.ts b/src/debugging/netSdk/NetSdkDebugHelper.ts index 6132f39654..fccbd78076 100644 --- a/src/debugging/netSdk/NetSdkDebugHelper.ts +++ b/src/debugging/netSdk/NetSdkDebugHelper.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See LICENSE.md in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IActionContext } from "@microsoft/vscode-azext-utils"; import * as path from "path"; import { WorkspaceFolder, commands, l10n, tasks } from "vscode"; import { ext } from "../../extensionVariables"; @@ -11,16 +10,16 @@ import { NetChooseBuildTypeContext, netContainerBuild } from "../../scaffolding/ import { AllNetContainerBuildOptions, NetContainerBuildOptionsKey } from "../../scaffolding/wizard/net/NetSdkChooseBuildStep"; import { NetSdkRunTaskDefinition, netSdkRunTaskProvider } from "../../tasks/netSdk/NetSdkRunTaskProvider"; import { normalizeArchitectureToRidArchitecture, normalizeOsToRidOs } from "../../tasks/netSdk/netSdkTaskUtils"; +import { NetCoreTaskHelper } from "../../tasks/netcore/NetCoreTaskHelper"; import { getNetCoreProjectInfo } from "../../utils/netCoreUtils"; import { getDockerOSType } from "../../utils/osUtils"; import { PlatformOS } from "../../utils/platform"; -import { quickPickProjectFileItem } from "../../utils/quickPickFile"; import { resolveVariables, unresolveWorkspaceFolder } from "../../utils/resolveVariables"; import { DockerDebugContext, DockerDebugScaffoldContext, ResolvedDebugConfiguration, inferContainerName } from "../DebugHelper"; import { DockerDebugConfiguration } from "../DockerDebugConfigurationProvider"; import { NetCoreDebugHelper, NetCoreDebugScaffoldingOptions, NetCoreProjectProperties } from "../netcore/NetCoreDebugHelper"; -export interface NetSdkProjectProperties extends NetCoreProjectProperties { +interface NetSdkProjectProperties extends NetCoreProjectProperties { containerWorkingDirectory: string; isSdkContainerSupportEnabled: boolean; imageName: string; @@ -37,16 +36,17 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { workspaceFolder: context.folder, }; - await netContainerBuild(netCoreBuildContext); + await netContainerBuild(netCoreBuildContext); // prompt user whether to use .NET container SDK build if (netCoreBuildContext?.containerBuildOptions === AllNetContainerBuildOptions[1]) { - const appProjectAbsolutePath = options?.appProject || await this.inferProjPath(context.actionContext, context.folder); + options = options || {}; + options.appProject = options.appProject || await NetCoreTaskHelper.inferAppProject(context); // This method internally checks the user-defined input first configurations.push({ name: 'Docker .NET Container SDK Launch', type: 'docker', request: 'launch', netCore: { - appProject: unresolveWorkspaceFolder(appProjectAbsolutePath, context.folder), + appProject: unresolveWorkspaceFolder(options.appProject, context.folder), buildWithSdk: true, }, }); @@ -69,7 +69,7 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { public async afterResolveDebugConfiguration(context: DockerDebugContext, debugConfiguration: DockerDebugConfiguration): Promise { const runDefinition: Omit = { netCore: { - appProject: debugConfiguration?.netCore?.appProject || await this.inferProjPath(context.actionContext, context.folder), + appProject: debugConfiguration.netCore.appProject, }, dockerRun: { image: context.runDefinition.dockerRun.image, @@ -139,16 +139,6 @@ export class NetSdkDebugHelper extends NetCoreDebugHelper { throw new Error(l10n.t("Your current project configuration or .NET SDK version doesn't support SDK Container build. Please choose a compatible project or update .NET SDK.")); } } - - /** - * @returns the project path stored in NetCoreDebugScaffoldingOptions, - * otherwise prompts the user to select a .csproj file and stores the path - * in the static variable projPath - */ - private async inferProjPath(actionContext: IActionContext, folder: WorkspaceFolder): Promise { - const projFileItem = await quickPickProjectFileItem(actionContext, undefined, folder, 'No project file could be found.'); - return projFileItem.absoluteFilePath; - } } export const netSdkDebugHelper = new NetSdkDebugHelper();