From 181fbcc1864c8e01cff91a836f1951055facb549 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Thu, 21 Jun 2018 20:00:53 +0200 Subject: [PATCH 1/4] Fix file name in example --- src/Cake.Issues.MsBuild/MsBuildIssuesAliases.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cake.Issues.MsBuild/MsBuildIssuesAliases.cs b/src/Cake.Issues.MsBuild/MsBuildIssuesAliases.cs index 16a869c..fee946b 100644 --- a/src/Cake.Issues.MsBuild/MsBuildIssuesAliases.cs +++ b/src/Cake.Issues.MsBuild/MsBuildIssuesAliases.cs @@ -144,7 +144,7 @@ public static ILogFileFormat MsBuildXmlFileLoggerFormat( /// var issues = /// ReadIssues( /// MsBuildIssuesFromFilePath( - /// @"c:\build\InspectCode.log", + /// @"c:\build\msbuild.xml", /// MsBuildXmlFileLoggerFormat), /// @"c:\repo"); /// ]]> @@ -211,7 +211,7 @@ public static IIssueProvider MsBuildIssuesFromContent( /// Date: Mon, 25 Jun 2018 21:16:45 +0200 Subject: [PATCH 2/4] (GH-10) Return project --- .../Cake.Issues.MsBuild.Tests.csproj | 2 + .../Testfiles/FullLog.xml | 925 ++++++++++++++++++ .../XmlFileLoggerFormatTests.cs | 191 ++++ .../XmlFileLoggerFormat.cs | 52 + 4 files changed, 1170 insertions(+) create mode 100644 src/Cake.Issues.MsBuild.Tests/Testfiles/FullLog.xml diff --git a/src/Cake.Issues.MsBuild.Tests/Cake.Issues.MsBuild.Tests.csproj b/src/Cake.Issues.MsBuild.Tests/Cake.Issues.MsBuild.Tests.csproj index e10406e..b572ebf 100644 --- a/src/Cake.Issues.MsBuild.Tests/Cake.Issues.MsBuild.Tests.csproj +++ b/src/Cake.Issues.MsBuild.Tests/Cake.Issues.MsBuild.Tests.csproj @@ -15,6 +15,7 @@ + @@ -23,6 +24,7 @@ + diff --git a/src/Cake.Issues.MsBuild.Tests/Testfiles/FullLog.xml b/src/Cake.Issues.MsBuild.Tests/Testfiles/FullLog.xml new file mode 100644 index 0000000..a4af77e --- /dev/null +++ b/src/Cake.Issues.MsBuild.Tests/Testfiles/FullLog.xml @@ -0,0 +1,925 @@ + + + + + + + Debug|AnyCPU +' == '') and ('' != 'true')).]]> + + Debug|AnyCPU +' == '') and ('' == 'true')).]]> + + + + + + + + + + + + + + + + Debug|AnyCPU +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Count())' != '0' and '$(ReferringTargetFrameworkForProjectReferences)' != '') was evaluated as ('0' != '0' and '.NETFramework,Version=v4.5.2' != '').]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '%(WithCulture)') != '') was evaluated as ( != '').]]> + + + + + + '%(WithCulture)') != '') was evaluated as ( != '').]]> + + + + + + + + + + + + + + + + + + + + + + + + + + C:\Source\Cake.Issues.MsBuild\src\ClassLibrary1\bin\Debug\ClassLibrary1.dll]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 19 + 0 + 30.05.2018 12:16:00 + 30.05.2018 12:16:09 + 00:00:09.5536676 + \ No newline at end of file diff --git a/src/Cake.Issues.MsBuild.Tests/XmlFileLoggerFormatTests.cs b/src/Cake.Issues.MsBuild.Tests/XmlFileLoggerFormatTests.cs index f9e6f26..c39f578 100644 --- a/src/Cake.Issues.MsBuild.Tests/XmlFileLoggerFormatTests.cs +++ b/src/Cake.Issues.MsBuild.Tests/XmlFileLoggerFormatTests.cs @@ -23,6 +23,190 @@ public void Should_Throw_If_Log_Is_Null() public sealed class TheReadIssuesMethod { + [Fact] + public void Should_Read_Full_Log_Correct() + { + // Given + var fixture = new MsBuildIssuesProviderFixture("FullLog.xml"); + + // When + var issues = fixture.ReadIssues().ToList(); + + // Then + issues.Count.ShouldBe(19); + CheckIssue( + issues[0], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Class1.cs", + 13, + "CS0219", + 300, + "Warning", + @"The variable 'foo' is assigned but its value is never used"); + CheckIssue( + issues[1], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Class1.cs", + 1, + "SA1652", + 300, + "Warning", + @"Enable XML documentation output"); + CheckIssue( + issues[2], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Class1.cs", + 1, + "SA1633", + 300, + "Warning", + @"The file header is missing or not located at the top of the file."); + CheckIssue( + issues[3], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Class1.cs", + 1, + "SA1200", + 300, + "Warning", + @"Using directive must appear within a namespace declaration"); + CheckIssue( + issues[4], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Class1.cs", + 2, + "SA1200", + 300, + "Warning", + @"Using directive must appear within a namespace declaration"); + CheckIssue( + issues[5], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Class1.cs", + 3, + "SA1200", + 300, + "Warning", + @"Using directive must appear within a namespace declaration"); + CheckIssue( + issues[6], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Class1.cs", + 4, + "SA1200", + 300, + "Warning", + @"Using directive must appear within a namespace declaration"); + CheckIssue( + issues[7], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Class1.cs", + 5, + "SA1200", + 300, + "Warning", + @"Using directive must appear within a namespace declaration"); + CheckIssue( + issues[8], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Properties\AssemblyInfo.cs", + 1, + "SA1652", + 300, + "Warning", + @"Enable XML documentation output"); + CheckIssue( + issues[9], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Properties\AssemblyInfo.cs", + 1, + "SA1633", + 300, + "Warning", + @"The file header is missing or not located at the top of the file."); + CheckIssue( + issues[10], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Properties\AssemblyInfo.cs", + 5, + "SA1028", + 300, + "Warning", + @"Code must not contain trailing whitespace"); + CheckIssue( + issues[11], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Properties\AssemblyInfo.cs", + 17, + "SA1028", + 300, + "Warning", + @"Code must not contain trailing whitespace"); + CheckIssue( + issues[12], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Properties\AssemblyInfo.cs", + 18, + "SA1028", + 300, + "Warning", + @"Code must not contain trailing whitespace"); + CheckIssue( + issues[13], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Properties\AssemblyInfo.cs", + 28, + "SA1028", + 300, + "Warning", + @"Code must not contain trailing whitespace"); + CheckIssue( + issues[14], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Properties\AssemblyInfo.cs", + 32, + "SA1028", + 300, + "Warning", + @"Code must not contain trailing whitespace"); + CheckIssue( + issues[15], + @"src\ClassLibrary1\ClassLibrary1.csproj", + null, + null, + "CA2210", + 300, + "Warning", + @"Microsoft.Design : Sign 'ClassLibrary1.dll' with a strong name key."); + CheckIssue( + issues[16], + @"src\ClassLibrary1\ClassLibrary1.csproj", + null, + null, + "CA1014", + 300, + "Warning", + @"Microsoft.Design : Mark 'ClassLibrary1.dll' with CLSCompliant(true) because it exposes externally visible types."); + CheckIssue( + issues[17], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Class1.cs", + 12, + "CA1822", + 300, + "Warning", + @"Microsoft.Performance : The 'this' parameter (or 'Me' in Visual Basic) of 'Class1.Foo()' is never used. Mark the member as static (or Shared in Visual Basic) or use 'this'/'Me' in the method body or at least one property accessor, if appropriate."); + CheckIssue( + issues[18], + @"src\ClassLibrary1\ClassLibrary1.csproj", + @"src\ClassLibrary1\Class1.cs", + 13, + "CA1804", + 300, + "Warning", + @"Microsoft.Performance : 'Class1.Foo()' declares a variable, 'foo', of type 'string', which is never used or is only assigned to. Use this variable or remove it."); + } + [Fact] public void Should_Read_Issue_With_File_Correct() { @@ -37,6 +221,7 @@ public void Should_Read_Issue_With_File_Correct() var issue = issues.Single(); CheckIssue( issue, + string.Empty, @"src\Cake.Issues.MsBuild.Tests\MsBuildIssuesProviderTests.cs", 1311, "CA2201", @@ -59,6 +244,7 @@ public void Should_Read_Issue_With_File_Without_Path_Correct() var issue = issues.Single(); CheckIssue( issue, + string.Empty, @"src\Cake.Issues.MsBuild.Tests\MsBuildIssuesProviderTests.cs", 13, "CS0219", @@ -81,6 +267,7 @@ public void Should_Read_Issue_With_Line_Zero_Correct() var issue = issues.Single(); CheckIssue( issue, + @"Cake.Prca.shfbproj", @"SHFB", null, "BE0006", @@ -103,6 +290,7 @@ public void Should_Read_Issue_Without_File_Correct() var issue = issues.Single(); CheckIssue( issue, + string.Empty, null, null, "CA1711", @@ -125,6 +313,7 @@ public void Should_Read_Issue_Without_Code_Correct() var issue = issues.Single(); CheckIssue( issue, + string.Empty, @"src\Cake.Issues.MsBuild.Tests\MsBuildIssuesProviderTests.cs", 21, null, @@ -135,6 +324,7 @@ public void Should_Read_Issue_Without_Code_Correct() private static void CheckIssue( IIssue issue, + string project, string affectedFileRelativePath, int? line, string rule, @@ -144,6 +334,7 @@ private static void CheckIssue( { issue.ProviderType.ShouldBe("Cake.Issues.MsBuild.MsBuildIssuesProvider"); issue.ProviderName.ShouldBe("MSBuild"); + issue.Project.ShouldBe(project); if (issue.AffectedFileRelativePath == null) { diff --git a/src/Cake.Issues.MsBuild/XmlFileLoggerFormat.cs b/src/Cake.Issues.MsBuild/XmlFileLoggerFormat.cs index b323797..ef23aac 100644 --- a/src/Cake.Issues.MsBuild/XmlFileLoggerFormat.cs +++ b/src/Cake.Issues.MsBuild/XmlFileLoggerFormat.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; + using System.Linq; using System.Xml.Linq; using Core.Diagnostics; @@ -38,6 +39,12 @@ public override IEnumerable ReadIssues( // Loop through all warning tags. foreach (var warning in logDocument.Descendants("warning")) { + // Read affected project from the warning. + if (!TryGetProject(warning, repositorySettings, out string project)) + { + continue; + } + // Read affected file from the warning. if (!this.TryGetFile(warning, repositorySettings, out string fileName)) { @@ -68,6 +75,7 @@ public override IEnumerable ReadIssues( IssueBuilder .NewIssue(warning.Value, issueProvider) .WithPriority(IssuePriority.Warning) + .InProject(project) .InFile(fileName, line) .OfRule(rule, ruleUrl) .Create()); @@ -126,6 +134,50 @@ private static bool TryGetRule(XElement warning, out string rule) return !string.IsNullOrWhiteSpace(rule); } + /// + /// Determines the project for a warning logged in a MsBuild log. + /// + /// Warning element from MsBuild log. + /// Repository settings to use. + /// Returns project. + /// True if the project could be parsed. + private static bool TryGetProject( + XElement warning, + RepositorySettings repositorySettings, + out string project) + { + project = string.Empty; + + var projectNode = warning.Ancestors("project").FirstOrDefault(); + if (projectNode == null) + { + return true; + } + + var projectAttr = projectNode.Attribute("file"); + if (projectAttr == null) + { + return true; + } + + project = projectAttr.Value; + if (string.IsNullOrWhiteSpace(project)) + { + return true; + } + + // Make path relative to repository root. + project = project.Substring(repositorySettings.RepositoryRoot.FullPath.Length); + + // Remove leading directory separator. + if (project.StartsWith(Path.DirectorySeparatorChar.ToString())) + { + project = project.Substring(1); + } + + return true; + } + /// /// Reads the affected file path from a warning logged in a MsBuild log. /// From e0d3e6f112256da4f42ae994c25fe5a68eb9df4c Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Tue, 26 Jun 2018 12:16:34 +0200 Subject: [PATCH 3/4] Update release notes link --- nuspec/nuget/Cake.Issues.MsBuild.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nuspec/nuget/Cake.Issues.MsBuild.nuspec b/nuspec/nuget/Cake.Issues.MsBuild.nuspec index 19a4494..79ed89d 100644 --- a/nuspec/nuget/Cake.Issues.MsBuild.nuspec +++ b/nuspec/nuget/Cake.Issues.MsBuild.nuspec @@ -23,7 +23,7 @@ See the Project Site for an overview of the whole ecosystem of addins for workin false Copyright © BBT Software AG and contributors Cake Script Cake-Issues Cake-IssueProvider CodeAnalysis Linting MsBuild - https://github.com/cake-contrib/Cake.Issues.MsBuild/releases/tag/0.3.0 + https://github.com/cake-contrib/Cake.Issues.MsBuild/releases/tag/0.3.1 From edcc087a9eb25c3494c7d01aae45861ff064288c Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Tue, 26 Jun 2018 12:17:24 +0200 Subject: [PATCH 4/4] Update FxCop Analyzers --- src/Cake.Issues.MsBuild/Cake.Issues.MsBuild.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cake.Issues.MsBuild/Cake.Issues.MsBuild.csproj b/src/Cake.Issues.MsBuild/Cake.Issues.MsBuild.csproj index fac1e9f..9605123 100644 --- a/src/Cake.Issues.MsBuild/Cake.Issues.MsBuild.csproj +++ b/src/Cake.Issues.MsBuild/Cake.Issues.MsBuild.csproj @@ -26,7 +26,7 @@ - +