mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
cmSarif: Classify results by diagnostic category
Add additional rules to CMake's SARIF reporting for diagnostic categories. Fixes: #27883
This commit is contained in:
@@ -11,7 +11,9 @@
|
||||
#include <cm/string_view>
|
||||
|
||||
#include "cmsys/FStream.hxx"
|
||||
#include "cmsys/String.h"
|
||||
|
||||
#include "cmDiagnostics.h"
|
||||
#include "cmListFileCache.h"
|
||||
#include "cmMessageType.h"
|
||||
#include "cmMessenger.h"
|
||||
@@ -72,6 +74,69 @@ cmSarif::Tool CreateCMakeTool()
|
||||
return cmSarif::Tool{ cmDriver };
|
||||
}
|
||||
|
||||
std::string RuleIdForMessageType(MessageType type,
|
||||
cmDiagnosticCategory category)
|
||||
{
|
||||
cm::string_view name = cmDiagnostics::GetCategoryString(category);
|
||||
if (!name.empty()) {
|
||||
// Strip the "CMD_" prefix from the category name and convert to PascalCase
|
||||
std::string sarifIdName;
|
||||
bool nextWord = true;
|
||||
for (char c : name.substr(4)) {
|
||||
if (c == '_') {
|
||||
nextWord = true;
|
||||
continue;
|
||||
}
|
||||
if (nextWord) {
|
||||
sarifIdName += c;
|
||||
nextWord = false;
|
||||
} else {
|
||||
sarifIdName += cmsysString_tolower(c);
|
||||
}
|
||||
}
|
||||
return cmStrCat("CMake.", sarifIdName);
|
||||
}
|
||||
|
||||
// Fall back to message type if not a diagnostic
|
||||
switch (type) {
|
||||
case MessageType::FATAL_ERROR:
|
||||
return "CMake.FatalError";
|
||||
case MessageType::INTERNAL_ERROR:
|
||||
return "CMake.InternalError";
|
||||
case MessageType::WARNING:
|
||||
return "CMake.Warning";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
cm::string_view NameForMessageType(MessageType type,
|
||||
cmDiagnosticCategory category)
|
||||
{
|
||||
if (category != cmDiagnostics::CMD_NONE) {
|
||||
return cmDiagnostics::GetCategoryString(category);
|
||||
}
|
||||
switch (type) {
|
||||
case MessageType::FATAL_ERROR:
|
||||
return "CMake Error";
|
||||
case MessageType::INTERNAL_ERROR:
|
||||
return "CMake Internal Error";
|
||||
case MessageType::WARNING:
|
||||
return "CMake Warning";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
cmSarif::ReportingDescriptor ReportingDescriptorForMessageType(
|
||||
MessageType type, cmDiagnosticCategory category)
|
||||
{
|
||||
cmSarif::ReportingDescriptor rd;
|
||||
rd.Id = RuleIdForMessageType(type, category);
|
||||
rd.Name = NameForMessageType(type, category);
|
||||
return rd;
|
||||
};
|
||||
|
||||
cmSarif::ResultSeverityLevel SarifLevelFromMessageType(MessageType type)
|
||||
{
|
||||
switch (type) {
|
||||
@@ -85,48 +150,6 @@ cmSarif::ResultSeverityLevel SarifLevelFromMessageType(MessageType type)
|
||||
}
|
||||
}
|
||||
|
||||
cm::string_view MessageRuleId(MessageType type)
|
||||
{
|
||||
switch (type) {
|
||||
case MessageType::FATAL_ERROR:
|
||||
return "CMake.FatalError";
|
||||
case MessageType::INTERNAL_ERROR:
|
||||
return "CMake.InternalError";
|
||||
case MessageType::WARNING:
|
||||
return "CMake.Warning";
|
||||
case MessageType::MESSAGE:
|
||||
return "CMake.Message";
|
||||
case MessageType::LOG:
|
||||
default:
|
||||
return "CMake.Log";
|
||||
}
|
||||
}
|
||||
|
||||
cm::string_view MessageDisplayName(MessageType type)
|
||||
{
|
||||
switch (type) {
|
||||
case MessageType::FATAL_ERROR:
|
||||
return "CMake Error";
|
||||
case MessageType::INTERNAL_ERROR:
|
||||
return "CMake Internal Error";
|
||||
case MessageType::WARNING:
|
||||
return "CMake Warning";
|
||||
case MessageType::MESSAGE:
|
||||
return "CMake Message";
|
||||
case MessageType::LOG:
|
||||
default:
|
||||
return "CMake Log";
|
||||
}
|
||||
}
|
||||
|
||||
cmSarif::ReportingDescriptor RuleForMessageType(MessageType type)
|
||||
{
|
||||
cmSarif::ReportingDescriptor rd;
|
||||
rd.Id = MessageRuleId(type);
|
||||
rd.Name = MessageDisplayName(type);
|
||||
return rd;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
cmCMakeSarifLogger::cmCMakeSarifLogger(cmake& cm)
|
||||
@@ -178,20 +201,32 @@ bool cmCMakeSarifLogger::WriteFile(std::string const& path,
|
||||
|
||||
// Helper to add rules to the run as encountered in results and get their
|
||||
// index for reporting
|
||||
std::unordered_map<cm::string_view, std::size_t> ruleIndices;
|
||||
auto use_rule = [&](MessageType t) {
|
||||
cm::string_view category_name = MessageRuleId(t);
|
||||
std::unordered_map<std::string, std::size_t> ruleIndices;
|
||||
auto use_rule = [&](MessageType type, cmDiagnosticCategory category) {
|
||||
std::string category_name = RuleIdForMessageType(type, category);
|
||||
auto result = ruleIndices.emplace(category_name, 0);
|
||||
if (result.second) {
|
||||
result.first->second = run.Tool.Driver.Rules.size();
|
||||
run.Tool.Driver.Rules.emplace_back(RuleForMessageType(t));
|
||||
run.Tool.Driver.Rules.emplace_back(
|
||||
ReportingDescriptorForMessageType(type, category));
|
||||
}
|
||||
return *result.first;
|
||||
};
|
||||
|
||||
cmMessenger const& messenger = *this->CM.GetMessenger();
|
||||
for (auto const& message : messenger.GetDisplayedMessages()) {
|
||||
std::pair<cm::string_view, std::size_t> ruleInfo = use_rule(message.Type);
|
||||
// SARIF should only emit diagnostic messages, not general messages/logs
|
||||
switch (message.Type) {
|
||||
case MessageType::MESSAGE:
|
||||
case MessageType::LOG:
|
||||
case MessageType::UNDEFINED:
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
std::pair<std::string, std::size_t> ruleInfo =
|
||||
use_rule(message.Type, message.Category);
|
||||
|
||||
cmSarif::Result result;
|
||||
result.RuleId = ruleInfo.first;
|
||||
|
||||
@@ -44,6 +44,48 @@
|
||||
},
|
||||
"ruleId": "CMake.Warning",
|
||||
"ruleIndex": 0
|
||||
},
|
||||
{
|
||||
"level": "warning",
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "GenerateSarifResults.cmake",
|
||||
"uriBaseId": "PATH:<SOURCE_DIR>"
|
||||
},
|
||||
"region": {
|
||||
"startLine": 11
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"message": {
|
||||
"text": "Example author warning message"
|
||||
},
|
||||
"ruleId": "CMake.Author",
|
||||
"ruleIndex": 1
|
||||
},
|
||||
{
|
||||
"level": "error",
|
||||
"locations": [
|
||||
{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "GenerateSarifResults.cmake",
|
||||
"uriBaseId": "PATH:<SOURCE_DIR>"
|
||||
},
|
||||
"region": {
|
||||
"startLine": 16
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"message": {
|
||||
"text": "Another example author warning message"
|
||||
},
|
||||
"ruleId": "CMake.Author",
|
||||
"ruleIndex": 1
|
||||
}
|
||||
],
|
||||
"tool": {
|
||||
@@ -53,6 +95,10 @@
|
||||
{
|
||||
"id": "CMake.Warning",
|
||||
"name": "CMake Warning"
|
||||
},
|
||||
{
|
||||
"id": "CMake.Author",
|
||||
"name": "CMD_AUTHOR"
|
||||
}
|
||||
],
|
||||
"version": "<IGNORE>"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -6,4 +6,16 @@ Call Stack \(most recent call first\):
|
||||
CMake Warning at GenerateSarifResults\.cmake:5 \(message\):
|
||||
A second example warning message
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)$
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
+
|
||||
CMake Warning \(author\) at GenerateSarifResults\.cmake:11 \(message\):
|
||||
Example author warning message
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
This warning is for project developers\. Use -Wno-author to suppress it\.
|
||||
+
|
||||
CMake Error \(author\) at GenerateSarifResults\.cmake:16 \(message\):
|
||||
Another example author warning message
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
This error is for project developers\. Use -Wno-error=author to suppress it\.$
|
||||
|
||||
@@ -6,3 +6,11 @@ message(WARNING "A second example warning message")
|
||||
|
||||
# Status message should not be logged
|
||||
message(STATUS "Example status message")
|
||||
|
||||
# Test diagnostic reporting
|
||||
message(AUTHOR_WARNING "Example author warning message")
|
||||
|
||||
# Diagnostic results should include a level specific to each reported item
|
||||
# Change it and issue another one
|
||||
cmake_diagnostic(SET CMD_AUTHOR SEND_ERROR)
|
||||
message(AUTHOR_WARNING "Another example author warning message")
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -8,4 +8,18 @@ CMake Warning at GenerateSarifResults\.cmake:5 \(message\):
|
||||
A second example warning message
|
||||
Call Stack \(most recent call first\):
|
||||
ToggleExportSarifVariable\.cmake:[0-9]+ \(include\)
|
||||
CMakeLists\.txt:[0-9]+ \(include\)$
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
+
|
||||
CMake Warning \(author\) at GenerateSarifResults\.cmake:11 \(message\):
|
||||
Example author warning message
|
||||
Call Stack \(most recent call first\):
|
||||
ToggleExportSarifVariable\.cmake:[0-9]+ \(include\)
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
This warning is for project developers\. Use -Wno-author to suppress it\.
|
||||
+
|
||||
CMake Error \(author\) at GenerateSarifResults\.cmake:16 \(message\):
|
||||
Another example author warning message
|
||||
Call Stack \(most recent call first\):
|
||||
ToggleExportSarifVariable\.cmake:[0-9]+ \(include\)
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
This error is for project developers\. Use -Wno-error=author to suppress it\.$
|
||||
|
||||
Reference in New Issue
Block a user