From 419d8cc7a2d0e5ffd2f3f8894a739827d0c2c549 Mon Sep 17 00:00:00 2001 From: Grzegorz Bizon Date: Fri, 28 Sep 2018 15:13:04 +0200 Subject: [PATCH] Calculate modified paths of a git push operation --- lib/gitlab/git/diff_stats_collection.rb | 4 ++ lib/gitlab/git/push.rb | 14 ++++++ .../gitlab/git/diff_stats_collection_spec.rb | 8 ++- spec/lib/gitlab/git/push_spec.rb | 49 ++++++++++++++++++- 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/lib/gitlab/git/diff_stats_collection.rb b/lib/gitlab/git/diff_stats_collection.rb index d4033f56387..998c41497a2 100644 --- a/lib/gitlab/git/diff_stats_collection.rb +++ b/lib/gitlab/git/diff_stats_collection.rb @@ -18,6 +18,10 @@ module Gitlab indexed_by_path[path] end + def paths + @collection.map(&:path) + end + private def indexed_by_path diff --git a/lib/gitlab/git/push.rb b/lib/gitlab/git/push.rb index b6e414927ea..603f860e4f8 100644 --- a/lib/gitlab/git/push.rb +++ b/lib/gitlab/git/push.rb @@ -28,6 +28,10 @@ module Gitlab Gitlab::Git.blank_ref?(@newrev) end + def branch_updated? + branch_push? && !branch_added? && !branch_removed? + end + def force_push? Gitlab::Checks::ForcePush.force_push?(@project, @oldrev, @newrev) end @@ -37,6 +41,16 @@ module Gitlab Gitlab::Git.branch_ref?(@ref) end end + + def modified_paths + unless branch_updated? + raise ArgumentError, 'Unable to calculate modified paths!' + end + + strong_memoize(:modified_paths) do + @project.repository.diff_stats(@oldrev, @newrev).paths + end + end end end end diff --git a/spec/lib/gitlab/git/diff_stats_collection_spec.rb b/spec/lib/gitlab/git/diff_stats_collection_spec.rb index 89927cbb3a6..b07690ef39c 100644 --- a/spec/lib/gitlab/git/diff_stats_collection_spec.rb +++ b/spec/lib/gitlab/git/diff_stats_collection_spec.rb @@ -14,7 +14,7 @@ describe Gitlab::Git::DiffStatsCollection do let(:diff_stats) { [stats_a, stats_b] } let(:collection) { described_class.new(diff_stats) } - describe '.find_by_path' do + describe '#find_by_path' do it 'returns stats by path when found' do expect(collection.find_by_path('foo')).to eq(stats_a) end @@ -23,4 +23,10 @@ describe Gitlab::Git::DiffStatsCollection do expect(collection.find_by_path('no-file')).to be_nil end end + + describe '#paths' do + it 'returns only modified paths' do + expect(collection.paths).to eq %w[foo bar] + end + end end diff --git a/spec/lib/gitlab/git/push_spec.rb b/spec/lib/gitlab/git/push_spec.rb index c87e972f31a..f19e05c4451 100644 --- a/spec/lib/gitlab/git/push_spec.rb +++ b/spec/lib/gitlab/git/push_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe Gitlab::Git::Push do set(:project) { create(:project, :repository) } - let(:oldrev) { project.commit('HEAD~10').id } + let(:oldrev) { project.commit('HEAD~2').id } let(:newrev) { project.commit.id } let(:ref) { 'refs/heads/some-branch' } @@ -35,12 +35,36 @@ describe Gitlab::Git::Push do end context 'when it is a tag push' do - let(:ref) { 'refs/tags/my-branch' } + let(:ref) { 'refs/tags/my-tag' } it { is_expected.not_to be_branch_push } end end + describe '#branch_updated?' do + context 'when it is a branch push with correct old and new revisions' do + it { is_expected.to be_branch_updated } + end + + context 'when it is not a branch push' do + let(:ref) { 'refs/tags/my-tag' } + + it { is_expected.not_to be_branch_updated } + end + + context 'when old revision is blank' do + let(:oldrev) { Gitlab::Git::BLANK_SHA } + + it { is_expected.not_to be_branch_updated } + end + + context 'when it is not a branch push' do + let(:newrev) { Gitlab::Git::BLANK_SHA } + + it { is_expected.not_to be_branch_updated } + end + end + describe '#force_push?' do context 'when old revision is an ancestor of the new revision' do let(:oldrev) { 'HEAD~3' } @@ -80,4 +104,25 @@ describe Gitlab::Git::Push do it { is_expected.to be_branch_removed } end end + + describe '#modified_paths' do + context 'when a push is a branch update' do + let(:oldrev) { '281d3a76f31c812dbf48abce82ccf6860adedd81' } + let(:new_rev) { '1b12f15a11fc6e62177bef08f47bc7b5ce50b141' } + + it 'returns modified paths' do + expect(subject.modified_paths).to eq ['bar/branch-test.txt', + 'files/js/commit.coffee', + 'with space/README.md'] + end + end + + context 'when a push is not a branch update' do + let(:oldrev) { Gitlab::Git::BLANK_SHA } + + it 'raises an error' do + expect { subject.modified_paths }.to raise_error(ArgumentError) + end + end + end end