microsoft / vscode-docker

Docker Extension for Visual Studio Code
https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker
Other
1.22k stars 518 forks source link

Unable to build using multi-root workspace #4405

Open villecoder opened 1 month ago

villecoder commented 1 month ago

Summary

A folder in a multi-root workspace is not being resolved to the actual folder. As such, the GetProjectProperties target fails when building with dotnet.

Environment: PopOS! 22.04

Expected Behavior

${workspaceFolder:[name]}/file is replaced with [path to folder]/file before executing command dotnet build /r:false ...

Actual result

The dotnet build command executes without substitution. The command executed is dotnet build r:/false ... ${workspaceFolder:[name]}/file.

Details

I'm using a .code-workspace file to share my debugging setup with my colleagues. I'm using this because our project is structured as a monorepo, and shared libraries are located a folder or two above the current working directory. I'm unable to kick off a debug task. I receive the following error: Unable to determine project information for target 'GetProjectProperties on project ${workspaceFolder:web}/back-end/WebProject.csproj. Process exited with code 2.

Here's my setup. Note: folder paths and project names have been changed due to confidentiality.

I define the multi root workspace as:

"folders": [
    {
        "path": "./",
        "name": "web"
    },
    {
        "path": "../../lib1",
        "name": "lib1",
    },
    {
        "path": "../../lib2",
        "name": "lib2"
    },
    {
        "path": "../../lib3",
        "name": "lib3"
    }
]

I define a launch configuration as:

    "launch": {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "Debug using Docker",
                "type": "docker",
                "request": "launch",
                "preLaunchTask": "docker-run: debug",
                "platform": "netCore",
                "removeContainerAfterDebug": true,
                "netCore": {
                    "appProject": "${workspaceFolder:web}/back-end/WebProject.csproj"
                }
            }
        ]
    },

And I define my build and launch tasks:

"tasks": {
  "version": "2.0.0",
  "tasks": [
      {
          "type": "docker-run",
          "label": "docker-run: debug",
          "dependsOn": [
              "docker-build: debug"
          ],
          "dockerRun": {
              "env": {
                  "DOTNET_ENVIRONMENT": "Development",
                  "ASPNETCORE_ENVIRONMENT": "Development",
                  "ASPNETCORE_URLS": "http://*:5010",
              },
              "network": "local_external_network",
              "ports": [
                  {
                      "containerPort": 5010,
                      "hostPort": 5010,
                      "protocol": "tcp"
                  }
              ],
              "volumes": [
                  {
                      "localPath": "${workspaceFolder:web}/.local/debug/",
                      "containerPath": "/var/lib/folder/",
                      "permissions": "rw"
                  }
              ]
          },
          "netCore": {
              "appProject": "${workspaceFolder:web}/back-end/Web.csproj",
              "enableDebugging": true
          }
      },
      {
          "type": "docker-build",
          "label": "docker-build: debug",
          "dependsOn": [
              "build: docker-debug"
          ],
          "dockerBuild": {
              "tag": "web:dev",
              "target": "final",
              "dockerfile": "${workspaceFolder:web}/back-end/Dockerfile",
              "context": "${workspaceFolder:web}/../..",
              "pull": true
          },
          "netCore": {
              "appProject": "${workspaceFolder:web}/back-end/Web.csproj",
              "enableDebugging": true
          }
      },
      {
          "label": "build: docker-debug",
          "command": "dotnet",
          "type": "process",
          "args": [
              "build",
              "${workspaceFolder:web}/Web.sln",
              "/property:GenerateFullPaths=true",
              "/consoleloggerparameters:NoSummary;ForceNoAlign",
              "/p:Debug=true",
              "/p:Docker=true"
          ],
          "problemMatcher": "$msCompile"
      },
  ]
},

I went down the rabbit hole and I think the issue lies in src/utils/resolveVariables.ts. In it, there's a hard-coded if condition that's replacing the string ${workspaceFolder} instead of using the workspace API. Reproduced here:

// Starting at Line 40...
// Replace workspace folder variables
if (folder) {
    switch (variable) {
        case '${workspaceFolder}':
        case '${workspaceRoot}':
            return path.normalize(folder.uri.fsPath);
        case '${userHome}':
            return os.homedir();
        case '${relativeFile}':
            return path.relative(path.normalize(folder.uri.fsPath), getActiveFilePath());
        default:
    }
}
bwateratmsft commented 4 weeks ago

I absolutely love bug reports with this much information :smile:

Thank you! We'll take a look.