diff --git a/README.md b/README.md index 1f18c025..32882bf9 100644 --- a/README.md +++ b/README.md @@ -553,13 +553,13 @@ The optional `CodeAnalysisRules` property allows you to disable individual rules Any rule violations found during analysis are reported as build warnings. -Individual rule violations can be configured to be reported as build errors as shown below. +Individual rule violations or groups of rules can be configured to be reported as build errors as shown below. ```xml True - +!SqlServer.Rules.SRN0005 + +!SqlServer.Rules.SRN0005;+!SqlServer.Rules.SRD* ``` diff --git a/src/DacpacTool/SqlRuleProblemExtensions.cs b/src/DacpacTool/SqlRuleProblemExtensions.cs index 07f50623..8992036f 100644 --- a/src/DacpacTool/SqlRuleProblemExtensions.cs +++ b/src/DacpacTool/SqlRuleProblemExtensions.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; using Microsoft.SqlServer.Dac.CodeAnalysis; @@ -20,6 +21,13 @@ public static string GetOutputMessage(this SqlRuleProblem sqlRuleProblem, HashSe { sqlRuleProblemSeverity = SqlRuleProblemSeverity.Error; } + + var wildCardErrorRules = errorRules + .Where(r => r.EndsWith("*", StringComparison.OrdinalIgnoreCase)); + if (wildCardErrorRules.Any(s => sqlRuleProblem.RuleId.StartsWith(s[..^1]))) + { + sqlRuleProblemSeverity = SqlRuleProblemSeverity.Error; + } var stringBuilder = new StringBuilder(); stringBuilder.Append(sqlRuleProblem.SourceName); diff --git a/test/DacpacTool.Tests/PackageAnalyzerTests.cs b/test/DacpacTool.Tests/PackageAnalyzerTests.cs index 9ea15d96..7d9a9d87 100644 --- a/test/DacpacTool.Tests/PackageAnalyzerTests.cs +++ b/test/DacpacTool.Tests/PackageAnalyzerTests.cs @@ -74,6 +74,49 @@ public void RunsAnalyzerWithWildcardSupressions() testConsole.Lines.ShouldContain($"Successfully analyzed package '{result.fileInfo.FullName}'"); } + [TestMethod] + public void RunsAnalyzerWithWarningsAsErrors() + { + // Arrange + var testConsole = (TestConsole)_console; + testConsole.Lines.Clear(); + var result = BuildSimpleModel(); + var packageAnalyzer = new PackageAnalyzer(_console, "+!SqlServer.Rules.SRD0006"); + + // Act + packageAnalyzer.Analyze(result.model, result.fileInfo); + + // Assert + testConsole.Lines.Count.ShouldBe(15); + + testConsole.Lines.ShouldContain($"Analyzing package '{result.fileInfo.FullName}'"); + testConsole.Lines.ShouldContain($"proc1.sql(1,47): Error SRD0006 : SqlServer.Rules : Avoid using SELECT *."); + testConsole.Lines.Count(l => l.Contains("Error ")).ShouldBe(1); + testConsole.Lines.ShouldContain($"Successfully analyzed package '{result.fileInfo.FullName}'"); + } + + [TestMethod] + public void RunsAnalyzerWithWarningsAsErrorsUsingWildcard() + { + // Arrange + var testConsole = (TestConsole)_console; + testConsole.Lines.Clear(); + var result = BuildSimpleModel(); + var packageAnalyzer = new PackageAnalyzer(_console, "+!SqlServer.Rules.SRD*"); + + // Act + packageAnalyzer.Analyze(result.model, result.fileInfo); + + // Assert + testConsole.Lines.Count.ShouldBe(15); + + testConsole.Lines.ShouldContain($"Analyzing package '{result.fileInfo.FullName}'"); + testConsole.Lines.ShouldContain($"proc1.sql(1,47): Error SRD0006 : SqlServer.Rules : Avoid using SELECT *."); + testConsole.Lines.ShouldContain($"-1(1,1): Error SRD0002 : SqlServer.Rules : Table does not have a primary key."); + testConsole.Lines.Count(l => l.Contains("): Error ")).ShouldBe(2); + testConsole.Lines.ShouldContain($"Successfully analyzed package '{result.fileInfo.FullName}'"); + } + private static (FileInfo fileInfo, TSqlModel model) BuildSimpleModel() { var tmodel = new TestModelBuilder()