Msbuild: MSBuild command parser confused by Fully Qualified Path to proj files in Linux root

Created on 21 Mar 2017  路  6Comments  路  Source: dotnet/msbuild

Steps to reproduce

On a linux machine, with root access:

  • cd /
  • dotnet new console
  • dotnet restore
  • dotnet msbuild /.csproj

Expected behavior

App builds

Actual behavior

MSBUILD : error MSB1001: Unknown switch.
Switch: /.csproj

For switch syntax, type "MSBuild /help"

The build failed. Please fix the build errors and run again.

Investigation

This is related to https://github.com/dotnet/templating/issues/454 and https://github.com/dotnet/cli/issues/6092

When creating a new project in root, the resultant csproj file gets named .csproj. This likely gets passed to MSBuld as /.csproj which, in turn, is interpreted as a parameter name [MSBuild parameters tend to be named /{some string}.

Though the CLI's new experience is likely not right, /.csproj looks like a perfectly valid fully-qualified file path on Linux.

Important

Furthermore, the same issue repros even if the csproj file has a name, e.g. foo.csproj so long as it is in the root. Specifically, dotnet msbuild /foo.csproj fails. The fully qualified path can only be passed in if the file resides in a subdirectory of root, not root directly.

Environment data

dotnet --info output:

.NET Command Line Tools (1.0.1)

Product Information:
 Version:            1.0.1
 Commit SHA-1 hash:  005db40cd1

Runtime Environment:
 OS Name:     debian
 OS Version:  8
 OS Platform: Linux
 RID:         debian.8-x64
 Base Path:   /usr/share/dotnet/sdk/1.0.1
bug up-for-grabs

Most helpful comment

Just for anyone coming across this issue from docker build, I manage to fix it my docker build by changing my Dockerfile line from:

 RUN dotnet restore src-identityserver.csproj

to

RUN dotnet restore ./src-identityserver.csproj

Seem to be enough to make MSBuild pick it up correctly and build the container.

All 6 comments

We actually have special magic to determine if a /-prefixed parameter is a path: https://github.com/Microsoft/msbuild/blob/c698d39bb389177224b2b3ff69155b51f3bd8d66/src/MSBuild/XMake.cs#L1420-L1421

Looks like the problem here is that LooksLikeUnixFilePath assumes that it's not in the root: it checks whether the first element is a directory that exists. In this case it's a file that exists.

You should be able to work around this if you're dealing with it manually by doing something like dotnet msbuild /src/../.csproj.

yep, I figured out that subdirectories work. However, the root directory issue should be looked at. It looks like docker containers typically start users out in the root of the container. I created a microsoft/dotnet container, ran dotnet new, and ended up with a broken project.

Sounds reasonable and should be a small, scoped change.

Does it make sense to ask the template engine to not create project in the root directory? (without a --force maybe)
Feels somehow dangerous to have the default globs search the entire container..

@patros fixed this for MSBuild (thanks!), but I think @dasMulli's point about accidentally globbing _the entire filesystem_ when building is a good one. @livarcocc that's worth considering as a feature in CLI.

Just for anyone coming across this issue from docker build, I manage to fix it my docker build by changing my Dockerfile line from:

 RUN dotnet restore src-identityserver.csproj

to

RUN dotnet restore ./src-identityserver.csproj

Seem to be enough to make MSBuild pick it up correctly and build the container.

Was this page helpful?
0 / 5 - 0 ratings