diff --git a/documentation/specs/proposed/BuildCheck.md b/documentation/specs/proposed/BuildCheck.md index 4fa78061b78..ea5c4f80376 100644 --- a/documentation/specs/proposed/BuildCheck.md +++ b/documentation/specs/proposed/BuildCheck.md @@ -75,15 +75,13 @@ Majority of following cases are included in appropriate context within the scena ```ini # I expect this to apply to all projects within my solution, but not to projects which are not part of the solution [ContosoFrontEnd.sln] -build_check.BC0101.IsEnabled=true build_check.BC0101.Severity=warning ``` * Attributing `.editorconfig` configurations to lower granularity than whole projects. E.g.: ```ini # I expect this to apply only to a scope of the imported file. Or possibly I expect this to apply to all projects importing this project. [ContosoCommonImport.proj] -buildcheck.BC0101.IsEnabled=true -buildcheck.BC0101.Severity=warning +build_check.BC0101.Severity=warning ``` * Respecting `.editorconfig` file in msbuild import locations (unless they are in the parent folders hierarchy of particular project file). * CodeFixes are not supported in V1 diff --git a/src/Build/BuildCheck/API/BuildAnalyzerConfiguration.cs b/src/Build/BuildCheck/API/BuildAnalyzerConfiguration.cs index ab817077725..f36ff6a0f3c 100644 --- a/src/Build/BuildCheck/API/BuildAnalyzerConfiguration.cs +++ b/src/Build/BuildCheck/API/BuildAnalyzerConfiguration.cs @@ -21,8 +21,7 @@ public class BuildAnalyzerConfiguration public static BuildAnalyzerConfiguration Default { get; } = new() { EvaluationAnalysisScope = BuildCheck.EvaluationAnalysisScope.ProjectOnly, - Severity = BuildAnalyzerResultSeverity.Info, - IsEnabled = false, + Severity = BuildAnalyzerResultSeverity.None }; public static BuildAnalyzerConfiguration Null { get; } = new(); @@ -45,7 +44,18 @@ public class BuildAnalyzerConfiguration /// If all rules within the analyzer are not enabled, it will not be run. /// If some rules are enabled and some are not, the analyzer will be run and reports will be post-filtered. /// - public bool? IsEnabled { get; internal init; } + public bool? IsEnabled { + get + { + // Do not consider Default as enabled, because the default severity of the rule coule be set to None + if (Severity.HasValue && Severity.Value != BuildAnalyzerResultSeverity.Default) + { + return !Severity.Value.Equals(BuildAnalyzerResultSeverity.None); + } + + return null; + } + } /// /// Creates a object based on the provided configuration dictionary. @@ -59,8 +69,7 @@ internal static BuildAnalyzerConfiguration Create(Dictionary? co return new() { EvaluationAnalysisScope = TryExtractValue(nameof(EvaluationAnalysisScope), configDictionary, out EvaluationAnalysisScope evaluationAnalysisScope) ? evaluationAnalysisScope : null, - Severity = TryExtractValue(nameof(Severity), configDictionary, out BuildAnalyzerResultSeverity severity) ? severity : null, - IsEnabled = TryExtractValue(nameof(IsEnabled), configDictionary, out bool isEnabled) ? isEnabled : null, + Severity = TryExtractValue(nameof(Severity), configDictionary, out BuildAnalyzerResultSeverity severity) ? severity : null }; } @@ -83,31 +92,6 @@ private static bool TryExtractValue(string key, Dictionary? c return isParsed; } - private static bool TryExtractValue(string key, Dictionary? config, out bool value) - { - value = default; - - if (config == null || !config.TryGetValue(key.ToLower(), out var stringValue) || stringValue is null) - { - return false; - } - - bool isParsed = false; - - if (bool.TryParse(stringValue, out bool boolValue)) - { - value = boolValue; - isParsed = true; - } - - if (!isParsed) - { - ThrowIncorrectValueException(key, stringValue); - } - - return isParsed; - } - private static void ThrowIncorrectValueException(string key, string value) { // TODO: It will be nice to have the filename where the incorrect configuration was placed. diff --git a/src/Build/BuildCheck/API/BuildAnalyzerResultSeverity.cs b/src/Build/BuildCheck/API/BuildAnalyzerResultSeverity.cs index 412a014be06..cd98bdbbf22 100644 --- a/src/Build/BuildCheck/API/BuildAnalyzerResultSeverity.cs +++ b/src/Build/BuildCheck/API/BuildAnalyzerResultSeverity.cs @@ -8,7 +8,28 @@ namespace Microsoft.Build.Experimental.BuildCheck; /// public enum BuildAnalyzerResultSeverity { - Info, + /// + /// When set, the default value of the BuildCheck rule will be used. + /// + Default, + + /// + /// When set to None the rule will not run. + /// + None, + + /// + /// Information level message. + /// + Suggestion, + + /// + /// Results a warning in build if the BuildCheck rule applied. + /// Warning, - Error, + + /// + /// Results an error in build if the BuildCheck rule applied. + /// + Error } diff --git a/src/Build/BuildCheck/API/BuildCheckResult.cs b/src/Build/BuildCheck/API/BuildCheckResult.cs index f6b54e1ed99..0f70c5228b7 100644 --- a/src/Build/BuildCheck/API/BuildCheckResult.cs +++ b/src/Build/BuildCheck/API/BuildCheckResult.cs @@ -31,7 +31,7 @@ public BuildCheckResult(BuildAnalyzerRule buildAnalyzerRule, ElementLocation loc internal BuildEventArgs ToEventArgs(BuildAnalyzerResultSeverity severity) => severity switch { - BuildAnalyzerResultSeverity.Info => new BuildCheckResultMessage(this), + BuildAnalyzerResultSeverity.Suggestion => new BuildCheckResultMessage(this), BuildAnalyzerResultSeverity.Warning => new BuildCheckResultWarning(this), BuildAnalyzerResultSeverity.Error => new BuildCheckResultError(this), _ => throw new ArgumentOutOfRangeException(nameof(severity), severity, null), diff --git a/src/Build/BuildCheck/Analyzers/DoubleWritesAnalyzer.cs b/src/Build/BuildCheck/Analyzers/DoubleWritesAnalyzer.cs index e5fc6b22cfd..6c1522c387d 100644 --- a/src/Build/BuildCheck/Analyzers/DoubleWritesAnalyzer.cs +++ b/src/Build/BuildCheck/Analyzers/DoubleWritesAnalyzer.cs @@ -23,7 +23,7 @@ internal sealed class DoubleWritesAnalyzer : BuildAnalyzer public static BuildAnalyzerRule SupportedRule = new BuildAnalyzerRule("BC0102", "DoubleWrites", "Two tasks should not write the same file", "Tasks {0} and {1} from projects {2} and {3} write the same file: {4}.", - new BuildAnalyzerConfiguration() { Severity = BuildAnalyzerResultSeverity.Warning, IsEnabled = true }); + new BuildAnalyzerConfiguration() { Severity = BuildAnalyzerResultSeverity.Warning }); public override string FriendlyName => "MSBuild.DoubleWritesAnalyzer"; diff --git a/src/Build/BuildCheck/Analyzers/SharedOutputPathAnalyzer.cs b/src/Build/BuildCheck/Analyzers/SharedOutputPathAnalyzer.cs index 74d0ba579a9..5da98f08463 100644 --- a/src/Build/BuildCheck/Analyzers/SharedOutputPathAnalyzer.cs +++ b/src/Build/BuildCheck/Analyzers/SharedOutputPathAnalyzer.cs @@ -18,7 +18,7 @@ internal sealed class SharedOutputPathAnalyzer : BuildAnalyzer public static BuildAnalyzerRule SupportedRule = new BuildAnalyzerRule("BC0101", "ConflictingOutputPath", "Two projects should not share their OutputPath nor IntermediateOutputPath locations", "Projects {0} and {1} have conflicting output paths: {2}.", - new BuildAnalyzerConfiguration() { Severity = BuildAnalyzerResultSeverity.Warning, IsEnabled = true }); + new BuildAnalyzerConfiguration() { Severity = BuildAnalyzerResultSeverity.Warning }); public override string FriendlyName => "MSBuild.SharedOutputPathAnalyzer"; diff --git a/src/Build/BuildCheck/Infrastructure/BuildAnalyzerConfigurationInternal.cs b/src/Build/BuildCheck/Infrastructure/BuildAnalyzerConfigurationInternal.cs index 9d7738922e7..b5ecb7c3f48 100644 --- a/src/Build/BuildCheck/Infrastructure/BuildAnalyzerConfigurationInternal.cs +++ b/src/Build/BuildCheck/Infrastructure/BuildAnalyzerConfigurationInternal.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using Microsoft.Build.Experimental.BuildCheck; namespace Microsoft.Build.Experimental.BuildCheck.Infrastructure; @@ -10,18 +11,25 @@ namespace Microsoft.Build.Experimental.BuildCheck.Infrastructure; /// internal sealed class BuildAnalyzerConfigurationInternal { - public BuildAnalyzerConfigurationInternal(string ruleId, EvaluationAnalysisScope evaluationAnalysisScope, BuildAnalyzerResultSeverity severity, bool isEnabled) + public BuildAnalyzerConfigurationInternal(string ruleId, EvaluationAnalysisScope evaluationAnalysisScope, BuildAnalyzerResultSeverity severity) { + if (severity == BuildAnalyzerResultSeverity.Default) + { + throw new ArgumentOutOfRangeException(nameof(severity), severity, "Severity 'Default' is not recognized by the BuildCheck reports infrastructure"); + } + RuleId = ruleId; EvaluationAnalysisScope = evaluationAnalysisScope; Severity = severity; - IsEnabled = isEnabled; } public string RuleId { get; } + public EvaluationAnalysisScope EvaluationAnalysisScope { get; } + public BuildAnalyzerResultSeverity Severity { get; } - public bool IsEnabled { get; } + + public bool IsEnabled => Severity >= BuildAnalyzerResultSeverity.Suggestion; // Intentionally not checking the RuleId // as for analyzers with multiple rules, we can squash config to a single one, @@ -29,6 +37,5 @@ public BuildAnalyzerConfigurationInternal(string ruleId, EvaluationAnalysisScope public bool IsSameConfigurationAs(BuildAnalyzerConfigurationInternal? other) => other != null && Severity == other.Severity && - IsEnabled == other.IsEnabled && EvaluationAnalysisScope == other.EvaluationAnalysisScope; } diff --git a/src/Build/BuildCheck/Infrastructure/ConfigurationProvider.cs b/src/Build/BuildCheck/Infrastructure/ConfigurationProvider.cs index ab2e298879b..1a06fc08ee1 100644 --- a/src/Build/BuildCheck/Infrastructure/ConfigurationProvider.cs +++ b/src/Build/BuildCheck/Infrastructure/ConfigurationProvider.cs @@ -33,7 +33,6 @@ internal sealed class ConfigurationProvider private readonly string[] _infrastructureConfigurationKeys = new string[] { nameof(BuildAnalyzerConfiguration.EvaluationAnalysisScope).ToLower(), - nameof(BuildAnalyzerConfiguration.IsEnabled).ToLower(), nameof(BuildAnalyzerConfiguration.Severity).ToLower() }; @@ -263,8 +262,7 @@ internal BuildAnalyzerConfigurationInternal MergeConfiguration( => new BuildAnalyzerConfigurationInternal( ruleId: ruleId, evaluationAnalysisScope: GetConfigValue(editorConfig, defaultConfig, cfg => cfg.EvaluationAnalysisScope), - isEnabled: GetConfigValue(editorConfig, defaultConfig, cfg => cfg.IsEnabled), - severity: GetConfigValue(editorConfig, defaultConfig, cfg => cfg.Severity)); + severity: GetSeverityValue(editorConfig, defaultConfig)); private BuildAnalyzerConfigurationInternal GetMergedConfiguration( string projectFullPath, @@ -280,6 +278,22 @@ private T GetConfigValue( propertyGetter(defaultValue) ?? EnsureNonNull(propertyGetter(BuildAnalyzerConfiguration.Default)); + private BuildAnalyzerResultSeverity GetSeverityValue(BuildAnalyzerConfiguration editorConfigValue, BuildAnalyzerConfiguration defaultValue) + { + BuildAnalyzerResultSeverity? resultSeverity = null; + + // Consider Default as null, so the severity from the default value could be selected. + // Default severity is not recognized by the infrastructure and serves for configuration purpuses only. + if (editorConfigValue.Severity != null && editorConfigValue.Severity != BuildAnalyzerResultSeverity.Default) + { + resultSeverity = editorConfigValue.Severity; + } + + resultSeverity ??= defaultValue.Severity ?? EnsureNonNull(BuildAnalyzerConfiguration.Default.Severity); + + return resultSeverity.Value; + } + private static T EnsureNonNull(T? value) where T : struct { if (value is null) diff --git a/src/Build/CompatibilitySuppressions.xml b/src/Build/CompatibilitySuppressions.xml new file mode 100644 index 00000000000..1fd3a166926 --- /dev/null +++ b/src/Build/CompatibilitySuppressions.xml @@ -0,0 +1,88 @@ + + + + + CP0002 + F:Microsoft.Build.Experimental.BuildCheck.BuildAnalyzerResultSeverity.Info + lib/net472/Microsoft.Build.dll + lib/net472/Microsoft.Build.dll + true + + + CP0002 + F:Microsoft.Build.Experimental.BuildCheck.BuildAnalyzerResultSeverity.Info + lib/net8.0/Microsoft.Build.dll + lib/net8.0/Microsoft.Build.dll + true + + + CP0002 + F:Microsoft.Build.Experimental.BuildCheck.BuildAnalyzerResultSeverity.Info + ref/net472/Microsoft.Build.dll + ref/net472/Microsoft.Build.dll + true + + + CP0002 + F:Microsoft.Build.Experimental.BuildCheck.BuildAnalyzerResultSeverity.Info + ref/net8.0/Microsoft.Build.dll + ref/net8.0/Microsoft.Build.dll + true + + + CP0011 + F:Microsoft.Build.Experimental.BuildCheck.BuildAnalyzerResultSeverity.Error + lib/net472/Microsoft.Build.dll + lib/net472/Microsoft.Build.dll + true + + + CP0011 + F:Microsoft.Build.Experimental.BuildCheck.BuildAnalyzerResultSeverity.Warning + lib/net472/Microsoft.Build.dll + lib/net472/Microsoft.Build.dll + true + + + CP0011 + F:Microsoft.Build.Experimental.BuildCheck.BuildAnalyzerResultSeverity.Error + lib/net8.0/Microsoft.Build.dll + lib/net8.0/Microsoft.Build.dll + true + + + CP0011 + F:Microsoft.Build.Experimental.BuildCheck.BuildAnalyzerResultSeverity.Warning + lib/net8.0/Microsoft.Build.dll + lib/net8.0/Microsoft.Build.dll + true + + + CP0011 + F:Microsoft.Build.Experimental.BuildCheck.BuildAnalyzerResultSeverity.Error + ref/net472/Microsoft.Build.dll + ref/net472/Microsoft.Build.dll + true + + + CP0011 + F:Microsoft.Build.Experimental.BuildCheck.BuildAnalyzerResultSeverity.Warning + ref/net472/Microsoft.Build.dll + ref/net472/Microsoft.Build.dll + true + + + CP0011 + F:Microsoft.Build.Experimental.BuildCheck.BuildAnalyzerResultSeverity.Error + ref/net8.0/Microsoft.Build.dll + ref/net8.0/Microsoft.Build.dll + true + + + CP0011 + F:Microsoft.Build.Experimental.BuildCheck.BuildAnalyzerResultSeverity.Warning + ref/net8.0/Microsoft.Build.dll + ref/net8.0/Microsoft.Build.dll + true + + \ No newline at end of file diff --git a/src/BuildCheck.UnitTests/BuildAnalyzerConfigurationInternalTests.cs b/src/BuildCheck.UnitTests/BuildAnalyzerConfigurationInternalTests.cs index 7bd57f8014b..2c559ffbe29 100644 --- a/src/BuildCheck.UnitTests/BuildAnalyzerConfigurationInternalTests.cs +++ b/src/BuildCheck.UnitTests/BuildAnalyzerConfigurationInternalTests.cs @@ -5,34 +5,59 @@ using Microsoft.Build.Experimental.BuildCheck.Infrastructure; using Microsoft.Build.Experimental.BuildCheck; using Shouldly; +using System; namespace Microsoft.Build.BuildCheck.UnitTests; public class BuildAnalyzerConfigurationInternalTests { [Theory] - [InlineData("ruleId", EvaluationAnalysisScope.ProjectOnly, BuildAnalyzerResultSeverity.Warning, true, true)] - [InlineData("ruleId2", EvaluationAnalysisScope.ProjectOnly, BuildAnalyzerResultSeverity.Warning, true, true)] - [InlineData("ruleId", EvaluationAnalysisScope.ProjectOnly, BuildAnalyzerResultSeverity.Error, true, false)] + [InlineData("ruleId", EvaluationAnalysisScope.ProjectOnly, BuildAnalyzerResultSeverity.Warning, true)] + [InlineData("ruleId2", EvaluationAnalysisScope.ProjectOnly, BuildAnalyzerResultSeverity.Warning, true)] + [InlineData("ruleId", EvaluationAnalysisScope.ProjectOnly, BuildAnalyzerResultSeverity.Error, false)] public void IsSameConfigurationAsTest( string secondRuleId, EvaluationAnalysisScope secondScope, BuildAnalyzerResultSeverity secondSeverity, - bool secondEnabled, bool isExpectedToBeSame) { BuildAnalyzerConfigurationInternal configuration1 = new BuildAnalyzerConfigurationInternal( ruleId: "ruleId", evaluationAnalysisScope: EvaluationAnalysisScope.ProjectOnly, - severity: BuildAnalyzerResultSeverity.Warning, - isEnabled: true); + severity: BuildAnalyzerResultSeverity.Warning); BuildAnalyzerConfigurationInternal configuration2 = new BuildAnalyzerConfigurationInternal( ruleId: secondRuleId, evaluationAnalysisScope: secondScope, - severity: secondSeverity, - isEnabled: secondEnabled); + severity: secondSeverity); configuration1.IsSameConfigurationAs(configuration2).ShouldBe(isExpectedToBeSame); } + + [Theory] + [InlineData( BuildAnalyzerResultSeverity.Warning, true)] + [InlineData(BuildAnalyzerResultSeverity.Suggestion, true)] + [InlineData(BuildAnalyzerResultSeverity.Error, true)] + [InlineData(BuildAnalyzerResultSeverity.None, false)] + public void BuildAnalyzerConfigurationInternal_Constructor_SeverityConfig(BuildAnalyzerResultSeverity severity, bool isEnabledExpected) + { + BuildAnalyzerConfigurationInternal configuration = new BuildAnalyzerConfigurationInternal( + ruleId: "ruleId", + evaluationAnalysisScope: EvaluationAnalysisScope.ProjectOnly, + severity: severity); + + configuration.IsEnabled.ShouldBe(isEnabledExpected); + } + + [Fact] + public void BuildAnalyzerConfigurationInternal_Constructor_SeverityConfig_Fails() + { + Should.Throw(() => + { + new BuildAnalyzerConfigurationInternal( + ruleId: "ruleId", + evaluationAnalysisScope: EvaluationAnalysisScope.ProjectOnly, + severity: BuildAnalyzerResultSeverity.Default); + }); + } } diff --git a/src/BuildCheck.UnitTests/BuildAnalyzerConfiguration_Test.cs b/src/BuildCheck.UnitTests/BuildAnalyzerConfiguration_Test.cs index edfdfaf4589..f1aff479f9e 100644 --- a/src/BuildCheck.UnitTests/BuildAnalyzerConfiguration_Test.cs +++ b/src/BuildCheck.UnitTests/BuildAnalyzerConfiguration_Test.cs @@ -33,43 +33,45 @@ public void CreateWithEmpty_ReturnsObjectWithNullValues() [Theory] [InlineData("error", BuildAnalyzerResultSeverity.Error)] - [InlineData("info", BuildAnalyzerResultSeverity.Info)] + [InlineData("ERROR", BuildAnalyzerResultSeverity.Error)] + [InlineData("suggestion", BuildAnalyzerResultSeverity.Suggestion)] + [InlineData("SUGGESTION", BuildAnalyzerResultSeverity.Suggestion)] [InlineData("warning", BuildAnalyzerResultSeverity.Warning)] [InlineData("WARNING", BuildAnalyzerResultSeverity.Warning)] + [InlineData("NONE", BuildAnalyzerResultSeverity.None)] + [InlineData("none", BuildAnalyzerResultSeverity.None)] + [InlineData("default", BuildAnalyzerResultSeverity.Default)] + [InlineData("DEFAULT", BuildAnalyzerResultSeverity.Default)] public void CreateBuildAnalyzerConfiguration_Severity(string parameter, BuildAnalyzerResultSeverity? expected) { var config = new Dictionary() { { "severity" , parameter }, }; + var buildConfig = BuildAnalyzerConfiguration.Create(config); buildConfig.ShouldNotBeNull(); buildConfig.Severity.ShouldBe(expected); - - buildConfig.IsEnabled.ShouldBeNull(); buildConfig.EvaluationAnalysisScope.ShouldBeNull(); } [Theory] - [InlineData("true", true)] - [InlineData("TRUE", true)] - [InlineData("false", false)] - [InlineData("FALSE", false)] - public void CreateBuildAnalyzerConfiguration_IsEnabled(string parameter, bool? expected) + [InlineData("error", true)] + [InlineData("warning", true)] + [InlineData("suggestion", true)] + [InlineData("none", false)] + [InlineData("default", null)] + public void CreateBuildAnalyzerConfiguration_SeverityAndEnabledOrder(string parameter, bool? expected) { var config = new Dictionary() { - { "isenabled" , parameter }, + { "severity", parameter }, }; - + var buildConfig = BuildAnalyzerConfiguration.Create(config); - buildConfig.ShouldNotBeNull(); buildConfig.IsEnabled.ShouldBe(expected); - - buildConfig.Severity.ShouldBeNull(); - buildConfig.EvaluationAnalysisScope.ShouldBeNull(); } [Theory] @@ -96,7 +98,6 @@ public void CreateBuildAnalyzerConfiguration_EvaluationAnalysisScope(string para [Theory] [InlineData("evaluationanalysisscope", "incorrec-value")] - [InlineData("isenabled", "incorrec-value")] [InlineData("severity", "incorrec-value")] public void CreateBuildAnalyzerConfiguration_ExceptionOnInvalidInputValue(string key, string value) { diff --git a/src/BuildCheck.UnitTests/ConfigurationProvider_Tests.cs b/src/BuildCheck.UnitTests/ConfigurationProvider_Tests.cs index d559e1724b1..d4fdb9d49df 100644 --- a/src/BuildCheck.UnitTests/ConfigurationProvider_Tests.cs +++ b/src/BuildCheck.UnitTests/ConfigurationProvider_Tests.cs @@ -76,7 +76,6 @@ public void GetRuleIdConfiguration_CustomConfigurationData() [*.csproj] build_check.rule_id.property1=value1 build_check.rule_id.property2=value2 - build_check.rule_id.isEnabled=true build_check.rule_id.isEnabled2=true any_other_key1=any_other_value1 any_other_key2=any_other_value2 @@ -106,7 +105,6 @@ public void GetRuleIdConfiguration_ReturnsBuildRuleConfiguration() root=true [*.csproj] - build_check.rule_id.isEnabled=true build_check.rule_id.Severity=Error build_check.rule_id.EvaluationAnalysisScope=ProjectOnly """); @@ -134,13 +132,11 @@ public void GetRuleIdConfiguration_CustomConfigurationValidity_NotValid_Differen [*.csproj] build_check.rule_id.property1=value1 build_check.rule_id.property2=value2 - build_check.rule_id.isEnabled=true build_check.rule_id.isEnabled2=true [test123.csproj] build_check.rule_id.property1=value2 build_check.rule_id.property2=value3 - build_check.rule_id.isEnabled=true build_check.rule_id.isEnabled2=tru1 """); @@ -199,13 +195,11 @@ public void GetRuleIdConfiguration_CustomConfigurationValidity_Valid() [*.csproj] build_check.rule_id.property1=value1 build_check.rule_id.property2=value2 - build_check.rule_id.isEnabled=true build_check.rule_id.isEnabled2=true [test123.csproj] build_check.rule_id.property1=value1 build_check.rule_id.property2=value2 - build_check.rule_id.isEnabled=true build_check.rule_id.isEnabled2=true """); @@ -218,4 +212,29 @@ public void GetRuleIdConfiguration_CustomConfigurationValidity_Valid() configurationProvider.CheckCustomConfigurationDataValidity(Path.Combine(workFolder1.Path, "test123.csproj"), "rule_id"); }); } + + [Theory] + [InlineData(BuildAnalyzerResultSeverity.Warning, BuildAnalyzerResultSeverity.Warning, true)] + [InlineData(BuildAnalyzerResultSeverity.Error, BuildAnalyzerResultSeverity.Error, true)] + [InlineData(BuildAnalyzerResultSeverity.Default, BuildAnalyzerResultSeverity.Warning, true)] + [InlineData(BuildAnalyzerResultSeverity.Suggestion, BuildAnalyzerResultSeverity.Suggestion, true)] + [InlineData(BuildAnalyzerResultSeverity.None, BuildAnalyzerResultSeverity.None, false)] + [InlineData(null, BuildAnalyzerResultSeverity.Warning, true)] + public void GetConfigurationProvider_MergesSeverity_Correctly(BuildAnalyzerResultSeverity? buildAnalyzerResultSeverity, BuildAnalyzerResultSeverity expectedSeverity, bool expectedEnablment) + { + var configurationProvider = new ConfigurationProvider(); + BuildAnalyzerConfiguration buildAnalyzerConfiguration = new BuildAnalyzerConfiguration() + { + Severity = buildAnalyzerResultSeverity + }; + + BuildAnalyzerConfiguration defaultValue = new BuildAnalyzerConfiguration() + { + Severity = BuildAnalyzerResultSeverity.Warning + }; + + var internalBuildAnalyzer = configurationProvider.MergeConfiguration("ruleId", defaultValue, buildAnalyzerConfiguration); + internalBuildAnalyzer.Severity.ShouldBe(expectedSeverity); + internalBuildAnalyzer.IsEnabled.ShouldBe(expectedEnablment); + } } diff --git a/src/BuildCheck.UnitTests/EndToEndTests.cs b/src/BuildCheck.UnitTests/EndToEndTests.cs index d3b68e4a80d..4436fd2436c 100644 --- a/src/BuildCheck.UnitTests/EndToEndTests.cs +++ b/src/BuildCheck.UnitTests/EndToEndTests.cs @@ -202,18 +202,14 @@ private void PrepareSampleProjectsAndConfig( root=true [*.csproj] - build_check.BC0101.IsEnabled=true build_check.BC0101.Severity={BC0101Severity} - build_check.BC0102.IsEnabled=true build_check.BC0102.Severity=warning - build_check.COND0543.IsEnabled=false build_check.COND0543.Severity=Error build_check.COND0543.EvaluationAnalysisScope=AnalyzedProjectOnly build_check.COND0543.CustomSwitch=QWERTY - build_check.BLA.IsEnabled=false """); // OSX links /var into /private, which makes Path.GetTempPath() return "/var..." but Directory.GetCurrentDirectory return "/private/var...". diff --git a/src/BuildCheck.UnitTests/TaskInvocationAnalysisDataTests.cs b/src/BuildCheck.UnitTests/TaskInvocationAnalysisDataTests.cs index e0600fc657c..1dea240c976 100644 --- a/src/BuildCheck.UnitTests/TaskInvocationAnalysisDataTests.cs +++ b/src/BuildCheck.UnitTests/TaskInvocationAnalysisDataTests.cs @@ -24,7 +24,7 @@ internal sealed class TestAnalyzer : BuildAnalyzer #region BuildAnalyzer initialization public static BuildAnalyzerRule SupportedRule = new BuildAnalyzerRule("BC0000", "TestRule", "TestDescription", "TestMessage", - new BuildAnalyzerConfiguration() { Severity = BuildAnalyzerResultSeverity.Warning, IsEnabled = true }); + new BuildAnalyzerConfiguration() { Severity = BuildAnalyzerResultSeverity.Warning }); public override string FriendlyName => "MSBuild.TestAnalyzer";