codeclimate_circle_ci_coverage 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 67bfae6c72737c855a4b3c6be69979a3ee84add6
4
- data.tar.gz: 92e7931968750958c8d59795d4da3620d2538c28
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NjJhM2VjY2MzNWNjMGZiZTA1OGUxMWJkMGVjZGFmOGY4MTY5N2I3Mg==
5
+ data.tar.gz: !binary |-
6
+ ZWVlZjNhY2MzNTI2Y2RlN2RhMzhkMjE3MDBjZmYxNDFkZjYwNTJkYg==
5
7
  SHA512:
6
- metadata.gz: cfbd85a77c464ffc845b7d8a6d497ff4489fc7cfa2d3afa26c4af362cdac5912f62e675f90a1434f3bb9ed268b120f481c597ec434d5bded13daaec423a2e492
7
- data.tar.gz: fb71b420138d3ab440c58440648b99d19af3653eaee7620a56e4e17c3f1e21fb63f9a4088a084aa0a8423ca4f5a4bfadd749143c0a6595fa6ff1f30d0f7449b6
8
+ metadata.gz: !binary |-
9
+ M2JhMzFiNjNjMmZiNDIzYmJlNjY2ZTE3MGI2NWUyOTlhODg0MmZmNjU4MzE1
10
+ MmM3NDEzYjk3NTdhZWJjNmE5NDU1ZGMxMjkyZTE5NDk5MzEwMWM0YWRkNGRl
11
+ MjNkMzdjYmVjYjlkNzkyYTI0NGVhZDdlNDI2YjliNzFjMTIzN2M=
12
+ data.tar.gz: !binary |-
13
+ NDM0ZGJiYTk1ZTU4OTg3MWUxNGM0ZjBhYTQ0NzJmYWJmOGNmNjE3MzRlZDQz
14
+ ZWU4Mzg3YzZiYTRlNzI1NGQyY2MzM2YxZTJjOTUxZjI1YTFmZGM1OTFjOGJj
15
+ ZDk1OGE5MzYzYzk1NTg4MzliZDFlN2UyM2ViODRmNGZmZGE5YTU=
@@ -19,58 +19,89 @@ class CoverageReporter
19
19
  @target_branch = target_branch
20
20
  end
21
21
 
22
+ def current_branch
23
+ ENV['CIRCLE_BRANCH']
24
+ end
25
+
26
+ def current_node
27
+ ENV['CIRCLE_NODE_INDEX'].to_i
28
+ end
29
+
22
30
  def run
23
- branch = ENV['CIRCLE_BRANCH']
24
- node_index = ENV['CIRCLE_NODE_INDEX'].to_i
25
- node_total = ENV['CIRCLE_NODE_TOTAL'].to_i
26
- coverage_dir = File.join("coverage")
31
+ # Only submit coverage to codeclimate on target branch
32
+ return if current_branch != target_branch
33
+ # Only run on node0
34
+ return unless current_node.zero?
27
35
 
28
- # Create directory if it doesn't exist
29
- FileUtils.mkdir_p coverage_dir
36
+ all_coverage_dir = File.join("all_coverage")
37
+ download_files(all_coverage_dir)
38
+ final_coverage_dir = File.join("combined_coverage")
30
39
 
31
- filename = '.resultset.json'
40
+ merged_result = load_and_merge_files(all_coverage_dir, final_coverage_dir)
41
+ output_result_html(merged_result)
42
+ upload_result_file(merged_result)
43
+ end
32
44
 
33
- SimpleCov.coverage_dir(coverage_dir)
45
+ # Public: Download the .resultset.json files from each of the nodes
46
+ # and store them in the `target_directory`
47
+ #
48
+ # They will be numbered 0.resultset.json, 1.resultset.json, etc.
49
+ def download_files(target_directory)
50
+ node_total = ENV['CIRCLE_NODE_TOTAL'].to_i
34
51
 
35
- # Only run on node0
36
- exit unless node_index.zero?
52
+ # Create directory if it doesn't exist
53
+ FileUtils.mkdir_p target_directory
37
54
 
38
55
  if node_total > 0
39
56
  # Copy coverage results from all nodes to circle artifacts directory
40
- 1.upto(node_total - 1) do |i|
57
+ 0.upto(node_total - 1) do |i|
41
58
  node = "node#{i}"
42
59
  # Modified because circleCI doesn't appear to deal with artifacts in the expected manner
43
60
  node_project_dir = `ssh #{node} 'printf $CIRCLE_PROJECT_REPONAME'`
44
- from = File.join("~/", node_project_dir, 'coverage', filename)
45
- to = File.join(coverage_dir, "#{i}#{filename}")
61
+ from = File.join("~/", node_project_dir, 'coverage', ".resultset.json")
62
+ to = File.join(target_directory, "#{i}.resultset.json")
46
63
  command = "scp #{node}:#{from} #{to}"
47
64
 
48
65
  puts "running command: #{command}"
49
66
  `#{command}`
50
67
  end
51
68
  end
69
+ end
52
70
 
53
- # Merge coverage results from other nodes
54
- # .resultset.json is a hidden file and thus ignored by the glob
55
- files = Dir.glob(File.join(coverage_dir, "*#{filename}"))
71
+ def load_and_merge_files(source_directory, target_directory)
72
+ FileUtils.mkdir_p target_directory
73
+ SimpleCov.coverage_dir(target_directory)
74
+
75
+ # Merge coverage results from all nodes
76
+ files = Dir.glob(File.join(source_directory, "*.resultset.json"))
56
77
  files.each_with_index do |file, i|
57
78
  resultset = JSON.load(File.read(file))
58
79
  resultset.each do |_command_name, data|
59
80
  result = SimpleCov::Result.from_hash(['command', i].join => data)
81
+
82
+ puts "Resetting result #{i} created_at from #{result.created_at} to #{Time.now}"
83
+ # It appears that sometimes the nodes provided by CircleCI have
84
+ # clocks which are not accurate/synchronized
85
+ # So we always set the created_at to Time.now so that the ResultMerger
86
+ # doesn't discard any results
87
+ result.created_at = Time.now
88
+
60
89
  SimpleCov::ResultMerger.store_result(result)
61
90
  end
62
91
  end
63
92
 
64
93
  merged_result = SimpleCov::ResultMerger.merged_result
65
94
  merged_result.command_name = 'RSpec'
95
+ merged_result
96
+ end
66
97
 
98
+ def output_result_html(merged_result)
67
99
  # Format merged result with html
68
100
  html_formatter = SimpleCov::Formatter::HTMLFormatter.new
69
101
  html_formatter.format(merged_result)
102
+ end
70
103
 
71
- # Only submit coverage to codeclimate on target branch
72
- exit if branch != target_branch
73
-
104
+ def upload_result_file(merged_result)
74
105
  # Post merged coverage result to codeclimate
75
106
  codeclimate_formatter = CodeClimate::TestReporter::Formatter.new
76
107
  codeclimate_formatter.format(merged_result)
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe CoverageReporter do
4
+ describe "#initial_test" do
5
+ it "passes" do
6
+ expect(1).to eq(1)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,98 @@
1
+ require 'codeclimate_circle_ci_coverage'
2
+
3
+ # This file was generated by the `rspec --init` command. Conventionally, all
4
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
5
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
6
+ # this file to always be loaded, without a need to explicitly require it in any
7
+ # files.
8
+ #
9
+ # Given that it is always loaded, you are encouraged to keep this file as
10
+ # light-weight as possible. Requiring heavyweight dependencies from this file
11
+ # will add to the boot time of your test suite on EVERY test run, even for an
12
+ # individual file that may not need all of that loaded. Instead, consider making
13
+ # a separate helper file that requires the additional dependencies and performs
14
+ # the additional setup, and require it from the spec files that actually need
15
+ # it.
16
+ #
17
+ # The `.rspec` file also contains a few flags that are not defaults but that
18
+ # users commonly want.
19
+ #
20
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
21
+ RSpec.configure do |config|
22
+ # rspec-expectations config goes here. You can use an alternate
23
+ # assertion/expectation library such as wrong or the stdlib/minitest
24
+ # assertions if you prefer.
25
+ config.expect_with :rspec do |expectations|
26
+ # This option will default to `true` in RSpec 4. It makes the `description`
27
+ # and `failure_message` of custom matchers include text for helper methods
28
+ # defined using `chain`, e.g.:
29
+ # be_bigger_than(2).and_smaller_than(4).description
30
+ # # => "be bigger than 2 and smaller than 4"
31
+ # ...rather than:
32
+ # # => "be bigger than 2"
33
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
34
+ end
35
+
36
+ # rspec-mocks config goes here. You can use an alternate test double
37
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
38
+ config.mock_with :rspec do |mocks|
39
+ # Prevents you from mocking or stubbing a method that does not exist on
40
+ # a real object. This is generally recommended, and will default to
41
+ # `true` in RSpec 4.
42
+ mocks.verify_partial_doubles = true
43
+ end
44
+
45
+ # The settings below are suggested to provide a good initial experience
46
+ # with RSpec, but feel free to customize to your heart's content.
47
+ =begin
48
+ # These two settings work together to allow you to limit a spec run
49
+ # to individual examples or groups you care about by tagging them with
50
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
51
+ # get run.
52
+ config.filter_run :focus
53
+ config.run_all_when_everything_filtered = true
54
+
55
+ # Allows RSpec to persist some state between runs in order to support
56
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
57
+ # you configure your source control system to ignore this file.
58
+ config.example_status_persistence_file_path = "spec/examples.txt"
59
+
60
+ # Limits the available syntax to the non-monkey patched syntax that is
61
+ # recommended. For more details, see:
62
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
63
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
64
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
65
+ config.disable_monkey_patching!
66
+
67
+ # This setting enables warnings. It's recommended, but in some cases may
68
+ # be too noisy due to issues in dependencies.
69
+ config.warnings = true
70
+
71
+ # Many RSpec users commonly either run the entire suite or an individual
72
+ # file, and it's useful to allow more verbose output when running an
73
+ # individual spec file.
74
+ if config.files_to_run.one?
75
+ # Use the documentation formatter for detailed output,
76
+ # unless a formatter has already been configured
77
+ # (e.g. via a command-line flag).
78
+ config.default_formatter = 'doc'
79
+ end
80
+
81
+ # Print the 10 slowest examples and example groups at the
82
+ # end of the spec run, to help surface which specs are running
83
+ # particularly slow.
84
+ config.profile_examples = 10
85
+
86
+ # Run specs in random order to surface order dependencies. If you find an
87
+ # order dependency and want to debug it, you can fix the order by providing
88
+ # the seed, which is printed after each run.
89
+ # --seed 1234
90
+ config.order = :random
91
+
92
+ # Seed global randomization in this process using the `--seed` CLI option.
93
+ # Setting this allows you to use `--seed` to deterministically reproduce
94
+ # test failures related to randomization by passing the same `--seed` value
95
+ # as the one that triggered the failure.
96
+ Kernel.srand config.seed
97
+ =end
98
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codeclimate_circle_ci_coverage
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robin Dunlop
@@ -14,44 +14,58 @@ dependencies:
14
14
  name: codeclimate-test-reporter
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: simplecov
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ~>
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ~>
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rubocop
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ~>
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ~>
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '3.2'
55
69
  description: A set of tools to support reporting SimpleCov Coverage to CodeClimate
56
70
  with Parallel tests on CircleCI
57
71
  email: robin@dunlopweb.com
@@ -63,6 +77,8 @@ files:
63
77
  - bin/report_coverage
64
78
  - lib/codeclimate_circle_ci_coverage.rb
65
79
  - lib/codeclimate_circle_ci_coverage/coverage_reporter.rb
80
+ - spec/coverage_reporter_spec.rb
81
+ - spec/spec_helper.rb
66
82
  homepage: http://rubygems.org/gems/codeclimate_circle_ci_coverage
67
83
  licenses:
68
84
  - MIT
@@ -73,18 +89,20 @@ require_paths:
73
89
  - lib
74
90
  required_ruby_version: !ruby/object:Gem::Requirement
75
91
  requirements:
76
- - - ">="
92
+ - - ! '>='
77
93
  - !ruby/object:Gem::Version
78
94
  version: '0'
79
95
  required_rubygems_version: !ruby/object:Gem::Requirement
80
96
  requirements:
81
- - - ">="
97
+ - - ! '>='
82
98
  - !ruby/object:Gem::Version
83
99
  version: '0'
84
100
  requirements: []
85
101
  rubyforge_project:
86
- rubygems_version: 2.4.8
102
+ rubygems_version: 2.4.6
87
103
  signing_key:
88
104
  specification_version: 4
89
105
  summary: CodeClimate Code Coverage reporting script for CircleCI
90
- test_files: []
106
+ test_files:
107
+ - spec/coverage_reporter_spec.rb
108
+ - spec/spec_helper.rb