simplecov-buildkite 0.1.1 → 0.2.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: 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#