circleci-coverage_reporter 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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)