simplecov-buildkite 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 983bfc983d04ce54e3ce8ff6e42a1fae9a5ff44692ddffdfeb9f49e9f05561ff
4
- data.tar.gz: ef42a76b01d7ab95c5ad61e89bf0e7d85f8a6c179523e9c042efb77347cfaa99
3
+ metadata.gz: 0dba2010d4af1552e27b2d57a1a205fdfef160adf7a279d8d3a68cbd5437ae1c
4
+ data.tar.gz: 24ec9a1c4157638a21f4cf51635223d21ee9ad62381f16e76e829c68062e6b40
5
5
  SHA512:
6
- metadata.gz: 2bea09dc88c7c1304c0a9f9b622905728b1151fef54c186b12d0ad2d42ea6c3e9bb59343e89927136433abb6935cb5daa2d6d4aebde5a269ec9941f128f02744
7
- data.tar.gz: 35d47820c5eaf13bf7a51ac38d0e1e089d8b4db7496dc91f47a0aaca4588332207b7315b5f0b794b63022f0d48a8c06bb3b47f1fc16fb950b3d93b1f061b7a36
6
+ metadata.gz: 7b2ffb9737e3f51d1432e82a1e3145a55f904e64e3f1ce317d83b249d8de74d9e5ad50bb10e1c7a7ceedfb8be37eb9b643ac3c52537540660b74d2011eee9997
7
+ data.tar.gz: 0f5f5908680fad034e77c3c14554cfc4f5ee3a4309f30c8bcb1afe1ddfcfc387c7def2ab7d41abdff429a0244a2d0d6d9786224cc8ae3e1e1e6888765d64cfdd
@@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [Unreleased]
8
+ - Nothing yet!
9
+
10
+ ## [0.2.0] - 2020-09-08
11
+ - git integration: SimpleCov groups are automatically generated based on branch
12
+ and commit metadata.
13
+ ([#2](https://github.com/ticky/simplecov-buildkite/pull/2),
14
+ [#8](https://github.com/ticky/simplecov-buildkite/pull/8))
15
+ - Headers are now in sentence case
16
+ ([#9](https://github.com/ticky/simplecov-buildkite/pull/9))
17
+ - Update specs for SimpleCov 0.19.0
18
+ ([#12](https://github.com/ticky/simplecov-buildkite/pull/12))
19
+
7
20
  ## [0.1.1] - 2018-05-30
8
21
  ### Changed
9
22
  - Output is now enclosed in a `<details>` for a brief summary with expandable
@@ -15,7 +28,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
15
28
  - Buildkite annotation formatter to consolidate reports from multiple simplecov
16
29
  runs into a Buildkite annotation.
17
30
 
18
- [Unreleased]: https://github.com/ticky/simplecov-buildkite/compare/v0.1.1...HEAD
31
+ [Unreleased]: https://github.com/ticky/simplecov-buildkite/compare/v0.2.0...HEAD
32
+ [0.2.0]: https://github.com/ticky/simplecov-buildkite/compare/v0.2.0...v0.1.1
19
33
  [0.1.1]: https://github.com/ticky/simplecov-buildkite/compare/v0.1.0...v0.1.1
20
34
  [0.1.0]: https://github.com/ticky/simplecov-buildkite/commits/v0.1.0
21
35
 
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # SimpleCov::Buildkite
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/simplecov-buildkite.svg)](https://rubygems.org/gems/simplecov-buildkite) [![Build Status](https://travis-ci.org/ticky/simplecov-buildkite.svg?branch=develop)](https://travis-ci.org/ticky/simplecov-buildkite)
4
+
3
5
  Generate [Buildkite annotations] from your [SimpleCov] coverage reports when running your build on [Buildkite].
4
6
 
5
7
  [Buildkite]: https://buildkite.com
@@ -34,6 +36,8 @@ require "simplecov"
34
36
  require "simplecov-buildkite"
35
37
 
36
38
  SimpleCov.start "rails" do
39
+ load_profile "buildkite"
40
+
37
41
  formatter SimpleCov::Formatter::MultiFormatter.new([
38
42
  SimpleCov::Formatter::HTMLFormatter,
39
43
  SimpleCov::Buildkite::AnnotationFormatter,
@@ -41,9 +45,9 @@ SimpleCov.start "rails" do
41
45
  end
42
46
  ```
43
47
 
44
- When run on Buildkite, this will also output a pretty Buildkite annotation:
48
+ When run on Buildkite with the `"buildkite"` profile enabled, this will also output a pretty Buildkite annotation, with coverage change breakdowns for the current PR or branch and commit:
45
49
 
46
- <img width="473" alt="Buildkite build showing a SimpleCov report in a Buildkite annotation" src="https://user-images.githubusercontent.com/282113/40627591-b8de5bc4-6274-11e8-8483-245e35c873af.png">
50
+ <img width="577" alt="Buildkite build showing a SimpleCov report in a Buildkite annotation" src="https://user-images.githubusercontent.com/282113/42116587-c2e9731e-7bac-11e8-9d2f-50fa7f071f09.png">
47
51
 
48
52
  [Rails]: https://rubyonrails.org
49
53
  [RSpec]: http://rspec.info
@@ -5,3 +5,4 @@ end
5
5
 
6
6
  require "simplecov/buildkite/version"
7
7
  require "simplecov/buildkite/annotation_formatter"
8
+ require "simplecov/buildkite/profiles"
@@ -1,19 +1,63 @@
1
1
  module SimpleCov::Buildkite
2
2
  class AnnotationFormatter
3
+ GIT_ANNOTATION_FORMAT_REGEX = /^Files (?<action>changed|added) in (?<changeset>[a-zA-Z0-9.]+)$/
4
+
3
5
  def format(result)
6
+ git_results, general_results = filter_git_groups(ignore_empty_groups(result.groups))
7
+ .values_at(:git, :general)
8
+
4
9
  message = <<~MESSAGE
5
- <details>
6
- <summary>#{format_element(result)}</summary>
7
- <ul>
8
- #{result.groups.map do |name, group|
9
- "<li><strong>#{name}</strong>: #{format_element(group)}</li>"
10
- end.join("\n")}
11
- </ul>
12
- </details>
10
+ #### Coverage
11
+
12
+ <dl class="flex flex-wrap m1 mxn2">
13
13
  MESSAGE
14
14
 
15
- if ENV["BUILDKITE"]
16
- system "buildkite-agent", "annotate", "--context", "simplecov", "--style", "info", message
15
+ git_results.to_a.reverse.each do |git_result|
16
+ name, group = git_result
17
+
18
+ matches = name.match GIT_ANNOTATION_FORMAT_REGEX
19
+
20
+ type = if matches[:action] == 'added'
21
+ 'New files'
22
+ else
23
+ 'Files changed'
24
+ end
25
+
26
+ changeset = if matches[:changeset].include?('...')
27
+ 'branch'
28
+ else
29
+ 'commit'
30
+ end
31
+
32
+ message += format_as_metric "#{type} in #{changeset}",
33
+ group,
34
+ changeset: matches[:changeset]
35
+ end
36
+
37
+ message += format_as_metric 'All files', result
38
+
39
+ message += <<~MESSAGE
40
+ </dl>
41
+ MESSAGE
42
+
43
+ if general_results.any?
44
+ message += <<~MESSAGE
45
+ <details><summary>Coverage breakdown</summary>
46
+
47
+ #{general_results.map do |name, group|
48
+ "- **#{name}**: #{format_group(group)}"
49
+ end.join("\n")}
50
+
51
+ </details>
52
+ MESSAGE
53
+ end
54
+
55
+ if ENV['BUILDKITE']
56
+ system 'buildkite-agent',
57
+ 'annotate',
58
+ '--context', 'simplecov',
59
+ '--style', 'info',
60
+ message
17
61
  else
18
62
  puts message
19
63
  end
@@ -21,12 +65,55 @@ module SimpleCov::Buildkite
21
65
 
22
66
  private
23
67
 
24
- def format_element(element)
25
- "#{element.covered_percent.round(2)}% coverage: #{format_integer(element.covered_lines)} of #{format_integer(element.covered_lines + element.missed_lines)} lines"
68
+ def ignore_empty_groups(groups)
69
+ groups.select do |_name, group|
70
+ (group.covered_lines + group.missed_lines).positive?
71
+ end
72
+ end
73
+
74
+ def filter_git_groups(groups)
75
+ groups.each_with_object(git: {}, general: {}) do |unzipped_group, cats|
76
+ name, group = unzipped_group
77
+
78
+ if name.match? GIT_ANNOTATION_FORMAT_REGEX
79
+ cats[:git][name] = group
80
+ else
81
+ cats[:general][name] = group
82
+ end
83
+ end
26
84
  end
27
85
 
28
86
  def format_integer(integer)
29
- integer.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")
87
+ Kernel.format('%<integer>d', integer: integer).gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")
88
+ end
89
+
90
+ def format_float(float)
91
+ Kernel.format('%<floored_float>g', floored_float: float.floor(2))
92
+ end
93
+
94
+ def format_as_metric(name, element, changeset: nil)
95
+ metric = <<~METRIC_HEADER
96
+ <div class="m2"><dt#{changeset.nil? ? '' : " title=\"#{changeset}\""}>#{name}</dt><dd>
97
+ METRIC_HEADER
98
+
99
+ metric += <<~METRIC_VALUE
100
+
101
+ **<span class="h2 regular">#{format_float(element.covered_percent)}</span>%**
102
+ #{format_line_count(element)}
103
+
104
+ METRIC_VALUE
105
+
106
+ metric += <<~METRIC_FOOTER
107
+ </dd></div>
108
+ METRIC_FOOTER
109
+ end
110
+
111
+ def format_group(element)
112
+ "#{format_float(element.covered_percent)}% coverage: #{format_line_count(element)}"
113
+ end
114
+
115
+ def format_line_count(element)
116
+ "#{format_integer(element.covered_lines)} of #{format_integer(element.covered_lines + element.missed_lines)} lines"
30
117
  end
31
118
  end
32
119
  end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SimpleCov::Buildkite::Profiles
4
+ def self.run(*args)
5
+ IO.popen(args, &:read).tap do
6
+ $?.success? or fail("Command exited with status #{$?.exitstatus}: #{args.join(" ")}")
7
+ end.chomp
8
+ end
9
+
10
+ def self.git(*args)
11
+ run 'git',
12
+ *args
13
+ end
14
+
15
+ def self.git_diff_names(*args, diff_filter: '')
16
+ git('diff',
17
+ '--name-only',
18
+ "--diff-filter=#{diff_filter}",
19
+ *args).split "\n"
20
+ end
21
+
22
+ def self.git_short_commit(commit)
23
+ git 'rev-parse',
24
+ '--short',
25
+ commit
26
+ end
27
+
28
+ def self.git_merge_base(*refs)
29
+ git 'merge-base',
30
+ *refs
31
+ end
32
+
33
+ SimpleCov.profiles.define 'buildkite' do
34
+ STDERR.puts 'SimpleCov::Buildkite profile initialising...'
35
+ fail('Not running on Buildkite') unless ENV['BUILDKITE'] == 'true'
36
+
37
+ branch_name = ENV['BUILDKITE_BRANCH']
38
+
39
+ STDERR.puts "branch_name=#{branch_name}"
40
+
41
+ base_branch_name = ENV['BUILDKITE_PULL_REQUEST_BASE_BRANCH']
42
+ if base_branch_name.nil? || base_branch_name.empty?
43
+ base_branch_name = ENV['BUILDKITE_PIPELINE_DEFAULT_BRANCH']
44
+ end
45
+
46
+ STDERR.puts "base_branch_name=#{base_branch_name}"
47
+
48
+ current_commit = ENV['BUILDKITE_COMMIT']
49
+
50
+ STDERR.puts "current_commit=#{current_commit}"
51
+
52
+ current_commit_short = git_short_commit(current_commit)
53
+
54
+ STDERR.puts "current_commit_short=#{current_commit_short}"
55
+
56
+ changed_files_in_commit = git_diff_names(current_commit,
57
+ diff_filter: 'd')
58
+
59
+ STDERR.puts "changed_files_in_commit.count=#{changed_files_in_commit.count}"
60
+
61
+ add_group "Files changed in #{current_commit_short}" do |tested_file|
62
+ changed_files_in_commit.detect do |changed_file|
63
+ tested_file.filename.end_with?(changed_file)
64
+ end
65
+ end
66
+
67
+ added_files_in_commit = git_diff_names(current_commit,
68
+ diff_filter: 'A')
69
+
70
+ STDERR.puts "added_files_in_commit.count=#{added_files_in_commit.count}"
71
+
72
+ add_group "Files added in #{current_commit_short}" do |tested_file|
73
+ added_files_in_commit.detect do |added_file|
74
+ tested_file.filename.end_with?(added_file)
75
+ end
76
+ end
77
+
78
+ # Compare with the base branch if it's not this branch
79
+ if base_branch_name && base_branch_name != branch_name
80
+ merge_base = git_merge_base(current_commit,
81
+ base_branch_name)
82
+
83
+ merge_base_short = git_short_commit(merge_base)
84
+
85
+ STDERR.puts "merge_base=#{merge_base}"
86
+ STDERR.puts "merge_base_short=#{merge_base_short}"
87
+
88
+ changed_files_in_branch = git_diff_names(merge_base,
89
+ current_commit,
90
+ diff_filter: 'd')
91
+
92
+ STDERR.puts "changed_files_in_branch.count=#{changed_files_in_branch.count}"
93
+
94
+ add_group "Files changed in #{merge_base_short}...#{current_commit_short}" do |tested_file|
95
+ changed_files_in_branch.detect do |changed_file|
96
+ tested_file.filename.end_with?(changed_file)
97
+ end
98
+ end
99
+
100
+ added_files_in_branch = git_diff_names(merge_base,
101
+ current_commit,
102
+ diff_filter: 'A')
103
+
104
+ STDERR.puts "added_files_in_branch.count=#{added_files_in_branch.count}"
105
+
106
+ add_group "Files added in #{merge_base_short}...#{current_commit_short}" do |tested_file|
107
+ added_files_in_branch.detect do |added_file|
108
+ tested_file.filename.end_with?(added_file)
109
+ end
110
+ end
111
+ end
112
+ rescue RuntimeError => error
113
+ STDERR.puts error
114
+ end
115
+ end
@@ -1,3 +1,3 @@
1
1
  module SimpleCov::Buildkite
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,35 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simplecov-buildkite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jessica Stokes
8
8
  - Samuel Cochran
9
9
  autorequire:
10
10
  bindir: bin
11
- cert_chain:
12
- - |
13
- -----BEGIN CERTIFICATE-----
14
- MIIDKDCCAhCgAwIBAgIBBTANBgkqhkiG9w0BAQUFADA6MQ0wCwYDVQQDDARzajI2
15
- MRQwEgYKCZImiZPyLGQBGRYEc2oyNjETMBEGCgmSJomT8ixkARkWA2NvbTAeFw0x
16
- NzA3MzEwNTQ3MDVaFw0xODA3MzEwNTQ3MDVaMDoxDTALBgNVBAMMBHNqMjYxFDAS
17
- BgoJkiaJk/IsZAEZFgRzajI2MRMwEQYKCZImiZPyLGQBGRYDY29tMIIBIjANBgkq
18
- hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr60Eo/ttCk8GMTMFiPr3GoYMIMFvLak
19
- xSmTk9YGCB6UiEePB4THSSA5w6IPyeaCF/nWkDp3/BAam0eZMWG1IzYQB23TqIM0
20
- 1xzcNRvFsn0aQoQ00k+sj+G83j3T5OOV5OZIlu8xAChMkQmiPd1NXc6uFv+Iacz7
21
- kj+CMsI9YUFdNoU09QY0b+u+Rb6wDYdpyvN60YC30h0h1MeYbvYZJx/iZK4XY5zu
22
- 4O/FL2ChjL2CPCpLZW55ShYyrzphWJwLOJe+FJ/ZBl6YXwrzQM9HKnt4titSNvyU
23
- KzE3L63A3PZvExzLrN9u09kuWLLJfXB2sGOlw3n9t72rJiuBr3/OQQIDAQABozkw
24
- NzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU99dfRjEKFyczTeIz
25
- m3ZsDWrNC80wDQYJKoZIhvcNAQEFBQADggEBADGiXpvK754s0zTFx3y31ZRDdvAI
26
- lA209JIjUlDyr9ptCRadihyfF2l9/hb+hLemiPEYppzG6vEK1TIyzbAR36yOJ8CX
27
- 4vPkCXLuwHhs6UIRbwN+IEy41nsIlBxmjLYei8h3t/G2Vm2oOaLdbjDXS+Srl9U8
28
- shsE8ft81PxSQfzEL7Mr9cC9XvWbHW+SyTpfGm8rAtaqZkNeke4U8a0di4oz2EfA
29
- P4lSfmXxsd1C71ckIp0cyXkPhyTtpyS/5hq9HhuUNzEHkSDe36/Rd1xYKV5JxMC2
30
- YAttWFUs06lor2q1wwncPaMtUtbWwW35+1IV6xhs2rFY6DD/I6ZkK3GnHdY=
31
- -----END CERTIFICATE-----
32
- date: 2018-05-30 00:00:00.000000000 Z
11
+ cert_chain: []
12
+ date: 2020-09-08 00:00:00.000000000 Z
33
13
  dependencies:
34
14
  - !ruby/object:Gem::Dependency
35
15
  name: simplecov
@@ -65,14 +45,14 @@ dependencies:
65
45
  requirements:
66
46
  - - "~>"
67
47
  - !ruby/object:Gem::Version
68
- version: '10.0'
48
+ version: '13.0'
69
49
  type: :development
70
50
  prerelease: false
71
51
  version_requirements: !ruby/object:Gem::Requirement
72
52
  requirements:
73
53
  - - "~>"
74
54
  - !ruby/object:Gem::Version
75
- version: '10.0'
55
+ version: '13.0'
76
56
  - !ruby/object:Gem::Dependency
77
57
  name: rspec
78
58
  requirement: !ruby/object:Gem::Requirement
@@ -102,6 +82,7 @@ files:
102
82
  - lib/simplecov-buildkite.rb
103
83
  - lib/simplecov/buildkite.rb
104
84
  - lib/simplecov/buildkite/annotation_formatter.rb
85
+ - lib/simplecov/buildkite/profiles.rb
105
86
  - lib/simplecov/buildkite/version.rb
106
87
  homepage: https://github.com/ticky/simplecov-buildkite
107
88
  licenses:
@@ -123,8 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
104
  - !ruby/object:Gem::Version
124
105
  version: '0'
125
106
  requirements: []
126
- rubyforge_project:
127
- rubygems_version: 2.7.7
107
+ rubygems_version: 3.0.3
128
108
  signing_key:
129
109
  specification_version: 4
130
110
  summary: Generate SimpleCov reports for your parallel Buildkite builds
@@ -1,2 +0,0 @@
1
- et�b���TB�=��Ø[�+x��;X�*C��^6�'J3����X��������x���$g��06q-��}^�e8 �@W& "�0� q��ϰ9��N| �Fk��*qN��q��Q������M��axؤ#���wG�J��jf�q��9��/�ؕ����0��6v�(�w!,�A���M�Z,� V)
2
- rn�j������TG?���/v��GJ�E6�8�X/"F~c\S����P�S��&�
data.tar.gz.sig DELETED
Binary file
metadata.gz.sig DELETED
@@ -1,2 +0,0 @@
1
- b'��2�+V��U j��\�S��l�-�M_SxfF�-�/8�?�0��e�i!��4���i|�t&K-s�;F���������rg'�B>|<�
2
- ���ʰ��C%K�07��z��G�B��)<~<�y���.cND��6`SM���?j��s��?�h7�r�r�k��),�˓���x�v(��i�V���<(@k����ݹ�̣��>.��жl���nc_b�>�EJ�D�{m#