simplecov_s3_codeclimate 0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 06e1440f057237a77b87ebacb357b63bba47152c
4
+ data.tar.gz: 1596f444e315d5a4e373a773128057d9a1e3f00a
5
+ SHA512:
6
+ metadata.gz: c15eed43527e1e4e9e178d133a720ab1dec77212d8dffcae9165c61f0f3851b855a4696b6041fa9f80646c3f0787debe2b6caf36e09fb1374669dbb309caba9d
7
+ data.tar.gz: 600c42e6f2ea57ee9b8a857acd2c44a998ba0552f5337428bbf9e44e329d441d305bde9f6e59e4602fec6d52c685684a49b429db2b0ff7b661eba618b019a3fe
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ .DS_Store
2
+ *.gem
3
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --format documentation --colour
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'rake'
7
+ gem 'pry'
8
+ end
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2013 Engine Yard
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # simplecov_s3_codeclimate
2
+
3
+ Sample Usage:
4
+
5
+ `Gemfile`
6
+
7
+ ```ruby
8
+ group :test do
9
+ gem 'simplecov_s3_codeclimate'
10
+ end
11
+ ```
12
+
13
+ `config/environment.rb`
14
+
15
+ ```ruby
16
+ require File.expand_path('../application', __FILE__)
17
+
18
+ if Rails.env.test?
19
+ require File.expand_path("../../spec/coverage_helper", __FILE__)
20
+ end
21
+ ```
22
+
23
+ `spec/coverage_helper.rb`
24
+
25
+ ```ruby
26
+ unless ENV["SKIP_COVERAGE"]
27
+ require 'simplecov'
28
+ SimpleCov.start(:rails)
29
+ SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
30
+ SimpleCov.at_exit do
31
+ SimpleCov.result.format!
32
+ end
33
+ # Yes this is a hack, the most reliable way to ensure that simplecov doesn't de-dupe your coverage results for having the same command_name: "rspec"
34
+ command_name "Test #{ARGV[0]}"
35
+ SimpleCov.merge_timeout 3600
36
+ end
37
+ ```
38
+
39
+ `lib/tasks/codeclimate_coverage.rake`
40
+
41
+ ```ruby
42
+ task :coverage do
43
+ require File.expand_path("../spec/coverage_helper", __FILE__)
44
+ cov = SimpleCov::S3::Codeclimate.new(
45
+ :fog => {
46
+ provider: 'AWS',
47
+ aws_access_key_id: "AWS_ACCESS_KEY_ID",
48
+ aws_secret_access_key: "AWS_SECRET_ACCESS_KEY",
49
+ region: "us-east-1",
50
+ },
51
+ project_name: "PROJECT_NAME",
52
+ build_id: "BUILD_ID", # Unique identifier for a CI build
53
+ build_unit: "BUILD_UNIT", # Unique identifier for a test run within a CI build
54
+ build_units: 1, # Total number of build_units within a CI build
55
+ bucket_name: "S3_BUCKET_NAME",
56
+ shared_secret: "XXXXXXXXXXXX", # Used so build units can find each other,
57
+ subfolder: 'OPTIONAL_SUBFOLDER' # Subfolder in S3 Bucket to store temp data
58
+ )
59
+ cov.push_partial
60
+ cov.pull_merge_and_push_full
61
+ end
62
+ ```
63
+
64
+ .gitinore:
65
+
66
+ #ignore generated coverage results
67
+ coverage
68
+
69
+ You must also have `CODECLIMATE_REPO_TOKEN` in your environment. See [their documentation](https://github.com/codeclimate/ruby-test-reporter) for more info.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ desc 'Default: run specs.'
4
+ task :default => :spec
5
+
6
+ desc "Run specs"
7
+ RSpec::Core::RakeTask.new do |t|
8
+ # Put spec opts in a file named .rspec in root
9
+ end
@@ -0,0 +1,7 @@
1
+ module SimpleCov
2
+ module S3
3
+ class Codeclimate
4
+ VERSION = '0.2'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,108 @@
1
+ require 'digest'
2
+ require 'securerandom'
3
+ require 'excon'
4
+ require 'fog'
5
+ require 'simplecov'
6
+ require 'json'
7
+ require 'codeclimate-test-reporter'
8
+
9
+ module SimpleCov
10
+ module S3
11
+ class Codeclimate
12
+ def self.ensured(task_to_invoke, &_block)
13
+ Rake::Task[task_to_invoke].invoke
14
+ ensure
15
+ begin
16
+ yield
17
+ rescue => exception
18
+ puts exception.inspect
19
+ puts exception.backtrace
20
+ end
21
+ end
22
+
23
+ def initialize(opts)
24
+ @connection = Fog::Storage.new(opts[:fog])
25
+ @shared_secret = opts[:shared_secret]
26
+ @bucket_name = opts[:bucket_name]
27
+ @subfolder = opts[:subfolder] || ''
28
+ @build_units = opts[:build_units].to_i
29
+ @build_unit = opts[:build_unit]
30
+ @build_id = opts[:build_id]
31
+ @project_name = opts[:project_name] || 'unknown'
32
+ @project_name = 'unknown' if @project_name.empty?
33
+ @history_limit = opts[:history_limit] || 15
34
+ end
35
+
36
+ def push_partial
37
+ result = SimpleCov::ResultMerger.merged_result
38
+ data_to_push = result.original_result.merge('BUILD_UNIT' => @build_unit).to_json
39
+ put_file("#{@project_name}-#{commit_time}-coverageJSON/#{hashed_build_id}/#{@build_unit}", data_to_push)
40
+ rescue => exception
41
+ puts exception.inspect
42
+ puts exception.backtrace
43
+ puts 'SOMEHTING WENT WRONG, PUSHING EMPTY COVERAGE FILE'
44
+ put_file("#{@project_name}-#{commit_time}-coverageJSON/#{hashed_build_id}/#{@build_unit}", {}.to_json)
45
+ end
46
+
47
+ def pull_merge_and_push_full
48
+ json_files_size = json_files.size
49
+ if json_files_size < @build_units
50
+ puts "Expected to see #{@build_units} files"
51
+ puts "currently only #{json_files_size}"
52
+ require 'pp'
53
+ pp json_files.map(&:key)
54
+ puts 'Assuming some other build unit will be the last to exit, and merge/post full coverage'
55
+ return false
56
+ end
57
+ puts "Coverage combined from #{json_files_size} units"
58
+ results = []
59
+ included_units = []
60
+ json_files.each do |file|
61
+ parsed = JSON.parse(file.body)
62
+ included_units << parsed.delete('BUILD_UNIT')
63
+ results << SimpleCov::Result.new(parsed)
64
+ end
65
+ puts "Included units: #{included_units.sort_by(&:to_s).inspect}"
66
+ merged = {}
67
+ results.each do |result|
68
+ merged = result.original_result.merge_resultset(merged)
69
+ end
70
+ result = SimpleCov::Result.new(merged)
71
+ CodeClimate::TestReporter::Formatter.new.format(result)
72
+ cleanup_files
73
+ end
74
+
75
+ private
76
+
77
+ def cleanup_files
78
+ json_files.each(&:destroy)
79
+ all_files = @connection.directories.get(@bucket_name, prefix: @project_name).files
80
+ return unless all_files.size > @history_limit
81
+ all_files.sort_by(&:last_modified)[0, all_files.size - @history_limit].each do |file|
82
+ puts "Cleaning up #{file.key}"
83
+ file.destroy
84
+ end
85
+ end
86
+
87
+ def put_file(path, data)
88
+ puts "Putting to #{path} data size #{data.size}"
89
+ @connection.directories.get(@bucket_name).files.create(key: "#{@subfolder}/#{path}", body: data, content_type: 'text/html')
90
+ end
91
+
92
+ def json_files
93
+ expected_dir = "#{@subfolder}/#{@project_name}-#{commit_time}-coverageJSON/#{hashed_build_id}/"
94
+ @connection.directories.get(@bucket_name, prefix: expected_dir).files
95
+ end
96
+
97
+ def commit_time
98
+ @commit_time ||= DateTime.parse(`git show | grep Date`.gsub('Date:', '').strip).strftime('%s')
99
+ end
100
+
101
+ def hashed_build_id
102
+ @hashed_build_id ||= begin
103
+ Digest::SHA1.hexdigest(@build_id + @shared_secret)
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
3
+ require 'simplecov_s3_codeclimate/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'simplecov_s3_codeclimate'
7
+ s.version = SimpleCov::S3::Codeclimate::VERSION
8
+ s.authors = ['Jacob', 'Jonah Hirsch']
9
+ s.email = %w(jacob@engineyard.com jonah@giftcardzen.com)
10
+ s.homepage = 'https://github.com/giftcardzen/simplecov-s3'
11
+ s.summary = 'Merge simplecov output using S3 as shared storage (and publish the results to Codeclimate)'
12
+ s.description = 'Merges simplecov output using S3 as shared storage. Once all coverage is compiled, pushes this data to Codeclimate.'
13
+ s.license = 'MIT'
14
+
15
+ s.files = (`git ls-files`.split("\n") - `git ls-files -- fake`.split("\n"))
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
18
+ s.require_paths = ['lib']
19
+
20
+ s.add_development_dependency 'rspec', '~> 0'
21
+ s.add_development_dependency 'reek', '~> 0'
22
+ s.add_development_dependency 'rubocop', '~> 0'
23
+ s.add_runtime_dependency 'fog', '~> 0'
24
+ s.add_runtime_dependency 'simplecov', '~> 0'
25
+ s.add_runtime_dependency 'codeclimate-test-reporter', '~> 0'
26
+ end
data/spec/a_spec.rb ADDED
@@ -0,0 +1,43 @@
1
+ require 'simplecov-s3-codeclimate'
2
+ require 'rspec'
3
+ require 'pry'
4
+
5
+ describe SimpleCov::S3 do
6
+
7
+ it "is just barely tested" do
8
+ Fog.mock!
9
+ def Excon.post(*args)
10
+ puts "Mocked!"
11
+ end
12
+ #TODO: generate some coverage data via SimpleCov.start ?
13
+ fog_opts = {
14
+ :provider => 'AWS',
15
+ :aws_access_key_id => "XXXXXX",
16
+ :aws_secret_access_key => "XXXXXXXXXXXXX",
17
+ :region => "us-east-1",
18
+ }
19
+ s3conn = Fog::Storage.new(fog_opts)
20
+ s3conn.directories.create(:key => "somebucket")
21
+ cov_opts = {
22
+ :fog => fog_opts,
23
+ :project_name => "ey/simplecov-s3", #ENV["TRAVIS_REPO_SLUG"],
24
+ :build_id => "123", #ENV["TRAVIS_BUILD_ID"],
25
+ :job_id => "456", #ENV["TRAVIS_JOB_ID"],
26
+ :build_unit => "5", #ENV["BUILD_UNIT"],
27
+ :build_units => 2,
28
+ :bucket_name => "somebucket",
29
+ :public_url_base => "http://somebucket.s3-website-us-east-1.amazonaws.com/",
30
+ :assets_url => "http://somebucket.s3-website-us-east-1.amazonaws.com/assets",
31
+ :shared_secret => "XXXXXXXXXXXX", #used so build units can find each other, and for covereage postback
32
+ :postback_url => "https://bot.example.org/coverage",
33
+ }
34
+ cov = SimpleCov::S3.new(cov_opts)
35
+ cov.push_partial
36
+ cov.pull_merge_and_push_full
37
+ cov2 = SimpleCov::S3.new(cov_opts.merge(:job_id => "457", :build_unit => "6"))
38
+ cov2.push_partial
39
+ cov2.pull_merge_and_push_full
40
+ #TODO: assert on the resulting contents of S3?
41
+ end
42
+
43
+ end
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simplecov_s3_codeclimate
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.2'
5
+ platform: ruby
6
+ authors:
7
+ - Jacob
8
+ - Jonah Hirsch
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-12-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: reek
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rubocop
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: fog
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: simplecov
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: codeclimate-test-reporter
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ description: Merges simplecov output using S3 as shared storage. Once all coverage
99
+ is compiled, pushes this data to Codeclimate.
100
+ email:
101
+ - jacob@engineyard.com
102
+ - jonah@giftcardzen.com
103
+ executables: []
104
+ extensions: []
105
+ extra_rdoc_files: []
106
+ files:
107
+ - ".gitignore"
108
+ - ".rspec"
109
+ - Gemfile
110
+ - LICENSE
111
+ - README.md
112
+ - Rakefile
113
+ - lib/simplecov_s3_codeclimate.rb
114
+ - lib/simplecov_s3_codeclimate/version.rb
115
+ - simplecov-s3-codeclimate.gemspec
116
+ - spec/a_spec.rb
117
+ homepage: https://github.com/giftcardzen/simplecov-s3
118
+ licenses:
119
+ - MIT
120
+ metadata: {}
121
+ post_install_message:
122
+ rdoc_options: []
123
+ require_paths:
124
+ - lib
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ requirements: []
136
+ rubyforge_project:
137
+ rubygems_version: 2.2.3
138
+ signing_key:
139
+ specification_version: 4
140
+ summary: Merge simplecov output using S3 as shared storage (and publish the results
141
+ to Codeclimate)
142
+ test_files:
143
+ - spec/a_spec.rb
144
+ has_rdoc: