Skip to content

Commit d373a41

Browse files
committed
Implemented a Ruby class to access GitVersion's information
1 parent 6eb0436 commit d373a41

File tree

3 files changed

+139
-0
lines changed

3 files changed

+139
-0
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
require 'json'
2+
require 'open3'
3+
4+
class GitVersion
5+
attr_reader :args
6+
attr_accessor :gitversion_exe
7+
8+
def initialize(args = [])
9+
@args = args
10+
end
11+
12+
def method_missing(symbol, *args)
13+
keys = [symbol.to_s, pascal_case(symbol.to_s)]
14+
15+
found_key = keys.find { |key| json.has_key?(key) }
16+
return json[found_key] if found_key
17+
18+
super
19+
end
20+
21+
def json
22+
@json ||= run_gitversion
23+
end
24+
25+
def gitversion_exe
26+
@gitversion_exe ||= File.join(File.dirname(__FILE__), '../bin/GitVersion.exe')
27+
end
28+
29+
private
30+
def run_gitversion
31+
cmd = [gitversion_exe]
32+
cmd << args
33+
cmd = cmd.flatten.reject(&:nil?)
34+
35+
stdout_and_stderr, status = Open3.capture2e(*cmd)
36+
37+
raise StandardError.new("Failed running #{cmd.join(' ')}, #{status}. We received the following output:\n#{stdout_and_stderr}") unless status.success?
38+
39+
JSON.parse(stdout_and_stderr)
40+
end
41+
42+
def pascal_case(str)
43+
str
44+
.to_s
45+
.split('_')
46+
.inject([]) { |buffer, e| buffer.push(e.capitalize) }
47+
.join
48+
end
49+
end
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
require 'git_version'
2+
3+
describe GitVersion do
4+
describe 'defaults' do
5+
its(:gitversion_exe) { should match(%r|\.\./bin/GitVersion.exe$|) }
6+
its(:args) { should be_empty }
7+
end
8+
9+
describe 'GitVersion.exe invocation' do
10+
before {
11+
allow(Open3).to receive(:capture2e).and_return(gitversion_exe_return)
12+
}
13+
14+
let(:gitversion_exe_return) { ['{ "Sha": 1234 }', OpenStruct.new(success?: true)] }
15+
16+
describe 'cached results' do
17+
context 'accessing multiple properties' do
18+
it 'should run GitVersion.exe only once' do
19+
subject.sha
20+
subject.sha
21+
22+
expect(Open3).to have_received(:capture2e).once
23+
end
24+
end
25+
end
26+
27+
describe 'arguments' do
28+
subject { described_class.new(args) }
29+
30+
let(:args) { %w(some additional args) }
31+
32+
it 'should pass args to the executable' do
33+
subject.sha
34+
35+
expect(Open3).to have_received(:capture2e).with(*([subject.gitversion_exe] + args))
36+
end
37+
end
38+
39+
context 'GitVersion.exe fails' do
40+
let(:gitversion_exe_return) { ['some error output', OpenStruct.new(success?: false)] }
41+
42+
it 'should fail' do
43+
expect { subject.it_does_not_matter }.to raise_error(StandardError, /Failed running.*some error output/m)
44+
end
45+
end
46+
end
47+
48+
describe 'after the executable has been built' do
49+
before {
50+
subject.gitversion_exe = File.expand_path('../../GemBuild/bin/GitVersion.exe')
51+
}
52+
53+
its(:json) { should_not be_nil }
54+
its(:sha) { should match(/[0-9 a-f]{40}/) }
55+
end
56+
57+
describe 'accessing properties' do
58+
before {
59+
allow(subject).to receive(:json).and_return(json)
60+
}
61+
62+
let(:json) { { 'InformationalVersion' => 'blah' } }
63+
64+
it 'should translate snake case to pascal case' do
65+
expect(subject.informational_version).to eq('blah')
66+
end
67+
68+
it 'should support pascal case' do
69+
pascal = subject.InformationalVersion
70+
snake = subject.informational_version
71+
72+
expect(pascal).to eq(snake)
73+
end
74+
75+
context 'with nil value' do
76+
let(:json) { { 'is_nil' => nil } }
77+
78+
it 'should yield nil' do
79+
expect(subject.is_nil).to be_nil
80+
end
81+
end
82+
end
83+
end
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
require 'rspec/its'
2+
3+
RSpec.configure do |config|
4+
config.expect_with :rspec do |c|
5+
c.syntax = :expect
6+
end
7+
end

0 commit comments

Comments
 (0)