Refactor to avoid public setters

This commit is contained in:
Michael B. Gale
2023-02-28 15:22:20 +00:00
parent e3762c7f93
commit fea29d5172
10 changed files with 172 additions and 144 deletions

View File

@@ -105,23 +105,30 @@ namespace Semmle.Autobuild.CSharp
// otherwise, we just report that the one script we found didn't work
if (this.autoBuildRule.BuildCommandAutoRule.CandidatePaths.Count() > 1)
{
message = MakeDiagnostic("multiple-build-scripts", "There are multiple potential build scripts");
message.MarkdownMessage =
"CodeQL found multiple potential build scripts for your project and " +
$"attempted to run `{relScriptPath}`, which failed. " +
"This may not be the right build script for your project. " +
$"Set up a [manual build command]({buildCommandDocsUrl}).";
message = new(
this.Options.Language,
"multiple-build-scripts",
"There are multiple potential build scripts",
markdownMessage:
"CodeQL found multiple potential build scripts for your project and " +
$"attempted to run `{relScriptPath}`, which failed. " +
"This may not be the right build script for your project. " +
$"Set up a [manual build command]({buildCommandDocsUrl})."
);
}
else
{
message = MakeDiagnostic("script-failure", "Unable to build project using build script");
message.MarkdownMessage =
"CodeQL attempted to build your project using a script located at " +
$"`{relScriptPath}`, which failed. " +
$"Set up a [manual build command]({buildCommandDocsUrl}).";
message = new(
this.Options.Language,
"script-failure",
"Unable to build project using build script",
markdownMessage:
"CodeQL attempted to build your project using a script located at " +
$"`{relScriptPath}`, which failed. " +
$"Set up a [manual build command]({buildCommandDocsUrl})."
);
}
message.Severity = DiagnosticMessage.TspSeverity.Error;
AddDiagnostic(message);
}
@@ -135,50 +142,63 @@ namespace Semmle.Autobuild.CSharp
// then neither of those rules would've worked
if (this.ProjectsOrSolutionsToBuild.Count == 0)
{
var message = MakeDiagnostic("no-projects-or-solutions", "No project or solutions files found");
message.PlaintextMessage =
"CodeQL could not find any project or solution files in your repository. " +
$"Set up a [manual build command]({buildCommandDocsUrl}).";
message.Severity = DiagnosticMessage.TspSeverity.Error;
AddDiagnostic(message);
this.AddDiagnostic(new(
this.Options.Language,
"no-projects-or-solutions",
"No project or solutions files found",
markdownMessage:
"CodeQL could not find any project or solution files in your repository. " +
$"Set up a [manual build command]({buildCommandDocsUrl})."
));
}
// show a warning if there are projects which are not compatible with .NET Core, in case that is unintentional
else if (foundNotDotNetProjects.Any())
{
var message = MakeDiagnostic("dotnet-incompatible-projects", "Some projects are incompatible with .NET Core");
message.MarkdownMessage =
"CodeQL found some projects which cannot be built with .NET Core:\n" +
autoBuildRule.DotNetRule.NotDotNetProjects.Select(p => this.MakeRelative(p.FullPath)).ToMarkdownList(MarkdownUtil.CodeFormatter, 5);
message.Severity = DiagnosticMessage.TspSeverity.Warning;
this.AddDiagnostic(new(
this.Options.Language,
"dotnet-incompatible-projects",
"Some projects are incompatible with .NET Core",
severity: DiagnosticMessage.TspSeverity.Warning,
markdownMessage: $"""
CodeQL found some projects which cannot be built with .NET Core:
AddDiagnostic(message);
{autoBuildRule.DotNetRule.NotDotNetProjects.Select(p => this.MakeRelative(p.FullPath)).ToMarkdownList(MarkdownUtil.CodeFormatter, 5)}
"""
));
}
// report any projects that failed to build with .NET Core
if (autoBuildRule.DotNetRule.FailedProjectsOrSolutions.Any())
{
var message = MakeDiagnostic("dotnet-build-failure", "Some projects or solutions failed to build using .NET Core");
message.MarkdownMessage =
"CodeQL was unable to build the following projects using .NET Core:\n" +
autoBuildRule.DotNetRule.FailedProjectsOrSolutions.Select(p => this.MakeRelative(p.FullPath)).ToMarkdownList(MarkdownUtil.CodeFormatter, 10) +
$"\nSet up a [manual build command]({buildCommandDocsUrl}).";
message.Severity = DiagnosticMessage.TspSeverity.Error;
this.AddDiagnostic(new(
this.Options.Language,
"dotnet-build-failure",
"Some projects or solutions failed to build using .NET Core",
markdownMessage: $"""
CodeQL was unable to build the following projects using .NET Core:
AddDiagnostic(message);
{autoBuildRule.DotNetRule.FailedProjectsOrSolutions.Select(p => this.MakeRelative(p.FullPath)).ToMarkdownList(MarkdownUtil.CodeFormatter, 10)}
Set up a [manual build command]({buildCommandDocsUrl}).
"""
));
}
// report any projects that failed to build with MSBuild
if (autoBuildRule.MsBuildRule.FailedProjectsOrSolutions.Any())
{
var message = MakeDiagnostic("msbuild-build-failure", "Some projects or solutions failed to build using MSBuild");
message.MarkdownMessage =
"CodeQL was unable to build the following projects using MSBuild:\n" +
autoBuildRule.MsBuildRule.FailedProjectsOrSolutions.Select(p => this.MakeRelative(p.FullPath)).ToMarkdownList(MarkdownUtil.CodeFormatter, 10) +
$"\nSet up a [manual build command]({buildCommandDocsUrl}).";
message.Severity = DiagnosticMessage.TspSeverity.Error;
this.AddDiagnostic(new(
this.Options.Language,
"msbuild-build-failure",
"Some projects or solutions failed to build using MSBuild",
markdownMessage: $"""
CodeQL was unable to build the following projects using MSBuild:
AddDiagnostic(message);
{autoBuildRule.MsBuildRule.FailedProjectsOrSolutions.Select(p => this.MakeRelative(p.FullPath)).ToMarkdownList(MarkdownUtil.CodeFormatter, 10)}
Set up a [manual build command]({buildCommandDocsUrl}).
"""
));
}
}

View File

@@ -26,16 +26,13 @@ namespace Semmle.Autobuild.CSharp
this.SDKName = sdkName;
}
public DiagnosticMessage ToDiagnosticMessage<T>(Autobuilder<T> builder) where T : AutobuildOptionsShared
{
var diag = builder.MakeDiagnostic(
$"missing-xamarin-{this.SDKName.ToLower()}-sdk",
$"Missing Xamarin SDK for {this.SDKName}"
);
diag.MarkdownMessage = $"[Configure your workflow]({docsUrl}) for this SDK before running CodeQL.";
return diag;
}
public DiagnosticMessage ToDiagnosticMessage<T>(Autobuilder<T> builder, DiagnosticMessage.TspSeverity? severity = null) where T : AutobuildOptionsShared => new(
builder.Options.Language,
$"missing-xamarin-{this.SDKName.ToLower()}-sdk",
$"Missing Xamarin SDK for {this.SDKName}",
severity: severity ?? DiagnosticMessage.TspSeverity.Error,
markdownMessage: $"[Configure your workflow]({docsUrl}) for this SDK before running CodeQL."
);
}
public MissingXamarinSdkRule() :
@@ -74,24 +71,23 @@ namespace Semmle.Autobuild.CSharp
this.MissingProjectFiles = new HashSet<string>();
}
public DiagnosticMessage ToDiagnosticMessage<T>(Autobuilder<T> builder) where T : AutobuildOptionsShared
{
var diag = builder.MakeDiagnostic(
$"missing-project-files",
$"Missing project files"
);
diag.MarkdownMessage =
"Some project files were not found when CodeQL built your project:\n\n" +
this.MissingProjectFiles.AsEnumerable().Select(p => builder.MakeRelative(p)).ToMarkdownList(MarkdownUtil.CodeFormatter, 5) +
"\n\nThis may lead to subsequent failures. " +
"You can check for common causes for missing project files:\n\n" +
$"- Ensure that the project is built using the {runsOnDocsUrl.ToMarkdownLink("intended operating system")} and that filenames on case-sensitive platforms are correctly specified.\n" +
$"- If your repository uses Git submodules, ensure that those are {checkoutDocsUrl.ToMarkdownLink("checked out")} before the CodeQL action is run.\n" +
"- If you auto-generate some project files as part of your build process, ensure that these are generated before the CodeQL action is run.";
diag.Severity = DiagnosticMessage.TspSeverity.Warning;
public DiagnosticMessage ToDiagnosticMessage<T>(Autobuilder<T> builder, DiagnosticMessage.TspSeverity? severity = null) where T : AutobuildOptionsShared => new(
builder.Options.Language,
"missing-project-files",
"Missing project files",
severity: severity ?? DiagnosticMessage.TspSeverity.Warning,
markdownMessage: $"""
Some project files were not found when CodeQL built your project:
return diag;
}
{this.MissingProjectFiles.AsEnumerable().Select(p => builder.MakeRelative(p)).ToMarkdownList(MarkdownUtil.CodeFormatter, 5)}
This may lead to subsequent failures. You can check for common causes for missing project files:
- Ensure that the project is built using the {runsOnDocsUrl.ToMarkdownLink("intended operating system")} and that filenames on case-sensitive platforms are correctly specified.
- If your repository uses Git submodules, ensure that those are {checkoutDocsUrl.ToMarkdownLink("checked out")} before the CodeQL action is run.
- If you auto-generate some project files as part of your build process, ensure that these are generated before the CodeQL action is run.
"""
);
}
public MissingProjectFileRule() :

View File

@@ -330,11 +330,9 @@ namespace Semmle.Autobuild.Shared
// if the build succeeded, all diagnostics we captured from the build output should be warnings;
// otherwise they should all be errors
var diagSeverity = buildResult == 0 ? DiagnosticMessage.TspSeverity.Warning : DiagnosticMessage.TspSeverity.Error;
this.DiagnosticClassifier.Results.Select(result => result.ToDiagnosticMessage(this)).ForEach(result =>
{
result.Severity = diagSeverity;
AddDiagnostic(result);
});
this.DiagnosticClassifier.Results
.Select(result => result.ToDiagnosticMessage(this, diagSeverity))
.ForEach(AddDiagnostic);
return buildResult;
}
@@ -344,25 +342,6 @@ namespace Semmle.Autobuild.Shared
/// </summary>
public abstract BuildScript GetBuildScript();
/// <summary>
/// Constructs a standard <see cref="DiagnosticMessage" /> for some message with
/// <see cref="id" /> and a human-friendly <see cref="name" />.
/// </summary>
/// <param name="id">The last part of the message id.</param>
/// <param name="name">The human-friendly description of the message.</param>
/// <returns>The resulting <see cref="DiagnosticMessage" />.</returns>
public DiagnosticMessage MakeDiagnostic(string id, string name)
{
DiagnosticMessage diag = new(new(
$"{this.Options.Language.UpperCaseName.ToLower()}/autobuilder/{id}",
name,
Options.Language.UpperCaseName.ToLower()
));
diag.Visibility.StatusPage = true;
return diag;
}
/// <summary>
/// Produces a diagnostic for the tool status page that we were unable to automatically
@@ -370,16 +349,16 @@ namespace Semmle.Autobuild.Shared
/// can be overriden to implement more specific messages depending on the origin of
/// the failure.
/// </summary>
protected virtual void AutobuildFailureDiagnostic()
{
var message = MakeDiagnostic("autobuild-failure", "Unable to build project");
message.PlaintextMessage =
"We were unable to automatically build your project. " +
"You can manually specify a suitable build command for your project.";
message.Severity = DiagnosticMessage.TspSeverity.Error;
AddDiagnostic(message);
}
protected virtual void AutobuildFailureDiagnostic() => AddDiagnostic(new DiagnosticMessage(
this.Options.Language,
"autobuild-failure",
"Unable to build project",
visibility: new DiagnosticMessage.TspVisibility(statusPage: true),
plaintextMessage: """
We were unable to automatically build your project.
Set up a manual build command.
"""
));
/// <summary>
/// Returns a build script that can be run upon autobuild failure.

View File

@@ -16,8 +16,11 @@ namespace Semmle.Autobuild.Shared
/// <param name="builder">
/// The autobuilder to use for constructing the base <see cref="DiagnosticMessage" />.
/// </param>
/// <param name="severity">
/// An optional severity value which overrides the default severity of the diagnostic.
/// </param>
/// <returns>The <see cref="DiagnosticMessage" /> corresponding to this result.</returns>
DiagnosticMessage ToDiagnosticMessage<T>(Autobuilder<T> builder) where T : AutobuildOptionsShared;
DiagnosticMessage ToDiagnosticMessage<T>(Autobuilder<T> builder, DiagnosticMessage.TspSeverity? severity = null) where T : AutobuildOptionsShared;
}
public class DiagnosticRule