5

Closed

mono xbuild packages don't restore

description

Under nuget 2.5, using xbuild (Mono 3.0.6 OSX) doesn't restore packages because of an extra space found on line 54 in the NuGet.targets file:

<RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir "$(SolutionDir) " </RestoreCommand>

The extra space is found here "$(SolutionDir) ". By removing the extra space such that it looks like "$(SolutionDir)", the package build process works perfectly.

This is very easy to fix in any repositories where the NuGet.targets file is already committed, but would be overwritten when pointing to a newer release of NuGet.
Closed Aug 13, 2013 at 6:15 PM by dotnetjunky
This is a dupe of #3278 and has been fixed in 2.7

comments

jonathansoliver wrote May 8, 2013 at 3:46 PM

This one's a nasty little one. The extra space is necessary on Windows for some crazy reason and NuGet returns an error on Windows if it's not there, but on Mac/Linux the extra space is actually considered to be a directory " " because it's not escaped. Weird. The best solution I have found is to create a variable based upon the OS condition and then provide that variable to command like so:
<SolutionDirParsed Condition=" '$(OS)' == 'Windows_NT' ">$(SolutionDir) </SolutionDirParsed>
<SolutionDirParsed Condition=" '$(OS)' != 'Windows_NT' ">$(SolutionDir)</SolutionDirParsed>
<RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)"  $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir "$(SolutionDirParsed)" </RestoreCommand>

mrdavidlaing wrote Jun 10, 2013 at 3:05 PM

knocte wrote Jun 19, 2013 at 10:16 PM

@jonathansoliver: can you elaborate on the "crazy reason"? What happens when the space is not there in Windows?

I also don't understand how the trailing space would be considered an extra directory in Linux/Mac.

jonathansoliver wrote Jun 20, 2013 at 3:23 AM

@knocte Without the extra space on Windows, the msbuild command fails, whereas it succeeds when the space is present. Conversely, in POSIX-based environments the space after the end of the $(SolutionDir) causes the build to fail, whereas removing it allows the build to succeed. I haven't dug into the source code of NuGet deep enough to understand why the extra space is significant on Windows-based builds. Ideally, the extra space should be removed from the NuGet.targets file, but the NuGet code would have to be updated to understand and handle the difference. The above code works around the issue for the time being and allows those wishing to perform a build on Mono to continue.

knocte wrote Jun 20, 2013 at 7:51 AM

"Without the extra space on Windows, the msbuild command fails, whereas it succeeds when the space is present. Conversely, in POSIX-based environments the space after the end of the $(SolutionDir) causes the build to fail, whereas removing it allows the build to succeed."

I think that was very clear already.

"The above code works around the issue for the time being and allows those wishing to perform a build on Mono to continue."

The workaround is very clear already too.

I'm just asking for more details because I'm interested in fixing the root cause (if that involves changing Nuget source code, I don't mind).

jonathansoliver wrote Jun 20, 2013 at 2:10 PM

If I remove the extra space on Windows, here's the exact error I get from MSBuild:
C:\projects\hydrospanner\src\Hydrospanner.sln" (default target) (1) ->
C:\projects\hydrospanner\src\Hydrospanner\Hydrospanner.csproj" (default target) (2) ->
RestorePackages target) ->
 C:\projects\hydrospanner\src\.nuget\NuGet.targets(92,9): error : Illegal characters in path. [C:\projects\hydrospanner\src\Hydrospannr\Hydrospanner.csproj]
 C:\projects\hydrospanner\src\.nuget\NuGet.targets(92,9): error MSB3073: The command ""C:\projects\hydrospanner\src\.nuget\NuGet.exe" install "C:\projects\hydrospanner\src\Hydrospanner\packages.config" -source ""  -NonInteractive -RequireConsent -solutionDir "C:\dev\publc\hydrospanner\src\" " exited with code 1. [C:\projects\hydrospanner\src\Hydrospanner\Hydrospanner.csproj]
Simply re-adding the trailing space after $(SolutionDir) solves the problem.

On Mono, if the space character is present following $(SolutionDir), it gives the following error:
/Volumes/C/projects/hydrospanner/src/Hydrospanner.sln (default targets) ->
(Build target) ->
/Volumes/C/projects/hydrospanner/src/Hydrospanner/Hydrospanner.csproj (default targets) ->
/Volumes/C/projects/hydrospanner/src/.nuget/NuGet.targets (RestorePackages target) ->

    /Volumes/C/projects/hydrospanner/src/.nuget/NuGet.targets: error : Command 'mono --runtime=v4.0.30319 /Volumes/C/projects/hydrospanner/src/.nuget/NuGet.exe install "packages.config" -source ""   -RequireConsent -solutionDir "/Volumes/C/projects/hydrospanner/src/ " ' exited with code: 1.
Notice how on POSIX-based systems, when you ask for a path which includes a trailing space, the path name must exist as an entry in the file system table with the space. There's no automatic trimming to help things along like Windows does. In Windows Explorer, if you ever create a filename with a leading or trailing space, it will automatically trim that space character, in Linux/OSX, they've given you enough rope to hang yourself if you decide to do that.

If you would like to send over patches, etc. for me to test in either environment, I'm more than happy to do so. Otherwise, VirtualBox is your friend.