2016-03-16 57 views
1

當使用MSBuild針對項目運行各種分析器時,所有故障都將以「靜態分析結果交換格式(SARIF)」格式輸出(請參閱例如https://github.com/sarif-standard/sarif-spec)。例如構建可產生以下解析MSBuild中的「靜態分析結果交換格式(SARIF)」

{ 
    "version": "0.1", 
    "toolInfo": { 
    "toolName": "Microsoft (R) Visual C# Compiler", 
    "productVersion": "1.1.0", 
    "fileVersion": "1.1.0" 
    }, 
    "issues": [ 
    { 
     "ruleId": "SA1401", 
     "locations": [ 
     { 
      "analysisTarget": [ 
      { 
       "uri": "C:\\SomeFile.cs", 
       "region": { 
       "startLine": 708, 
       "startColumn": 30, 
       "endLine": 708, 
       "endColumn": 36 
       } 
      } 
      ] 
     } 
     ], 
     "shortMessage": "Field must be private", 
     "fullMessage": "A field within a C# class has an access modifier other than private.", 
     "properties": { 
     "severity": "Warning", 
     "warningLevel": "1", 
     "defaultSeverity": "Warning", 
     "title": "Fields must be private", 
     "category": "StyleCop.CSharp.MaintainabilityRules", 
     "helpLink": "https:\/\/github.com\/DotNetAnalyzers\/StyleCopAnalyzers\/blob\/master\/documentation\/SA1401.md", 
     "isEnabledByDefault": "True", 
     "isSuppressedInSource": "True" 
     } 
    } 
    ] 
} 

現在我想能夠在可能的最簡單的方法來分析上述數據(如果遇到任何非抑制問題打破建立)。如何去做這件事?

PS。最好我也想避免實現我自己的MSBuild任務並安裝特定的軟件(例如PowerShell 3.0 - ConvertFrom-Json)。

回答

0

由於顯然是做這個的沒有內置的方式,我結束了使用內聯MSBuild任務(https://msdn.microsoft.com/en-US/library/dd722601.aspx),定義爲

<UsingTask TaskName="ParseUnsupressedAnalysisIssues" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" > 
    <ParameterGroup> 
     <Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" /> 
     <Result ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true" /> 
    </ParameterGroup> 
    <Task> 
     <Reference Include="System.Runtime.Serialization" /> 
     <Reference Include="System.Xml" /> 
     <Reference Include="System.Xml.Linq" /> 
     <Using Namespace="System"/> 
     <Using Namespace="System.Collections.Generic"/> 
     <Using Namespace="System.IO"/> 
     <Using Namespace="System.Linq"/> 
     <Using Namespace="System.Runtime.Serialization.Json"/> 
     <Using Namespace="System.Xml"/> 
     <Using Namespace="System.Xml.Linq"/> 
     <Code Type="Fragment" Language="cs"> 
      <![CDATA[ 
      List<TaskItem> taskItems = new List<TaskItem>(); 
      foreach(ITaskItem item in Files) 
      { 
       try 
       { 
        string path = item.GetMetadata("FullPath"); 
        using (FileStream fs = new FileStream(path, FileMode.Open)) 
        using (XmlDictionaryReader reader = JsonReaderWriterFactory.CreateJsonReader(fs, XmlDictionaryReaderQuotas.Max)) 
        { 
         XElement doc = XElement.Load(reader); 
         XElement issuesRoot = doc.Elements("issues").SingleOrDefault(); 
         List<XElement> unsupressedIssues = issuesRoot.Elements("item").Where(e => !"True".Equals((string)e.Element("properties").Element("isSuppressedInSource"), StringComparison.Ordinal)).ToList(); 
         string unsupressedIssuesString = string.Join(Environment.NewLine, unsupressedIssues); 
         if(!string.IsNullOrEmpty(unsupressedIssuesString)) 
         { 
          taskItems.Add(new TaskItem(item.ItemSpec)); 
          Console.WriteLine(unsupressedIssuesString); 
         } 
        } 
       } 
       catch(Exception e) 
       { 
        taskItems.Add(new TaskItem(item.ItemSpec)); 
        Console.WriteLine(e.ToString()); 
       } 
      } 

      Result = taskItems.ToArray(); 
      ]]> 
     </Code> 
    </Task> 
</UsingTask> 

然後可以援引作爲

<ParseUnsupressedAnalysisIssues Files="@(AnalyzerFiles)"> 
    <Output ItemName="FailedAnalyzerFiles" TaskParameter="Result" /> 
</ParseUnsupressedAnalysisIssues> 
<Error Text="FxCopAll: Following assemblies had analyzer errors @(FailedAnalyzerFiles)" Condition="'@(FailedAnalyzerFiles->Count())' &gt; 0" Code="2"/> 
3

有一個SARIF SDK可用於處理SARIF文件。它以NuGet軟件包Sarif.Sdk的形式提供,源代碼位於Microsoft/sarif-sdk項目的GitHub上。有一個如何操作的文檔docs/how-to.md,它顯示瞭如何從磁盤讀取SARIF文件並將其反序列化爲SarifLog對象;那麼您可以瀏覽SARIF對象模型來檢查單個結果。

在你的情況,你有興趣在結果的的isSuppressedInSource屬性的方法文檔說明了如何檢索財產「屬性包」:

Result result = …; 

string isSuppressedInSource = result.GetProperty("isSuppressedInSource"); 

的的Sarif規範是available online,並有一個SARIF home page鏈接到更多的信息。

最後:請注意,SARIF格式在Visual Studio 2015 Update 2和Update 3之間發生了顯着變化。格式現在處於穩定的1.0.0版本。

(注意:對不起,到了SDK,NuGet包,以及如何對不提供直接的鏈接,我沒有足夠的聲譽點後兩個以上的鏈路)