Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/badges/tests.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 8 additions & 2 deletions code/+matbox/+tasks/+internal/createBadge.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function createBadge(label, message, color, projectRootDirectory)
function createBadge(label, message, color, projectRootDirectory, options)
% createBadge - Write a badge as JSON or as a legacy SVG file
%
% Writes a badge description as a JSON file (docs/reports/badges) when
Expand All @@ -10,17 +10,23 @@ function createBadge(label, message, color, projectRootDirectory)
% pybadges Python package, for callers without a render step: local runs
% and repositories pinned to older matbox-actions versions. This
% fallback will be removed in a future major release.
%
% Optional name/value arguments:
% Counts - Scalar struct of named counts added to the badge JSON for
% segmented rendering. The legacy SVG fallback ignores it.

arguments
label (1,1) string
message (1,1) string
color (1,1) string
projectRootDirectory (1,1) string {mustBeFolder}
options.Counts struct {mustBeScalarOrEmpty} = struct.empty
end

if strcmpi(getenv("MATBOX_BADGE_FORMAT"), "json")
matbox.utility.writeBadgeJSONFile(label, message, color, ...
"OutputFolder", fullfile(projectRootDirectory, "docs", "reports", "badges"))
"OutputFolder", fullfile(projectRootDirectory, "docs", "reports", "badges"), ...
"Counts", options.Counts)
else
matbox.utility.createBadgeSvg(label, message, color, projectRootDirectory)
end
Expand Down
10 changes: 9 additions & 1 deletion code/+matbox/+tasks/codecheckToolbox.m
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,16 @@ function createCodeIssuesBadge(issueCount, projectRootDir)
color = "red";
end

% The counts let matbox-actions draw one segment per severity. The
% label, message and color still describe a complete single badge
% for renderers that ignore the counts.
counts = struct( ...
"error", issueCount.Error, ...
"warning", issueCount.Warning, ...
"info", issueCount.Info);

matbox.tasks.internal.createBadge("code issues", ...
string(issueCount.Total), color, projectRootDir)
string(issueCount.Total), color, projectRootDir, "Counts", counts)
end

function ME = throwUnresolvedCodeIssuesException()
Expand Down
8 changes: 8 additions & 0 deletions code/+matbox/+utility/writeBadgeJSONFile.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ function writeBadgeJSONFile(label, message, color, projectRootDirectory, options
%
% FileName - Name of file excluding extension
%
% Counts - Scalar struct of named counts written to a "counts" field,
% for renderers that draw one segment per count. The field
% is omitted when Counts is empty (default).
%
% Example:
%
% writeBadgeJSONFile("Test Coverage", "90%", "green") creates a file
Expand All @@ -44,6 +48,7 @@ function writeBadgeJSONFile(label, message, color, projectRootDirectory, options
projectRootDirectory (1,1) string = missing
options.OutputFolder (1,1) string = missing
options.FileName (1,1) string = missing
options.Counts struct {mustBeScalarOrEmpty} = struct.empty
end

if ismissing(options.OutputFolder)
Expand All @@ -62,6 +67,9 @@ function writeBadgeJSONFile(label, message, color, projectRootDirectory, options
badgeInfo.label = label;
badgeInfo.message = message;
badgeInfo.color = color;
if ~isempty(options.Counts)
badgeInfo.counts = options.Counts;
end
badgeJSON = jsonencode(badgeInfo);

if ismissing(options.FileName)
Expand Down
17 changes: 17 additions & 0 deletions tools/tests/+matboxtools/+unittest/TasksTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,23 @@ function testCodecheckToolboxCreatesBadgeJson(testCase)
testCase.verifyEqual(badgeInfo.label, 'code issues')
testCase.verifyTrue(ismember(string(badgeInfo.color), ...
["green", "yellow", "red"]))

% The per-severity counts must add up to the total in the message
testCase.assertTrue(isfield(badgeInfo, "counts"), ...
"Expected badge JSON to contain a counts field.")
counts = badgeInfo.counts;
testCase.verifyEqual(sort(string(fieldnames(counts))), ...
["error"; "info"; "warning"])
testCase.verifyEqual(counts.error + counts.warning + counts.info, ...
str2double(badgeInfo.message))
end

function testWriteBadgeJSONFileOmitsCountsByDefault(testCase)
matbox.utility.writeBadgeJSONFile("tests", "1 passed", "green", ...
"OutputFolder", pwd)

badgeInfo = jsondecode(fileread(fullfile(pwd, "tests.json")));
testCase.verifyFalse(isfield(badgeInfo, "counts"))
end

function testPackageToolbox(testCase)
Expand Down