Commit ae88355b authored by Rémy Coutable's avatar Rémy Coutable

Retrieve Git-specific env in Gitlab::Git::RevList and add a new #new_refs method

Signed-off-by: default avatarRémy Coutable <remy@rymai.me>
parent cb20cfa2
...@@ -8,13 +8,9 @@ module Gitlab ...@@ -8,13 +8,9 @@ module Gitlab
if Gitlab::Git.blank_ref?(oldrev) || Gitlab::Git.blank_ref?(newrev) if Gitlab::Git.blank_ref?(oldrev) || Gitlab::Git.blank_ref?(newrev)
false false
else else
missed_ref, exit_status = Gitlab::Git::RevList.new(oldrev, newrev, project: project, env: env).execute Gitlab::Git::RevList.new(
path_to_repo: project.repository.path_to_repo,
if exit_status == 0 oldrev: oldrev, newrev: newrev).missed_ref.present?
missed_ref.present?
else
raise "Got a non-zero exit code while calling out to `git rev-list` in the force-push check."
end
end end
end end
end end
......
module Gitlab module Gitlab
module Git module Git
class RevList class RevList
attr_reader :project, :env attr_reader :oldrev, :newrev, :path_to_repo
ALLOWED_VARIABLES = %w[GIT_OBJECT_DIRECTORY GIT_ALTERNATE_OBJECT_DIRECTORIES].freeze def initialize(path_to_repo:, newrev:, oldrev: nil)
@oldrev = oldrev
def initialize(oldrev, newrev, project:, env: nil) @newrev = newrev
@project = project @path_to_repo = path_to_repo
@env = env.presence || {}
@args = [Gitlab.config.git.bin_path,
"--git-dir=#{project.repository.path_to_repo}",
"rev-list",
"--max-count=1",
oldrev,
"^#{newrev}"]
end end
def execute # This method returns an array of new references
Gitlab::Popen.popen(@args, nil, parse_environment_variables) def new_refs
execute([*base_args, newrev, '--not', '--all'])
end end
def valid? # This methods returns an array of missed references
environment_variables.all? do |(name, value)| def missed_ref
value.to_s.start_with?(project.repository.path_to_repo) execute([*base_args, '--max-count=1', oldrev, "^#{newrev}"])
end
end end
private private
def parse_environment_variables def execute(args)
return {} unless valid? output, status = Gitlab::Popen.popen(args, nil, Gitlab::Git::Env.all.stringify_keys)
unless status.zero?
raise "Got a non-zero exit code while calling out `#{args.join(' ')}`."
end
environment_variables output.split("\n")
end end
def environment_variables def base_args
@environment_variables ||= env.slice(*ALLOWED_VARIABLES).compact [
Gitlab.config.git.bin_path,
"--git-dir=#{path_to_repo}",
'rev-list'
]
end end
end end
end end
......
...@@ -3,58 +3,54 @@ require 'spec_helper' ...@@ -3,58 +3,54 @@ require 'spec_helper'
describe Gitlab::Git::RevList, lib: true do describe Gitlab::Git::RevList, lib: true do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
context "validations" do before do
described_class::ALLOWED_VARIABLES.each do |var| expect(Gitlab::Git::Env).to receive(:all).and_return({
context var do GIT_OBJECT_DIRECTORY: 'foo',
it "accepts values starting with the project repo path" do GIT_ALTERNATE_OBJECT_DIRECTORIES: 'bar'
env = { var => "#{project.repository.path_to_repo}/objects" } })
rev_list = described_class.new('oldrev', 'newrev', project: project, env: env)
expect(rev_list).to be_valid
end
it "rejects values starting not with the project repo path" do
env = { var => "/some/other/path" }
rev_list = described_class.new('oldrev', 'newrev', project: project, env: env)
expect(rev_list).not_to be_valid
end
it "rejects values containing the project repo path but not starting with it" do
env = { var => "/some/other/path/#{project.repository.path_to_repo}" }
rev_list = described_class.new('oldrev', 'newrev', project: project, env: env)
expect(rev_list).not_to be_valid
end
it "ignores nil values" do
env = { var => nil }
rev_list = described_class.new('oldrev', 'newrev', project: project, env: env)
expect(rev_list).to be_valid
end
end
end
end end
context "#execute" do context "#new_refs" do
let(:env) { { "GIT_OBJECT_DIRECTORY" => project.repository.path_to_repo } } let(:rev_list) { Gitlab::Git::RevList.new(newrev: 'newrev', path_to_repo: project.repository.path_to_repo) }
let(:rev_list) { Gitlab::Git::RevList.new('oldrev', 'newrev', project: project, env: env) }
it 'calls out to `popen`' do
it "calls out to `popen` without environment variables if the record is invalid" do expect(Gitlab::Popen).to receive(:popen).with([
allow(rev_list).to receive(:valid?).and_return(false) Gitlab.config.git.bin_path,
"--git-dir=#{project.repository.path_to_repo}",
expect(Open3).to receive(:popen3).with(hash_excluding(env), any_args) 'rev-list',
'newrev',
rev_list.execute '--not',
'--all'
],
nil,
{
'GIT_OBJECT_DIRECTORY' => 'foo',
'GIT_ALTERNATE_OBJECT_DIRECTORIES' => 'bar'
}).and_return(["sha1\nsha2", 0])
expect(rev_list.new_refs).to eq(%w[sha1 sha2])
end end
end
it "calls out to `popen` with environment variables if the record is valid" do context "#missed_ref" do
allow(rev_list).to receive(:valid?).and_return(true) let(:rev_list) { Gitlab::Git::RevList.new(oldrev: 'oldrev', newrev: 'newrev', path_to_repo: project.repository.path_to_repo) }
expect(Open3).to receive(:popen3).with(hash_including(env), any_args) it 'calls out to `popen`' do
expect(Gitlab::Popen).to receive(:popen).with([
rev_list.execute Gitlab.config.git.bin_path,
"--git-dir=#{project.repository.path_to_repo}",
'rev-list',
'--max-count=1',
'oldrev',
'^newrev'
],
nil,
{
'GIT_OBJECT_DIRECTORY' => 'foo',
'GIT_ALTERNATE_OBJECT_DIRECTORIES' => 'bar'
}).and_return(["sha1\nsha2", 0])
expect(rev_list.missed_ref).to eq(%w[sha1 sha2])
end end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment