Skip to content

Commit 7a6199e

Browse files
author
Kevin Paulisse
committed
Create spec coverage for catalog-utils/git
1 parent b4cfb75 commit 7a6199e

2 files changed

Lines changed: 144 additions & 21 deletions

File tree

  • lib/octocatalog-diff/catalog-util
  • spec/octocatalog-diff/tests/catalog-util

lib/octocatalog-diff/catalog-util/git.rb

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,36 @@ def self.check_out_git_archive(options = {})
2929
if dir.nil? || !File.directory?(dir)
3030
raise OctocatalogDiff::Errors::GitCheckoutError, "Source directory #{dir.inspect} does not exist"
3131
end
32-
if dir.nil? || !File.directory?(path)
32+
if path.nil? || !File.directory?(path)
3333
raise OctocatalogDiff::Errors::GitCheckoutError, "Target directory #{path.inspect} does not exist"
3434
end
3535

36-
# To get the options working correctly (-o pipefail in particular) this needs to run under
37-
# bash. It's just creating a script, rather than figuring out all the shell escapes...
38-
begin
39-
tmp_script = Tempfile.new(['git-checkout', '.sh'])
40-
tmp_script.write "#!/bin/bash\n"
41-
tmp_script.write "set -euf -o pipefail\n"
42-
tmp_script.write "git archive --format=tar #{Shellwords.escape(branch)} | \\\n"
43-
tmp_script.write " ( cd #{Shellwords.escape(path)} && tar -xf - )\n"
44-
tmp_script.close
45-
FileUtils.chmod 0o755, tmp_script.path
46-
47-
logger.debug("Begin git archive #{dir}:#{branch} -> #{path}")
48-
output, status = Open3.capture2e(tmp_script.path, chdir: dir)
49-
unless status.exitstatus.zero?
50-
raise OctocatalogDiff::Errors::GitCheckoutError, "Git archive #{branch}->#{path} failed: #{output}"
51-
end
52-
logger.debug("Success git archive #{dir}:#{branch}")
53-
ensure
54-
FileUtils.rm_f tmp_script.path if File.exist?(tmp_script.path)
36+
# Create and execute checkout script
37+
script = create_git_checkout_script(branch, path)
38+
logger.debug("Begin git archive #{dir}:#{branch} -> #{path}")
39+
output, status = Open3.capture2e(script, chdir: dir)
40+
unless status.exitstatus.zero?
41+
raise OctocatalogDiff::Errors::GitCheckoutError, "Git archive #{branch}->#{path} failed: #{output}"
5542
end
43+
logger.debug("Success git archive #{dir}:#{branch}")
44+
end
45+
46+
# Create the temporary file used to interact with the git command line.
47+
# To get the options working correctly (-o pipefail in particular) this needs to run under
48+
# bash. It's just creating a script, rather than figuring out all the shell escapes...
49+
# @param branch [String] Branch name
50+
# @param path [String] Target directory
51+
# @return [String] Name of script
52+
def self.create_git_checkout_script(branch, path)
53+
tmp_script = Tempfile.new(['git-checkout', '.sh'])
54+
tmp_script.write "#!/bin/bash\n"
55+
tmp_script.write "set -euf -o pipefail\n"
56+
tmp_script.write "git archive --format=tar #{Shellwords.escape(branch)} | \\\n"
57+
tmp_script.write " ( cd #{Shellwords.escape(path)} && tar -xf - )\n"
58+
tmp_script.close
59+
FileUtils.chmod 0o755, tmp_script.path
60+
at_exit { FileUtils.rm_f tmp_script.path if File.exist?(tmp_script.path) }
61+
tmp_script.path
5662
end
5763

5864
# Determine the SHA of origin/master (or any other branch really) in the git repo
@@ -63,7 +69,7 @@ def self.branch_sha(options = {})
6369
branch = options.fetch(:branch)
6470
dir = options.fetch(:basedir)
6571
if dir.nil? || !File.directory?(dir)
66-
raise OctocatalogDiff::Errors::GitCheckoutError, "Git directory #{dir.inspect} does not exist"
72+
raise Errno::ENOENT, "Git directory #{dir.inspect} does not exist"
6773
end
6874
repo = Rugged::Repository.new(dir)
6975
repo.branches[branch].target_id
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# frozen_string_literal: true
2+
3+
require_relative '../spec_helper'
4+
5+
require OctocatalogDiff::Spec.require_path('catalog-util/git')
6+
require OctocatalogDiff::Spec.require_path('errors')
7+
8+
require 'ostruct'
9+
10+
describe OctocatalogDiff::CatalogUtil::Git do
11+
before(:each) do
12+
@logger, @logger_str = OctocatalogDiff::Spec.setup_logger
13+
allow(File).to receive(:'directory?').with('/tmp/foo').and_return(false)
14+
allow(File).to receive(:'directory?').with('/tmp/bar').and_return(true)
15+
end
16+
17+
describe '#check_out_git_archive' do
18+
context 'with invalid directory' do
19+
it 'should raise OctocatalogDiff::Errors::GitCheckoutError if basedir is nil' do
20+
opts = { branch: 'foo', path: '/tmp/foo', basedir: nil, logger: @logger }
21+
expect do
22+
described_class.check_out_git_archive(opts)
23+
end.to raise_error(OctocatalogDiff::Errors::GitCheckoutError, /Source directory/)
24+
end
25+
26+
it 'should raise OctocatalogDiff::Errors::GitCheckoutError if basedir does not exist' do
27+
opts = { branch: 'foo', path: '/tmp/foo', basedir: '/tmp/foo', logger: @logger }
28+
expect do
29+
described_class.check_out_git_archive(opts)
30+
end.to raise_error(OctocatalogDiff::Errors::GitCheckoutError, /Source directory/)
31+
end
32+
33+
it 'should raise OctocatalogDiff::Errors::GitCheckoutError if path is nil' do
34+
opts = { branch: 'foo', path: nil, basedir: '/tmp/bar', logger: @logger }
35+
expect do
36+
described_class.check_out_git_archive(opts)
37+
end.to raise_error(OctocatalogDiff::Errors::GitCheckoutError, /Target directory/)
38+
end
39+
40+
it 'should raise OctocatalogDiff::Errors::GitCheckoutError if path does not exist' do
41+
opts = { branch: 'foo', path: '/tmp/foo', basedir: '/tmp/bar', logger: @logger }
42+
expect do
43+
described_class.check_out_git_archive(opts)
44+
end.to raise_error(OctocatalogDiff::Errors::GitCheckoutError, /Target directory/)
45+
end
46+
end
47+
48+
context 'with valid directory' do
49+
context 'with successful script run' do
50+
it 'should log proper messages and not raise error' do
51+
expect(described_class).to receive(:create_git_checkout_script).and_return('/tmp/baz.sh')
52+
expect(Open3).to receive(:capture2e)
53+
.with('/tmp/baz.sh', chdir: '/tmp/bar')
54+
.and_return(['asldfkj', OpenStruct.new(exitstatus: 0)])
55+
opts = { branch: 'foo', path: '/tmp/bar', basedir: '/tmp/bar', logger: @logger }
56+
described_class.check_out_git_archive(opts)
57+
expect(@logger_str.string).to match(%r{Success git archive /tmp/bar:foo})
58+
end
59+
end
60+
61+
context 'with failed script run' do
62+
it 'should raise OctocatalogDiff::Errors::GitCheckoutError' do
63+
expect(described_class).to receive(:create_git_checkout_script).and_return('/tmp/baz.sh')
64+
expect(Open3).to receive(:capture2e)
65+
.with('/tmp/baz.sh', chdir: '/tmp/bar')
66+
.and_return(['errors abound', OpenStruct.new(exitstatus: 1)])
67+
opts = { branch: 'foo', path: '/tmp/bar', basedir: '/tmp/bar', logger: @logger }
68+
expect do
69+
described_class.check_out_git_archive(opts)
70+
end.to raise_error(OctocatalogDiff::Errors::GitCheckoutError, 'Git archive foo->/tmp/bar failed: errors abound')
71+
end
72+
end
73+
end
74+
end
75+
76+
describe '#create_git_checkout_script' do
77+
it 'should create the temporary script' do
78+
result = described_class.create_git_checkout_script('foo', '/tmp/baz')
79+
expect(result).to be_a_kind_of(String)
80+
expect(File.file?(result)).to eq(true)
81+
82+
text = File.read(result)
83+
expect(text).to match(/git archive --format=tar foo \|/)
84+
expect(text).to match(%r{\( cd /tmp/baz && tar -xf - \)})
85+
86+
expect(File.executable?(result)).to eq(true)
87+
end
88+
end
89+
90+
describe '#branch_sha' do
91+
context 'with invalid directory' do
92+
it 'should raise Errno::ENOENT if basedir is nil' do
93+
opts = { branch: 'foo', basedir: nil }
94+
expect do
95+
described_class.branch_sha(opts)
96+
end.to raise_error(Errno::ENOENT, /Git directory/)
97+
end
98+
99+
it 'should raise Errno::ENOENT if basedir does not exist' do
100+
opts = { branch: 'foo', basedir: '/tmp/foo' }
101+
expect do
102+
described_class.branch_sha(opts)
103+
end.to raise_error(Errno::ENOENT, /Git directory/)
104+
end
105+
end
106+
107+
context 'with valid directory' do
108+
it 'should return the sha from rugged' do
109+
opts = { branch: 'foo', basedir: '/tmp/bar' }
110+
expect(Rugged::Repository).to receive(:new).with('/tmp/bar')
111+
.and_return(OpenStruct.new(branches: { 'foo' => OpenStruct.new(target_id: 'abcdef012345') }))
112+
result = described_class.branch_sha(opts)
113+
expect(result).to eq('abcdef012345')
114+
end
115+
end
116+
end
117+
end

0 commit comments

Comments
 (0)