formulahendry / vscode-dotnet-test-explorer

.NET Core Test Explorer for Visual Studio Code

Home Page:https://marketplace.visualstudio.com/items?itemName=formulahendry.dotnet-test-explorer

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Project discovery with UNC Paths doesn't work (and workaround)

VisualMelon opened this issue · comments

VS Code 1.30.2, Windows 10

Project discovery doesn't work with UNC file paths. It seems this is a consequence of issues with node-glob and executing via child_process, because it uses a shell, and cmd dislikes UNC paths.

If the workspace has a UNC path, and you set the testProjectPath setting to something (e.g. "*/*.csproj"), then it fails, with node-glob returning nothing. Stuffing some code into TestDirectories.parseTestDirectories to change how it handles UNC resolves this issue. The next problem comes in testDiscovery.js, function executeDotnetTest, which tries to pass this UNC path to child_process.exec as the working directory; it seems that the working directoy is not ultimately set (I think this is CMD's fault), as the dotnet process complains it can't find a project (MSB1003), even when one exists (and compiles, etc. same code on a non-UNC path works).

I can't find much information about child_process support for UNC, but it seems that exec runs in a shell, and the shell (CMD) is swallowing the UNC path before defaulting to C:\Windows. It seems this can be worked around by calling through powershell (alternatively, the csproj could be detected manually and full address provided). This issue of course applies to all calls that go through Executor.exec.

The workaround is as follows, making 2 changes to files in formulahendry.dotnet-test-explorer-0.6.1\out\src.

Code to fix UNC in TestDirectories.cs (might have side-effects I've not noticed):

let isUnc = globPattern.startsWith("\\\\");
if (isUnc)
{
    const partialPaths = glob.sync(testDirectoryGlob, {cwd: folder.uri.fsPath});
    const matchingDirsForWorkspaceFolder = partialPaths.map(x => folder.uri.fsPath + "/" + x);
    
    matchingDirs.push(...matchingDirsForWorkspaceFolder);
    logger_1.Logger.Log(`Found ${matchingDirsForWorkspaceFolder.length} matches for pattern in folder ${folder.uri.fsPath}`);
}
else
{
    const matchingDirsForWorkspaceFolder = glob.sync(globPattern);
    
    matchingDirs.push(...matchingDirsForWorkspaceFolder);
    logger_1.Logger.Log(`Found ${matchingDirsForWorkspaceFolder.length} matches for pattern in folder ${folder.uri.fsPath}`);
}

Escaping the quotes and passing commands through powershell in executor.js seems to make everything work thereafter:

command = command.replace(/\"/g, "\\\"");
command = `powershell -command "cd '${cwd}'; ${command} | ft"`;

Hey! Thanks for reporting and also for suggesting fixes, much appreciated 👍

Historically we're wary when adding os/shell specific changes and making assumptions on shell availability (although assuming that a windows uses has powershell might be a safe bet).

IIRC, is there not a way to map a UNC path to a drive in windows? Have you tried if that works? I realize it might not be a good enough workaround for you, I'm just curious if that works.

Historically we're wary when adding os/shell specific changes and making assumptions on shell availability (although assuming that a windows uses has powershell might be a safe bet).

Absolutely: the PowerShell 'workaround' is just that; certainly not shippable.

IIRC, is there not a way to map a UNC path to a drive in windows? Have you tried if that works? I realize it might not be a good enough workaround for you, I'm just curious if that works.

Yep, that does seem to work.

I'm adding this to "known issues" and closing this.