construi 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|