Fix 4508: CLI verbs that call into msbuild should control their output (#4719)

* Fix 4508: CLI verbs that call into msbuild should control their output

* fix failing tests + tiny bufix in dotnet test
This commit is contained in:
Krzysztof Wicher 2016-11-15 11:56:39 -08:00 committed by GitHub
parent 43df9a170d
commit 7a3bc96f75
11 changed files with 128 additions and 5 deletions

View file

@ -2,15 +2,15 @@
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="SayHello">
<Message Text="Hello, from MSBuild!" />
<Message Importance="high" Text="Hello, from MSBuild!" />
</Target>
<Target Name="SayGoodbye">
<Message Text="Goodbye, from MSBuild. :'(" />
<Message Importance="high" Text="Goodbye, from MSBuild. :'(" />
</Target>
<Target Name="SayThis">
<Message Text="You want me to say '$(This)'" />
<Message Importance="high" Text="You want me to say '$(This)'" />
</Target>
</Project>

View file

@ -13,6 +13,7 @@
<Target Name="Publish"
DependsOnTargets="Validate" />
<Target Name="Restore"
DependsOnTargets="Validate" />
@ -28,5 +29,9 @@
<Error Condition=" '$(CscToolExe)' == '' "
Text="Expect CscToolExe to be set, but it is not." />
<Message Importance="low" Text="Message with low importance" />
<Message Importance="normal" Text="Message with normal importance" />
<Message Importance="high" Text="Message with high importance" />
</Target>
</Project>

View file

@ -36,6 +36,7 @@ namespace Microsoft.DotNet.Tools.Build
CommandOption noIncrementalOption = app.Option("--no-incremental", "Set this flag to turn off incremental build", CommandOptionType.NoValue);
CommandOption noDependenciesOption = app.Option("--no-dependencies", "Set this flag to ignore project to project references and only build the root project", CommandOptionType.NoValue);
CommandOption verbosityOption = MSBuildForwardingApp.AddVerbosityOption(app);
app.OnExecute(() =>
{
@ -85,6 +86,11 @@ namespace Microsoft.DotNet.Tools.Build
msbuildArgs.Add("/p:BuildProjectReferences=false");
}
if (verbosityOption.HasValue())
{
msbuildArgs.Add($"/verbosity:{verbosityOption.Value()}");
}
msbuildArgs.AddRange(app.RemainingArguments);
return new MSBuildForwardingApp(msbuildArgs).Execute();

View file

@ -31,6 +31,7 @@ namespace Microsoft.DotNet.Tools.Clean
CommandOption outputOption = app.Option("-o|--output <OUTPUT_DIR>", "Directory in which the build outputs have been placed", CommandOptionType.SingleValue);
CommandOption frameworkOption = app.Option("-f|--framework <FRAMEWORK>", "Clean a specific framework", CommandOptionType.SingleValue);
CommandOption configurationOption = app.Option("-c|--configuration <CONFIGURATION>", "Clean a specific configuration", CommandOptionType.SingleValue);
CommandOption verbosityOption = MSBuildForwardingApp.AddVerbosityOption(app);
app.OnExecute(() =>
{
@ -58,6 +59,11 @@ namespace Microsoft.DotNet.Tools.Clean
msbuildArgs.Add($"/p:Configuration={configurationOption.Value()}");
}
if (verbosityOption.HasValue())
{
msbuildArgs.Add($"/verbosity:{verbosityOption.Value()}");
}
msbuildArgs.AddRange(app.RemainingArguments);
return new MSBuildForwardingApp(msbuildArgs).Execute();

View file

@ -8,6 +8,7 @@ using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.DotNet.Tools.MSBuild
{
@ -27,7 +28,7 @@ namespace Microsoft.DotNet.Tools.MSBuild
};
private readonly IEnumerable<string> _msbuildRequiredParameters =
new List<string> { "/m" };
new List<string> { "/m", "/v:m" };
public MSBuildForwardingApp(IEnumerable<string> argsToForward)
{
@ -68,6 +69,11 @@ namespace Microsoft.DotNet.Tools.MSBuild
}
}
internal static CommandOption AddVerbosityOption(CommandLineApplication app)
{
return app.Option("-v|--verbosity", "Set the verbosity level of the command. Allowed values are q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]", CommandOptionType.SingleValue);
}
private static string GetMSBuildExePath()
{
return Path.Combine(

View file

@ -49,6 +49,7 @@ namespace Microsoft.DotNet.Tools.Pack
var argRoot = cmd.Argument("<PROJECT>",
"The project to pack, defaults to the project file in the current directory. Can be a path to any project file",
multipleValues:true);
CommandOption verbosityOption = MSBuildForwardingApp.AddVerbosityOption(cmd);
cmd.OnExecute(() =>
{
@ -92,6 +93,11 @@ namespace Microsoft.DotNet.Tools.Pack
msbuildArgs.Add($"/p:Serviceable=true");
}
if (verbosityOption.HasValue())
{
msbuildArgs.Add($"/verbosity:{verbosityOption.Value()}");
}
msbuildArgs.AddRange(argRoot.Values);
msbuildArgs.AddRange(cmd.RemainingArguments);

View file

@ -3,6 +3,7 @@
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.MSBuild;
namespace Microsoft.DotNet.Tools.Publish
{
@ -43,6 +44,7 @@ namespace Microsoft.DotNet.Tools.Publish
CommandOption versionSuffixOption = app.Option(
"--version-suffix <VERSION_SUFFIX>", "Defines the value for the $(VersionSuffix) property in the project",
CommandOptionType.SingleValue);
CommandOption verbosityOption = MSBuildForwardingApp.AddVerbosityOption(app);
app.OnExecute(() =>
{
@ -54,6 +56,7 @@ namespace Microsoft.DotNet.Tools.Publish
publish.OutputPath = outputOption.Value();
publish.Configuration = configurationOption.Value();
publish.VersionSuffix = versionSuffixOption.Value();
publish.Verbosity = verbosityOption.Value();
publish.ExtraMSBuildArguments = app.RemainingArguments;
return publish.Execute();

View file

@ -16,6 +16,7 @@ namespace Microsoft.DotNet.Tools.Publish
public string OutputPath { get; set; }
public string Configuration { get; set; }
public string VersionSuffix { get; set; }
public string Verbosity { get; set; }
public List<string> ExtraMSBuildArguments { get; set; }
@ -59,6 +60,11 @@ namespace Microsoft.DotNet.Tools.Publish
msbuildArgs.Add($"/p:VersionSuffix={VersionSuffix}");
}
if (!string.IsNullOrEmpty(Verbosity))
{
msbuildArgs.Add($"/verbosity:{Verbosity}");
}
msbuildArgs.AddRange(ExtraMSBuildArguments);
return new MSBuildForwardingApp(msbuildArgs).Execute();

View file

@ -65,6 +65,8 @@ namespace Microsoft.DotNet.Tools.Restore
"Set this flag to ignore project to project references and only restore the root project",
CommandOptionType.NoValue);
CommandOption verbosityOption = MSBuildForwardingApp.AddVerbosityOption(cmd);
cmd.OnExecute(() =>
{
var msbuildArgs = new List<string>()
@ -109,6 +111,11 @@ namespace Microsoft.DotNet.Tools.Restore
msbuildArgs.Add($"/p:RestoreRecursive=false");
}
if (verbosityOption.HasValue())
{
msbuildArgs.Add($"/verbosity:{verbosityOption.Value()}");
}
// Add in arguments
msbuildArgs.AddRange(argRoot.Values);

View file

@ -87,6 +87,8 @@ namespace Microsoft.DotNet.Tools.Test
@"Do not build project before testing.",
CommandOptionType.NoValue);
CommandOption verbosityOption = MSBuildForwardingApp.AddVerbosityOption(cmd);
cmd.OnExecute(() =>
{
var msbuildArgs = new List<string>()
@ -94,7 +96,6 @@ namespace Microsoft.DotNet.Tools.Test
"/t:VSTest"
};
msbuildArgs.Add("/verbosity:quiet");
msbuildArgs.Add("/nologo");
if (settingOption.HasValue())
@ -147,6 +148,15 @@ namespace Microsoft.DotNet.Tools.Test
msbuildArgs.Add($"/p:VSTestNoBuild=true");
}
if (verbosityOption.HasValue())
{
msbuildArgs.Add($"/verbosity:{verbosityOption.Value()}");
}
else
{
msbuildArgs.Add("/verbosity:quiet");
}
string defaultproject = GetSingleTestProjectToRunTestIfNotProvided(argRoot.Value, cmd.RemainingArguments);
if(!string.IsNullOrEmpty(defaultproject))

View file

@ -31,5 +31,73 @@ namespace Microsoft.DotNet.Cli.MSBuild.IntegrationTests
.Execute(command)
.Should().Pass();
}
[Theory]
[InlineData("build")]
[InlineData("clean")]
[InlineData("pack")]
[InlineData("publish")]
public void When_dotnet_command_invokes_msbuild_with_no_args_verbosity_is_set_to_minimum(string command)
{
var testInstance = TestAssets.Get("MSBuildIntegration")
.CreateInstance(identifier: command)
.WithSourceFiles();
var cmd = new DotnetCommand()
.WithWorkingDirectory(testInstance.Root)
.ExecuteWithCapturedOutput(command);
cmd.Should().Pass();
cmd.StdOut.Should().NotContain("Message with normal importance");
// sanity check
cmd.StdOut.Should().Contain("Message with high importance");
}
[Theory]
[InlineData("build")]
[InlineData("clean")]
[InlineData("pack")]
[InlineData("publish")]
[InlineData("test")]
public void When_dotnet_command_invokes_msbuild_with_diag_verbosity_Then_arg_is_passed(string command)
{
var testInstance = TestAssets.Get("MSBuildIntegration")
.CreateInstance(identifier: command)
.WithSourceFiles();
var cmd = new DotnetCommand()
.WithWorkingDirectory(testInstance.Root)
.ExecuteWithCapturedOutput($"{command} -v diag");
cmd.Should().Pass();
cmd.StdOut.Should().Contain("Message with low importance");
}
[Fact]
public void When_dotnet_test_invokes_msbuild_with_no_args_verbosity_is_set_to_quiet()
{
string command = "test";
var testInstance = TestAssets.Get("MSBuildIntegration")
.CreateInstance(identifier: command)
.WithSourceFiles();
var cmd = new DotnetCommand()
.WithWorkingDirectory(testInstance.Root)
.ExecuteWithCapturedOutput(command);
cmd.Should().Pass();
cmd.StdOut.Should().NotContain("Message with high importance");
}
[Fact]
public void When_dotnet_msbuild_command_is_invoked_with_non_msbuild_switch_Then_it_fails()
{
string command = "msbuild";
var testInstance = TestAssets.Get("MSBuildIntegration")
.CreateInstance(identifier: command)
.WithSourceFiles();
var cmd = new DotnetCommand()
.WithWorkingDirectory(testInstance.Root)
.ExecuteWithCapturedOutput($"{command} -v diag");
cmd.ExitCode.Should().NotBe(0);
}
}
}