Skip to content

Commit

Permalink
feat: Enhance markdown summary reporter to use collapsable sections
Browse files Browse the repository at this point in the history
  • Loading branch information
abhisek committed Nov 18, 2024
1 parent 3c70b4a commit 3cf8d01
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 13 deletions.
37 changes: 37 additions & 0 deletions pkg/reporter/markdown/markdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,69 @@ type MarkdownBuilder struct {
content bytes.Buffer
}

type MarkdownCollapsibleSection struct {
title string
builder *MarkdownBuilder

// Only github for now
flavor string
}

func (s *MarkdownCollapsibleSection) Builder() *MarkdownBuilder {
return s.builder
}

func NewMarkdownBuilder() *MarkdownBuilder {
return &MarkdownBuilder{}
}

// AddHeader adds a header to the markdown document.
func (mb *MarkdownBuilder) AddHeader(level int, text string) {
mb.content.WriteString(fmt.Sprintf("%s %s\n", strings.Repeat("#", level), text))
}

// AddParagraph adds a paragraph to the markdown document.
func (mb *MarkdownBuilder) AddParagraph(text string) {
mb.content.WriteString(fmt.Sprintf("%s\n\n", text))
}

// AddBulletPoint adds a bullet point to the markdown document.
func (mb *MarkdownBuilder) AddBulletPoint(text string) {
mb.content.WriteString(fmt.Sprintf("- %s\n", text))
}

// AddNumberedPoint adds a numbered point to the markdown document.
func (mb *MarkdownBuilder) AddNumberedPoint(number int, text string) {
mb.content.WriteString(fmt.Sprintf("%d. %s\n", number, text))
}

// AddCodeSnippet adds a code snippet to the markdown document.
func (mb *MarkdownBuilder) AddCodeSnippet(code, language string) {
mb.content.WriteString("```" + language + "\n")
mb.content.WriteString(code + "\n")
mb.content.WriteString("```\n")
}

// StartCollapsibleSection starts a collapsible section in the markdown document.
func (mb *MarkdownBuilder) StartCollapsibleSection(title string) *MarkdownCollapsibleSection {
return &MarkdownCollapsibleSection{
title: title,
flavor: "github",
builder: NewMarkdownBuilder(),
}
}

// AddCollapsibleSection adds a collapsible section to the markdown document.
func (mb *MarkdownBuilder) AddCollapsibleSection(section *MarkdownCollapsibleSection) {
if section.flavor != "github" {
return
}

mb.content.WriteString(fmt.Sprintf("<details>\n<summary>%s</summary>\n\n", section.title))
mb.content.WriteString(section.builder.Build())
mb.content.WriteString("</details>\n\n")
}

func (mb *MarkdownBuilder) Build() string {
return mb.content.String()
}
9 changes: 9 additions & 0 deletions pkg/reporter/markdown/markdown_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ func TestMarkdownBuilder(t *testing.T) {
},
"- AAAA\n- BBBB",
},
{
"Has collapsible section",
func(builder *MarkdownBuilder) {
section := builder.StartCollapsibleSection("Title")
section.Builder().AddParagraph("AAAABBBB")
builder.AddCollapsibleSection(section)
},
"<details>\n<summary>Title</summary>\n\nAAAABBBB\n\n</details>",
},
}

for _, test := range cases {
Expand Down
31 changes: 18 additions & 13 deletions pkg/reporter/markdown_summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,8 @@ func (r *markdownSummaryReporter) addChangedPackageSection(builder *markdown.Mar
return nil
}

builder.AddHeader(2, "New Packages")
section := builder.StartCollapsibleSection("Changed Packages")
section.Builder().AddHeader(2, "Changed Packages")

for _, pkg := range internalModel.packages {
pkgModel := pkg.GetPackage()
Expand All @@ -292,17 +293,22 @@ func (r *markdownSummaryReporter) addChangedPackageSection(builder *markdown.Mar
statusEmoji = markdown.EmojiWarning
}

builder.AddBulletPoint(fmt.Sprintf("%s [`%s`] `%s@%s`",
section.Builder().AddBulletPoint(fmt.Sprintf("%s [`%s`] `%s@%s`",
statusEmoji,
pkgModel.GetEcosystem(), pkgModel.GetName(), pkgModel.GetVersion()))
}

builder.AddCollapsibleSection(section)
return nil
}

func (r *markdownSummaryReporter) addViolationSection(builder *markdown.MarkdownBuilder,
internalModel *vetResultInternalModel) error {
isHeaderAdded := false

section := builder.StartCollapsibleSection("Policy Violations")
section.Builder().AddHeader(2, "Violations")

hasViolations := false

for _, pkg := range internalModel.packages {
packageViolations := pkg.GetViolations()
Expand All @@ -317,18 +323,13 @@ func (r *markdownSummaryReporter) addViolationSection(builder *markdown.Markdown
continue
}

// We use this weird logic to ensure we don't end up adding
// section header if there are no package with violations
if !isHeaderAdded {
builder.AddHeader(2, "Packages Violating Policy")
isHeaderAdded = true
}
hasViolations = true

externalReferenceEmojiUrl := fmt.Sprintf("[%s](%s)",
markdown.EmojiLink,
r.getPackageExternalReferenceUrl(pkgModel))

builder.AddHeader(3, fmt.Sprintf("[%s] `%s@%s` %s",
section.Builder().AddHeader(3, fmt.Sprintf("[%s] `%s@%s` %s",
pkgModel.GetEcosystem(), pkgModel.GetName(), pkgModel.GetVersion(),
externalReferenceEmojiUrl))

Expand All @@ -343,12 +344,12 @@ func (r *markdownSummaryReporter) addViolationSection(builder *markdown.Markdown
}
*/

builder.AddBulletPoint(fmt.Sprintf(":arrow_right: Found in manifest `%s`", path))
section.Builder().AddBulletPoint(fmt.Sprintf(":arrow_right: Found in manifest `%s`", path))
}
}

for _, v := range packageViolations {
builder.AddBulletPoint(fmt.Sprintf(":warning: %s", v.GetFilter().GetSummary()))
section.Builder().AddBulletPoint(fmt.Sprintf(":warning: %s", v.GetFilter().GetSummary()))
}

advices := pkg.GetAdvices()
Expand All @@ -358,10 +359,14 @@ func (r *markdownSummaryReporter) addViolationSection(builder *markdown.Markdown
continue
}

builder.AddBulletPoint(fmt.Sprintf(":zap: %s", advSummary))
section.Builder().AddBulletPoint(fmt.Sprintf(":zap: %s", advSummary))
}
}

if hasViolations {
builder.AddCollapsibleSection(section)
}

return nil
}

Expand Down

0 comments on commit 3cf8d01

Please sign in to comment.