Skip to content

Commit 1e2329d

Browse files
committed
Add diagnostic for missing project files
1 parent 3bf6b6f commit 1e2329d

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

csharp/autobuilder/Semmle.Autobuild.CSharp/CSharpDiagnosticClassifier.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
34
using System.Text.RegularExpressions;
45
using Semmle.Autobuild.Shared;
@@ -56,6 +57,70 @@ public override void Fire(DiagnosticClassifier classifier, Match match)
5657
}
5758
}
5859

60+
public class MissingProjectFileRule : DiagnosticRule
61+
{
62+
private const string runsOnDocsUrl = "https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idruns-on";
63+
private const string checkoutDocsUrl = "https://github.com/actions/checkout#usage";
64+
65+
public class Result : IDiagnosticsResult
66+
{
67+
/// <summary>
68+
/// A set of missing project files.
69+
/// </summary>
70+
public HashSet<string> MissingProjectFiles { get; }
71+
72+
public Result()
73+
{
74+
this.MissingProjectFiles = new HashSet<string>();
75+
}
76+
77+
public DiagnosticMessage ToDiagnosticMessage<T>(Autobuilder<T> builder) where T : AutobuildOptionsShared
78+
{
79+
var diag = builder.MakeDiagnostic(
80+
$"missing-project-files",
81+
$"Missing project files"
82+
);
83+
diag.MarkdownMessage =
84+
"Some project files were not found when CodeQL built your project:\n\n" +
85+
this.MissingProjectFiles.AsEnumerable().ToMarkdownList(MarkdownUtil.CodeFormatter, 5) +
86+
"\n\nThis may lead to subsequent failures. " +
87+
"You can check for common causes for missing project files:\n\n" +
88+
$"- Ensure that the project is built using the {runsOnDocsUrl.ToMarkdownLink("intended operating system")} and that filenames on case-sensitive platforms are correctly specified.\n" +
89+
$"- If your repository uses Git submodules, ensure that those are {checkoutDocsUrl.ToMarkdownLink("checked out")} before the CodeQL action is run.\n" +
90+
"- If you auto-generate some project files as part of your build process, ensure that these are generated before the CodeQL action is run.";
91+
diag.Severity = DiagnosticMessage.TspSeverity.Warning;
92+
93+
return diag;
94+
}
95+
}
96+
97+
public MissingProjectFileRule() :
98+
base("MSB3202: The project file \"(?<projectFile>[^\"]+)\" was not found. \\[(?<location>[^\\]]+)\\]")
99+
{
100+
}
101+
102+
public override void Fire(DiagnosticClassifier classifier, Match match)
103+
{
104+
if (!match.Groups.TryGetValue("projectFile", out var projectFile))
105+
throw new ArgumentException("Expected regular expression match to contain projectFile");
106+
if (!match.Groups.TryGetValue("location", out var location))
107+
throw new ArgumentException("Expected regular expression match to contain location");
108+
109+
var result = classifier.Results.OfType<Result>().FirstOrDefault();
110+
111+
// if we do not yet have a result for this rule, create one and add it to the list
112+
// of results the classifier knows about
113+
if (result is null)
114+
{
115+
result = new Result();
116+
classifier.Results.Add(result);
117+
}
118+
119+
// then add the missing project file
120+
result.MissingProjectFiles.Add(projectFile.Value);
121+
}
122+
}
123+
59124
/// <summary>
60125
/// Implements a <see cref="DiagnosticClassifier" /> which applies C#-specific rules to
61126
/// the build output.
@@ -66,6 +131,7 @@ public CSharpDiagnosticClassifier()
66131
{
67132
// add C#-specific rules to this classifier
68133
this.AddRule(new MissingXamarinSdkRule());
134+
this.AddRule(new MissingProjectFileRule());
69135
}
70136
}
71137
}

csharp/autobuilder/Semmle.Autobuild.Shared/MarkdownUtil.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ public static class MarkdownUtil
1313
/// <returns>A function which formats items as markdown inline code.</returns>
1414
public static readonly Func<string, string> CodeFormatter = item => $"`{item}`";
1515

16+
/// <summary>
17+
/// Formats the string as a markdown link.
18+
/// </summary>
19+
/// <param name="link">The URL for the link.</param>
20+
/// <param name="title">The text that is displayed.</param>
21+
/// <returns>A string containing a markdown-formatted link.</returns>
22+
public static string ToMarkdownLink(this string link, string title) => $"[{title}]({link})";
23+
1624
/// <summary>
1725
/// Renders <see cref="projects" /> as a markdown list of the project paths.
1826
/// </summary>

0 commit comments

Comments
 (0)