diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/Common/CommonOptions.cs b/src/Cli/Microsoft.DotNet.Cli.Definitions/Common/CommonOptions.cs index fb71ab59bf6b..b3c9b952f58f 100644 --- a/src/Cli/Microsoft.DotNet.Cli.Definitions/Common/CommonOptions.cs +++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/Common/CommonOptions.cs @@ -201,7 +201,12 @@ public static Option CreateUseCurrentRuntimeOption(string description) => { Description = description, HelpName = CommandDefinitionStrings.ConfigurationArgumentName, - IsDynamic = true + IsDynamic = true, + DefaultValueFactory = _ => + { + string? configuration = Environment.GetEnvironmentVariable("Configuration"); + return string.IsNullOrWhiteSpace(configuration) ? null : configuration; + } }.ForwardAsSingle(o => $"--property:Configuration={o}"); public static Option CreateVersionSuffixOption() => @@ -380,4 +385,3 @@ public static void ValidateSelfContainedOptions(bool hasSelfContainedOption, boo Arity = ArgumentArity.Zero }; } - diff --git a/src/Cli/Microsoft.DotNet.Cli.Definitions/Help/HelpBuilder.cs b/src/Cli/Microsoft.DotNet.Cli.Definitions/Help/HelpBuilder.cs index 4b79d871777c..4975f91d6c65 100644 --- a/src/Cli/Microsoft.DotNet.Cli.Definitions/Help/HelpBuilder.cs +++ b/src/Cli/Microsoft.DotNet.Cli.Definitions/Help/HelpBuilder.cs @@ -253,8 +253,10 @@ string GetSymbolDefaultValue(Symbol symbol) var isSingleArgument = defaultArguments.Length == 1; var argumentDefaultValues = defaultArguments - .Select(argument => GetArgumentDefaultValue(symbol, argument, isSingleArgument, context)); - return $"[{string.Join(", ", argumentDefaultValues)}]"; + .Select(argument => GetArgumentDefaultValue(symbol, argument, isSingleArgument, context)) + .Where(value => !string.IsNullOrWhiteSpace(value)) + .ToArray(); + return argumentDefaultValues.Length == 0 ? "" : $"[{string.Join(", ", argumentDefaultValues)}]"; } } diff --git a/test/dotnet.Tests/CliSchemaTests.cs b/test/dotnet.Tests/CliSchemaTests.cs index 467d3cbc609b..e897f372b3d4 100644 --- a/test/dotnet.Tests/CliSchemaTests.cs +++ b/test/dotnet.Tests/CliSchemaTests.cs @@ -77,7 +77,7 @@ public CliSchemaTests() ], "helpName": "CONFIGURATION", "valueType": "System.String", - "hasDefaultValue": false, + "hasDefaultValue": true, "arity": { "minimum": 1, "maximum": 1 @@ -799,7 +799,7 @@ public CliSchemaTests() ], "helpName": "CONFIGURATION", "valueType": "System.String", - "hasDefaultValue": false, + "hasDefaultValue": true, "arity": { "minimum": 1, "maximum": 1 diff --git a/test/dotnet.Tests/CommandTests/Test/GivenDotnetTestBuildsAndRunsTestsWithDifferentOptions.cs b/test/dotnet.Tests/CommandTests/Test/GivenDotnetTestBuildsAndRunsTestsWithDifferentOptions.cs index 2e139459aab6..e995ea20d5ac 100644 --- a/test/dotnet.Tests/CommandTests/Test/GivenDotnetTestBuildsAndRunsTestsWithDifferentOptions.cs +++ b/test/dotnet.Tests/CommandTests/Test/GivenDotnetTestBuildsAndRunsTestsWithDifferentOptions.cs @@ -55,6 +55,21 @@ public void RunWithSolutionPathWithFailingTests_ShouldReturnExitCodeAtLeastOneTe result.ExitCode.Should().Be(ExitCodes.AtLeastOneTestFailed); } + [TestMethod] + public void RunWithSolutionPath_ShouldUseConfigurationEnvironmentVariable() + { + TestAsset testInstance = TestAssetsManager.CopyTestAsset("MultiTestProjectSolutionWithTests", Guid.NewGuid().ToString()).WithSource(); + + CommandResult result = new DotnetTestCommand(Log, disableNewOutput: false) + .WithWorkingDirectory(testInstance.Path) + .WithEnvironmentVariable("Configuration", TestingConstants.Release) + .Execute("--solution", "MultiTestProjectSolutionWithTests.sln"); + + Assert.MatchesRegex(RegexPatternHelper.GenerateProjectRegexPattern("TestProject", TestingConstants.Failed, true, TestingConstants.Release), result.StdOut); + Assert.MatchesRegex(RegexPatternHelper.GenerateProjectRegexPattern("OtherTestProject", TestingConstants.Passed, true, TestingConstants.Release), result.StdOut); + result.ExitCode.Should().Be(ExitCodes.AtLeastOneTestFailed); + } + [TestMethod, CombinatorialData] public void RunWithSolutionFilterPathWithFailingTests_ShouldReturnExitCodeGenericFailure( [CombinatorialValues(TestingConstants.Debug, TestingConstants.Release)] string configuration, diff --git a/test/dotnet.Tests/ParserTests/CommonOptionsTests.cs b/test/dotnet.Tests/ParserTests/CommonOptionsTests.cs index 2419e57e9d0c..d098fc233ce3 100644 --- a/test/dotnet.Tests/ParserTests/CommonOptionsTests.cs +++ b/test/dotnet.Tests/ParserTests/CommonOptionsTests.cs @@ -3,12 +3,87 @@ using System.CommandLine; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.CommandLine; namespace Microsoft.DotNet.Tests.ParserTests; [TestClass] public class CommonOptionsTests { + [TestMethod] + public void ConfigurationDefaultsToEnvironmentVariable() + { + string? originalConfiguration = Environment.GetEnvironmentVariable("Configuration"); + + try + { + Environment.SetEnvironmentVariable("Configuration", "EnvironmentConfiguration"); + var command = new RootCommand(); + var option = CommonOptions.CreateConfigurationOption("Configuration"); + command.Options.Add(option); + + var result = command.Parse([]); + + result.GetValue(option).Should().Be("EnvironmentConfiguration"); + result.OptionValuesToBeForwarded(command).Should().ContainSingle() + .Which.Should().Be("--property:Configuration=EnvironmentConfiguration"); + } + finally + { + Environment.SetEnvironmentVariable("Configuration", originalConfiguration); + } + } + + [TestMethod] + public void ExplicitConfigurationOverridesEnvironmentVariable() + { + string? originalConfiguration = Environment.GetEnvironmentVariable("Configuration"); + + try + { + Environment.SetEnvironmentVariable("Configuration", "EnvironmentConfiguration"); + var command = new RootCommand(); + var option = CommonOptions.CreateConfigurationOption("Configuration"); + command.Options.Add(option); + + var result = command.Parse(["--configuration", "ExplicitConfiguration"]); + + result.GetValue(option).Should().Be("ExplicitConfiguration"); + result.OptionValuesToBeForwarded(command).Should().ContainSingle() + .Which.Should().Be("--property:Configuration=ExplicitConfiguration"); + } + finally + { + Environment.SetEnvironmentVariable("Configuration", originalConfiguration); + } + } + + [TestMethod] + [DataRow("")] + [DataRow(" ")] + [DataRow("\t")] + public void EmptyOrWhitespaceConfigurationEnvironmentVariableIsIgnored(string configuration) + { + string? originalConfiguration = Environment.GetEnvironmentVariable("Configuration"); + + try + { + Environment.SetEnvironmentVariable("Configuration", configuration); + var command = new RootCommand(); + var option = CommonOptions.CreateConfigurationOption("Configuration"); + command.Options.Add(option); + + var result = command.Parse([]); + + result.GetValue(option).Should().BeNull(); + result.OptionValuesToBeForwarded(command).Should().BeEmpty(); + } + finally + { + Environment.SetEnvironmentVariable("Configuration", originalConfiguration); + } + } + [TestMethod] public void Duplicates() {