Skip to content
This repository was archived by the owner on Jul 19, 2025. It is now read-only.

Commit 96e24ad

Browse files
committed
Merge pull request #52 from codeclimate/force_blob_id_encoding
Force UTF-8 to calculate blob ids.
2 parents 157c308 + aa57b82 commit 96e24ad

File tree

9 files changed

+114
-85
lines changed

9 files changed

+114
-85
lines changed

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
language: ruby
2+
before_script:
3+
- git config --global user.email "[email protected]"
4+
- git config --global user.name "Code Climate CI"
25
rvm:
36
- 1.9.3
47
- 2.1.2

lib/code_climate/test_reporter/ci.rb

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,65 +2,65 @@ module CodeClimate
22
module TestReporter
33
class Ci
44

5-
def self.service_data
6-
if ENV['TRAVIS']
5+
def self.service_data(env = ENV)
6+
if env['TRAVIS']
77
{
88
name: "travis-ci",
9-
branch: ENV['TRAVIS_BRANCH'],
10-
build_identifier: ENV['TRAVIS_JOB_ID'],
11-
pull_request: ENV['TRAVIS_PULL_REQUEST']
9+
branch: env['TRAVIS_BRANCH'],
10+
build_identifier: env['TRAVIS_JOB_ID'],
11+
pull_request: env['TRAVIS_PULL_REQUEST']
1212
}
13-
elsif ENV['CIRCLECI']
13+
elsif env['CIRCLECI']
1414
{
1515
name: "circlci",
16-
build_identifier: ENV['CIRCLE_BUILD_NUM'],
17-
branch: ENV['CIRCLE_BRANCH'],
18-
commit_sha: ENV['CIRCLE_SHA1']
16+
build_identifier: env['CIRCLE_BUILD_NUM'],
17+
branch: env['CIRCLE_BRANCH'],
18+
commit_sha: env['CIRCLE_SHA1']
1919
}
20-
elsif ENV['SEMAPHORE']
20+
elsif env['SEMAPHORE']
2121
{
2222
name: "semaphore",
23-
branch: ENV['BRANCH_NAME'],
24-
build_identifier: ENV['SEMAPHORE_BUILD_NUMBER']
23+
branch: env['BRANCH_NAME'],
24+
build_identifier: env['SEMAPHORE_BUILD_NUMBER']
2525
}
26-
elsif ENV['JENKINS_URL']
26+
elsif env['JENKINS_URL']
2727
{
2828
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']
29+
build_identifier: env['BUILD_NUMBER'],
30+
build_url: env['BUILD_URL'],
31+
branch: env['GIT_BRANCH'],
32+
commit_sha: env['GIT_COMMIT']
3333
}
34-
elsif ENV['TDDIUM']
34+
elsif env['TDDIUM']
3535
{
3636
name: "tddium",
37-
build_identifier: ENV['TDDIUM_SESSION_ID'],
38-
worker_id: ENV['TDDIUM_TID']
37+
build_identifier: env['TDDIUM_SESSION_ID'],
38+
worker_id: env['TDDIUM_TID']
3939
}
40-
elsif ENV['WERCKER']
40+
elsif env['WERCKER']
4141
{
4242
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']
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']
4747
}
48-
elsif ENV['CI_NAME'] =~ /DRONE/i
48+
elsif env['CI_NAME'] =~ /DRONE/i
4949
{
5050
name: "drone",
51-
build_identifier: ENV['CI_BUILD_NUMBER'],
52-
build_url: ENV['CI_BUILD_URL'],
53-
branch: ENV['CI_BRANCH'],
54-
commit_sha: ENV['CI_BUILD_NUMBER'],
55-
pull_request: ENV['CI_PULL_REQUEST']
51+
build_identifier: env['CI_BUILD_NUMBER'],
52+
build_url: env['CI_BUILD_URL'],
53+
branch: env['CI_BRANCH'],
54+
commit_sha: env['CI_BUILD_NUMBER'],
55+
pull_request: env['CI_PULL_REQUEST']
5656
}
57-
elsif ENV['CI_NAME'] =~ /codeship/i
57+
elsif env['CI_NAME'] =~ /codeship/i
5858
{
5959
name: "codeship",
60-
build_identifier: ENV['CI_BUILD_NUMBER'],
61-
build_url: ENV['CI_BUILD_URL'],
62-
branch: ENV['CI_BRANCH'],
63-
commit_sha: ENV['CI_COMMIT_ID'],
60+
build_identifier: env['CI_BUILD_NUMBER'],
61+
build_url: env['CI_BUILD_URL'],
62+
branch: env['CI_BRANCH'],
63+
commit_sha: env['CI_COMMIT_ID'],
6464
}
6565
else
6666
{}

lib/code_climate/test_reporter/formatter.rb

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# encoding: utf-8
2+
13
require "tmpdir"
24
require "securerandom"
35
require "json"
@@ -80,10 +82,13 @@ def to_payload(result)
8082
end
8183

8284
def calculate_blob_id(path)
83-
content = File.open(path, "rb") {|f| f.read }
84-
header = "blob #{content.length}\0"
85-
store = header + content
86-
Digest::SHA1.hexdigest(store)
85+
File.open(path, "rb") do |file|
86+
header = "blob #{file.size}\0"
87+
content = file.read.force_encoding("iso-8859-1").encode("utf-8", replace: nil)
88+
store = header + content
89+
90+
return Digest::SHA1.hexdigest(store)
91+
end
8792
end
8893

8994
def short_filename(filename)

lib/code_climate/test_reporter/git.rb

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,21 @@ def info
1212
end
1313

1414
def branch_from_git_or_ci
15-
git_branch = branch_from_git
16-
ci_branch = Ci.service_data[:branch]
17-
18-
if ci_branch.to_s.strip.size > 0
19-
ci_branch.sub(/^origin\//, "")
20-
elsif git_branch.to_s.strip.size > 0 && !git_branch.to_s.strip.start_with?("(")
21-
git_branch.sub(/^origin\//, "")
22-
else
23-
"master"
24-
end
15+
clean_service_branch || clean_git_branch || "master"
16+
end
17+
18+
def clean_service_branch
19+
ci_branch = String(Ci.service_data[:branch])
20+
clean = ci_branch.strip.sub(/^origin\//, "")
21+
22+
clean.size > 0 ? clean : nil
23+
end
24+
25+
def clean_git_branch
26+
git_branch = String(branch_from_git)
27+
clean = git_branch.sub(/^origin\//, "") unless git_branch.start_with?("(")
28+
29+
clean.size > 0 ? clean : nil
2530
end
2631

2732
private
@@ -32,9 +37,7 @@ def committed_at
3237
end
3338

3439
def branch_from_git
35-
branch = `git branch`.split("\n").delete_if { |i| i[0] != "*" }
36-
branch = [branch].flatten.first
37-
branch ? branch.gsub("* ","") : nil
40+
`git rev-parse --abbrev-ref HEAD`.chomp
3841
end
3942
end
4043
end

spec/fixtures/encoding_test.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# encoding: utf-8
2+
class EncodingTest
3+
def foo
4+
"ä"
5+
end
6+
end

spec/fixtures/encoding_test_iso.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# encoding: iso-8859-1
2+
class EncodingTest
3+
def foo
4+
"ä"
5+
end
6+
end

spec/lib/ci_spec.rb

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,11 @@ module CodeClimate::TestReporter
55

66
describe '.service_data' do
77
before :each do
8-
ENV['SEMAPHORE'] = 'yes?'
9-
ENV['BRANCH_NAME'] = 'master'
10-
ENV['SEMAPHORE_BUILD_NUMBER'] = '1234'
11-
end
12-
13-
after :each do
14-
ENV.delete('SEMAPHORE')
15-
ENV.delete('BRANCH_NAME')
16-
ENV.delete('SEMAPHORE_BUILD_NUMBER')
8+
@env = {
9+
'SEMAPHORE' => 'yes?',
10+
'BRANCH_NAME' => 'master',
11+
'SEMAPHORE_BUILD_NUMBER' => '1234'
12+
}
1713
end
1814

1915
it 'returns a hash of CI environment info' do
@@ -23,9 +19,8 @@ module CodeClimate::TestReporter
2319
build_identifier: '1234'
2420
}
2521

26-
expect(Ci.service_data).to include expected_semaphore_hash
22+
expect(Ci.service_data(@env)).to include expected_semaphore_hash
2723
end
2824
end
29-
3025
end
3126
end

spec/lib/formatter_spec.rb

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ module CodeClimate::TestReporter
7070
"simplecov_root" => Dir.pwd,
7171
"gem_version" => VERSION
7272
},
73-
"ci_service" => {}
7473
}
7574
}
7675

@@ -106,34 +105,46 @@ module CodeClimate::TestReporter
106105

107106
uncompressed = inflate(app.request_body)
108107

109-
expect(JSON.parse(uncompressed)).to eq(expected_request)
108+
expected_request.merge!("ci_service" => Ci.service_data)
109+
expected_json = JSON.parse(expected_request.to_json, symbolize_names: true)
110+
111+
expect(JSON.parse(uncompressed, symbolize_names: true)).to eq(expected_json)
110112
expect(app.http_user_agent).to include("v#{CodeClimate::TestReporter::VERSION}")
111113
end
112-
end
113114

114-
describe '#short_filename' do
115-
let(:formatter) { CodeClimate::TestReporter::Formatter.new }
116-
it 'should return the filename of the file relative to the SimpleCov root' do
117-
expect(formatter.short_filename('file1')).to eq('file1')
118-
expect(formatter.short_filename("#{::SimpleCov.root}/file1")).to eq('file1')
119-
end
115+
describe '#short_filename' do
116+
it 'should return the filename of the file relative to the SimpleCov root' do
117+
expect(formatter.short_filename('file1')).to eq('file1')
118+
expect(formatter.short_filename("#{::SimpleCov.root}/file1")).to eq('file1')
119+
end
120120

121-
context "with path prefix" do
122-
before do
123-
CodeClimate::TestReporter.configure do |config|
124-
config.path_prefix = 'custom'
121+
context "with path prefix" do
122+
before do
123+
CodeClimate::TestReporter.configure do |config|
124+
config.path_prefix = 'custom'
125+
end
125126
end
126-
end
127127

128-
after do
129-
CodeClimate::TestReporter.configure do |config|
130-
config.path_prefix = nil
128+
after do
129+
CodeClimate::TestReporter.configure do |config|
130+
config.path_prefix = nil
131+
end
132+
end
133+
134+
it 'should include the path prefix if set' do
135+
expect(formatter.short_filename('file1')).to eq('custom/file1')
136+
expect(formatter.short_filename("#{::SimpleCov.root}/file1")).to eq('custom/file1')
131137
end
132138
end
139+
end
140+
141+
describe "#calculate_blob_id" do
142+
it "forces UTF-8 as encoding for the file content" do
143+
blob_id = formatter.calculate_blob_id(File.expand_path("../../fixtures/encoding_test_iso.rb", __FILE__))
144+
expect(blob_id).to_not be_nil
133145

134-
it 'should include the path prefix if set' do
135-
expect(formatter.short_filename('file1')).to eq('custom/file1')
136-
expect(formatter.short_filename("#{::SimpleCov.root}/file1")).to eq('custom/file1')
146+
blob_id = formatter.calculate_blob_id(File.expand_path("../../fixtures/encoding_test.rb", __FILE__))
147+
expect(blob_id).to_not be_nil
137148
end
138149
end
139150
end

spec/lib/git_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ module CodeClimate::TestReporter
2424
it 'returns the branch from git if there is no ci branch' do
2525
allow(Ci).to receive(:service_data).and_return({})
2626

27-
expect(Git.branch_from_git_or_ci).to eq Git.send(:branch_from_git)
27+
expect(Git.branch_from_git_or_ci).to eq Git.clean_git_branch
2828
end
2929

3030
it 'returns master otherwise' do

0 commit comments

Comments
 (0)