summaryrefslogtreecommitdiff
path: root/app/models/suggestion.rb
diff options
context:
space:
mode:
authorOswaldo Ferreira <oswaldo@gitlab.com>2018-12-13 19:17:19 +0000
committerPhil Hughes <me@iamphill.com>2018-12-13 19:17:19 +0000
commited3034bbb71d43b12944a9da29b5264cb3ff3312 (patch)
tree3110713f4455a4b3a830e177422663e082fc0eb9 /app/models/suggestion.rb
parenteb81c1239ef86561b4304339609be32318419dbb (diff)
downloadgitlab-ce-ed3034bbb71d43b12944a9da29b5264cb3ff3312.tar.gz
Allow suggesting single line changes in diffs
Diffstat (limited to 'app/models/suggestion.rb')
-rw-r--r--app/models/suggestion.rb61
1 files changed, 61 insertions, 0 deletions
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