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.
Files changed (56) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +5 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +4 -0
  7. data/Rakefile +7 -0
  8. data/VERSION +1 -0
  9. data/bin/construi +6 -0
  10. data/construi.gemspec +29 -0
  11. data/lib/construi.rb +36 -0
  12. data/lib/construi/config.rb +36 -0
  13. data/lib/construi/container.rb +69 -0
  14. data/lib/construi/image.rb +74 -0
  15. data/lib/construi/version.rb +3 -0
  16. data/spec/sanity_spec.rb +7 -0
  17. data/spec/spec_helper.rb +78 -0
  18. data/vendor/bundle/ruby/1.9.1/build_info/codeclimate-test-reporter-0.4.6.info +1 -0
  19. data/vendor/bundle/ruby/1.9.1/cache/codeclimate-test-reporter-0.4.6.gem +0 -0
  20. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/.gitignore +18 -0
  21. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/.rspec +2 -0
  22. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/.travis.yml +8 -0
  23. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/Gemfile +12 -0
  24. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/LICENSE.txt +40 -0
  25. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/README.md +131 -0
  26. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/Rakefile +6 -0
  27. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/bin/cc-tddium-post-worker +24 -0
  28. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/codeclimate-test-reporter.gemspec +29 -0
  29. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/config/cacert.pem +3895 -0
  30. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter.rb +56 -0
  31. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/calculate_blob.rb +39 -0
  32. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/ci.rb +89 -0
  33. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/client.rb +99 -0
  34. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/configuration.rb +57 -0
  35. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/exception_message.rb +74 -0
  36. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/formatter.rb +114 -0
  37. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/git.rb +68 -0
  38. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/payload_validator.rb +59 -0
  39. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/code_climate/test_reporter/version.rb +5 -0
  40. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/lib/codeclimate-test-reporter.rb +8 -0
  41. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/fixtures/encoding_test.rb +6 -0
  42. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/fixtures/encoding_test_iso.rb +6 -0
  43. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/lib/calculate_blob_spec.rb +27 -0
  44. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/lib/ci_spec.rb +26 -0
  45. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/lib/client_spec.rb +24 -0
  46. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/lib/configuration_spec.rb +75 -0
  47. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/lib/formatter_spec.rb +141 -0
  48. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/lib/git_spec.rb +39 -0
  49. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/lib/payload_validator_spec.rb +89 -0
  50. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/lib/test_reporter_spec.rb +36 -0
  51. data/vendor/bundle/ruby/1.9.1/gems/codeclimate-test-reporter-0.4.6/spec/spec_helper.rb +46 -0
  52. data/vendor/bundle/ruby/1.9.1/gems/json-1.8.2/ext/json/Makefile +174 -0
  53. data/vendor/bundle/ruby/1.9.1/gems/json-1.8.2/ext/json/ext/generator/Makefile +221 -0
  54. data/vendor/bundle/ruby/1.9.1/gems/json-1.8.2/ext/json/ext/parser/Makefile +221 -0
  55. data/vendor/bundle/ruby/1.9.1/specifications/codeclimate-test-reporter-0.4.6.gemspec +50 -0
  56. metadata +199 -0
@@ -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