codecov 0.2.12 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 98728653c21cce7decd7a9b031e54e950da789d70c464bb61e53e1964372ac1d
4
- data.tar.gz: 8d45300d929ff5bd39cb5cfb562960ef1bf3b36b1f51754376f25c8ac8ae3a31
3
+ metadata.gz: 28cb9ca7e98d8d586f0c8118cc099def187c61c2cd1bc36882dd835959030404
4
+ data.tar.gz: 2ae5223947def7a015e0b92fb591f1090cb086406d7f44e284a241a022a54fa4
5
5
  SHA512:
6
- metadata.gz: bdd1f35739f17cc5110ea0c2fa51bf4939812b96ff96009311dfb52ea67b63107cdbfbb8ad6e9b76f1cdc1104a136407bf1f9e89d1509c717131d9b03e62a986
7
- data.tar.gz: 84673f1a411a1b7746b04448a79aa9a84b3e5606d14f7c70b6adee66be765f66ba2caed073cda2dc837788b7a67cc3a0c6c232655533e1170ea0865b30f77c93
6
+ metadata.gz: f43851f9d6c5b8603bea783df5f52dfc40cc5290dfeb741cee23639bd00a60ab1916b73001f7b17652b11839f995b8bc963b151a71e4a7615510f1f129fe6d28
7
+ data.tar.gz: '082f364e342d308a06b25c7955949e225bc8c93d730cbb86d1542c881175441740ffd802e070c071a65f45a8e5df4a536fd4811ef0fc18d732d9e04a8dc046bb'
@@ -6,617 +6,12 @@ require 'net/http'
6
6
  require 'simplecov'
7
7
  require 'zlib'
8
8
 
9
- class SimpleCov::Formatter::Codecov
10
- VERSION = '0.2.12'
11
-
12
- ### CIs
13
- RECOGNIZED_CIS = [
14
- APPVEYOR = 'Appveyor CI',
15
- AZUREPIPELINES = 'Azure Pipelines',
16
- BITBUCKET = 'Bitbucket',
17
- BITRISE = 'Bitrise CI',
18
- BUILDKITE = 'Buildkite CI',
19
- CIRCLE = 'Circle CI',
20
- CODEBUILD = 'Codebuild CI',
21
- CODESHIP = 'Codeship CI',
22
- DRONEIO = 'Drone CI',
23
- GITHUB = 'GitHub Actions',
24
- GITLAB = 'GitLab CI',
25
- HEROKU = 'Heroku CI',
26
- JENKINS = 'Jenkins CI',
27
- SEMAPHORE = 'Semaphore CI',
28
- SHIPPABLE = 'Shippable',
29
- SOLANO = 'Solano CI',
30
- TEAMCITY = 'TeamCity CI',
31
- TRAVIS = 'Travis CI',
32
- WERCKER = 'Wercker CI'
33
- ].freeze
34
-
35
- def display_header
36
- puts [
37
- '',
38
- ' _____ _',
39
- ' / ____| | |',
40
- '| | ___ __| | ___ ___ _____ __',
41
- '| | / _ \ / _\`|/ _ \/ __/ _ \ \ / /',
42
- '| |___| (_) | (_| | __/ (_| (_) \ V /',
43
- ' \_____\___/ \__,_|\___|\___\___/ \_/',
44
- " Ruby-#{VERSION}",
45
- ''
46
- ].join("\n")
47
- end
48
-
49
- def detect_ci
50
- ci = if (ENV['CI'] == 'True') && (ENV['APPVEYOR'] == 'True')
51
- APPVEYOR
52
- elsif !ENV['TF_BUILD'].nil?
53
- AZUREPIPELINES
54
- elsif (ENV['CI'] == 'true') && !ENV['BITBUCKET_BRANCH'].nil?
55
- BITBUCKET
56
- elsif (ENV['CI'] == 'true') && (ENV['BITRISE_IO'] == 'true')
57
- BITRISE
58
- elsif (ENV['CI'] == 'true') && (ENV['BUILDKITE'] == 'true')
59
- BUILDKITE
60
- elsif (ENV['CI'] == 'true') && (ENV['CIRCLECI'] == 'true')
61
- CIRCLE
62
- elsif ENV['CODEBUILD_CI'] == 'true'
63
- CODEBUILD
64
- elsif (ENV['CI'] == 'true') && (ENV['CI_NAME'] == 'codeship')
65
- CODESHIP
66
- elsif ((ENV['CI'] == 'true') || (ENV['CI'] == 'drone')) && (ENV['DRONE'] == 'true')
67
- DRONEIO
68
- elsif (ENV['CI'] == 'true') && (ENV['GITHUB_ACTIONS'] == 'true')
69
- GITHUB
70
- elsif !ENV['GITLAB_CI'].nil?
71
- GITLAB
72
- elsif ENV['HEROKU_TEST_RUN_ID']
73
- HEROKU
74
- elsif !ENV['JENKINS_URL'].nil?
75
- JENKINS
76
- elsif (ENV['CI'] == 'true') && (ENV['SEMAPHORE'] == 'true')
77
- SEMAPHORE
78
- elsif (ENV['CI'] == 'true') && (ENV['SHIPPABLE'] == 'true')
79
- SHIPPABLE
80
- elsif ENV['TDDIUM'] == 'true'
81
- SOLANO
82
- elsif ENV['CI_SERVER_NAME'] == 'TeamCity'
83
- TEAMCITY
84
- elsif (ENV['CI'] == 'true') && (ENV['TRAVIS'] == 'true')
85
- TRAVIS
86
- elsif (ENV['CI'] == 'true') && !ENV['WERCKER_GIT_BRANCH'].nil?
87
- WERCKER
88
- end
89
-
90
- if !RECOGNIZED_CIS.include?(ci)
91
- puts [red('x>'), 'No CI provider detected.'].join(' ')
92
- else
93
- puts "==> #{ci} detected"
94
- end
95
-
96
- ci
97
- end
98
-
99
- def build_params(ci)
100
- params = {
101
- 'token' => ENV['CODECOV_TOKEN'],
102
- 'flags' => ENV['CODECOV_FLAG'] || ENV['CODECOV_FLAGS'],
103
- 'package' => "ruby-#{VERSION}"
104
- }
105
-
106
- case ci
107
- when APPVEYOR
108
- # http://www.appveyor.com/docs/environment-variables
109
- params[:service] = 'appveyor'
110
- params[:branch] = ENV['APPVEYOR_REPO_BRANCH']
111
- params[:build] = ENV['APPVEYOR_JOB_ID']
112
- params[:pr] = ENV['APPVEYOR_PULL_REQUEST_NUMBER']
113
- params[:job] = ENV['APPVEYOR_ACCOUNT_NAME'] + '/' + ENV['APPVEYOR_PROJECT_SLUG'] + '/' + ENV['APPVEYOR_BUILD_VERSION']
114
- params[:slug] = ENV['APPVEYOR_REPO_NAME']
115
- params[:commit] = ENV['APPVEYOR_REPO_COMMIT']
116
- when AZUREPIPELINES
117
- params[:service] = 'azure_pipelines'
118
- params[:branch] = ENV['BUILD_SOURCEBRANCH']
119
- params[:pull_request] = ENV['SYSTEM_PULLREQUEST_PULLREQUESTNUMBER']
120
- params[:job] = ENV['SYSTEM_JOBID']
121
- params[:build] = ENV['BUILD_BUILDID']
122
- params[:build_url] = "#{ENV['SYSTEM_TEAMFOUNDATIONSERVERURI']}/#{ENV['SYSTEM_TEAMPROJECT']}/_build/results?buildId=#{ENV['BUILD_BUILDID']}"
123
- params[:commit] = ENV['BUILD_SOURCEVERSION']
124
- params[:slug] = ENV['BUILD_REPOSITORY_ID']
125
- when BITBUCKET
126
- # https://confluence.atlassian.com/bitbucket/variables-in-pipelines-794502608.html
127
- params[:service] = 'bitbucket'
128
- params[:branch] = ENV['BITBUCKET_BRANCH']
129
- # BITBUCKET_COMMIT does not always provide full commit sha due to a bug https://jira.atlassian.com/browse/BCLOUD-19393#
130
- params[:commit] = (ENV['BITBUCKET_COMMIT'].length < 40 ? nil : ENV['BITBUCKET_COMMIT'])
131
- params[:build] = ENV['BITBUCKET_BUILD_NUMBER']
132
- when BITRISE
133
- # http://devcenter.bitrise.io/faq/available-environment-variables/
134
- params[:service] = 'bitrise'
135
- params[:branch] = ENV['BITRISE_GIT_BRANCH']
136
- params[:pr] = ENV['BITRISE_PULL_REQUEST']
137
- params[:build] = ENV['BITRISE_BUILD_NUMBER']
138
- params[:build_url] = ENV['BITRISE_BUILD_URL']
139
- params[:commit] = ENV['BITRISE_GIT_COMMIT']
140
- params[:slug] = ENV['BITRISEIO_GIT_REPOSITORY_OWNER'] + '/' + ENV['BITRISEIO_GIT_REPOSITORY_SLUG']
141
- when BUILDKITE
142
- # https://buildkite.com/docs/guides/environment-variables
143
- params[:service] = 'buildkite'
144
- params[:branch] = ENV['BUILDKITE_BRANCH']
145
- params[:build] = ENV['BUILDKITE_BUILD_NUMBER']
146
- params[:job] = ENV['BUILDKITE_JOB_ID']
147
- params[:build_url] = ENV['BUILDKITE_BUILD_URL']
148
- params[:slug] = ENV['BUILDKITE_PROJECT_SLUG']
149
- params[:commit] = ENV['BUILDKITE_COMMIT']
150
- when CIRCLE
151
- # https://circleci.com/docs/environment-variables
152
- params[:service] = 'circleci'
153
- params[:build] = ENV['CIRCLE_BUILD_NUM']
154
- params[:job] = ENV['CIRCLE_NODE_INDEX']
155
- params[:slug] = if !ENV['CIRCLE_PROJECT_REPONAME'].nil?
156
- ENV['CIRCLE_PROJECT_USERNAME'] + '/' + ENV['CIRCLE_PROJECT_REPONAME']
157
- else
158
- ENV['CIRCLE_REPOSITORY_URL'].gsub(/^.*:/, '').gsub(/\.git$/, '')
159
- end
160
- params[:pr] = ENV['CIRCLE_PR_NUMBER']
161
- params[:branch] = ENV['CIRCLE_BRANCH']
162
- params[:commit] = ENV['CIRCLE_SHA1']
163
- when CODEBUILD
164
- # https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html
165
- params[:service] = 'codebuild'
166
- params[:branch] = ENV['CODEBUILD_WEBHOOK_HEAD_REF'].split('/')[2]
167
- params[:build] = ENV['CODEBUILD_BUILD_ID']
168
- params[:commit] = ENV['CODEBUILD_RESOLVED_SOURCE_VERSION']
169
- params[:job] = ENV['CODEBUILD_BUILD_ID']
170
- params[:slug] = ENV['CODEBUILD_SOURCE_REPO_URL'].match(/.*github.com\/(?<slug>.*).git/)['slug']
171
- params[:pr] = if ENV['CODEBUILD_SOURCE_VERSION']
172
- matched = ENV['CODEBUILD_SOURCE_VERSION'].match(%r{pr/(?<pr>.*)})
173
- matched.nil? ? ENV['CODEBUILD_SOURCE_VERSION'] : matched['pr']
174
- end
175
- when CODESHIP
176
- # https://www.codeship.io/documentation/continuous-integration/set-environment-variables/
177
- params[:service] = 'codeship'
178
- params[:branch] = ENV['CI_BRANCH']
179
- params[:commit] = ENV['CI_COMMIT_ID']
180
- params[:build] = ENV['CI_BUILD_NUMBER']
181
- params[:build_url] = ENV['CI_BUILD_URL']
182
- when DRONEIO
183
- # https://semaphoreapp.com/docs/available-environment-variables.html
184
- params[:service] = 'drone.io'
185
- params[:branch] = ENV['DRONE_BRANCH']
186
- params[:commit] = ENV['DRONE_COMMIT_SHA']
187
- params[:job] = ENV['DRONE_JOB_NUMBER']
188
- params[:build] = ENV['DRONE_BUILD_NUMBER']
189
- params[:build_url] = ENV['DRONE_BUILD_LINK'] || ENV['DRONE_BUILD_URL'] || ENV['CI_BUILD_URL']
190
- params[:pr] = ENV['DRONE_PULL_REQUEST']
191
- params[:tag] = ENV['DRONE_TAG']
192
- when GITHUB
193
- # https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables
194
- params[:service] = 'github-actions'
195
- params[:branch] = ENV['GITHUB_HEAD_REF'] || ENV['GITHUB_REF'].sub('refs/head/', '')
196
- # PR refs are in the format: refs/pull/7/merge for pull_request events
197
- params[:pr] = ENV['GITHUB_REF'].split('/')[2] unless ENV['GITHUB_HEAD_REF'].nil? || ENV['GITHUB_HEAD_REF'].empty?
198
- params[:slug] = ENV['GITHUB_REPOSITORY']
199
- params[:build] = ENV['GITHUB_RUN_ID']
200
- params[:commit] = ENV['GITHUB_SHA']
201
- when GITLAB
202
- # http://doc.gitlab.com/ci/examples/README.html#environmental-variables
203
- # https://gitlab.com/gitlab-org/gitlab-ci-runner/blob/master/lib/build.rb#L96
204
- # GitLab Runner v9 renamed some environment variables, so we check both old and new variable names.
205
- params[:service] = 'gitlab'
206
- params[:branch] = ENV['CI_BUILD_REF_NAME'] || ENV['CI_COMMIT_REF_NAME']
207
- params[:build] = ENV['CI_BUILD_ID'] || ENV['CI_JOB_ID']
208
- slug = ENV['CI_BUILD_REPO'] || ENV['CI_REPOSITORY_URL']
209
- params[:slug] = slug.split('/', 4)[-1].sub('.git', '') if slug
210
- params[:commit] = ENV['CI_BUILD_REF'] || ENV['CI_COMMIT_SHA']
211
- when HEROKU
212
- params[:service] = 'heroku'
213
- params[:branch] = ENV['HEROKU_TEST_RUN_BRANCH']
214
- params[:build] = ENV['HEROKU_TEST_RUN_ID']
215
- params[:commit] = ENV['HEROKU_TEST_RUN_COMMIT_VERSION']
216
- when JENKINS
217
- # https://wiki.jenkins-ci.org/display/JENKINS/Building+a+software+project
218
- # https://wiki.jenkins-ci.org/display/JENKINS/GitHub+pull+request+builder+plugin#GitHubpullrequestbuilderplugin-EnvironmentVariables
219
- params[:service] = 'jenkins'
220
- params[:branch] = ENV['ghprbSourceBranch'] || ENV['GIT_BRANCH']
221
- params[:commit] = ENV['ghprbActualCommit'] || ENV['GIT_COMMIT']
222
- params[:pr] = ENV['ghprbPullId']
223
- params[:build] = ENV['BUILD_NUMBER']
224
- params[:root] = ENV['WORKSPACE']
225
- params[:build_url] = ENV['BUILD_URL']
226
- when SEMAPHORE
227
- # https://semaphoreapp.com/docs/available-environment-variables.html
228
- params[:service] = 'semaphore'
229
- params[:branch] = ENV['BRANCH_NAME']
230
- params[:commit] = ENV['REVISION']
231
- params[:build] = ENV['SEMAPHORE_BUILD_NUMBER']
232
- params[:job] = ENV['SEMAPHORE_CURRENT_THREAD']
233
- params[:slug] = ENV['SEMAPHORE_REPO_SLUG']
234
- when SHIPPABLE
235
- # http://docs.shippable.com/en/latest/config.html#common-environment-variables
236
- params[:service] = 'shippable'
237
- params[:branch] = ENV['BRANCH']
238
- params[:build] = ENV['BUILD_NUMBER']
239
- params[:build_url] = ENV['BUILD_URL']
240
- params[:pull_request] = ENV['PULL_REQUEST']
241
- params[:slug] = ENV['REPO_NAME']
242
- params[:commit] = ENV['COMMIT']
243
- when SOLANO
244
- # http://docs.solanolabs.com/Setup/tddium-set-environment-variables/
245
- params[:service] = 'solano'
246
- params[:branch] = ENV['TDDIUM_CURRENT_BRANCH']
247
- params[:commit] = ENV['TDDIUM_CURRENT_COMMIT']
248
- params[:build] = ENV['TDDIUM_TID']
249
- params[:pr] = ENV['TDDIUM_PR_ID']
250
- when TEAMCITY
251
- # https://confluence.jetbrains.com/display/TCD8/Predefined+Build+Parameters
252
- # Teamcity does not automatically make build parameters available as environment variables.
253
- # Add the following environment parameters to the build configuration
254
- # env.TEAMCITY_BUILD_BRANCH = %teamcity.build.branch%
255
- # env.TEAMCITY_BUILD_ID = %teamcity.build.id%
256
- # env.TEAMCITY_BUILD_URL = %teamcity.serverUrl%/viewLog.html?buildId=%teamcity.build.id%
257
- # env.TEAMCITY_BUILD_COMMIT = %system.build.vcs.number%
258
- # env.TEAMCITY_BUILD_REPOSITORY = %vcsroot.<YOUR TEAMCITY VCS NAME>.url%
259
- params[:service] = 'teamcity'
260
- params[:branch] = ENV['TEAMCITY_BUILD_BRANCH']
261
- params[:build] = ENV['TEAMCITY_BUILD_ID']
262
- params[:build_url] = ENV['TEAMCITY_BUILD_URL']
263
- params[:commit] = ENV['TEAMCITY_BUILD_COMMIT']
264
- params[:slug] = ENV['TEAMCITY_BUILD_REPOSITORY'].split('/', 4)[-1].sub('.git', '')
265
- when TRAVIS
266
- # http://docs.travis-ci.com/user/ci-environment/#Environment-variables
267
- params[:service] = 'travis'
268
- params[:branch] = ENV['TRAVIS_BRANCH']
269
- params[:pull_request] = ENV['TRAVIS_PULL_REQUEST']
270
- params[:job] = ENV['TRAVIS_JOB_ID']
271
- params[:slug] = ENV['TRAVIS_REPO_SLUG']
272
- params[:build] = ENV['TRAVIS_JOB_NUMBER']
273
- params[:commit] = ENV['TRAVIS_COMMIT']
274
- params[:env] = ENV['TRAVIS_RUBY_VERSION']
275
- when WERCKER
276
- # http://devcenter.wercker.com/articles/steps/variables.html
277
- params[:service] = 'wercker'
278
- params[:branch] = ENV['WERCKER_GIT_BRANCH']
279
- params[:build] = ENV['WERCKER_MAIN_PIPELINE_STARTED']
280
- params[:slug] = ENV['WERCKER_GIT_OWNER'] + '/' + ENV['WERCKER_GIT_REPOSITORY']
281
- params[:commit] = ENV['WERCKER_GIT_COMMIT']
282
- end
283
-
284
- if params[:branch].nil?
285
- # find branch, commit, repo from git command
286
- branch = `git rev-parse --abbrev-ref HEAD`.strip
287
- params[:branch] = branch != 'HEAD' ? branch : 'master'
288
- end
289
-
290
- if !ENV['VCS_COMMIT_ID'].nil?
291
- params[:commit] = ENV['VCS_COMMIT_ID']
292
-
293
- elsif params[:commit].nil?
294
- params[:commit] = `git rev-parse HEAD`.strip
295
- end
296
-
297
- slug = ENV['CODECOV_SLUG']
298
- params[:slug] = slug unless slug.nil?
299
-
300
- params[:pr] = params[:pr].sub('#', '') unless params[:pr].nil?
301
-
302
- params
303
- end
304
-
305
- def retry_request(req, https)
306
- retries = 3
307
- begin
308
- response = https.request(req)
309
- rescue Timeout::Error, SocketError => e
310
- retries -= 1
311
-
312
- if retries.zero?
313
- puts 'Timeout or connection error uploading coverage reports to Codecov. Out of retries.'
314
- puts e
315
- return response
316
- end
317
-
318
- puts 'Timeout or connection error uploading coverage reports to Codecov. Retrying...'
319
- puts e
320
- retry
321
- rescue StandardError => e
322
- puts 'Error uploading coverage reports to Codecov. Sorry'
323
- puts e.class.name
324
- puts e
325
- puts "Backtrace:\n\t#{e.backtrace}"
326
- return response
327
- end
328
-
329
- response
330
- end
331
-
332
- def create_report(report)
333
- result = {
334
- 'meta' => {
335
- 'version' => 'codecov-ruby/v' + VERSION
336
- }
337
- }
338
- result.update(result_to_codecov(report))
339
- result
340
- end
341
-
342
- def gzip_report(report)
343
- puts [green('==>'), 'Gzipping contents'].join(' ')
344
-
345
- io = StringIO.new
346
- gzip = Zlib::GzipWriter.new(io)
347
- gzip << report
348
- gzip.close
349
-
350
- io.string
351
- end
352
-
353
- def upload_to_codecov(ci, report)
354
- url = ENV['CODECOV_URL'] || 'https://codecov.io'
355
- is_enterprise = url != 'https://codecov.io'
356
-
357
- params = build_params(ci)
358
- params_secret_token = params.clone
359
- params_secret_token['token'] = 'secret'
360
-
361
- query = URI.encode_www_form(params)
362
- query_without_token = URI.encode_www_form(params_secret_token)
363
-
364
- gzipped_report = gzip_report(report['codecov'])
365
-
366
- report['params'] = params
367
- report['query'] = query
368
-
369
- puts [green('==>'), 'Uploading reports'].join(' ')
370
- puts " url: #{url}"
371
- puts " query: #{query_without_token}"
372
-
373
- response = false
374
- unless is_enterprise
375
- response = upload_to_v4(url, gzipped_report, query, query_without_token)
376
- return false if response == false
377
- end
378
-
379
- response || upload_to_v2(url, gzipped_report, query, query_without_token)
380
- end
381
-
382
- def upload_to_v4(url, report, query, query_without_token)
383
- uri = URI.parse(url.chomp('/') + '/upload/v4')
384
- https = Net::HTTP.new(uri.host, uri.port)
385
- https.use_ssl = !url.match(/^https/).nil?
386
-
387
- puts [green('-> '), 'Pinging Codecov'].join(' ')
388
- puts "#{url}#{uri.path}?#{query_without_token}"
389
-
390
- req = Net::HTTP::Post.new(
391
- "#{uri.path}?#{query}",
392
- {
393
- 'X-Reduced-Redundancy' => 'false',
394
- 'X-Content-Encoding' => 'application/x-gzip',
395
- 'Content-Type' => 'text/plain'
396
- }
397
- )
398
- response = retry_request(req, https)
399
- if !response&.code || response.code == '400'
400
- puts red(response&.body)
401
- return false
402
- end
403
-
404
- reports_url = response.body.lines[0]
405
- s3target = response.body.lines[1]
406
- puts [green('-> '), 'Uploading to'].join(' ')
407
- puts s3target
408
-
409
- uri = URI(s3target)
410
- https = Net::HTTP.new(uri.host, uri.port)
411
- https.use_ssl = true
412
- req = Net::HTTP::Put.new(
413
- s3target,
414
- {
415
- 'Content-Encoding' => 'gzip',
416
- 'Content-Type' => 'text/plain'
417
- }
418
- )
419
- req.body = report
420
- res = retry_request(req, https)
421
- if res&.body == ''
422
- {
423
- 'uploaded' => true,
424
- 'url' => reports_url,
425
- 'meta' => {
426
- 'status' => res.code
427
- },
428
- 'message' => 'Coverage reports upload successfully'
429
- }.to_json
430
- else
431
- puts [black('-> '), 'Could not upload reports via v4 API, defaulting to v2'].join(' ')
432
- puts red(res&.body || 'nil')
433
- nil
434
- end
435
- end
436
-
437
- def upload_to_v2(url, report, query, query_without_token)
438
- uri = URI.parse(url.chomp('/') + '/upload/v2')
439
- https = Net::HTTP.new(uri.host, uri.port)
440
- https.use_ssl = !url.match(/^https/).nil?
441
-
442
- puts [green('-> '), 'Uploading to Codecov'].join(' ')
443
- puts "#{url}#{uri.path}?#{query_without_token}"
444
-
445
- req = Net::HTTP::Post.new(
446
- "#{uri.path}?#{query}",
447
- {
448
- 'Accept' => 'application/json',
449
- 'Content-Encoding' => 'gzip',
450
- 'Content-Type' => 'text/plain',
451
- 'X-Content-Encoding' => 'gzip'
452
- }
453
- )
454
- req.body = report
455
- res = retry_request(req, https)
456
- res&.body
457
- end
458
-
459
- def handle_report_response(report)
460
- if report['result']['uploaded']
461
- puts " View reports at #{report['result']['url']}"
462
- else
463
- puts red(' X> Failed to upload coverage reports')
464
- end
465
- end
9
+ require_relative 'codecov/formatter'
10
+ require_relative 'codecov/uploader'
466
11
 
12
+ class SimpleCov::Formatter::Codecov
467
13
  def format(result, disable_net_blockers = true)
468
- net_blockers(:off) if disable_net_blockers
469
-
470
- display_header
471
- ci = detect_ci
472
- report = create_report(result)
473
- response = upload_to_codecov(ci, report)
474
- if response == false
475
- report['result'] = { 'uploaded' => false }
476
- return report
477
- end
478
-
479
- report['result'] = JSON.parse(response)
480
- handle_report_response(report)
481
-
482
- net_blockers(:on) if disable_net_blockers
483
- report
484
- end
485
-
486
- private
487
-
488
- # Format SimpleCov coverage data for the Codecov.io API.
489
- #
490
- # @param result [SimpleCov::Result] The coverage data to process.
491
- # @return [Hash]
492
- def result_to_codecov(result)
493
- {
494
- 'codecov' => result_to_codecov_report(result),
495
- 'coverage' => result_to_codecov_coverage(result),
496
- 'messages' => result_to_codecov_messages(result)
497
- }
498
- end
499
-
500
- def result_to_codecov_report(result)
501
- report = file_network.join("\n").concat("\n")
502
- report = report.concat({ 'coverage' => result_to_codecov_coverage(result) }.to_json)
503
- report
504
- end
505
-
506
- def file_network
507
- invalid_file_types = [
508
- 'woff', 'eot', 'otf', # fonts
509
- 'gif', 'png', 'jpg', 'jpeg', 'psd', # images
510
- 'ptt', 'pptx', 'numbers', 'pages', 'md', 'txt', 'xlsx', 'docx', 'doc', 'pdf', 'csv', # docs
511
- 'yml', 'yaml', '.gitignore'
512
- ].freeze
513
-
514
- invalid_directories = [
515
- 'node_modules/',
516
- 'public/',
517
- 'storage/',
518
- 'tmp/',
519
- 'vendor/'
520
- ]
521
-
522
- puts [green('==>'), 'Appending file network'].join(' ')
523
- network = []
524
- Dir['**/*'].keep_if do |file|
525
- if File.file?(file) && !file.end_with?(*invalid_file_types) && invalid_directories.none? { |dir| file.include?(dir) }
526
- network.push(file)
527
- end
528
- end
529
-
530
- network.push('<<<<<< network')
531
- network
532
- end
533
-
534
- # Format SimpleCov coverage data for the Codecov.io coverage API.
535
- #
536
- # @param result [SimpleCov::Result] The coverage data to process.
537
- # @return [Hash<String, Array>]
538
- def result_to_codecov_coverage(result)
539
- result.files.each_with_object({}) do |file, memo|
540
- memo[shortened_filename(file)] = file_to_codecov(file)
541
- end
542
- end
543
-
544
- # Format SimpleCov coverage data for the Codecov.io messages API.
545
- #
546
- # @param result [SimpleCov::Result] The coverage data to process.
547
- # @return [Hash<String, Hash>]
548
- def result_to_codecov_messages(result)
549
- result.files.each_with_object({}) do |file, memo|
550
- memo[shortened_filename(file)] = file.lines.each_with_object({}) do |line, lines_memo|
551
- lines_memo[line.line_number.to_s] = 'skipped' if line.skipped?
552
- end
553
- end
554
- end
555
-
556
- # Format coverage data for a single file for the Codecov.io API.
557
- #
558
- # @param file [SimpleCov::SourceFile] The file to process.
559
- # @return [Array<nil, Integer>]
560
- def file_to_codecov(file)
561
- # Initial nil is required to offset line numbers.
562
- [nil] + file.lines.map do |line|
563
- if line.skipped?
564
- nil
565
- else
566
- line.coverage
567
- end
568
- end
569
- end
570
-
571
- # Get a filename relative to the project root. Based on
572
- # https://github.com/colszowka/simplecov-html, copyright Christoph Olszowka.
573
- #
574
- # @param file [SimeplCov::SourceFile] The file to use.
575
- # @return [String]
576
- def shortened_filename(file)
577
- file.filename.gsub(/^#{SimpleCov.root}/, '.').gsub(%r{^\./}, '')
578
- end
579
-
580
- # Toggle VCR and WebMock on or off
581
- #
582
- # @param switch Toggle switch for Net Blockers.
583
- # @return [Boolean]
584
- def net_blockers(switch)
585
- throw 'Only :on or :off' unless %i[on off].include? switch
586
-
587
- if defined?(VCR)
588
- case switch
589
- when :on
590
- VCR.turn_on!
591
- when :off
592
- VCR.turn_off!(ignore_cassettes: true)
593
- end
594
- end
595
-
596
- if defined?(WebMock)
597
- # WebMock on by default
598
- # VCR depends on WebMock 1.8.11; no method to check whether enabled.
599
- case switch
600
- when :on
601
- WebMock.enable!
602
- when :off
603
- WebMock.disable!
604
- end
605
- end
606
-
607
- true
608
- end
609
-
610
- # Convenience color methods
611
- def black(str)
612
- str.nil? ? '' : "\e[30m#{str}\e[0m"
613
- end
614
-
615
- def red(str)
616
- str.nil? ? '' : "\e[31m#{str}\e[0m"
617
- end
618
-
619
- def green(str)
620
- str.nil? ? '' : "\e[32m#{str}\e[0m"
14
+ report = Codecov::SimpleCov::Formatter.format(result)
15
+ Codecov::Uploader.upload(report, disable_net_blockers)
621
16
  end
622
17
  end