Skip to content

Commit

Permalink
fix: use Crystal http client
Browse files Browse the repository at this point in the history
  • Loading branch information
mrexox committed Jun 27, 2023
1 parent 27bb656 commit 5aa64c3
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 26 deletions.
1 change: 1 addition & 0 deletions .ameba.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Metrics/CyclomaticComplexity:
- src/coverage_reporter/parsers/lcov_parser.cr
- src/coverage_reporter/parsers/gcov_parser.cr
- src/coverage_reporter/parsers/coveragepy_parser.cr
- src/coverage_reporter/cli/cmd.cr

Lint/PercentArrays:
Enabled: true
Expand Down
34 changes: 30 additions & 4 deletions src/coverage_reporter/api.cr
Original file line number Diff line number Diff line change
@@ -1,19 +1,45 @@
require "./config"
require "./api/*"
require "http"

module CoverageReporter
module Api
extend self

DEFAULT_HEADERS = {
class HTTPError < Exception
getter status_code : Int32
getter response : String

def initialize(response : HTTP::Client::Response)
super(response.status_message)
@status_code = response.status_code
@response = response.body
end
end

class InternalServerError < HTTPError; end

class UnprocessableEntity < HTTPError; end

DEFAULT_HEADERS = HTTP::Headers{
"X-Coveralls-Reporter" => "coverage-reporter",
"X-Coveralls-Reporter-Version" => VERSION,
"X-Coveralls-Source" => ENV["COVERALLS_SOURCE_HEADER"]?.presence || "cli",
"Accept" => "*/*",
"User-Agent" => "Crystal #{Crystal::VERSION}",
}

def show_response(res)
# TODO: include info about account status
Log.info "---\n✅ API Response: #{res.body}\n- 💛, Coveralls"
def handle_response(res)
case res.status
when HTTP::Status::OK
Log.info "---\n✅ API Response: #{res.body}\n- 💛, Coveralls"
when HTTP::Status::INTERNAL_SERVER_ERROR
raise InternalServerError.new(res)
when HTTP::Status::UNPROCESSABLE_ENTITY
raise UnprocessableEntity.new(res)
else
raise HTTPError.new(res)
end
end
end
end
47 changes: 35 additions & 12 deletions src/coverage_reporter/api/jobs.cr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require "../source_files"
require "../git"
require "../config"
require "crest"
require "http"
require "compress/gzip"
require "json"

Expand Down Expand Up @@ -37,11 +37,11 @@ module CoverageReporter
data = build_request
api_url = "#{@config.endpoint}/api/#{API_VERSION}/jobs"

headers = DEFAULT_HEADERS.merge({
"Content-Type" => "application/gzip",
headers = DEFAULT_HEADERS.dup
headers.merge!(HTTP::Headers{
"X-Coveralls-Coverage-Formats" => @source_files.map(&.format.to_s).sort!.uniq!.join(","),
"X-Coveralls-CI" => @config[:service_name]?,
}.compact)
"X-Coveralls-CI" => @config[:service_name]? || "unknown",
})

Log.info " ·job_flag: #{@config.flag_name}" if @config.flag_name
Log.info "🚀 Posting coverage data to #{api_url}"
Expand All @@ -55,14 +55,17 @@ module CoverageReporter
Compress::Gzip::Writer.open(io, &.print(data.to_json.to_s))
end

res = Crest.post(
api_url,
headers: headers,
form: gzipped_json,
tls: ENV["COVERALLS_ENDPOINT"]? ? OpenSSL::SSL::Context::Client.insecure : nil,
)
with_file(IO::Memory.new(gzipped_json)) do |content_type, body|
headers.merge!(HTTP::Headers{"Content-Type" => content_type})
response = HTTP::Client.post(
api_url,
body: body,
headers: headers,
tls: ENV["COVERALLS_ENDPOINT"]? ? OpenSSL::SSL::Context::Client.insecure : nil
)

Api.show_response(res)
Api.handle_response(response)
end
end

private def build_request
Expand All @@ -75,5 +78,25 @@ module CoverageReporter
}
)
end

private def with_file(gzfile, &)
IO.pipe do |reader, writer|
channel = Channel(String).new(1)

spawn do
HTTP::FormData.build(writer) do |formdata|
channel.send(formdata.content_type)

metadata = HTTP::FormData::FileMetadata.new(filename: "json_file")
headers = HTTP::Headers{"Content-Type" => "application/x-gzip"}
formdata.file("json_file", gzfile, metadata, headers)
end

writer.close
end

yield(channel.receive, reader)
end
end
end
end
19 changes: 11 additions & 8 deletions src/coverage_reporter/api/webhook.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require "crest"
# require "crest"
require "http"
require "json"

module CoverageReporter
Expand All @@ -22,18 +23,20 @@ module CoverageReporter
Log.debug "---\n⛑ Debug Output:\n#{data.to_pretty_json}"

return if dry_run
headers = DEFAULT_HEADERS.dup
headers.merge!(HTTP::Headers{
"Content-Type" => "application/json",
"X-Coveralls-CI" => @config[:service_name]? || "unknown",
})

res = Crest.post(
res = HTTP::Client.post(
webhook_url,
headers: DEFAULT_HEADERS.merge({
"Content-Type" => "application/json",
"X-Coveralls-CI" => @config[:service_name]?,
}.compact),
form: data.to_json,
headers: headers,
body: data.to_json,
tls: ENV["COVERALLS_ENDPOINT"]? ? OpenSSL::SSL::Context::Client.insecure : nil
)

Api.show_response(res)
Api.handle_response(res)
end
end
end
13 changes: 11 additions & 2 deletions src/coverage_reporter/cli/cmd.cr
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ module CoverageReporter::Cli
Coveralls Coverage Reporter v#{CoverageReporter::VERSION}
ERROR
exit 1
rescue ex : Crest::InternalServerError
rescue ex : Api::InternalServerError
Log.error "⚠️ Internal server error. Please contact Coveralls team."
exit 1
rescue ex : Crest::UnprocessableEntity
rescue ex : Api::UnprocessableEntity
Log.error <<-ERROR
---
Error: #{ex.message}
Expand All @@ -59,6 +59,15 @@ module CoverageReporter::Cli
- 💛, Coveralls
ERROR
exit 1
rescue ex : Api::HTTPError
Log.error <<-ERROR
Unhandled HTTP error:
---
Error: #{ex.message} (#{ex.status_code})
Message: #{ex.response}
---
ERROR
exit 1
rescue ex
raise(ex) if opts.try(&.debug?)

Expand Down

0 comments on commit 5aa64c3

Please sign in to comment.