2021-03-22 12:50:37 +00:00
|
|
|
require 'helper'
|
|
|
|
require 'inspec/fetcher'
|
2016-09-08 09:11:44 +00:00
|
|
|
|
2019-11-18 18:20:35 +00:00
|
|
|
describe Inspec::Fetcher::Git do
|
|
|
|
let(:fetcher) { Inspec::Fetcher::Git }
|
2016-09-08 09:11:44 +00:00
|
|
|
|
2021-03-22 12:50:37 +00:00
|
|
|
it 'registers with the fetchers registry' do
|
2019-11-22 15:09:51 +00:00
|
|
|
reg = Inspec::Fetcher::Registry.registry
|
2021-03-22 12:50:37 +00:00
|
|
|
_(reg['git']).must_equal fetcher
|
2016-09-08 09:11:44 +00:00
|
|
|
end
|
|
|
|
|
2021-03-22 12:50:37 +00:00
|
|
|
it 'handles sources beginning with `git@`' do
|
|
|
|
f = fetcher.resolve('git@github.com:foo/bar')
|
2019-09-30 22:31:55 +00:00
|
|
|
_(f).wont_be_nil
|
2019-11-18 18:20:35 +00:00
|
|
|
_(f).must_be_kind_of Inspec::Fetcher::Git
|
2018-11-08 20:55:15 +00:00
|
|
|
end
|
|
|
|
|
2021-03-22 12:50:37 +00:00
|
|
|
it 'handles sources ending with `.git`' do
|
|
|
|
f = fetcher.resolve('https://github.com/foo/bar.git')
|
2019-09-30 22:31:55 +00:00
|
|
|
_(f).wont_be_nil
|
2019-11-18 18:20:35 +00:00
|
|
|
_(f).must_be_kind_of Inspec::Fetcher::Git
|
2018-11-08 20:55:15 +00:00
|
|
|
end
|
|
|
|
|
2021-03-22 12:50:37 +00:00
|
|
|
it 'handles sources specified by a :git key' do
|
|
|
|
f = fetcher.resolve({ git: 'https://example.com/foo.gi' })
|
2019-09-30 22:31:55 +00:00
|
|
|
_(f).wont_be_nil
|
2019-11-18 18:20:35 +00:00
|
|
|
_(f).must_be_kind_of Inspec::Fetcher::Git
|
2016-09-08 09:11:44 +00:00
|
|
|
end
|
|
|
|
|
2021-03-22 12:50:37 +00:00
|
|
|
describe 'when given a valid repository' do
|
|
|
|
let(:git_dep_dir) { 'test-directory' }
|
|
|
|
let(:git_master_ref) { 'bf4d5774f02d24155bfc34b5897d22785a304cfa' }
|
|
|
|
let(:git_branch_ref) { 'b979579e5fc8edb72511fe5d2a1230dede71eff7' }
|
|
|
|
let(:git_tag_ref) { 'efc85d89ee9d5798ca93ee95db0c711b99061590' }
|
2019-06-11 22:24:35 +00:00
|
|
|
let(:git_output) do
|
2019-07-09 00:20:30 +00:00
|
|
|
out = mock
|
2021-03-22 12:50:37 +00:00
|
|
|
out.stubs(:stdout).returns('')
|
2016-09-08 09:11:44 +00:00
|
|
|
out.stubs(:exitstatus).returns(0)
|
2021-03-22 12:50:37 +00:00
|
|
|
out.stubs(:stderr).returns('')
|
2016-09-08 09:11:44 +00:00
|
|
|
out.stubs(:status).returns(true)
|
|
|
|
out.stubs(:error!).returns(false)
|
|
|
|
out.stubs(:run_command).returns(true)
|
|
|
|
out
|
2019-06-11 22:24:35 +00:00
|
|
|
end
|
2016-09-08 09:11:44 +00:00
|
|
|
|
2019-06-11 22:24:35 +00:00
|
|
|
let(:git_ls_remote_output) do
|
2019-07-09 00:20:30 +00:00
|
|
|
out = mock
|
2016-09-08 09:11:44 +00:00
|
|
|
out.stubs(:stdout).returns("9abea97db10a428709353fd582b969d0e17cb923\tHEAD
|
|
|
|
bf4d5774f02d24155bfc34b5897d22785a304cfa\trefs/heads/master
|
|
|
|
b979579e5fc8edb72511fe5d2a1230dede71eff7\trefs/heads/somebranch
|
|
|
|
d9d5a6fe85c3df709bb1c878c2de8f2cb5893ced\trefs/tags/boringtag
|
|
|
|
ad280246a1a2b3d1b1179e1a8d9e1a044e7ee94f\trefs/tags/antag
|
|
|
|
efc85d89ee9d5798ca93ee95db0c711b99061590\trefs/tags/antag^{}
|
|
|
|
be002c56b0806ea40aabf7a2b742c41182336198\trefs/tags/anothertag
|
|
|
|
a7729ce65636d6d8b80159dd5dd7a40fdb6f2501\trefs/tags/anothertag^{}\n")
|
|
|
|
out.stubs(:exitstatus).returns(0)
|
2021-03-22 12:50:37 +00:00
|
|
|
out.stubs(:stderr).returns('')
|
|
|
|
out.stubs(:error!).returns(false)
|
|
|
|
out.stubs(:run_command).returns(true)
|
|
|
|
out
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:git_remote_head_master) do
|
|
|
|
out = mock
|
|
|
|
out.stubs(:stdout).returns("master\n")
|
|
|
|
out.stubs(:exitstatus).returns(0)
|
|
|
|
out.stubs(:stderr).returns('')
|
2016-09-08 09:11:44 +00:00
|
|
|
out.stubs(:error!).returns(false)
|
|
|
|
out.stubs(:run_command).returns(true)
|
|
|
|
out
|
2019-06-11 22:24:35 +00:00
|
|
|
end
|
2016-09-08 09:11:44 +00:00
|
|
|
|
|
|
|
before do
|
|
|
|
# git fetcher likes to make directories, let's stub that for every test
|
2021-03-22 12:50:37 +00:00
|
|
|
Dir.stubs(:mktmpdir).yields('test-tmp-dir')
|
|
|
|
File.stubs(:directory?).with('fetchpath/.git').returns(false)
|
2016-09-08 09:11:44 +00:00
|
|
|
FileUtils.stubs(:mkdir_p)
|
|
|
|
end
|
|
|
|
|
2021-03-22 12:50:37 +00:00
|
|
|
def expect_git_remote_head_master(remote_url)
|
|
|
|
Mixlib::ShellOut.expects(:new).with("git remote show #{remote_url} | grep 'HEAD branch' | cut -d ':' -f 2",
|
|
|
|
{}).returns(git_remote_head_master)
|
|
|
|
end
|
|
|
|
|
2016-09-08 09:11:44 +00:00
|
|
|
def expect_ls_remote(ref)
|
2021-03-22 12:50:37 +00:00
|
|
|
Mixlib::ShellOut.expects(:new).with("git ls-remote \"#{git_dep_dir}\" \"#{ref}*\"",
|
|
|
|
{}).returns(git_ls_remote_output)
|
2016-09-08 09:11:44 +00:00
|
|
|
end
|
|
|
|
|
2021-03-22 12:50:37 +00:00
|
|
|
def expect_checkout(ref, at = 'test-tmp-dir')
|
2019-06-11 22:24:35 +00:00
|
|
|
Mixlib::ShellOut.expects(:new).with("git checkout #{ref}", { cwd: at }).returns(git_output)
|
2016-09-08 09:11:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def expect_clone
|
2021-03-22 12:50:37 +00:00
|
|
|
Mixlib::ShellOut.expects(:new).with("git clone #{git_dep_dir} ./", { cwd: 'test-tmp-dir' }).returns(git_output)
|
2016-09-08 09:11:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def expect_mv_into_place
|
2021-03-22 12:50:37 +00:00
|
|
|
FileUtils.expects(:cp_r).with('test-tmp-dir/.', 'fetchpath')
|
2016-09-08 09:11:44 +00:00
|
|
|
end
|
|
|
|
|
2021-03-22 12:50:37 +00:00
|
|
|
it 'resolves to the revision of master when head branch master' do
|
|
|
|
expect_git_remote_head_master(git_dep_dir)
|
|
|
|
expect_ls_remote('master')
|
2019-06-11 22:24:35 +00:00
|
|
|
result = fetcher.resolve({ git: git_dep_dir })
|
2019-09-30 22:31:55 +00:00
|
|
|
_(result.resolved_source).must_equal({ git: git_dep_dir, ref: git_master_ref })
|
2016-09-08 09:11:44 +00:00
|
|
|
end
|
|
|
|
|
2021-03-22 12:50:37 +00:00
|
|
|
it 'can resolve a tag' do
|
|
|
|
expect_ls_remote('antag')
|
|
|
|
result = fetcher.resolve({ git: git_dep_dir, tag: 'antag' })
|
2019-09-30 22:31:55 +00:00
|
|
|
_(result.resolved_source).must_equal({ git: git_dep_dir, ref: git_tag_ref })
|
2016-09-08 09:11:44 +00:00
|
|
|
end
|
|
|
|
|
2021-03-22 12:50:37 +00:00
|
|
|
it 'can resolve a branch' do
|
|
|
|
expect_ls_remote('somebranch')
|
|
|
|
result = fetcher.resolve({ git: git_dep_dir, branch: 'somebranch' })
|
2019-09-30 22:31:55 +00:00
|
|
|
_(result.resolved_source).must_equal({ git: git_dep_dir, ref: git_branch_ref })
|
2016-09-08 09:11:44 +00:00
|
|
|
end
|
|
|
|
|
2021-03-22 12:50:37 +00:00
|
|
|
it 'assumes the ref you gave it is the thing you want' do
|
|
|
|
result = fetcher.resolve({ git: git_dep_dir, ref: 'a_test_ref' })
|
|
|
|
_(result.resolved_source).must_equal({ git: git_dep_dir, ref: 'a_test_ref' })
|
2016-09-08 09:11:44 +00:00
|
|
|
end
|
|
|
|
|
2021-03-22 12:50:37 +00:00
|
|
|
it 'fetches to the given location' do
|
|
|
|
expect_git_remote_head_master(git_dep_dir)
|
|
|
|
expect_ls_remote('master')
|
2019-07-09 00:20:30 +00:00
|
|
|
expect_clone
|
2016-09-08 09:11:44 +00:00
|
|
|
expect_checkout(git_master_ref)
|
2019-07-09 00:20:30 +00:00
|
|
|
expect_mv_into_place
|
2019-06-11 22:24:35 +00:00
|
|
|
result = fetcher.resolve({ git: git_dep_dir })
|
2021-03-22 12:50:37 +00:00
|
|
|
result.fetch('fetchpath')
|
2016-09-08 09:11:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it "doesn't refetch an already cloned repo" do
|
2021-03-22 12:50:37 +00:00
|
|
|
File.expects(:directory?).with('fetchpath/.git').at_least_once.returns(true)
|
|
|
|
expect_git_remote_head_master(git_dep_dir)
|
|
|
|
expect_ls_remote('master')
|
|
|
|
expect_checkout(git_master_ref, 'fetchpath')
|
2019-06-11 22:24:35 +00:00
|
|
|
result = fetcher.resolve({ git: git_dep_dir })
|
2021-03-22 12:50:37 +00:00
|
|
|
result.fetch('fetchpath')
|
2016-09-08 09:11:44 +00:00
|
|
|
end
|
|
|
|
|
2021-03-22 12:50:37 +00:00
|
|
|
it 'returns the repo_path that we fetched to as the archive_path' do
|
|
|
|
File.expects(:directory?).with('fetchpath/.git').at_least_once.returns(true)
|
|
|
|
expect_git_remote_head_master(git_dep_dir)
|
|
|
|
expect_ls_remote('master')
|
|
|
|
expect_checkout(git_master_ref, 'fetchpath')
|
2019-06-11 22:24:35 +00:00
|
|
|
result = fetcher.resolve({ git: git_dep_dir })
|
2021-03-22 12:50:37 +00:00
|
|
|
result.fetch('fetchpath')
|
|
|
|
_(result.archive_path).must_equal 'fetchpath'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'when given a repository with default branch main' do
|
|
|
|
let(:git_default_main) { 'inspec-test-profile-default-main' }
|
|
|
|
let(:git_main_ref) { '69220a2ba6a3b276184f328e69a953e83e283323' }
|
|
|
|
|
|
|
|
let(:git_remote_head_main) do
|
|
|
|
out = mock
|
|
|
|
out.stubs(:stdout).returns("main\n")
|
|
|
|
out.stubs(:exitstatus).returns(0)
|
|
|
|
out.stubs(:stderr).returns('')
|
|
|
|
out.stubs(:error!).returns(false)
|
|
|
|
out.stubs(:run_command).returns(true)
|
|
|
|
out
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:git_ls_remote_output_for_main) do
|
|
|
|
out = mock
|
|
|
|
out.stubs(:stdout).returns("69220a2ba6a3b276184f328e69a953e83e283323\trefs/heads/main")
|
|
|
|
out.stubs(:exitstatus).returns(0)
|
|
|
|
out.stubs(:stderr).returns('')
|
|
|
|
out.stubs(:error!).returns(false)
|
|
|
|
out.stubs(:run_command).returns(true)
|
|
|
|
out
|
|
|
|
end
|
|
|
|
|
|
|
|
def expect_git_remote_head_main(remote_url)
|
|
|
|
Mixlib::ShellOut.expects(:new).with("git remote show #{remote_url} | grep 'HEAD branch' | cut -d ':' -f 2",
|
|
|
|
{}).returns(git_remote_head_main)
|
|
|
|
end
|
|
|
|
|
|
|
|
def expect_ls_remote(ref)
|
|
|
|
Mixlib::ShellOut.expects(:new).with("git ls-remote \"#{git_default_main}\" \"#{ref}*\"",
|
|
|
|
{}).returns(git_ls_remote_output_for_main)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'resolves to the revision of main when head branch main' do
|
|
|
|
expect_git_remote_head_main(git_default_main)
|
|
|
|
expect_ls_remote('main')
|
|
|
|
result = fetcher.resolve({ git: git_default_main })
|
|
|
|
_(result.resolved_source).must_equal({ git: git_default_main, ref: git_main_ref })
|
2016-09-08 09:11:44 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|