circleci-coverage_reporter 0.5.0 → 0.6.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -0
  3. data/CHANGELOG.md +9 -1
  4. data/Gemfile +1 -0
  5. data/README.md +10 -19
  6. data/Rakefile +1 -1
  7. data/bin/rspec +18 -0
  8. data/bin/rubocop +18 -0
  9. data/bin/yard +18 -0
  10. data/lib/circleci/coverage_reporter/artifact.rb +8 -4
  11. data/lib/circleci/coverage_reporter/build.rb +9 -0
  12. data/lib/circleci/coverage_reporter/client.rb +13 -2
  13. data/lib/circleci/coverage_reporter/configuration.rb +7 -31
  14. data/lib/circleci/coverage_reporter/report.rb +43 -29
  15. data/lib/circleci/coverage_reporter/reporters/base.rb +119 -0
  16. data/lib/circleci/coverage_reporter/reporters/flow.rb +32 -0
  17. data/lib/circleci/coverage_reporter/reporters/link.rb +51 -0
  18. data/lib/circleci/coverage_reporter/reporters/rubycritic.rb +33 -0
  19. data/lib/circleci/coverage_reporter/reporters/simplecov.rb +32 -0
  20. data/lib/circleci/coverage_reporter/result.rb +12 -0
  21. data/lib/circleci/coverage_reporter/runner.rb +3 -9
  22. data/lib/circleci/coverage_reporter/vcs/base.rb +23 -0
  23. data/lib/circleci/coverage_reporter/vcs/github.rb +39 -0
  24. data/lib/circleci/coverage_reporter/version.rb +1 -1
  25. data/lib/circleci/coverage_reporter.rb +4 -4
  26. metadata +13 -20
  27. data/lib/circleci/coverage_reporter/abstract_build_result.rb +0 -24
  28. data/lib/circleci/coverage_reporter/abstract_current_result.rb +0 -45
  29. data/lib/circleci/coverage_reporter/abstract_reporter.rb +0 -56
  30. data/lib/circleci/coverage_reporter/abstract_result.rb +0 -21
  31. data/lib/circleci/coverage_reporter/abstract_vcs_client.rb +0 -21
  32. data/lib/circleci/coverage_reporter/flow/build_result.rb +0 -23
  33. data/lib/circleci/coverage_reporter/flow/current_result.rb +0 -23
  34. data/lib/circleci/coverage_reporter/flow/reporter.rb +0 -37
  35. data/lib/circleci/coverage_reporter/github_client.rb +0 -35
  36. data/lib/circleci/coverage_reporter/link/current_result.rb +0 -28
  37. data/lib/circleci/coverage_reporter/link/reporter.rb +0 -35
  38. data/lib/circleci/coverage_reporter/reports_renderer.rb +0 -24
  39. data/lib/circleci/coverage_reporter/rubycritic/build_result.rb +0 -23
  40. data/lib/circleci/coverage_reporter/rubycritic/current_result.rb +0 -29
  41. data/lib/circleci/coverage_reporter/rubycritic/reporter.rb +0 -37
  42. data/lib/circleci/coverage_reporter/simplecov/build_result.rb +0 -23
  43. data/lib/circleci/coverage_reporter/simplecov/current_result.rb +0 -23
  44. data/lib/circleci/coverage_reporter/simplecov/reporter.rb +0 -37
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5b6110a90fbfd7d2fc4c619c19e3fde834e00f47
4
- data.tar.gz: a6a18c2bc9e49123deab1ab7b4fada4716005179
3
+ metadata.gz: a7aca8bd4148d9c5416e8238dea67eb03dbd6f2c
4
+ data.tar.gz: 693fafae6e3340ce02cad34b682b5dbbc9f00b48
5
5
  SHA512:
6
- metadata.gz: bd8c11e4303da250ff42dc38f5fa7ed39d4dda60316c2b71d79c385c7b223d8af8ced3afbde6b1f9f6d16c8f67eb3be868b7c1e125a9ed3ce5504e343dc95245
7
- data.tar.gz: 9cd3f642aa61f91e7295769c16bea3af2f8809cfedd5204cf5a671c94055aaa60ff3c1e31a9d1feda998454d7a522de91e30cf7b2767521c4a9856eaf38d6a33
6
+ metadata.gz: 8864275c0508988de280fd1424ffab28075e980c0388eb8a82b741517266d056d0cf9f01822cbdb60d369ba7520eab6a73c2d632ffba9afbe4f6330426edc82a
7
+ data.tar.gz: 0fa44d79b06c75752d09dfaa4f8b4a7faf177e470bce2bcc2190686b3ea111def27dbc3e7ccdee1bea713eb95b8369a510ee634175fddfdb37be2a6f00c85246
data/.rubocop.yml CHANGED
@@ -11,6 +11,10 @@ Metrics/BlockLength:
11
11
  Style/AndOr:
12
12
  EnforcedStyle: conditionals
13
13
 
14
+ Style/ClassAndModuleChildren:
15
+ Exclude:
16
+ - 'spec/**/*.rb'
17
+
14
18
  Style/Documentation:
15
19
  Enabled: false
16
20
 
data/CHANGELOG.md CHANGED
@@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.6.0] - 2017-05-30
10
+ ### Changed
11
+ - Refactor how to implement reporter. Now a reporter consists of a single ruby class
12
+
13
+ ### Removed
14
+ - Remove template configuration
15
+
9
16
  ## [0.5.0] - 2017-05-18
10
17
  ### Added
11
18
  - Add Link reporter
@@ -60,7 +67,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
60
67
  ### Added
61
68
  - Initial release
62
69
 
63
- [Unreleased]: https://github.com/increments/circleci-coverage_reporter/compare/v0.5.0...HEAD
70
+ [Unreleased]: https://github.com/increments/circleci-coverage_reporter/compare/v0.6.0...HEAD
71
+ [0.6.0]: https://github.com/increments/circleci-coverage_reporter/compare/v0.5.0...v0.6.0
64
72
  [0.5.0]: https://github.com/increments/circleci-coverage_reporter/compare/v0.4.0...v0.5.0
65
73
  [0.4.0]: https://github.com/increments/circleci-coverage_reporter/compare/v0.3.1...v0.4.0
66
74
  [0.3.1]: https://github.com/increments/circleci-coverage_reporter/compare/v0.3.0...v0.3.1
data/Gemfile CHANGED
@@ -3,6 +3,7 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  group :development, :test do
6
+ gem 'ffaker', '~> 2.5'
6
7
  gem 'rake', '~> 11.0'
7
8
  gem 'rspec', '~> 3.5'
8
9
  gem 'rspec_junit_formatter', '~> 0.2', require: false
data/README.md CHANGED
@@ -56,7 +56,7 @@ CircleCI::CoverageReporter.run
56
56
  ## Reporters
57
57
  ### SimpleCov
58
58
 
59
- `CircleCI::CoverageReporter::SimpleCov::Reporter` handles coverage files generated by
59
+ `CircleCI::CoverageReporter::Reporters::SimpleCovReporter` handles coverage files generated by
60
60
  [SimpleCov](https://github.com/colszowka/simplecov).
61
61
 
62
62
  It expects that coverage files are located in `$CIRCLE_ARTIFACTS/coverage` directory:
@@ -73,13 +73,13 @@ If you put files in another directory, say `$CIRCLE_ARTIFACTS/foo/bar`, you have
73
73
 
74
74
  ```ruby
75
75
  CircleCI::CoverageReporter.configure do |config|
76
- config.reporters << CircleCI::CoverageReporter::SimpleCov::Reporter.new('foo/bar')
76
+ config.reporters << CircleCI::CoverageReporter::Reporters::SimpleCov.new(dir: 'foo/bar')
77
77
  end
78
78
  ```
79
79
 
80
80
  ### Flow
81
81
 
82
- `CircleCI::CoverageReporter::Flow::Reporter` handles coverage files generated by
82
+ `CircleCI::CoverageReporter::Reporters::FlowReporter` handles coverage files generated by
83
83
  [flow-coverage-report](https://github.com/rpl/flow-coverage-report)
84
84
 
85
85
  It expects that there is `$CIRCLE_ARTIFACTS/flow-coverage/flow-coverage.json`:
@@ -93,36 +93,27 @@ you have to set reporter as follows:
93
93
 
94
94
  ```ruby
95
95
  CircleCI::CoverageReporter.configure do |config|
96
- config.reporters << CircleCI::CoverageReporter::Flow::Reporter.new('foo/bar')
96
+ config.reporters << CircleCI::CoverageReporter::Reporters::Flow.new(dir: 'foo/bar')
97
97
  end
98
98
  ```
99
99
 
100
100
  ### RubyCritic
101
101
 
102
- `CircleCI::CoverageReporter::RubyCritic::Reporter` handles code quality files generated by
102
+ `CircleCI::CoverageReporter::Reporters::RubyCritic` handles code quality files generated by
103
103
  [rubycritic](https://github.com/whitesmith/rubycritic)
104
104
 
105
- At least json format report is required:
106
-
107
105
  ```bash
108
106
  bundle exec rubycritic -p $CIRCLE_ARTIFACTS/rubycritic -f json --no-browser --mode-ci app
109
- bundle exec rubycritic -p $CIRCLE_ARTIFACTS/rubycritic -f html --no-browser --mode-ci app # optional
107
+ bundle exec rubycritic -p $CIRCLE_ARTIFACTS/rubycritic -f html --no-browser --mode-ci app
110
108
  ```
111
109
 
112
- ## Configuring
113
- ### Template
110
+ ### Link
114
111
 
115
- You can change template for comment body in ERB format with `reports` (an array of
116
- [`Report`](http://www.rubydoc.info/gems/circleci-coverage_reporter/CircleCI/CoverageReporter/Report))
117
- and `vcs_type` (always `"github"`).
112
+ `CircleCI::CoverageReporter::Reporters::Link` reports a link to an artifact file.
118
113
 
119
- ```rb
114
+ ```ruby
120
115
  CircleCI::CoverageReporter.configure do |config|
121
- config.tempalte = <<-'ERB'
122
- <%- reports.each do |report| -%>
123
- [<%= report.type %>](<%= report.url %>) <%= report.coverage %>%
124
- <%- end -%>
125
- ERB
116
+ config.reporters << CircleCI::CoverateReporter::Reporters::Link.new(path: 'path/to/file', name: 'NAME')
126
117
  end
127
118
  ```
128
119
 
data/Rakefile CHANGED
@@ -14,7 +14,7 @@ RuboCop::RakeTask.new
14
14
  YARD::Rake::YardocTask.new
15
15
 
16
16
  CircleCI::CoverageReporter.configure do |config|
17
- config.reporters << CircleCI::CoverageReporter::Link::Reporter.new('doc', 'index.html', name: 'YARD')
17
+ config.reporters << CircleCI::CoverageReporter::Reporters::Link.new(path: 'doc/index.html', name: 'YARD')
18
18
  end
19
19
 
20
20
  desc 'Run RubyCritic'
data/bin/rspec ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rspec' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ require 'rubygems'
16
+ require 'bundler/setup'
17
+
18
+ load Gem.bin_path('rspec-core', 'rspec')
data/bin/rubocop ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rubocop' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ require 'rubygems'
16
+ require 'bundler/setup'
17
+
18
+ load Gem.bin_path('rubocop', 'rubocop')
data/bin/yard ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'yard' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require 'pathname'
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ require 'rubygems'
16
+ require 'bundler/setup'
17
+
18
+ load Gem.bin_path('yard', 'yard')
@@ -1,13 +1,17 @@
1
1
  module CircleCI
2
2
  module CoverageReporter
3
3
  # Encapsulate a CircleCI artifact
4
- Artifact = Struct.new(:path, :pretty_path, :node_index, :url) do
4
+ #
5
+ # @attr path [String] abstract path to the artifact in CircleCI container
6
+ # @attr url [String] URL of the artifact
7
+ Artifact = Struct.new(:path, :url) do
8
+ # @param value [String]
5
9
  # @return [Boolean]
6
- def end_with?(value)
7
- pretty_path.end_with?(value)
10
+ def match?(value)
11
+ path.end_with?(value)
8
12
  end
9
13
 
10
- # @return [String]
14
+ # @return [String] content of the artifact
11
15
  def body
12
16
  @body ||= CoverageReporter.client.get(url).body
13
17
  end
@@ -1,6 +1,9 @@
1
1
  module CircleCI
2
2
  module CoverageReporter
3
3
  # Encapsulate a CircleCI build
4
+ #
5
+ # @attr vcs_revision [String] revision of git
6
+ # @attr build_number [Integer] the ID of the CircleCI build
4
7
  Build = Struct.new(:vcs_revision, :build_number) do
5
8
  # @param revision [String]
6
9
  # @return [Boolean]
@@ -12,6 +15,12 @@ module CircleCI
12
15
  def artifacts
13
16
  @artifacts ||= CoverageReporter.client.artifacts(build_number)
14
17
  end
18
+
19
+ # @param string [String]
20
+ # @return [Artifact, nil]
21
+ def find_artifact(string)
22
+ artifacts.find { |artifact| artifact.match?(string) }
23
+ end
15
24
  end
16
25
  end
17
26
  end
@@ -6,12 +6,16 @@ require_relative 'errors'
6
6
 
7
7
  module CircleCI
8
8
  module CoverageReporter
9
+ # CircleCI API client
9
10
  class Client
10
11
  CIRCLECI_ENDPOINT = 'https://circleci.com/api/v1.1'.freeze
11
12
 
13
+ # Fetch a build data from API and create a {Build} object for it.
14
+ #
12
15
  # @param build_number [Integer, nil]
13
16
  # @return [Build, nil]
14
17
  # @raise [RequestError]
18
+ # @see https://circleci.com/docs/api/v1-reference/#build
15
19
  def single_build(build_number)
16
20
  return unless build_number
17
21
  resp = get(single_build_url(build_number))
@@ -20,9 +24,12 @@ module CircleCI
20
24
  create_build(body)
21
25
  end
22
26
 
27
+ # Retrieve artifacts for the build.
28
+ #
23
29
  # @param build_number [Integer]
24
30
  # @return [Array<Artifact>]
25
31
  # @raise [RequestError]
32
+ # @see https://circleci.com/docs/api/v1-reference/#build-artifacts
26
33
  def artifacts(build_number)
27
34
  resp = get(artifacts_url(build_number))
28
35
  body = JSON.parse(resp.body)
@@ -30,6 +37,8 @@ module CircleCI
30
37
  body.map(&method(:create_artifact))
31
38
  end
32
39
 
40
+ # Find the latest build number for the given vcs revision.
41
+ #
33
42
  # @param revision [String]
34
43
  # @param branch [String, nil]
35
44
  # @return [Integer, nil]
@@ -38,6 +47,8 @@ module CircleCI
38
47
  build ? build.build_number : nil
39
48
  end
40
49
 
50
+ # Raw entry point for GET APIs.
51
+ #
41
52
  # @param url [String]
42
53
  # @param params [Hash]
43
54
  # @return [Faraday::Response]
@@ -54,7 +65,7 @@ module CircleCI
54
65
  end
55
66
 
56
67
  # @param build_number [Integer]
57
- # @return [String]
68
+ # @return [String] URL for "Artifacts of a Bulid API"
58
69
  def artifacts_url(build_number)
59
70
  [
60
71
  CIRCLECI_ENDPOINT,
@@ -104,7 +115,7 @@ module CircleCI
104
115
  # @param hash [Hash]
105
116
  # @return [Artifact]
106
117
  def create_artifact(hash)
107
- Artifact.new(hash['path'], hash['pretty_path'], hash['node_index'], hash['url'])
118
+ Artifact.new(hash['path'], hash['url'])
108
119
  end
109
120
 
110
121
  # @param hash [Hash]
@@ -1,29 +1,15 @@
1
- require_relative 'flow/reporter'
2
- require_relative 'rubycritic/reporter'
3
- require_relative 'simplecov/reporter'
1
+ require_relative 'reporters/flow'
2
+ require_relative 'reporters/rubycritic'
3
+ require_relative 'reporters/simplecov'
4
4
 
5
5
  module CircleCI
6
6
  module CoverageReporter
7
7
  class Configuration
8
8
  DEFAULT_REPORTERS = [
9
- SimpleCov::Reporter.new,
10
- Flow::Reporter.new,
11
- RubyCritic::Reporter.new
9
+ Reporters::SimpleCov.new,
10
+ Reporters::Flow.new,
11
+ Reporters::RubyCritic.new
12
12
  ].freeze
13
- DEFAULT_TEMPLATE = <<~'ERB'.freeze
14
- <%- reports.each do |report| -%>
15
- <%
16
- link = "[#{report.reporter.name}](#{report.current_result.url})"
17
- emoji = report.base_diff.nil? || report.base_diff.nan? || report.base_diff.round(2).zero? ? nil : report.base_diff.positive? ? ' :chart_with_upwards_trend:' : ' :chart_with_downwards_trend:'
18
- base_progress = report.base_diff ? "[master](#{report.base_result.url}): #{report.pretty_base_diff}" : nil
19
- branch_progress = report.branch_diff ? "[previous](#{report.previous_result.url}): #{report.pretty_branch_diff}" : nil
20
- progresses = [base_progress, branch_progress].compact
21
- progress = progresses.empty? ? nil : " (#{progresses.join(', ')})"
22
- -%>
23
- <%= link %>: <%= report.current_result.pretty_coverage %><%= emoji %><%= progress %>
24
- <%- end -%>
25
- ERB
26
- DEFAULT_TEMPLATE_TRIM_MODE = '-'.freeze
27
13
  DEFAULT_VCS_TYPE = 'github'.freeze
28
14
 
29
15
  attr_accessor :circleci_token, :vcs_token
@@ -35,7 +21,7 @@ module CircleCI
35
21
  "#{user_name}/#{repository_name}"
36
22
  end
37
23
 
38
- # @return [Array<AbstractReporter>]
24
+ # @return [Array<Reporters::Base>]
39
25
  def reporters
40
26
  @reporters ||= DEFAULT_REPORTERS.dup
41
27
  end
@@ -75,16 +61,6 @@ module CircleCI
75
61
  @repository_name ||= ENV['CIRCLE_PROJECT_REPONAME']
76
62
  end
77
63
 
78
- # @return [String]
79
- def template
80
- @template ||= DEFAULT_TEMPLATE
81
- end
82
-
83
- # @return [String, nil]
84
- def template_trim_mode
85
- @template_trim_mode ||= DEFAULT_TEMPLATE_TRIM_MODE
86
- end
87
-
88
64
  # @return [String]
89
65
  def user_name
90
66
  @user_name ||= ENV['CIRCLE_PROJECT_USERNAME']
@@ -1,22 +1,13 @@
1
1
  module CircleCI
2
2
  module CoverageReporter
3
+ # Encapsulate a report created by a reporter.
4
+ #
5
+ # @see Reporters::Base#report
3
6
  class Report
4
- # @return [AbstractReporter]
5
- attr_reader :reporter
6
-
7
- # @return [AbstractResult]
8
- attr_reader :current_result
9
-
10
- # @return [AbstractResult, nil]
11
- attr_reader :base_result
12
-
13
- # @return [AbstractResult, nil]
14
- attr_reader :previous_result
15
-
16
- # @param reporter [AbstractReporter]
17
- # @param current [AbstractCurrentResult]
18
- # @param base [AbstractBuildResult, nil]
19
- # @param previous [AbstractBuildResult, nil]
7
+ # @param reporter [Reporters::Base] the reporter of the report
8
+ # @param current [Result]
9
+ # @param base [Result, nil] result at master branch
10
+ # @param previous [Result, nil] result at previous build in same branch
20
11
  def initialize(reporter, current, base: nil, previous: nil)
21
12
  @reporter = reporter
22
13
  @current_result = current
@@ -24,24 +15,49 @@ module CircleCI
24
15
  @previous_result = previous
25
16
  end
26
17
 
27
- # @return [String] coverage reporter name
28
- def type
29
- reporter.name
18
+ # @return [String]
19
+ def to_s
20
+ "#{link}: #{current_result.pretty_coverage}#{emoji}#{progress}"
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :reporter, :current_result, :base_result, :previous_result
26
+
27
+ # @return [String]
28
+ def link
29
+ "[#{reporter.name}](#{current_result.url})"
30
+ end
31
+
32
+ # @return [String]
33
+ def emoji
34
+ if base_diff.nil? || base_diff.nan? || base_diff.round(2).zero?
35
+ ''
36
+ elsif base_diff.positive?
37
+ ':chart_with_upwards_trend:'
38
+ else
39
+ ':chart_with_downwards_trend:'
40
+ end
30
41
  end
31
42
 
32
43
  # @return [String]
33
- def pretty_coverage
34
- current_result.pretty_coverage
44
+ def progress
45
+ progresses.empty? ? '' : "(#{progresses.join(', ')})"
35
46
  end
36
47
 
37
- # @return [Float] coverage percent of the current build result
38
- def coverage
39
- current_result.coverage
48
+ # @return [Array<String>]
49
+ def progresses
50
+ [base_progress, branch_progress].compact
40
51
  end
41
52
 
42
- # @return [String] URL for current coverage build result
43
- def url
44
- current_result.url
53
+ # @return [String, nil]
54
+ def base_progress
55
+ base_diff ? "[master](#{base_result.url}): #{pretty_base_diff}" : nil
56
+ end
57
+
58
+ # @return [String, nil]
59
+ def branch_progress
60
+ branch_diff ? "[previous](#{previous_result.url}): #{pretty_branch_diff}" : nil
45
61
  end
46
62
 
47
63
  # @return [String, nil]
@@ -68,8 +84,6 @@ module CircleCI
68
84
  current_result.coverage - previous_result.coverage
69
85
  end
70
86
 
71
- private
72
-
73
87
  # @param diff [Float]
74
88
  # @return [String]
75
89
  def pretty_diff(diff)