microsoft / microsoft/vscode-containers

Unable to build using multi-root workspace

Open
#101 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

.NET
Dominant language
TypeScript
Stars
139
Forks
87
Avg merge
9h 15m
Merged PRs (30d)
9

Description

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:
    }
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/utils/resolveVariables.ts at the workspace folder variable switch, then inspect the workspace API used by the extension. Reproduce the issue with the multi-root .code-workspace, launch configuration, and tasks shown in the report. Done means ${workspaceFolder:web} resolves to the named folder path before the dotnet command executes.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, typescript
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.