From f9b939fe8996210666f4740d16e997081023bb23 Mon Sep 17 00:00:00 2001 From: Peter Huene Date: Thu, 26 Apr 2018 10:53:54 -0700 Subject: [PATCH] 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. --- .../ProjectPrintsNoWarn.csproj | 12 +++++ .../ArgumentEscaper.cs | 20 +++------ .../MSBuildForwardingAppWithoutLogging.cs | 44 +++++++++++++------ src/dotnet/commands/dotnet-test/Program.cs | 13 ------ .../GivenDotnetBuildInvocation.cs | 28 ++++++------ .../GivenDotnetCleanInvocation.cs | 12 ++--- .../GivenDotnetMSBuildBuildsProjects.cs | 20 +++++++++ .../GivenDotnetPackInvocation.cs | 20 ++++----- .../GivenDotnetPublishInvocation.cs | 22 +++++----- .../GivenDotnetRestoreInvocation.cs | 24 +++++----- .../GivenDotnetStoreInvocation.cs | 12 ++--- 11 files changed, 128 insertions(+), 99 deletions(-) create mode 100644 TestAssets/TestProjects/ProjectPrintsNoWarn/ProjectPrintsNoWarn.csproj diff --git a/TestAssets/TestProjects/ProjectPrintsNoWarn/ProjectPrintsNoWarn.csproj b/TestAssets/TestProjects/ProjectPrintsNoWarn/ProjectPrintsNoWarn.csproj new file mode 100644 index 000000000..4e83f2fad --- /dev/null +++ b/TestAssets/TestProjects/ProjectPrintsNoWarn/ProjectPrintsNoWarn.csproj @@ -0,0 +1,12 @@ + + + + library + netcoreapp2.0 + + + + + + + diff --git a/src/Microsoft.DotNet.Cli.Utils/ArgumentEscaper.cs b/src/Microsoft.DotNet.Cli.Utils/ArgumentEscaper.cs index afaa58d48..c87268c00 100644 --- a/src/Microsoft.DotNet.Cli.Utils/ArgumentEscaper.cs +++ b/src/Microsoft.DotNet.Cli.Utils/ArgumentEscaper.cs @@ -59,14 +59,10 @@ namespace Microsoft.DotNet.Cli.Utils /// private static IEnumerable EscapeArgArray(IEnumerable args) { - var escapedArgs = new List(); - foreach (var arg in args) { - escapedArgs.Add(EscapeSingleArg(arg)); + yield return EscapeSingleArg(arg); } - - return escapedArgs; } /// @@ -79,23 +75,19 @@ namespace Microsoft.DotNet.Cli.Utils /// /// /// - private static IEnumerable EscapeArgArrayForCmd(IEnumerable arguments) + private static IEnumerable EscapeArgArrayForCmd(IEnumerable args) { - var escapedArgs = new List(); - - foreach (var arg in arguments) + foreach (var arg in args) { - escapedArgs.Add(EscapeArgForCmd(arg)); + yield return EscapeArgForCmd(arg); } - - return escapedArgs; } - public static string EscapeSingleArg(string arg) + public static string EscapeSingleArg(string arg, bool forceQuotes = false) { var sb = new StringBuilder(); - var needsQuotes = ShouldSurroundWithQuotes(arg); + var needsQuotes = forceQuotes || ShouldSurroundWithQuotes(arg); var isQuoted = needsQuotes || IsSurroundedWithQuotes(arg); if (needsQuotes) sb.Append("\""); diff --git a/src/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs b/src/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs index d46eb52f2..cee835aa0 100644 --- a/src/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs +++ b/src/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs @@ -34,7 +34,7 @@ namespace Microsoft.DotNet.Cli.Utils { _forwardingApp = new ForwardingAppImplementation( msbuildPath ?? GetMSBuildExePath(), - _msbuildRequiredParameters.Concat(argsToForward.Select(Escape)), + _msbuildRequiredParameters.Concat(argsToForward.Select(QuotePropertyValue)), environmentVariables: _msbuildRequiredEnvironmentVariables); } @@ -49,13 +49,6 @@ namespace Microsoft.DotNet.Cli.Utils return GetProcessStartInfo().Execute(); } - private static string Escape(string arg) => - // this is a workaround for https://github.com/Microsoft/msbuild/issues/1622 - IsRestoreSources(arg) ? - arg.Replace(";", "%3B") - .Replace("://", ":%2F%2F") : - arg; - private static string GetMSBuildExePath() { return Path.Combine( @@ -82,12 +75,37 @@ namespace Microsoft.DotNet.Cli.Utils return new Muxer().MuxerPath; } - private static bool IsRestoreSources(string arg) + private static bool IsPropertyArgument(string arg) { - return arg.StartsWith("/p:RestoreSources=", StringComparison.OrdinalIgnoreCase) || - arg.StartsWith("/property:RestoreSources=", StringComparison.OrdinalIgnoreCase) || - arg.StartsWith("-p:RestoreSources=", StringComparison.OrdinalIgnoreCase) || - arg.StartsWith("-property:RestoreSources=", StringComparison.OrdinalIgnoreCase); + return + arg.StartsWith("/p:", StringComparison.OrdinalIgnoreCase) || + arg.StartsWith("/property:", StringComparison.OrdinalIgnoreCase) || + arg.StartsWith("-p:", StringComparison.OrdinalIgnoreCase) || + arg.StartsWith("-property:", StringComparison.OrdinalIgnoreCase); + } + + private static string QuotePropertyValue(string arg) + { + if (!IsPropertyArgument(arg)) + { + return arg; + } + + var parts = arg.Split(new[] { '=' }, 2); + if (parts.Length != 2) + { + return arg; + } + + // Escaping `://` is a workaround for https://github.com/Microsoft/msbuild/issues/1622 + // The issue is that MSBuild is collapsing multiple slashes to a single slash due to a bad regex. + var value = parts[1].Replace("://", ":%2f%2f"); + if (ArgumentEscaper.IsSurroundedWithQuotes(value)) + { + return $"{parts[0]}={value}"; + } + + return $"{parts[0]}={ArgumentEscaper.EscapeSingleArg(value, forceQuotes: true)}"; } } } diff --git a/src/dotnet/commands/dotnet-test/Program.cs b/src/dotnet/commands/dotnet-test/Program.cs index 95a8f2418..7fd8103b9 100644 --- a/src/dotnet/commands/dotnet-test/Program.cs +++ b/src/dotnet/commands/dotnet-test/Program.cs @@ -125,19 +125,6 @@ namespace Microsoft.DotNet.Tools.Test return arg; } - private static string[] GetSemiColonEscapedArgs(List args) - { - int counter = 0; - string[] array = new string[args.Count]; - - foreach (string arg in args) - { - array[counter++] = GetSemiColonEscapedString(arg); - } - - return array; - } - private static void UpdateRunSettingsArgumentsText() { DefaultHelpViewText.Synopsis.AdditionalArguments = " [[--] ...]]"; diff --git a/test/dotnet-msbuild.Tests/GivenDotnetBuildInvocation.cs b/test/dotnet-msbuild.Tests/GivenDotnetBuildInvocation.cs index 3a4821f5a..022a2b78c 100644 --- a/test/dotnet-msbuild.Tests/GivenDotnetBuildInvocation.cs +++ b/test/dotnet-msbuild.Tests/GivenDotnetBuildInvocation.cs @@ -13,21 +13,21 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests [Theory] [InlineData(new string[] { }, "-target:Build")] - [InlineData(new string[] { "-o", "foo" }, "-target:Build -property:OutputPath=foo")] - [InlineData(new string[] { "-property:Verbosity=diag" }, "-target:Build -property:Verbosity=diag")] - [InlineData(new string[] { "--output", "foo" }, "-target:Build -property:OutputPath=foo")] - [InlineData(new string[] { "-o", "foo1 foo2" }, "-target:Build \"-property:OutputPath=foo1 foo2\"")] + [InlineData(new string[] { "-o", "foo" }, @"-target:Build -property:OutputPath=\""foo\""")] + [InlineData(new string[] { "-property:Verbosity=diag" }, @"-target:Build -property:Verbosity=\""diag\""")] + [InlineData(new string[] { "--output", "foo" }, @"-target:Build -property:OutputPath=\""foo\""")] + [InlineData(new string[] { "-o", "foo1 foo2" }, @"-target:Build ""-property:OutputPath=\""foo1 foo2\""""")] [InlineData(new string[] { "--no-incremental" }, "-target:Rebuild")] - [InlineData(new string[] { "-r", "rid" }, "-target:Build -property:RuntimeIdentifier=rid")] - [InlineData(new string[] { "--runtime", "rid" }, "-target:Build -property:RuntimeIdentifier=rid")] - [InlineData(new string[] { "-c", "config" }, "-target:Build -property:Configuration=config")] - [InlineData(new string[] { "--configuration", "config" }, "-target:Build -property:Configuration=config")] - [InlineData(new string[] { "--version-suffix", "mysuffix" }, "-target:Build -property:VersionSuffix=mysuffix")] - [InlineData(new string[] { "--no-dependencies" }, "-target:Build -property:BuildProjectReferences=false")] + [InlineData(new string[] { "-r", "rid" }, @"-target:Build -property:RuntimeIdentifier=\""rid\""")] + [InlineData(new string[] { "--runtime", "rid" }, @"-target:Build -property:RuntimeIdentifier=\""rid\""")] + [InlineData(new string[] { "-c", "config" }, @"-target:Build -property:Configuration=\""config\""")] + [InlineData(new string[] { "--configuration", "config" }, @"-target:Build -property:Configuration=\""config\""")] + [InlineData(new string[] { "--version-suffix", "mysuffix" }, @"-target:Build -property:VersionSuffix=\""mysuffix\""")] + [InlineData(new string[] { "--no-dependencies" }, @"-target:Build -property:BuildProjectReferences=\""false\""")] [InlineData(new string[] { "-v", "diag" }, "-target:Build -verbosity:diag")] [InlineData(new string[] { "--verbosity", "diag" }, "-target:Build -verbosity:diag")] [InlineData(new string[] { "--no-incremental", "-o", "myoutput", "-r", "myruntime", "-v", "diag", "/ArbitrarySwitchForMSBuild" }, - "-target:Rebuild -property:OutputPath=myoutput -property:RuntimeIdentifier=myruntime -verbosity:diag /ArbitrarySwitchForMSBuild")] + @"-target:Rebuild -property:OutputPath=\""myoutput\"" -property:RuntimeIdentifier=\""myruntime\"" -verbosity:diag /ArbitrarySwitchForMSBuild")] public void MsbuildInvocationIsCorrect(string[] args, string expectedAdditionalArgs) { expectedAdditionalArgs = (string.IsNullOrEmpty(expectedAdditionalArgs) ? "" : $" {expectedAdditionalArgs}"); @@ -43,10 +43,10 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests } [Theory] - [InlineData(new string[] { "-f", "tfm" }, "-target:Restore", "-target:Build -property:TargetFramework=tfm")] + [InlineData(new string[] { "-f", "tfm" }, "-target:Restore", @"-target:Build -property:TargetFramework=\""tfm\""")] [InlineData(new string[] { "-o", "myoutput", "-f", "tfm", "-v", "diag", "/ArbitrarySwitchForMSBuild" }, - "-target:Restore -property:OutputPath=myoutput -verbosity:diag /ArbitrarySwitchForMSBuild", - "-target:Build -property:OutputPath=myoutput -property:TargetFramework=tfm -verbosity:diag /ArbitrarySwitchForMSBuild")] + @"-target:Restore -property:OutputPath=\""myoutput\"" -verbosity:diag /ArbitrarySwitchForMSBuild", + @"-target:Build -property:OutputPath=\""myoutput\"" -property:TargetFramework=\""tfm\"" -verbosity:diag /ArbitrarySwitchForMSBuild")] public void MsbuildInvocationIsCorrectForSeparateRestore( string[] args, string expectedAdditionalArgsForRestore, diff --git a/test/dotnet-msbuild.Tests/GivenDotnetCleanInvocation.cs b/test/dotnet-msbuild.Tests/GivenDotnetCleanInvocation.cs index 4c7d89890..9f9ced642 100644 --- a/test/dotnet-msbuild.Tests/GivenDotnetCleanInvocation.cs +++ b/test/dotnet-msbuild.Tests/GivenDotnetCleanInvocation.cs @@ -22,12 +22,12 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests [Theory] [InlineData(new string[] { }, "")] - [InlineData(new string[] { "-o", "" }, "-property:OutputPath=")] - [InlineData(new string[] { "--output", "" }, "-property:OutputPath=")] - [InlineData(new string[] { "-f", "" }, "-property:TargetFramework=")] - [InlineData(new string[] { "--framework", "" }, "-property:TargetFramework=")] - [InlineData(new string[] { "-c", "" }, "-property:Configuration=")] - [InlineData(new string[] { "--configuration", "" }, "-property:Configuration=")] + [InlineData(new string[] { "-o", "" }, @"-property:OutputPath=\""\""")] + [InlineData(new string[] { "--output", "" }, @"-property:OutputPath=\""\""")] + [InlineData(new string[] { "-f", "" }, @"-property:TargetFramework=\""\""")] + [InlineData(new string[] { "--framework", "" }, @"-property:TargetFramework=\""\""")] + [InlineData(new string[] { "-c", "" }, @"-property:Configuration=\""\""")] + [InlineData(new string[] { "--configuration", "" }, @"-property:Configuration=\""\""")] [InlineData(new string[] { "-v", "diag" }, "-verbosity:diag")] [InlineData(new string[] { "--verbosity", "diag" }, "-verbosity:diag")] public void MsbuildInvocationIsCorrect(string[] args, string expectedAdditionalArgs) diff --git a/test/dotnet-msbuild.Tests/GivenDotnetMSBuildBuildsProjects.cs b/test/dotnet-msbuild.Tests/GivenDotnetMSBuildBuildsProjects.cs index b07fb937c..1c0ea1047 100644 --- a/test/dotnet-msbuild.Tests/GivenDotnetMSBuildBuildsProjects.cs +++ b/test/dotnet-msbuild.Tests/GivenDotnetMSBuildBuildsProjects.cs @@ -159,6 +159,26 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests $"The MSBuild logger argument should not be specified when telemetry is disabled."); } + [Theory] + [InlineData("/p")] + [InlineData("/property")] + [InlineData("-p")] + [InlineData("-property")] + public void GivenAPropertyValueWithASemicolonItIsQuotedToMSBuild(string propertyOption) + { + var testInstance = TestAssets.Get("ProjectPrintsNoWarn") + .CreateInstance() + .WithSourceFiles(); + + new MSBuildCommand() + .WithWorkingDirectory(testInstance.Root) + .ExecuteWithCapturedOutput($@"/restore {propertyOption}:NoWarn=1234;5678;90\") + .Should() + .Pass() + .And + .HaveStdOutContaining(@"NoWarn => 1234;5678;90\"); + } + private string[] GetArgsForMSBuild(Func sentinelExists) { Telemetry.Telemetry telemetry; diff --git a/test/dotnet-msbuild.Tests/GivenDotnetPackInvocation.cs b/test/dotnet-msbuild.Tests/GivenDotnetPackInvocation.cs index e0b766da5..41fe24ee5 100644 --- a/test/dotnet-msbuild.Tests/GivenDotnetPackInvocation.cs +++ b/test/dotnet-msbuild.Tests/GivenDotnetPackInvocation.cs @@ -16,16 +16,16 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests [Theory] [InlineData(new string[] { }, "")] - [InlineData(new string[] { "-o", "" }, "-property:PackageOutputPath=")] - [InlineData(new string[] { "--output", "" }, "-property:PackageOutputPath=")] - [InlineData(new string[] { "--no-build" }, "-property:NoBuild=true")] - [InlineData(new string[] { "--include-symbols" }, "-property:IncludeSymbols=true")] - [InlineData(new string[] { "--include-source" }, "-property:IncludeSource=true")] - [InlineData(new string[] { "-c", "" }, "-property:Configuration=")] - [InlineData(new string[] { "--configuration", "" }, "-property:Configuration=")] - [InlineData(new string[] { "--version-suffix", "" }, "-property:VersionSuffix=")] - [InlineData(new string[] { "-s" }, "-property:Serviceable=true")] - [InlineData(new string[] { "--serviceable" }, "-property:Serviceable=true")] + [InlineData(new string[] { "-o", "" }, @"-property:PackageOutputPath=\""\""")] + [InlineData(new string[] { "--output", "" }, @"-property:PackageOutputPath=\""\""")] + [InlineData(new string[] { "--no-build" }, @"-property:NoBuild=\""true\""")] + [InlineData(new string[] { "--include-symbols" }, @"-property:IncludeSymbols=\""true\""")] + [InlineData(new string[] { "--include-source" }, @"-property:IncludeSource=\""true\""")] + [InlineData(new string[] { "-c", "" }, @"-property:Configuration=\""\""")] + [InlineData(new string[] { "--configuration", "" }, @"-property:Configuration=\""\""")] + [InlineData(new string[] { "--version-suffix", "" }, @"-property:VersionSuffix=\""\""")] + [InlineData(new string[] { "-s" }, @"-property:Serviceable=\""true\""")] + [InlineData(new string[] { "--serviceable" }, @"-property:Serviceable=\""true\""")] [InlineData(new string[] { "-v", "diag" }, "-verbosity:diag")] [InlineData(new string[] { "--verbosity", "diag" }, "-verbosity:diag")] [InlineData(new string[] { "" }, "")] diff --git a/test/dotnet-msbuild.Tests/GivenDotnetPublishInvocation.cs b/test/dotnet-msbuild.Tests/GivenDotnetPublishInvocation.cs index b66155261..9e6e6220a 100644 --- a/test/dotnet-msbuild.Tests/GivenDotnetPublishInvocation.cs +++ b/test/dotnet-msbuild.Tests/GivenDotnetPublishInvocation.cs @@ -24,14 +24,14 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests [Theory] [InlineData(new string[] { }, "")] - [InlineData(new string[] { "-r", "" }, "-property:RuntimeIdentifier=")] - [InlineData(new string[] { "--runtime", "" }, "-property:RuntimeIdentifier=")] - [InlineData(new string[] { "-o", "" }, "-property:PublishDir=")] - [InlineData(new string[] { "--output", "" }, "-property:PublishDir=")] - [InlineData(new string[] { "-c", "" }, "-property:Configuration=")] - [InlineData(new string[] { "--configuration", "" }, "-property:Configuration=")] - [InlineData(new string[] { "--version-suffix", "" }, "-property:VersionSuffix=")] - [InlineData(new string[] { "--manifest", "" }, "-property:TargetManifestFiles=")] + [InlineData(new string[] { "-r", "" }, @"-property:RuntimeIdentifier=\""\""")] + [InlineData(new string[] { "--runtime", "" }, @"-property:RuntimeIdentifier=\""\""")] + [InlineData(new string[] { "-o", "" }, @"-property:PublishDir=\""\""")] + [InlineData(new string[] { "--output", "" }, @"-property:PublishDir=\""\""")] + [InlineData(new string[] { "-c", "" }, @"-property:Configuration=\""\""")] + [InlineData(new string[] { "--configuration", "" }, @"-property:Configuration=\""\""")] + [InlineData(new string[] { "--version-suffix", "" }, @"-property:VersionSuffix=\""\""")] + [InlineData(new string[] { "--manifest", "" }, @"-property:TargetManifestFiles=\""\""")] [InlineData(new string[] { "-v", "minimal" }, "-verbosity:minimal")] [InlineData(new string[] { "--verbosity", "minimal" }, "-verbosity:minimal")] [InlineData(new string[] { "" }, "")] @@ -53,8 +53,8 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests } [Theory] - [InlineData(new string[] { "-f", "" }, "-property:TargetFramework=")] - [InlineData(new string[] { "--framework", "" }, "-property:TargetFramework=")] + [InlineData(new string[] { "-f", "" }, @"-property:TargetFramework=\""\""")] + [InlineData(new string[] { "--framework", "" }, @"-property:TargetFramework=\""\""")] public void MsbuildInvocationIsCorrectForSeparateRestore(string[] args, string expectedAdditionalArgs) { expectedAdditionalArgs = (string.IsNullOrEmpty(expectedAdditionalArgs) ? "" : $" {expectedAdditionalArgs}"); @@ -86,7 +86,7 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests command.GetProcessStartInfo() .Arguments .Should() - .Be($"{ExpectedPrefix} -target:Publish -property:NoBuild=true"); + .Be($"{ExpectedPrefix} -target:Publish -property:NoBuild=\\\"true\\\""); } [Theory] diff --git a/test/dotnet-msbuild.Tests/GivenDotnetRestoreInvocation.cs b/test/dotnet-msbuild.Tests/GivenDotnetRestoreInvocation.cs index e4ae26741..c1e515234 100644 --- a/test/dotnet-msbuild.Tests/GivenDotnetRestoreInvocation.cs +++ b/test/dotnet-msbuild.Tests/GivenDotnetRestoreInvocation.cs @@ -15,18 +15,18 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests [Theory] [InlineData(new string[] { }, "")] - [InlineData(new string[] { "-s", "" }, "-property:RestoreSources=")] - [InlineData(new string[] { "--source", "" }, "-property:RestoreSources=")] - [InlineData(new string[] { "-s", "", "-s", "" }, "-property:RestoreSources=%3B")] - [InlineData(new string[] { "-r", "" }, "-property:RuntimeIdentifiers=")] - [InlineData(new string[] { "--runtime", "" }, "-property:RuntimeIdentifiers=")] - [InlineData(new string[] { "-r", "", "-r", "" }, "-property:RuntimeIdentifiers=%3B")] - [InlineData(new string[] { "--packages", "" }, "-property:RestorePackagesPath=")] - [InlineData(new string[] { "--disable-parallel" }, "-property:RestoreDisableParallel=true")] - [InlineData(new string[] { "--configfile", "" }, "-property:RestoreConfigFile=")] - [InlineData(new string[] { "--no-cache" }, "-property:RestoreNoCache=true")] - [InlineData(new string[] { "--ignore-failed-sources" }, "-property:RestoreIgnoreFailedSources=true")] - [InlineData(new string[] { "--no-dependencies" }, "-property:RestoreRecursive=false")] + [InlineData(new string[] { "-s", "" }, @"-property:RestoreSources=\""\""")] + [InlineData(new string[] { "--source", "" }, @"-property:RestoreSources=\""\""")] + [InlineData(new string[] { "-s", "", "-s", "" }, @"-property:RestoreSources=\""%3B\""")] + [InlineData(new string[] { "-r", "" }, @"-property:RuntimeIdentifiers=\""\""")] + [InlineData(new string[] { "--runtime", "" }, @"-property:RuntimeIdentifiers=\""\""")] + [InlineData(new string[] { "-r", "", "-r", "" }, @"-property:RuntimeIdentifiers=\""%3B\""")] + [InlineData(new string[] { "--packages", "" }, @"-property:RestorePackagesPath=\""\""")] + [InlineData(new string[] { "--disable-parallel" }, @"-property:RestoreDisableParallel=\""true\""")] + [InlineData(new string[] { "--configfile", "" }, @"-property:RestoreConfigFile=\""\""")] + [InlineData(new string[] { "--no-cache" }, @"-property:RestoreNoCache=\""true\""")] + [InlineData(new string[] { "--ignore-failed-sources" }, @"-property:RestoreIgnoreFailedSources=\""true\""")] + [InlineData(new string[] { "--no-dependencies" }, @"-property:RestoreRecursive=\""false\""")] [InlineData(new string[] { "-v", "minimal" }, @"-verbosity:minimal")] [InlineData(new string[] { "--verbosity", "minimal" }, @"-verbosity:minimal")] public void MsbuildInvocationIsCorrect(string[] args, string expectedAdditionalArgs) diff --git a/test/dotnet-msbuild.Tests/GivenDotnetStoreInvocation.cs b/test/dotnet-msbuild.Tests/GivenDotnetStoreInvocation.cs index 47854f569..a7dd9459e 100644 --- a/test/dotnet-msbuild.Tests/GivenDotnetStoreInvocation.cs +++ b/test/dotnet-msbuild.Tests/GivenDotnetStoreInvocation.cs @@ -26,11 +26,11 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests } [Theory] - [InlineData(new string[] { "-f", "" }, @"-property:TargetFramework=")] - [InlineData(new string[] { "--framework", "" }, @"-property:TargetFramework=")] - [InlineData(new string[] { "-r", "" }, @"-property:RuntimeIdentifier=")] - [InlineData(new string[] { "--runtime", "" }, @"-property:RuntimeIdentifier=")] - [InlineData(new string[] { "--manifest", "one.xml", "--manifest", "two.xml", "--manifest", "three.xml" }, @"-property:AdditionalProjects=one.xml%3Btwo.xml%3Bthree.xml")] + [InlineData(new string[] { "-f", "" }, @"-property:TargetFramework=\""\""")] + [InlineData(new string[] { "--framework", "" }, @"-property:TargetFramework=\""\""")] + [InlineData(new string[] { "-r", "" }, @"-property:RuntimeIdentifier=\""\""")] + [InlineData(new string[] { "--runtime", "" }, @"-property:RuntimeIdentifier=\""\""")] + [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(); @@ -51,7 +51,7 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests var msbuildPath = ""; StoreCommand.FromArgs(args, msbuildPath) - .GetProcessStartInfo().Arguments.Should().Be($"{ExpectedPrefix} -property:ComposeDir={Path.GetFullPath(path)}"); + .GetProcessStartInfo().Arguments.Should().Be($"{ExpectedPrefix} -property:ComposeDir=\\\"{Path.GetFullPath(path)}\\\""); } } }