Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/models')
-rw-r--r--app/models/concerns/noteable.rb4
-rw-r--r--app/models/diff_note.rb13
-rw-r--r--app/models/merge_request.rb5
-rw-r--r--app/models/note.rb12
-rw-r--r--app/models/suggestion.rb61
5 files changed, 94 insertions, 1 deletions
diff --git a/app/models/concerns/noteable.rb b/app/models/concerns/noteable.rb
index eb315058c3a..f2cad09e779 100644
--- a/app/models/concerns/noteable.rb
+++ b/app/models/concerns/noteable.rb
@@ -26,6 +26,10 @@ module Noteable
DiscussionNote.noteable_types.include?(base_class_name)
end
+ def supports_suggestion?
+ false
+ end
+
def discussions_rendered_on_frontend?
false
end
diff --git a/app/models/diff_note.rb b/app/models/diff_note.rb
index c32008aa9c7..279603496b0 100644
--- a/app/models/diff_note.rb
+++ b/app/models/diff_note.rb
@@ -66,10 +66,23 @@ class DiffNote < Note
self.original_position.diff_refs == diff_refs
end
+ def supports_suggestion?
+ return false unless noteable.supports_suggestion? && on_text?
+ # We don't want to trigger side-effects of `diff_file` call.
+ return false unless file = fetch_diff_file
+ return false unless line = file.line_for_position(self.original_position)
+
+ line&.suggestible?
+ end
+
def discussion_first_note?
self == discussion.first_note
end
+ def banzai_render_context(field)
+ super.merge(suggestions_filter_enabled: supports_suggestion?)
+ end
+
private
def enqueue_diff_file_creation_job
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index a13cac73d04..8052a54c504 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -363,6 +363,11 @@ class MergeRequest < ActiveRecord::Base
end
end
+ def supports_suggestion?
+ # Should be `true` when removing the FF.
+ Suggestion.feature_enabled?
+ end
+
# Calls `MergeWorker` to proceed with the merge process and
# updates `merge_jid` with the MergeWorker#jid.
# This helps tracking enqueued and ongoing merge jobs.
diff --git a/app/models/note.rb b/app/models/note.rb
index 17c7d97fa0a..becf14e9785 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -69,6 +69,12 @@ class Note < ActiveRecord::Base
belongs_to :last_edited_by, class_name: 'User'
has_many :todos
+
+ # The delete_all definition is required here in order
+ # to generate the correct DELETE sql for
+ # suggestions.delete_all calls
+ has_many :suggestions, -> { order(:relative_order) },
+ inverse_of: :note, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
has_many :events, as: :target, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
has_one :system_note_metadata
has_one :note_diff_file, inverse_of: :diff_note, foreign_key: :diff_note_id
@@ -110,7 +116,7 @@ class Note < ActiveRecord::Base
scope :inc_author, -> { includes(:author) }
scope :inc_relations_for_view, -> do
includes(:project, { author: :status }, :updated_by, :resolved_by, :award_emoji,
- :system_note_metadata, :note_diff_file)
+ :system_note_metadata, :note_diff_file, :suggestions)
end
scope :with_notes_filter, -> (notes_filter) do
@@ -226,6 +232,10 @@ class Note < ActiveRecord::Base
Gitlab::HookData::NoteBuilder.new(self).build
end
+ def supports_suggestion?
+ false
+ end
+
def for_commit?
noteable_type == "Commit"
end
diff --git a/app/models/suggestion.rb b/app/models/suggestion.rb
new file mode 100644
index 00000000000..cec5ea30f9d
--- /dev/null
+++ b/app/models/suggestion.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+class Suggestion < ApplicationRecord
+ FEATURE_FLAG = :diff_suggestions
+
+ belongs_to :note, inverse_of: :suggestions
+ validates :note, presence: true
+ validates :commit_id, presence: true, if: :applied?
+
+ delegate :original_position, :position, :diff_file,
+ :noteable, to: :note
+
+ def self.feature_enabled?
+ Feature.enabled?(FEATURE_FLAG)
+ end
+
+ def project
+ noteable.source_project
+ end
+
+ def branch
+ noteable.source_branch
+ end
+
+ # For now, suggestions only serve as a way to send patches that
+ # will change a single line (being able to apply multiple in the same place),
+ # which explains `from_line` and `to_line` being the same line.
+ # We'll iterate on that in https://gitlab.com/gitlab-org/gitlab-ce/issues/53310
+ # when allowing multi-line suggestions.
+ def from_line
+ position.new_line
+ end
+ alias_method :to_line, :from_line
+
+ def from_original_line
+ original_position.new_line
+ end
+ alias_method :to_original_line, :from_original_line
+
+ # `from_line_index` and `to_line_index` represents diff/blob line numbers in
+ # index-like way (N-1).
+ def from_line_index
+ from_line - 1
+ end
+ alias_method :to_line_index, :from_line_index
+
+ def appliable?
+ return false unless note.supports_suggestion?
+
+ !applied? &&
+ noteable.opened? &&
+ different_content? &&
+ note.active?
+ end
+
+ private
+
+ def different_content?
+ from_content != to_content
+ end
+end