Skip to content

Commit

Permalink
Merge pull request #527 from crystal-ameba/github-actions-formatter
Browse files Browse the repository at this point in the history
Add GitHub Actions formatter
  • Loading branch information
Sija authored Dec 6, 2024
2 parents 9093abc + 9c07970 commit 29989b0
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 6 deletions.
30 changes: 30 additions & 0 deletions spec/ameba/formatter/github_actions_formatter_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require "../../spec_helper"

module Ameba::Formatter
describe GitHubActionsFormatter do
describe "#source_finished" do
it "writes valid source" do
output = IO::Memory.new
subject = GitHubActionsFormatter.new(output)

source = Source.new "", "/path/to/file.cr"

subject.source_finished(source)
output.to_s.should be_empty
end

it "writes invalid source" do
output = IO::Memory.new
subject = GitHubActionsFormatter.new(output)

source = Source.new "", "/path/to/file.cr"
location = Crystal::Location.new("/path/to/file.cr", 1, 2)

source.add_issue DummyRule.new, location, location, "message\n2nd line"

subject.source_finished(source)
output.to_s.should eq("::notice file=/path/to/file.cr,line=1,col=2,endLine=1,endColumn=2,title=Ameba/DummyRule::message%0A2nd line\n")
end
end
end
end
13 changes: 7 additions & 6 deletions src/ameba/config.cr
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ class Ameba::Config
include GlobUtils

AVAILABLE_FORMATTERS = {
progress: Formatter::DotFormatter,
todo: Formatter::TODOFormatter,
flycheck: Formatter::FlycheckFormatter,
silent: Formatter::BaseFormatter,
disabled: Formatter::DisabledFormatter,
json: Formatter::JSONFormatter,
progress: Formatter::DotFormatter,
todo: Formatter::TODOFormatter,
flycheck: Formatter::FlycheckFormatter,
silent: Formatter::BaseFormatter,
disabled: Formatter::DisabledFormatter,
json: Formatter::JSONFormatter,
"github-actions": Formatter::GitHubActionsFormatter,
}

XDG_CONFIG_HOME = ENV.fetch("XDG_CONFIG_HOME", "~/.config")
Expand Down
69 changes: 69 additions & 0 deletions src/ameba/formatter/github_actions_formatter.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
module Ameba::Formatter
# A formatter that outputs issues in a GitHub Actions compatible format.
#
# See [GitHub Actions documentation](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions) for details.
class GitHubActionsFormatter < BaseFormatter
@mutex = Mutex.new

# Reports a result of the inspection of a corresponding source.
def source_finished(source : Source) : Nil
source.issues.each do |issue|
next if issue.disabled?

@mutex.synchronize do
output << "::"
output << command_name(issue.rule.severity)
output << " "
output << "file="
output << escape_property(source.path)
if location = issue.location
output << ",line="
output << location.line_number
output << ",col="
output << location.column_number
end
if end_location = issue.end_location
output << ",endLine="
output << end_location.line_number
output << ",endColumn="
output << end_location.column_number
end
output << ",title="
output << escape_property(issue.rule.name)
output << "::"
output << escape_data(issue.message)
output << "\n"
end
end
end

private def command_name(severity : Severity) : String
case severity
in .error? then "error"
in .warning? then "warning"
in .convention? then "notice"
end
end

# See for details:
# - https://github.com/actions/toolkit/blob/74906bea83a0dbf6aaba2d00b732deb0c3aefd2d/packages/core/src/command.ts#L92-L97
# - https://github.com/actions/toolkit/issues/193
private def escape_data(string : String) : String
string
.gsub('%', "%25")
.gsub('\r', "%0D")
.gsub('\n', "%0A")
end

# See for details:
# - https://github.com/actions/toolkit/blob/74906bea83a0dbf6aaba2d00b732deb0c3aefd2d/packages/core/src/command.ts#L99-L106
private def escape_property(string : String) : String
string
.gsub('%', "%25")
.gsub('\r', "%0D")
.gsub('\n', "%0A")
.gsub(':', "%3A")
.gsub(',', "%2C")
end
end
end

0 comments on commit 29989b0

Please sign in to comment.