diff options
author | Oswaldo Ferreira <oswaldo@gitlab.com> | 2019-03-15 20:35:34 +0300 |
---|---|---|
committer | Oswaldo Ferreira <oswaldo@gitlab.com> | 2019-03-27 18:26:53 +0300 |
commit | 03e0604d5ded6402c7fddc4001ab23d9712c98de (patch) | |
tree | 33cf57e25d71e9a9c0ab39149cbcb285f0f05a31 /lib | |
parent | 1db3926dd2a5de719859ea962d4e1360b375d87b (diff) |
Prepare suggestion implementation for multi-line
Adds the groundwork needed in order to persist multi-line suggestions,
while providing the parsing strategy which will be reused for the
**Preview** as well.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/entities.rb | 2 | ||||
-rw-r--r-- | lib/banzai/suggestions_parser.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/diff/suggestion.rb | 52 | ||||
-rw-r--r-- | lib/gitlab/diff/suggestions_parser.rb | 41 | ||||
-rw-r--r-- | lib/gitlab/import_export/import_export.yml | 1 |
5 files changed, 96 insertions, 2 deletions
diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 6fd267ff2ed..0871ea8d21e 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -1558,8 +1558,6 @@ module API class Suggestion < Grape::Entity expose :id - expose :from_original_line - expose :to_original_line expose :from_line expose :to_line expose :appliable?, as: :appliable diff --git a/lib/banzai/suggestions_parser.rb b/lib/banzai/suggestions_parser.rb index 09f36635020..0d7f751bfc1 100644 --- a/lib/banzai/suggestions_parser.rb +++ b/lib/banzai/suggestions_parser.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +# TODO: Delete when https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/26107 +# exchange this parser by `Gitlab::Diff::SuggestionsParser`. module Banzai module SuggestionsParser # Returns the content of each suggestion code block. diff --git a/lib/gitlab/diff/suggestion.rb b/lib/gitlab/diff/suggestion.rb new file mode 100644 index 00000000000..027c7a31bcf --- /dev/null +++ b/lib/gitlab/diff/suggestion.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module Gitlab + module Diff + class Suggestion + include Suggestible + include Gitlab::Utils::StrongMemoize + + attr_reader :diff_file, :lines_above, :lines_below, + :target_line + + def initialize(text, line:, above:, below:, diff_file:) + @text = text + @target_line = line + @lines_above = above.to_i + @lines_below = below.to_i + @diff_file = diff_file + end + + def to_hash + { + from_content: from_content, + to_content: to_content, + lines_above: @lines_above, + lines_below: @lines_below + } + end + + def from_content + strong_memoize(:from_content) do + fetch_from_content + end + end + + def to_content + # The parsed suggestion doesn't have information about the correct + # ending characters (we may have a line break, or not), so we take + # this information from the last line being changed (last + # characters). + endline_chars = line_break_chars(from_content.lines.last) + "#{@text}#{endline_chars}" + end + + private + + def line_break_chars(line) + match = /\r\n|\r|\n/.match(line) + match[0] if match + end + end + end +end diff --git a/lib/gitlab/diff/suggestions_parser.rb b/lib/gitlab/diff/suggestions_parser.rb index 043bd9a4bcb..c8c03d5d001 100644 --- a/lib/gitlab/diff/suggestions_parser.rb +++ b/lib/gitlab/diff/suggestions_parser.rb @@ -5,6 +5,47 @@ module Gitlab class SuggestionsParser # Matches for instance "-1", "+1" or "-1+2". SUGGESTION_CONTEXT = /^(\-(?<above>\d+))?(\+(?<below>\d+))?$/.freeze + + class << self + # Returns an array of Gitlab::Diff::Suggestion which represents each + # suggestion in the given text. + # + def parse(text, position:, project:) + return [] unless position.complete? + + html = Banzai.render(text, project: nil, no_original_data: true) + doc = Nokogiri::HTML(html) + suggestion_nodes = doc.search('pre.suggestion') + + return [] if suggestion_nodes.empty? + + diff_file = position.diff_file(project.repository) + + suggestion_nodes.map do |node| + lang_param = node['data-lang-params'] + + lines_above, lines_below = nil + + if lang_param && suggestion_params = fetch_suggestion_params(lang_param) + lines_above, lines_below = + suggestion_params[:above], + suggestion_params[:below] + end + + Gitlab::Diff::Suggestion.new(node.text, + line: position.new_line, + above: lines_above.to_i, + below: lines_below.to_i, + diff_file: diff_file) + end + end + + private + + def fetch_suggestion_params(lang_param) + lang_param.match(SUGGESTION_CONTEXT) + end + end end end end diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml index a0aab9fcbaf..89667976217 100644 --- a/lib/gitlab/import_export/import_export.yml +++ b/lib/gitlab/import_export/import_export.yml @@ -33,6 +33,7 @@ project_tree: - :user - merge_requests: - :metrics + - :suggestions - notes: - :author - events: |