diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/MSBuildArgs.cs b/src/Cli/Microsoft.DotNet.Cli.Utils/MSBuildArgs.cs index 1e241c72a420..859d02baddb1 100644 --- a/src/Cli/Microsoft.DotNet.Cli.Utils/MSBuildArgs.cs +++ b/src/Cli/Microsoft.DotNet.Cli.Utils/MSBuildArgs.cs @@ -58,7 +58,6 @@ private MSBuildArgs(ReadOnlyDictionary? properties, ReadOnlyDict /// processing of the SDK and returns a structured set of MSBuild arguments grouped by purpose. /// /// the complete set of forwarded MSBuild arguments and un-parsed, potentially MSBuild-relevant arguments - /// public static MSBuildArgs AnalyzeMSBuildArguments(IEnumerable forwardedAndUserFacingArgs, params Option[] options) { var fakeCommand = new System.CommandLine.Command("dotnet"); @@ -66,7 +65,7 @@ public static MSBuildArgs AnalyzeMSBuildArguments(IEnumerable forwardedA { fakeCommand.Options.Add(option); } -; + var parseResult = fakeCommand.Parse([.. forwardedAndUserFacingArgs], _analysisParsingConfiguration); var globalProperties = parseResult.GetResult("--property") is OptionResult propResult ? propResult.GetValueOrDefault?>() : null; var restoreProperties = parseResult.GetResult("--restoreProperty") is OptionResult restoreResult ? restoreResult.GetValueOrDefault?>() : null; diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs b/src/Cli/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs index 64e6fea0ccf9..e546fb0feab3 100644 --- a/src/Cli/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs +++ b/src/Cli/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs @@ -5,11 +5,10 @@ using System.Diagnostics; using Microsoft.DotNet.Cli.Utils.Extensions; -using Microsoft.DotNet.Cli; namespace Microsoft.DotNet.Cli.Utils; -internal class MSBuildForwardingAppWithoutLogging +internal sealed class MSBuildForwardingAppWithoutLogging { private static readonly bool AlwaysExecuteMSBuildOutOfProc = Env.GetEnvironmentVariableAsBool("DOTNET_CLI_RUN_MSBUILD_OUTOFPROC"); private static readonly bool UseMSBuildServer = Env.GetEnvironmentVariableAsBool("DOTNET_CLI_USE_MSBUILD_SERVER", false); @@ -41,7 +40,9 @@ public static string MSBuildVersion private readonly Dictionary _msbuildRequiredEnvironmentVariables = GetMSBuildRequiredEnvironmentVariables(); - private readonly List _msbuildRequiredParameters = [ "-maxcpucount", "--verbosity:m" ]; + private readonly List _msbuildRequiredParameters = ["-maxcpucount", $"--verbosity:{DefaultVerbosity}"]; + + internal const VerbosityOptions DefaultVerbosity = VerbosityOptions.m; public MSBuildForwardingAppWithoutLogging(MSBuildArgs msbuildArgs, string? msbuildPath = null, bool includeLogo = false, bool isRestoring = true) { @@ -93,7 +94,7 @@ public ProcessStartInfo GetProcessStartInfo() public string[] GetAllArguments() { - return [.. _msbuildRequiredParameters, ..EmitMSBuildArgs(_msbuildArgs) ]; + return [.. _msbuildRequiredParameters, .. EmitMSBuildArgs(_msbuildArgs)]; } private string[] EmitMSBuildArgs(MSBuildArgs msbuildArgs) => [ diff --git a/src/Cli/dotnet/Commands/Run/VirtualProjectBuildingCommand.cs b/src/Cli/dotnet/Commands/Run/VirtualProjectBuildingCommand.cs index fa2104c5ce4d..4dfd660b6633 100644 --- a/src/Cli/dotnet/Commands/Run/VirtualProjectBuildingCommand.cs +++ b/src/Cli/dotnet/Commands/Run/VirtualProjectBuildingCommand.cs @@ -105,7 +105,7 @@ public VirtualProjectBuildingCommand( Debug.Assert(Path.IsPathFullyQualified(entryPointFileFullPath)); EntryPointFileFullPath = entryPointFileFullPath; - MSBuildArgs = msbuildArgs.CloneWithAdditionalProperties(new Dictionary(StringComparer.OrdinalIgnoreCase) + MSBuildArgs = msbuildArgs.CloneWithAdditionalProperties(new Dictionary(2, StringComparer.OrdinalIgnoreCase) { // See https://github.com/dotnet/msbuild/blob/main/documentation/specs/build-nonexistent-projects-by-default.md. { "_BuildNonexistentProjectsByDefault", bool.TrueString }, @@ -160,7 +160,7 @@ public ImmutableArray Directives public override int Execute() { - var verbosity = MSBuildArgs.Verbosity ?? VerbosityOptions.quiet; + var verbosity = MSBuildArgs.Verbosity ?? MSBuildForwardingAppWithoutLogging.DefaultVerbosity; var consoleLogger = TerminalLogger.CreateTerminalOrConsoleLogger([$"--verbosity:{verbosity}", .. MSBuildArgs.OtherMSBuildArgs]); var binaryLogger = GetBinaryLogger(MSBuildArgs.OtherMSBuildArgs); diff --git a/test/dotnet.Tests/CommandTests/Run/RunFileTests.cs b/test/dotnet.Tests/CommandTests/Run/RunFileTests.cs index 091e2b0ba6fd..b5cb0dca767b 100644 --- a/test/dotnet.Tests/CommandTests/Run/RunFileTests.cs +++ b/test/dotnet.Tests/CommandTests/Run/RunFileTests.cs @@ -1164,6 +1164,68 @@ public void TerminalLogger(bool on) } } + [Fact] + public void Verbosity_Run() + { + var testInstance = _testAssetsManager.CreateTestDirectory(); + var programFile = Path.Join(testInstance.Path, "Program.cs"); + File.WriteAllText(programFile, s_program); + + new DotnetCommand(Log, "run", "Program.cs", "--no-cache") + .WithWorkingDirectory(testInstance.Path) + .Execute() + .Should().Pass() + // no additional build messages + .And.HaveStdOut("Hello from Program") + .And.NotHaveStdErr(); + } + + [Fact] // https://github.com/dotnet/sdk/issues/50227 + public void Verbosity_Build() + { + var testInstance = _testAssetsManager.CreateTestDirectory(); + var programFile = Path.Join(testInstance.Path, "Program.cs"); + File.WriteAllText(programFile, s_program); + + new DotnetCommand(Log, "build", "Program.cs") + .WithWorkingDirectory(testInstance.Path) + .Execute() + .Should().Pass() + // should print path to the built DLL + .And.HaveStdOutContaining("Program.dll"); + } + + [Fact] + public void Verbosity_CompilationDiagnostics() + { + var testInstance = _testAssetsManager.CreateTestDirectory(); + + File.WriteAllText(Path.Join(testInstance.Path, "Program.cs"), """ + string x = null; + Console.WriteLine("ran" + x); + """); + + new DotnetCommand(Log, "run", "Program.cs") + .WithWorkingDirectory(testInstance.Path) + .Execute() + .Should().Pass() + // warning CS8600: Converting null literal or possible null value to non-nullable type. + .And.HaveStdOutContaining("warning CS8600") + .And.HaveStdOutContaining("ran"); + + File.WriteAllText(Path.Join(testInstance.Path, "Program.cs"), """ + Console.Write + """); + + new DotnetCommand(Log, "run", "Program.cs") + .WithWorkingDirectory(testInstance.Path) + .Execute() + .Should().Fail() + // error CS1002: ; expected + .And.HaveStdOutContaining("error CS1002") + .And.HaveStdErrContaining(CliCommandStrings.RunCommandException); + } + /// /// Default projects include embedded resources by default. ///