require 'spec_helper' module Omnibus describe GitFetcher do include_examples 'a software' let(:remote) { remote_git_repo('zlib') } let(:version) { 'master' } let(:source) do { git: remote } end subject { described_class.new(software) } describe '#fetch_required?' do context 'when the repo is not cloned' do it 'return true' do expect(subject.fetch_required?).to be_truthy end end context 'when the repo is cloned' do before { subject.fetch } context 'when the revisions are different' do it 'return true' do # Dirty the project_dir to differ the revisions Dir.chdir(project_dir) do FileUtils.touch("file-#{Time.now.to_i}") git %|add .| git %|commit -am "Add new file"| end expect(subject.fetch_required?).to be_truthy end end context 'when the revisions are the same' do it 'return false' do expect(subject.fetch_required?).to be(false) end end end end describe '#version_guid' do it 'includes the current revision' do expect(subject.version_guid).to match(/^git:[0-9a-f]{40}/) end end describe '#clean' do context 'when the project directory exists' do before do subject.fetch create_file("#{project_dir}/file_a") create_file("#{project_dir}/.file_b") end it 'cleans the git repo' do subject.clean expect("#{project_dir}/file_a").to_not be_a_file expect("#{project_dir}/.file_b").to_not be_a_file end it 'returns true' do expect(subject.clean).to be_truthy end end context 'when the project directory does not exist' do before do remove_directory(project_dir) end it 'returns false' do expect(subject.clean).to be(false) end end end describe '#fetch' do let(:revision) { shellout!('git rev-parse HEAD', cwd: project_dir).stdout.strip } it 'clones the repository' do subject.fetch expect("#{project_dir}/.git").to be_a_directory end context 'when the version is a tag' do let(:version) { 'v1.2.3' } let(:remote) { remote_git_repo('zlib', tags: [version]) } it 'parses the tag' do subject.fetch expect(revision).to eq('53c72c4abcc961b153996f5b5f402ce715e47146') end end context 'when the version is an annnotated tag' do let(:version) { 'v1.2.4' } let(:remote) { remote_git_repo('zlib', annotated_tags: [version]) } it 'it defererences and parses the annotated tag' do subject.fetch expect(revision).to eq('efde208366abd0f91419d8a54b45e3f6e0540105') end end context 'when the version is a branch' do let(:version) { 'sethvargo/magic_ponies' } let(:remote) { remote_git_repo('zlib', branches: [version]) } it 'parses the branch' do subject.fetch expect(revision).to eq('171a1aec35ac0a050f8dccd9c9ef4609b1d8d8ea') end end context 'when the version is a full SHA-1' do let(:version) { '45ded6d3b1a35d66ed866b2c3eb418426e6382b0' } let(:remote) { remote_git_repo('zlib') } it 'parses the full SHA-1' do subject.fetch expect(revision).to eq('45ded6d3b1a35d66ed866b2c3eb418426e6382b0') end end context 'when the version is a abbreviated SHA-1' do let(:version) { '45ded6d' } let(:remote) { remote_git_repo('zlib') } it 'parses the abbreviated SHA-1' do subject.fetch expect(revision).to eq('45ded6d3b1a35d66ed866b2c3eb418426e6382b0') end end context 'when the version is a non-existent ref' do let(:version) { 'fufufufufu' } let(:remote) { remote_git_repo('zlib') } it 'raise an exception' do expect { subject.fetch }.to raise_error(UnresolvableGitReference) end end end describe '#version_for_cache' do let(:revision) { shellout!('git rev-parse HEAD', cwd: project_dir).stdout.strip } it 'includes the revision' do expect(subject.version_for_cache).to eq("revision:#{revision}") end end end end