mirror of
https://github.com/github/codeql.git
synced 2026-07-07 12:35:33 +02:00
Add diagnostics rule for arbitrary build messages
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Semmle.Util;
|
||||
|
||||
@@ -57,6 +59,112 @@ namespace Semmle.Autobuild.Shared
|
||||
public virtual void Fire(DiagnosticClassifier classifier, Match match) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="DiagnosticRule" /> which detects arbitrary build messages from MSBuild, CSC, NETSDK, etc. and
|
||||
/// reports them, up to a limit, as telemetry-only diagnostics.
|
||||
/// </summary>
|
||||
public class BuildMessageRule : DiagnosticRule
|
||||
{
|
||||
public class Result : IDiagnosticsResult, IEquatable<Result>
|
||||
{
|
||||
/// <summary>
|
||||
/// A value indicating whether this a warning or an error.
|
||||
/// </summary>
|
||||
public string Type { get; }
|
||||
/// <summary>
|
||||
/// The source of the message, such as "MSB" or "NETSDK".
|
||||
/// </summary>
|
||||
public string Source { get; }
|
||||
/// <summary>
|
||||
/// The numeric id of the message.
|
||||
/// </summary>
|
||||
public int Code { get; }
|
||||
/// <summary>
|
||||
/// The message contents.
|
||||
/// </summary>
|
||||
public string Message { get; }
|
||||
|
||||
public Result(string type, string source, int code, string message)
|
||||
{
|
||||
this.Type = type;
|
||||
this.Source = source;
|
||||
this.Code = code;
|
||||
this.Message = message;
|
||||
}
|
||||
|
||||
public DiagnosticMessage ToDiagnosticMessage<T>(Autobuilder<T> builder, DiagnosticMessage.TspSeverity? severity = null) where T : AutobuildOptionsShared => new(
|
||||
builder.Options.Language,
|
||||
$"{this.Source.ToLower()}-{this.Code}",
|
||||
$"{this.Source.ToUpper()}{this.Code}",
|
||||
plaintextMessage: this.Message,
|
||||
severity:
|
||||
this.Type.Equals("error") ?
|
||||
DiagnosticMessage.TspSeverity.Error :
|
||||
DiagnosticMessage.TspSeverity.Warning,
|
||||
// the messages we capture here are visible in the build log, so there is no need
|
||||
// to show them other than in telemetry
|
||||
visibility: new(telemetry: true)
|
||||
);
|
||||
|
||||
public bool Equals(Result? x)
|
||||
{
|
||||
return x is not null &&
|
||||
x.Code == this.Code &&
|
||||
x.Type == this.Type &&
|
||||
x.Source == this.Source &&
|
||||
x.Message == this.Message;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is Result && this.Equals(obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(this.Type, this.Source, this.Code, this.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The maximum number of diagnostics we should emit for this rule.
|
||||
/// </summary>
|
||||
private const int maxDiagnostics = 10;
|
||||
/// <summary>
|
||||
/// The number of diagnostics this rule has emitted so far.
|
||||
/// </summary>
|
||||
private int diagnostics = 0;
|
||||
|
||||
public BuildMessageRule() : base("(?<type>error|warning) (?<source>[A-Z]+)(?<code>\\d+): (?<message>.*)") { }
|
||||
|
||||
public override void Fire(DiagnosticClassifier classifier, Match match)
|
||||
{
|
||||
if (!match.Groups.TryGetValue("type", out var type))
|
||||
throw new ArgumentException("Expected regular expression match to contain type");
|
||||
if (!match.Groups.TryGetValue("source", out var source))
|
||||
throw new ArgumentException("Expected regular expression match to contain source");
|
||||
if (!match.Groups.TryGetValue("code", out var codeStr))
|
||||
throw new ArgumentException("Expected regular expression match to contain code");
|
||||
if (!match.Groups.TryGetValue("message", out var message))
|
||||
throw new ArgumentException("Expected regular expression match to contain message");
|
||||
if (!int.TryParse(codeStr.Value, out var code))
|
||||
throw new ArgumentException("Expected code to be numeric");
|
||||
|
||||
// check that we have not yet exceeded our limit for emitting diagnostics
|
||||
if (this.diagnostics < BuildMessageRule.maxDiagnostics)
|
||||
{
|
||||
var result = new Result(type.Value, source.Value, code, message.Value);
|
||||
|
||||
// add this result if we don't already have an identical one
|
||||
if (!classifier.Results.OfType<Result>().Any(d => d.Equals(result)))
|
||||
{
|
||||
classifier.Results.Add(result);
|
||||
this.diagnostics++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DiagnosticClassifier
|
||||
{
|
||||
private readonly List<DiagnosticRule> rules;
|
||||
@@ -66,6 +174,8 @@ namespace Semmle.Autobuild.Shared
|
||||
{
|
||||
this.rules = new List<DiagnosticRule>();
|
||||
this.Results = new List<IDiagnosticsResult>();
|
||||
|
||||
this.AddRule(new BuildMessageRule());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -34,3 +34,35 @@
|
||||
"telemetry": true
|
||||
}
|
||||
}
|
||||
{
|
||||
"attributes": {},
|
||||
"helpLinks": [],
|
||||
"internal": false,
|
||||
"location": {},
|
||||
"plaintextMessage": "The reference assemblies for .NETFramework,Version=v4.0 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/developerpacks [<test-root-directory>/test.csproj]",
|
||||
"severity": "error",
|
||||
"source": {
|
||||
"extractorName": "csharp",
|
||||
"id": "csharp/autobuilder/msb-3644",
|
||||
"name": "MSB3644"
|
||||
},
|
||||
"visibility": {
|
||||
"telemetry": true
|
||||
}
|
||||
}
|
||||
{
|
||||
"attributes": {},
|
||||
"helpLinks": [],
|
||||
"internal": false,
|
||||
"location": {},
|
||||
"plaintextMessage": "Too many project files specified",
|
||||
"severity": "error",
|
||||
"source": {
|
||||
"extractorName": "csharp",
|
||||
"id": "csharp/autobuilder/msbuild-4",
|
||||
"name": "MSBUILD4"
|
||||
},
|
||||
"visibility": {
|
||||
"telemetry": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,3 +34,35 @@
|
||||
"telemetry": true
|
||||
}
|
||||
}
|
||||
{
|
||||
"attributes": {},
|
||||
"helpLinks": [],
|
||||
"internal": false,
|
||||
"location": {},
|
||||
"plaintextMessage": "The project file \"<test-root-directory>/Example.Test.csproj\" was not found. [<test-root-directory>/test.sln]",
|
||||
"severity": "error",
|
||||
"source": {
|
||||
"extractorName": "csharp",
|
||||
"id": "csharp/autobuilder/msb-3202",
|
||||
"name": "MSB3202"
|
||||
},
|
||||
"visibility": {
|
||||
"telemetry": true
|
||||
}
|
||||
}
|
||||
{
|
||||
"attributes": {},
|
||||
"helpLinks": [],
|
||||
"internal": false,
|
||||
"location": {},
|
||||
"plaintextMessage": "The project file \"<test-root-directory>/Example.csproj\" was not found. [<test-root-directory>/test.sln]",
|
||||
"severity": "error",
|
||||
"source": {
|
||||
"extractorName": "csharp",
|
||||
"id": "csharp/autobuilder/msb-3202",
|
||||
"name": "MSB3202"
|
||||
},
|
||||
"visibility": {
|
||||
"telemetry": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,3 +52,35 @@
|
||||
"telemetry": true
|
||||
}
|
||||
}
|
||||
{
|
||||
"attributes": {},
|
||||
"helpLinks": [],
|
||||
"internal": false,
|
||||
"location": {},
|
||||
"plaintextMessage": "The imported project \"/usr/local/share/dotnet/sdk/7.0.102/Xamarin/iOS/Xamarin.iOS.CSharp.targets\" was not found. Confirm that the expression in the Import declaration \"/usr/local/share/dotnet/sdk/7.0.102/Xamarin/iOS/Xamarin.iOS.CSharp.targets\" is correct, and that the file exists on disk. [<test-root-directory>/test.csproj]",
|
||||
"severity": "error",
|
||||
"source": {
|
||||
"extractorName": "csharp",
|
||||
"id": "csharp/autobuilder/msb-4019",
|
||||
"name": "MSB4019"
|
||||
},
|
||||
"visibility": {
|
||||
"telemetry": true
|
||||
}
|
||||
}
|
||||
{
|
||||
"attributes": {},
|
||||
"helpLinks": [],
|
||||
"internal": false,
|
||||
"location": {},
|
||||
"plaintextMessage": "Too many project files specified",
|
||||
"severity": "error",
|
||||
"source": {
|
||||
"extractorName": "csharp",
|
||||
"id": "csharp/autobuilder/msbuild-4",
|
||||
"name": "MSBUILD4"
|
||||
},
|
||||
"visibility": {
|
||||
"telemetry": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"attributes": {},
|
||||
"helpLinks": [],
|
||||
"internal": false,
|
||||
"location": {},
|
||||
"plaintextMessage": "Too many project files specified",
|
||||
"severity": "error",
|
||||
"source": {
|
||||
"extractorName": "csharp",
|
||||
"id": "csharp/autobuilder/msbuild-4",
|
||||
"name": "MSBUILD4"
|
||||
},
|
||||
"visibility": {
|
||||
"telemetry": true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user