diff --git a/TestAssets/TestProjects/ProjectPrintsNoWarn/ProjectPrintsNoWarn.csproj b/TestAssets/TestProjects/ProjectPrintsNoWarn/ProjectPrintsNoWarn.csproj
deleted file mode 100644
index 4e83f2fad..000000000
--- a/TestAssets/TestProjects/ProjectPrintsNoWarn/ProjectPrintsNoWarn.csproj
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
- library
- netcoreapp2.0
-
-
-
-
-
-
-
diff --git a/src/Microsoft.DotNet.Cli.Utils/ArgumentEscaper.cs b/src/Microsoft.DotNet.Cli.Utils/ArgumentEscaper.cs
index c87268c00..afaa58d48 100644
--- a/src/Microsoft.DotNet.Cli.Utils/ArgumentEscaper.cs
+++ b/src/Microsoft.DotNet.Cli.Utils/ArgumentEscaper.cs
@@ -59,10 +59,14 @@ namespace Microsoft.DotNet.Cli.Utils
///
private static IEnumerable EscapeArgArray(IEnumerable args)
{
+ var escapedArgs = new List();
+
foreach (var arg in args)
{
- yield return EscapeSingleArg(arg);
+ escapedArgs.Add(EscapeSingleArg(arg));
}
+
+ return escapedArgs;
}
///
@@ -75,19 +79,23 @@ namespace Microsoft.DotNet.Cli.Utils
///
///
///
- private static IEnumerable EscapeArgArrayForCmd(IEnumerable args)
+ private static IEnumerable EscapeArgArrayForCmd(IEnumerable arguments)
{
- foreach (var arg in args)
+ var escapedArgs = new List();
+
+ foreach (var arg in arguments)
{
- yield return EscapeArgForCmd(arg);
+ escapedArgs.Add(EscapeArgForCmd(arg));
}
+
+ return escapedArgs;
}
- public static string EscapeSingleArg(string arg, bool forceQuotes = false)
+ public static string EscapeSingleArg(string arg)
{
var sb = new StringBuilder();
- var needsQuotes = forceQuotes || ShouldSurroundWithQuotes(arg);
+ var needsQuotes = 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 cee835aa0..d46eb52f2 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(QuotePropertyValue)),
+ _msbuildRequiredParameters.Concat(argsToForward.Select(Escape)),
environmentVariables: _msbuildRequiredEnvironmentVariables);
}
@@ -49,6 +49,13 @@ 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(
@@ -75,37 +82,12 @@ namespace Microsoft.DotNet.Cli.Utils
return new Muxer().MuxerPath;
}
- private static bool IsPropertyArgument(string arg)
+ private static bool IsRestoreSources(string arg)
{
- 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)}";
+ 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);
}
}
}
diff --git a/src/dotnet/commands/dotnet-test/Program.cs b/src/dotnet/commands/dotnet-test/Program.cs
index 320aaba02..ac7062f03 100644
--- a/src/dotnet/commands/dotnet-test/Program.cs
+++ b/src/dotnet/commands/dotnet-test/Program.cs
@@ -124,6 +124,19 @@ 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 022a2b78c..3a4821f5a 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 9f9ced642..4c7d89890 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", "