diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-15 12:09:18 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-15 12:09:18 +0000 |
commit | b7c735c8ac11b8182807070fc6f84f2606e15427 (patch) | |
tree | e74b4d25abb8bbf23546f001dd94515e2840a3a3 /app/services/discussions | |
parent | 221b529789f4090341a825695aeb49b8df6dd11d (diff) | |
download | gitlab-ce-b7c735c8ac11b8182807070fc6f84f2606e15427.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/services/discussions')
-rw-r--r-- | app/services/discussions/capture_diff_note_position_service.rb | 65 | ||||
-rw-r--r-- | app/services/discussions/capture_diff_note_positions_service.rb | 34 |
2 files changed, 99 insertions, 0 deletions
diff --git a/app/services/discussions/capture_diff_note_position_service.rb b/app/services/discussions/capture_diff_note_position_service.rb new file mode 100644 index 00000000000..273a60f7e55 --- /dev/null +++ b/app/services/discussions/capture_diff_note_position_service.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +module Discussions + class CaptureDiffNotePositionService + def initialize(merge_request, paths) + @project = merge_request.project + @tracer = build_tracer(merge_request, paths) + end + + def execute(discussion) + # The service has been implemented for text only + # The impact of image notes on this service is being investigated in + # https://gitlab.com/gitlab-org/gitlab/-/issues/213989 + return unless discussion.on_text? + + result = tracer&.trace(discussion.position) + return unless result + + position = result[:position] + + # Currently position data is copied across all notes of a discussion + # It makes sense to store a position only for the first note instead + # Within the newly introduced table we can start doing just that + DiffNotePosition.create_or_update_for(discussion.notes.first, + diff_type: :head, + position: position, + line_code: position.line_code(project.repository)) + end + + private + + attr_reader :tracer, :project + + def build_tracer(merge_request, paths) + return if paths.blank? + + old_diff_refs, new_diff_refs = build_diff_refs(merge_request) + + return unless old_diff_refs && new_diff_refs + + Gitlab::Diff::PositionTracer.new( + project: project, + old_diff_refs: old_diff_refs, + new_diff_refs: new_diff_refs, + paths: paths.uniq) + end + + def build_diff_refs(merge_request) + merge_ref_head = merge_request.merge_ref_head + return unless merge_ref_head + + start_sha, base_sha = merge_ref_head.parent_ids + new_diff_refs = Gitlab::Diff::DiffRefs.new( + base_sha: base_sha, + start_sha: start_sha, + head_sha: merge_ref_head.id) + + old_diff_refs = merge_request.diff_refs + + return if new_diff_refs == old_diff_refs + + [old_diff_refs, new_diff_refs] + end + end +end diff --git a/app/services/discussions/capture_diff_note_positions_service.rb b/app/services/discussions/capture_diff_note_positions_service.rb new file mode 100644 index 00000000000..3684a3f679a --- /dev/null +++ b/app/services/discussions/capture_diff_note_positions_service.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Discussions + class CaptureDiffNotePositionsService + def initialize(merge_request) + @merge_request = merge_request + end + + def execute + return unless merge_request.has_complete_diff_refs? + + discussions, paths = build_discussions + + service = Discussions::CaptureDiffNotePositionService.new(merge_request, paths) + + discussions.each do |discussion| + service.execute(discussion) + end + end + + private + + attr_reader :merge_request + + def build_discussions + active_diff_discussions = merge_request.notes.new_diff_notes.discussions.select do |discussion| + discussion.active?(merge_request.diff_refs) + end + paths = active_diff_discussions.flat_map { |n| n.diff_file.paths } + + [active_diff_discussions, paths] + end + end +end |