Commit 7582bc8b authored by Bob Van Landuyt's avatar Bob Van Landuyt

Unlink a project from a fork network when it's source was deleted.

We need to close all merge requests coming from the project within the
entire fork network.
parent 39d00bdd
...@@ -12,4 +12,8 @@ class ForkNetwork < ActiveRecord::Base ...@@ -12,4 +12,8 @@ class ForkNetwork < ActiveRecord::Base
def find_forks_in(other_projects) def find_forks_in(other_projects)
projects.where(id: other_projects) projects.where(id: other_projects)
end end
def merge_requests
MergeRequest.where(target_project: projects)
end
end end
...@@ -3,18 +3,24 @@ module Projects ...@@ -3,18 +3,24 @@ module Projects
def execute def execute
return unless @project.forked? return unless @project.forked?
@project.forked_from_project.lfs_objects.find_each do |lfs_object| if fork_source = @project.fork_source
lfs_object.projects << @project fork_source.lfs_objects.find_each do |lfs_object|
lfs_object.projects << @project
end
refresh_forks_count(fork_source)
end end
merge_requests = @project.forked_from_project.merge_requests.opened.from_project(@project) merge_requests = @project.fork_network
.merge_requests
.opened
.where.not(target_project: @project)
.from_project(@project)
merge_requests.each do |mr| merge_requests.each do |mr|
::MergeRequests::CloseService.new(@project, @current_user).execute(mr) ::MergeRequests::CloseService.new(@project, @current_user).execute(mr)
end end
refresh_forks_count(@project.forked_from_project)
@project.fork_network_member.destroy @project.fork_network_member.destroy
@project.forked_project_link.destroy @project.forked_project_link.destroy
end end
......
...@@ -24,6 +24,16 @@ describe ForkNetwork do ...@@ -24,6 +24,16 @@ describe ForkNetwork do
end end
end end
describe '#merge_requests' do
it 'finds merge requests within the fork network' do
project = create(:project)
forked_project = fork_project(project)
merge_request = create(:merge_request, source_project: forked_project, target_project: project)
expect(project.fork_network.merge_requests).to include(merge_request)
end
end
context 'for a deleted project' do context 'for a deleted project' do
it 'keeps the fork network' do it 'keeps the fork network' do
project = create(:project, :public) project = create(:project, :public)
......
...@@ -12,6 +12,9 @@ describe Projects::UnlinkForkService do ...@@ -12,6 +12,9 @@ describe Projects::UnlinkForkService do
context 'with opened merge request on the source project' do context 'with opened merge request on the source project' do
let(:merge_request) { create(:merge_request, source_project: forked_project, target_project: fork_link.forked_from_project) } let(:merge_request) { create(:merge_request, source_project: forked_project, target_project: fork_link.forked_from_project) }
let(:merge_request2) { create(:merge_request, source_project: forked_project, target_project: fork_project(project)) }
let(:merge_request_in_fork) { create(:merge_request, source_project: forked_project, target_project: forked_project) }
let(:mr_close_service) { MergeRequests::CloseService.new(forked_project, user) } let(:mr_close_service) { MergeRequests::CloseService.new(forked_project, user) }
before do before do
...@@ -22,9 +25,14 @@ describe Projects::UnlinkForkService do ...@@ -22,9 +25,14 @@ describe Projects::UnlinkForkService do
it 'close all pending merge requests' do it 'close all pending merge requests' do
expect(mr_close_service).to receive(:execute).with(merge_request) expect(mr_close_service).to receive(:execute).with(merge_request)
expect(mr_close_service).to receive(:execute).with(merge_request2)
subject.execute subject.execute
end end
it 'does not close merge requests for the project being unlinked' do
expect(mr_close_service).not_to receive(:execute).with(merge_request_in_fork)
end
end end
it 'remove fork relation' do it 'remove fork relation' do
...@@ -53,4 +61,14 @@ describe Projects::UnlinkForkService do ...@@ -53,4 +61,14 @@ describe Projects::UnlinkForkService do
expect(source.forks_count).to be_zero expect(source.forks_count).to be_zero
end end
context 'when the original project was deleted' do
it 'does not fail when the original project is deleted' do
source = forked_project.forked_from_project
source.destroy
forked_project.reload
expect { subject.execute }.not_to raise_error
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