dotnet-installer/test/dotnet-msbuild.Tests/GivenDotnetStoreInvocation.cs
Peter Huene f9b939fe89
Fix MSBuild invocation to quote property option values.
This commit ensures that any `/property` option's value is surrounded by quotes
to allow MSBuild to properly interpret special characters like semicolons.

Users familiar with MSBuild expect `/property:Name="Value"` to handle
semicolons. However, since `dotnet` parses the command line first, the
quotes get processed by its command line parser.  This results in
`/property:Name=Value` being passed to MSBuild, which will not parse a "Value"
containing a semicolon correctly.

Since it is safe to always quote the property value for this option, this fix
simply ensures that the value is surrounded by quotes.

This fixes the issue for all commands that forward arguments to MSBuild.

Fixes #7791.
2018-04-26 14:38:21 -07:00

57 lines
2.6 KiB
C#

// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using FluentAssertions;
using Microsoft.DotNet.Tools.Store;
using System.IO;
using System.Linq;
using Xunit;
namespace Microsoft.DotNet.Cli.MSBuild.Tests
{
public class GivenDotnetStoreInvocation
{
const string ExpectedPrefix = "exec <msbuildpath> -maxcpucount -verbosity:m -target:ComposeStore <project>";
static readonly string[] ArgsPrefix = { "--manifest", "<project>" };
[Theory]
[InlineData("-m")]
[InlineData("--manifest")]
public void ItAddsProjectToMsbuildInvocation(string optionName)
{
var msbuildPath = "<msbuildpath>";
string[] args = new string[] { optionName, "<project>" };
StoreCommand.FromArgs(args, msbuildPath)
.GetProcessStartInfo().Arguments.Should().Be($"{ExpectedPrefix}");
}
[Theory]
[InlineData(new string[] { "-f", "<tfm>" }, @"-property:TargetFramework=\""<tfm>\""")]
[InlineData(new string[] { "--framework", "<tfm>" }, @"-property:TargetFramework=\""<tfm>\""")]
[InlineData(new string[] { "-r", "<rid>" }, @"-property:RuntimeIdentifier=\""<rid>\""")]
[InlineData(new string[] { "--runtime", "<rid>" }, @"-property:RuntimeIdentifier=\""<rid>\""")]
[InlineData(new string[] { "--manifest", "one.xml", "--manifest", "two.xml", "--manifest", "three.xml" }, @"-property:AdditionalProjects=\""one.xml%3Btwo.xml%3Bthree.xml\""")]
public void MsbuildInvocationIsCorrect(string[] args, string expectedAdditionalArgs)
{
args = ArgsPrefix.Concat(args).ToArray();
expectedAdditionalArgs = (string.IsNullOrEmpty(expectedAdditionalArgs) ? "" : $" {expectedAdditionalArgs}");
var msbuildPath = "<msbuildpath>";
StoreCommand.FromArgs(args, msbuildPath)
.GetProcessStartInfo().Arguments.Should().Be($"{ExpectedPrefix}{expectedAdditionalArgs}");
}
[Theory]
[InlineData("-o")]
[InlineData("--output")]
public void ItAddsOutputPathToMsBuildInvocation(string optionName)
{
string path = "/some/path";
var args = ArgsPrefix.Concat(new string[] { optionName, path }).ToArray();
var msbuildPath = "<msbuildpath>";
StoreCommand.FromArgs(args, msbuildPath)
.GetProcessStartInfo().Arguments.Should().Be($"{ExpectedPrefix} -property:ComposeDir=\\\"{Path.GetFullPath(path)}\\\"");
}
}
}