construi 0.1.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 +15 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +4 -0
- data/Rakefile +7 -0
- data/VERSION +1 -0
- data/bin/construi +6 -0
- data/construi.gemspec +29 -0
- data/lib/construi.rb +36 -0
- data/lib/construi/config.rb +36 -0
- data/lib/construi/container.rb +69 -0
- data/lib/construi/image.rb +74 -0
- data/lib/construi/version.rb +3 -0
- data/spec/sanity_spec.rb +7 -0
- data/spec/spec_helper.rb +78 -0
- data/vendor/bundle/ruby/1.9.1/build_info/codeclimate-test-reporter-0.4.6.info +1 -0
- data/vendor/bundle/ruby/1.9.1/cache/codeclimate-test-reporter-0.4.6.gem +0 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/.gitignore +18 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/.rspec +2 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/.travis.yml +8 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/Gemfile +12 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/LICENSE.txt +40 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/README.md +131 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/Rakefile +6 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/bin/cc-tddium-post-worker +24 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/codeclimate-test-reporter.gemspec +29 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/config/cacert.pem +3895 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter.rb +56 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/calculate_blob.rb +39 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/ci.rb +89 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/client.rb +99 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/configuration.rb +57 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/exception_message.rb +74 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/formatter.rb +114 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/git.rb +68 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/payload_validator.rb +59 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/version.rb +5 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/codeclimate-test-reporter.rb +8 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/fixtures/encoding_test.rb +6 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/fixtures/encoding_test_iso.rb +6 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/lib/calculate_blob_spec.rb +27 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/lib/ci_spec.rb +26 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/lib/client_spec.rb +24 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/lib/configuration_spec.rb +75 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/lib/formatter_spec.rb +141 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/lib/git_spec.rb +39 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/lib/payload_validator_spec.rb +89 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/lib/test_reporter_spec.rb +36 -0
- data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/spec_helper.rb +46 -0
- data/vendor/bundle/ruby/1.9.1/gems/json-1.8.2/ext/json/Makefile +174 -0
- data/vendor/bundle/ruby/1.9.1/gems/json-1.8.2/ext/json/ext/generator/Makefile +221 -0
- data/vendor/bundle/ruby/1.9.1/gems/json-1.8.2/ext/json/ext/parser/Makefile +221 -0
- data/vendor/bundle/ruby/1.9.1/specifications/codeclimate-test-reporter-0.4.6.gemspec +50 -0
- metadata +199 -0
data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter.rb
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module CodeClimate
|
|
2
|
+
module TestReporter
|
|
3
|
+
|
|
4
|
+
def self.start
|
|
5
|
+
if run?
|
|
6
|
+
require "simplecov"
|
|
7
|
+
::SimpleCov.add_filter 'vendor'
|
|
8
|
+
::SimpleCov.formatter = Formatter
|
|
9
|
+
::SimpleCov.start(configuration.profile) do
|
|
10
|
+
skip_token CodeClimate::TestReporter.configuration.skip_token
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.run?
|
|
16
|
+
environment_variable_set? && run_on_current_branch?
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.environment_variable_set?
|
|
20
|
+
return @environment_variable_set if defined?(@environment_variable_set)
|
|
21
|
+
|
|
22
|
+
@environment_variable_set = !!ENV["CODECLIMATE_REPO_TOKEN"]
|
|
23
|
+
unless @environment_variable_set
|
|
24
|
+
logger.info("Not reporting to Code Climate because ENV['CODECLIMATE_REPO_TOKEN'] is not set.")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
@environment_variable_set
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.run_on_current_branch?
|
|
31
|
+
return @run_on_current_branch if defined?(@run_on_current_branch)
|
|
32
|
+
|
|
33
|
+
@run_on_current_branch = true if configured_branch.nil?
|
|
34
|
+
@run_on_current_branch ||= !!(current_branch =~ /#{configured_branch}/i)
|
|
35
|
+
|
|
36
|
+
unless @run_on_current_branch
|
|
37
|
+
logger.info("Not reporting to Code Climate because #{configured_branch} is set as the reporting branch.")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
@run_on_current_branch
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.configured_branch
|
|
44
|
+
configuration.branch
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.current_branch
|
|
48
|
+
Git.branch_from_git_or_ci
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.logger
|
|
52
|
+
CodeClimate::TestReporter.configuration.logger
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module CodeClimate
|
|
2
|
+
module TestReporter
|
|
3
|
+
|
|
4
|
+
class CalculateBlob
|
|
5
|
+
|
|
6
|
+
def initialize(file_path)
|
|
7
|
+
@file_path = file_path
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def blob_id
|
|
11
|
+
calculate_with_file or calculate_with_git
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def calculate_with_file
|
|
17
|
+
File.open(@file_path, "rb") do |file|
|
|
18
|
+
header = "blob #{file.size}\0"
|
|
19
|
+
content = file.read
|
|
20
|
+
store = header + content
|
|
21
|
+
|
|
22
|
+
return Digest::SHA1.hexdigest(store)
|
|
23
|
+
end
|
|
24
|
+
rescue EncodingError
|
|
25
|
+
puts "WARNING: Unable to read #{@file_path}\nUsing git for blob calculation"
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def calculate_with_git
|
|
30
|
+
output = `git hash-object -t blob #{@file_path}`.chomp
|
|
31
|
+
raise 'ERROR: Failed to calculate blob with git' unless $?.success?
|
|
32
|
+
|
|
33
|
+
output
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
module CodeClimate
|
|
2
|
+
module TestReporter
|
|
3
|
+
class Ci
|
|
4
|
+
|
|
5
|
+
def self.service_data(env = ENV)
|
|
6
|
+
if env['TRAVIS']
|
|
7
|
+
{
|
|
8
|
+
name: "travis-ci",
|
|
9
|
+
branch: env['TRAVIS_BRANCH'],
|
|
10
|
+
build_identifier: env['TRAVIS_JOB_ID'],
|
|
11
|
+
pull_request: env['TRAVIS_PULL_REQUEST']
|
|
12
|
+
}
|
|
13
|
+
elsif env['CIRCLECI']
|
|
14
|
+
{
|
|
15
|
+
name: "circlci",
|
|
16
|
+
build_identifier: env['CIRCLE_BUILD_NUM'],
|
|
17
|
+
branch: env['CIRCLE_BRANCH'],
|
|
18
|
+
commit_sha: env['CIRCLE_SHA1']
|
|
19
|
+
}
|
|
20
|
+
elsif env['SEMAPHORE']
|
|
21
|
+
{
|
|
22
|
+
name: "semaphore",
|
|
23
|
+
branch: env['BRANCH_NAME'],
|
|
24
|
+
build_identifier: env['SEMAPHORE_BUILD_NUMBER']
|
|
25
|
+
}
|
|
26
|
+
elsif env['JENKINS_URL']
|
|
27
|
+
{
|
|
28
|
+
name: "jenkins",
|
|
29
|
+
build_identifier: env['BUILD_NUMBER'],
|
|
30
|
+
build_url: env['BUILD_URL'],
|
|
31
|
+
branch: env['GIT_BRANCH'],
|
|
32
|
+
commit_sha: env['GIT_COMMIT']
|
|
33
|
+
}
|
|
34
|
+
elsif env['TDDIUM']
|
|
35
|
+
{
|
|
36
|
+
name: "tddium",
|
|
37
|
+
build_identifier: env['TDDIUM_SESSION_ID'],
|
|
38
|
+
worker_id: env['TDDIUM_TID']
|
|
39
|
+
}
|
|
40
|
+
elsif env['WERCKER']
|
|
41
|
+
{
|
|
42
|
+
name: "wercker",
|
|
43
|
+
build_identifier: env['WERCKER_BUILD_ID'],
|
|
44
|
+
build_url: env['WERCKER_BUILD_URL'],
|
|
45
|
+
branch: env['WERCKER_GIT_BRANCH'],
|
|
46
|
+
commit_sha: env['WERCKER_GIT_COMMIT']
|
|
47
|
+
}
|
|
48
|
+
elsif env['APPVEYOR']
|
|
49
|
+
{
|
|
50
|
+
name: "appveyor",
|
|
51
|
+
build_identifier: env['APPVEYOR_BUILD_ID'],
|
|
52
|
+
build_url: env['APPVEYOR_API_URL'],
|
|
53
|
+
branch: env['APPVEYOR_REPO_BRANCH'],
|
|
54
|
+
commit_sha: env['APPVEYOR_REPO_COMMIT'],
|
|
55
|
+
pull_request: env['APPVEYOR_PULL_REQUEST_NUMBER']
|
|
56
|
+
}
|
|
57
|
+
elsif env['CI_NAME'] =~ /DRONE/i
|
|
58
|
+
{
|
|
59
|
+
name: "drone",
|
|
60
|
+
build_identifier: env['CI_BUILD_NUMBER'],
|
|
61
|
+
build_url: env['CI_BUILD_URL'],
|
|
62
|
+
branch: env['CI_BRANCH'],
|
|
63
|
+
commit_sha: env['CI_BUILD_NUMBER'],
|
|
64
|
+
pull_request: env['CI_PULL_REQUEST']
|
|
65
|
+
}
|
|
66
|
+
elsif env['CI_NAME'] =~ /codeship/i
|
|
67
|
+
{
|
|
68
|
+
name: "codeship",
|
|
69
|
+
build_identifier: env['CI_BUILD_NUMBER'],
|
|
70
|
+
build_url: env['CI_BUILD_URL'],
|
|
71
|
+
branch: env['CI_BRANCH'],
|
|
72
|
+
commit_sha: env['CI_COMMIT_ID'],
|
|
73
|
+
}
|
|
74
|
+
elsif env['BUILDBOX']
|
|
75
|
+
{
|
|
76
|
+
name: "buildbox",
|
|
77
|
+
build_identifier: env['BUILDBOX_JOB_ID'],
|
|
78
|
+
build_url: env['BUILDBOX_BUILD_URL'],
|
|
79
|
+
branch: env['BUILDBOX_BRANCH'],
|
|
80
|
+
commit_sha: env['BUILDBOX_COMMIT']
|
|
81
|
+
}
|
|
82
|
+
else
|
|
83
|
+
{}
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require "uri"
|
|
3
|
+
require "net/https"
|
|
4
|
+
|
|
5
|
+
module CodeClimate
|
|
6
|
+
module TestReporter
|
|
7
|
+
|
|
8
|
+
class Client
|
|
9
|
+
|
|
10
|
+
DEFAULT_TIMEOUT = 5 # in seconds
|
|
11
|
+
USER_AGENT = "Code Climate (Ruby Test Reporter v#{VERSION})"
|
|
12
|
+
|
|
13
|
+
def host
|
|
14
|
+
ENV["CODECLIMATE_API_HOST"] ||
|
|
15
|
+
"https://codeclimate.com"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def batch_post_results(files)
|
|
19
|
+
uri = URI.parse("#{host}/test_reports/batch")
|
|
20
|
+
http = http_client(uri)
|
|
21
|
+
|
|
22
|
+
boundary = SecureRandom.uuid
|
|
23
|
+
post_body = []
|
|
24
|
+
post_body << "--#{boundary}\r\n"
|
|
25
|
+
post_body << "Content-Disposition: form-data; name=\"repo_token\"\r\n"
|
|
26
|
+
post_body << "\r\n"
|
|
27
|
+
post_body << ENV["CODECLIMATE_REPO_TOKEN"]
|
|
28
|
+
files.each_with_index do |file, index|
|
|
29
|
+
post_body << "\r\n--#{boundary}\r\n"
|
|
30
|
+
post_body << "Content-Disposition: form-data; name=\"coverage_reports[#{index}]\"; filename=\"#{File.basename(file)}\"\r\n"
|
|
31
|
+
post_body << "Content-Type: application/json\r\n"
|
|
32
|
+
post_body << "\r\n"
|
|
33
|
+
post_body << File.read(file)
|
|
34
|
+
end
|
|
35
|
+
post_body << "\r\n--#{boundary}--\r\n"
|
|
36
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
|
37
|
+
request["User-Agent"] = USER_AGENT
|
|
38
|
+
request.body = post_body.join
|
|
39
|
+
request["Content-Type"] = "multipart/form-data, boundary=#{boundary}"
|
|
40
|
+
response = http.request(request)
|
|
41
|
+
|
|
42
|
+
if response.code.to_i >= 200 && response.code.to_i < 300
|
|
43
|
+
response
|
|
44
|
+
else
|
|
45
|
+
raise "HTTP Error: #{response.code}"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def post_results(result)
|
|
50
|
+
uri = URI.parse("#{host}/test_reports")
|
|
51
|
+
http = http_client(uri)
|
|
52
|
+
|
|
53
|
+
request = Net::HTTP::Post.new(uri.path)
|
|
54
|
+
request["User-Agent"] = USER_AGENT
|
|
55
|
+
request["Content-Type"] = "application/json"
|
|
56
|
+
|
|
57
|
+
if CodeClimate::TestReporter.configuration.gzip_request
|
|
58
|
+
request["Content-Encoding"] = "gzip"
|
|
59
|
+
request.body = compress(result.to_json)
|
|
60
|
+
else
|
|
61
|
+
request.body = result.to_json
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
response = http.request(request)
|
|
65
|
+
|
|
66
|
+
if response.code.to_i >= 200 && response.code.to_i < 300
|
|
67
|
+
response
|
|
68
|
+
else
|
|
69
|
+
raise "HTTP Error: #{response.code}"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def http_client(uri)
|
|
76
|
+
Net::HTTP.new(uri.host, uri.port).tap do |http|
|
|
77
|
+
if uri.scheme == "https"
|
|
78
|
+
http.use_ssl = true
|
|
79
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
80
|
+
http.ca_file = File.expand_path('../../../../config/cacert.pem', __FILE__)
|
|
81
|
+
http.verify_depth = 5
|
|
82
|
+
end
|
|
83
|
+
http.open_timeout = CodeClimate::TestReporter.configuration.timeout
|
|
84
|
+
http.read_timeout = CodeClimate::TestReporter.configuration.timeout
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def compress(str)
|
|
89
|
+
sio = StringIO.new("w")
|
|
90
|
+
gz = Zlib::GzipWriter.new(sio)
|
|
91
|
+
gz.write(str)
|
|
92
|
+
gz.close
|
|
93
|
+
sio.string
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'logger'
|
|
2
|
+
|
|
3
|
+
module CodeClimate
|
|
4
|
+
module TestReporter
|
|
5
|
+
@@configuration = nil
|
|
6
|
+
|
|
7
|
+
def self.configure
|
|
8
|
+
@@configuration = Configuration.new
|
|
9
|
+
|
|
10
|
+
if block_given?
|
|
11
|
+
yield configuration
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
configuration
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.configuration
|
|
18
|
+
@@configuration || configure
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class Configuration
|
|
22
|
+
attr_accessor :branch, :path_prefix, :gzip_request, :git_dir
|
|
23
|
+
|
|
24
|
+
attr_writer :logger, :profile, :timeout
|
|
25
|
+
|
|
26
|
+
def initialize
|
|
27
|
+
@gzip_request = true
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def logger
|
|
31
|
+
@logger ||= default_logger
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def profile
|
|
35
|
+
@profile ||= "test_frameworks"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def skip_token
|
|
39
|
+
@skip_token ||= "nocov"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def timeout
|
|
43
|
+
@timeout ||= Client::DEFAULT_TIMEOUT
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def default_logger
|
|
49
|
+
log = Logger.new($stderr)
|
|
50
|
+
log.level = Logger::INFO
|
|
51
|
+
|
|
52
|
+
log
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
module CodeClimate
|
|
2
|
+
module TestReporter
|
|
3
|
+
|
|
4
|
+
class WebMockMessage
|
|
5
|
+
def library_name
|
|
6
|
+
"WebMock"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def instructions
|
|
10
|
+
<<-STR
|
|
11
|
+
WebMock.disable_net_connect!(:allow => "codeclimate.com")
|
|
12
|
+
STR
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class VCRMessage
|
|
17
|
+
def library_name
|
|
18
|
+
"VCR"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def instructions
|
|
22
|
+
<<-STR
|
|
23
|
+
VCR.configure do |config|
|
|
24
|
+
# your existing configuration
|
|
25
|
+
config.ignore_hosts 'codeclimate.com'
|
|
26
|
+
end
|
|
27
|
+
STR
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class ExceptionMessage
|
|
32
|
+
|
|
33
|
+
HTTP_STUBBING_MESSAGES = {
|
|
34
|
+
"VCR::Errors::UnhandledHTTPRequestError" => VCRMessage,
|
|
35
|
+
"WebMock::NetConnectNotAllowedError" => WebMockMessage
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
def initialize(exception)
|
|
39
|
+
@exception = exception
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def message
|
|
43
|
+
parts = []
|
|
44
|
+
parts << "Code Climate encountered an exception: #{exception_class}"
|
|
45
|
+
if http_stubbing_exception
|
|
46
|
+
message = http_stubbing_exception.new
|
|
47
|
+
parts << "======"
|
|
48
|
+
parts << "Hey! Looks like you are using #{message.library_name}, which will prevent the codeclimate-test-reporter from reporting results to codeclimate.com.
|
|
49
|
+
Add the following to your spec or test helper to ensure codeclimate-test-reporter can post coverage results:"
|
|
50
|
+
parts << "\n" + message.instructions + "\n"
|
|
51
|
+
parts << "======"
|
|
52
|
+
parts << "If this doesn't work, please consult https://codeclimate.com/docs#test-coverage-troubleshooting"
|
|
53
|
+
parts << "======"
|
|
54
|
+
else
|
|
55
|
+
parts << @exception.message
|
|
56
|
+
@exception.backtrace.each do |line|
|
|
57
|
+
parts << line
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
parts.join("\n")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def exception_class
|
|
66
|
+
@exception.class.to_s
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def http_stubbing_exception
|
|
70
|
+
HTTP_STUBBING_MESSAGES[exception_class]
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require "tmpdir"
|
|
4
|
+
require "securerandom"
|
|
5
|
+
require "json"
|
|
6
|
+
require "digest/sha1"
|
|
7
|
+
require "simplecov"
|
|
8
|
+
|
|
9
|
+
require "code_climate/test_reporter/exception_message"
|
|
10
|
+
require "code_climate/test_reporter/payload_validator"
|
|
11
|
+
|
|
12
|
+
module CodeClimate
|
|
13
|
+
module TestReporter
|
|
14
|
+
class Formatter
|
|
15
|
+
def format(result)
|
|
16
|
+
return true unless CodeClimate::TestReporter.run?
|
|
17
|
+
|
|
18
|
+
print "Coverage = #{result.source_files.covered_percent.round(2)}%. "
|
|
19
|
+
|
|
20
|
+
payload = to_payload(result)
|
|
21
|
+
PayloadValidator.validate(payload)
|
|
22
|
+
if tddium? || ENV["TO_FILE"]
|
|
23
|
+
file_path = File.join(Dir.tmpdir, "codeclimate-test-coverage-#{SecureRandom.uuid}.json")
|
|
24
|
+
print "Coverage results saved to #{file_path}... "
|
|
25
|
+
File.open(file_path, "w") { |file| file.write(payload.to_json) }
|
|
26
|
+
else
|
|
27
|
+
client = Client.new
|
|
28
|
+
print "Sending report to #{client.host} for branch #{Git.branch_from_git_or_ci}... "
|
|
29
|
+
client.post_results(payload)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
puts "done."
|
|
33
|
+
true
|
|
34
|
+
rescue => ex
|
|
35
|
+
puts ExceptionMessage.new(ex).message
|
|
36
|
+
false
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def partial?
|
|
40
|
+
tddium?
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def to_payload(result)
|
|
44
|
+
totals = Hash.new(0)
|
|
45
|
+
source_files = result.files.map do |file|
|
|
46
|
+
totals[:total] += file.lines.count
|
|
47
|
+
totals[:covered] += file.covered_lines.count
|
|
48
|
+
totals[:missed] += file.missed_lines.count
|
|
49
|
+
|
|
50
|
+
{
|
|
51
|
+
name: short_filename(file.filename),
|
|
52
|
+
blob_id: CalculateBlob.new(file.filename).blob_id,
|
|
53
|
+
coverage: file.coverage.to_json,
|
|
54
|
+
covered_percent: round(file.covered_percent, 2),
|
|
55
|
+
covered_strength: round(file.covered_strength, 2),
|
|
56
|
+
line_counts: {
|
|
57
|
+
total: file.lines.count,
|
|
58
|
+
covered: file.covered_lines.count,
|
|
59
|
+
missed: file.missed_lines.count
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
{
|
|
65
|
+
repo_token: ENV["CODECLIMATE_REPO_TOKEN"],
|
|
66
|
+
source_files: source_files,
|
|
67
|
+
run_at: result.created_at.to_i,
|
|
68
|
+
covered_percent: result.source_files.covered_percent.round(2),
|
|
69
|
+
covered_strength: result.source_files.covered_strength.round(2),
|
|
70
|
+
line_counts: totals,
|
|
71
|
+
partial: partial?,
|
|
72
|
+
git: Git.info,
|
|
73
|
+
environment: {
|
|
74
|
+
test_framework: result.command_name.downcase,
|
|
75
|
+
pwd: Dir.pwd,
|
|
76
|
+
rails_root: (Rails.root.to_s rescue nil),
|
|
77
|
+
simplecov_root: ::SimpleCov.root,
|
|
78
|
+
gem_version: VERSION
|
|
79
|
+
},
|
|
80
|
+
ci_service: ci_service_data
|
|
81
|
+
}
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def short_filename(filename)
|
|
86
|
+
return filename unless ::SimpleCov.root
|
|
87
|
+
filename = filename.gsub(::SimpleCov.root, '.').gsub(/^\.\//, '')
|
|
88
|
+
apply_prefix filename
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def tddium?
|
|
92
|
+
ci_service_data && ci_service_data[:name] == "tddium"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Convert to Float before rounding.
|
|
96
|
+
# Fixes [#7] possible segmentation fault when calling #round on a Rational
|
|
97
|
+
def round(numeric, precision)
|
|
98
|
+
Float(numeric).round(precision)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
private
|
|
102
|
+
|
|
103
|
+
def apply_prefix filename
|
|
104
|
+
prefix = CodeClimate::TestReporter.configuration.path_prefix
|
|
105
|
+
return filename if prefix.nil?
|
|
106
|
+
"#{prefix}/#{filename}"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def ci_service_data
|
|
110
|
+
@ci_service_data ||= Ci.service_data
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|