diff options
author | Phil Hughes <me@iamphill.com> | 2018-12-13 19:17:19 +0000 |
---|---|---|
committer | John Jarvis <jarv@gitlab.com> | 2018-12-14 13:11:14 +0100 |
commit | f151556e331d46a2bc190a5fbeaf5e967eb8397b (patch) | |
tree | 64b65ebd21985170b32a39342a63c62eff17f942 /lib | |
parent | 73518d57bb46c0756fc2aa92bfdba3438425fdb6 (diff) | |
download | gitlab-ce-f151556e331d46a2bc190a5fbeaf5e967eb8397b.tar.gz |
Merge branch 'osw-suggest-diff-line-change' into 'master'
Allow suggesting single line changes in diffs
See merge request gitlab-org/gitlab-ce!23147
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/api.rb | 1 | ||||
-rw-r--r-- | lib/api/entities.rb | 12 | ||||
-rw-r--r-- | lib/api/suggestions.rb | 31 | ||||
-rw-r--r-- | lib/banzai/filter/suggestion_filter.rb | 25 | ||||
-rw-r--r-- | lib/banzai/filter/syntax_highlight_filter.rb | 2 | ||||
-rw-r--r-- | lib/banzai/pipeline/gfm_pipeline.rb | 1 | ||||
-rw-r--r-- | lib/banzai/pipeline/post_process_pipeline.rb | 3 | ||||
-rw-r--r-- | lib/banzai/suggestions_parser.rb | 14 | ||||
-rw-r--r-- | lib/gitlab/diff/file.rb | 10 | ||||
-rw-r--r-- | lib/gitlab/diff/line.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/usage_data.rb | 2 |
11 files changed, 103 insertions, 2 deletions
diff --git a/lib/api/api.rb b/lib/api/api.rb index 8abb24e6f69..f1448da7403 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -149,6 +149,7 @@ module API mount ::API::Snippets mount ::API::Submodules mount ::API::Subscriptions + mount ::API::Suggestions mount ::API::SystemHooks mount ::API::Tags mount ::API::Templates diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 5dbfbb85e9e..b83a5c14190 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -1495,5 +1495,17 @@ module API expose :label, using: Entities::LabelBasic expose :action end + + class Suggestion < Grape::Entity + expose :id + expose :from_original_line + expose :to_original_line + expose :from_line + expose :to_line + expose :appliable?, as: :appliable + expose :applied + expose :from_content + expose :to_content + end end end diff --git a/lib/api/suggestions.rb b/lib/api/suggestions.rb new file mode 100644 index 00000000000..d008d1b9e97 --- /dev/null +++ b/lib/api/suggestions.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module API + class Suggestions < Grape::API + before { authenticate! } + + resource :suggestions do + desc 'Apply suggestion patch in the Merge Request it was created' do + success Entities::Suggestion + end + params do + requires :id, type: String, desc: 'The suggestion ID' + end + put ':id/apply' do + suggestion = Suggestion.find_by_id(params[:id]) + + not_found! unless suggestion + authorize! :apply_suggestion, suggestion + + result = ::Suggestions::ApplyService.new(current_user).execute(suggestion) + + if result[:status] == :success + present suggestion, with: Entities::Suggestion, current_user: current_user + else + http_status = result[:http_status] || 400 + render_api_error!(result[:message], http_status) + end + end + end + end +end diff --git a/lib/banzai/filter/suggestion_filter.rb b/lib/banzai/filter/suggestion_filter.rb new file mode 100644 index 00000000000..822db7cf26e --- /dev/null +++ b/lib/banzai/filter/suggestion_filter.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Banzai + module Filter + class SuggestionFilter < HTML::Pipeline::Filter + # Class used for tagging elements that should be rendered + TAG_CLASS = 'js-render-suggestion'.freeze + + def call + return doc unless Suggestion.feature_enabled? + return doc unless suggestions_filter_enabled? + + doc.search('pre.suggestion > code').each do |node| + node.add_class(TAG_CLASS) + end + + doc + end + + def suggestions_filter_enabled? + context[:suggestions_filter_enabled] + end + end + end +end diff --git a/lib/banzai/filter/syntax_highlight_filter.rb b/lib/banzai/filter/syntax_highlight_filter.rb index 8a7f9045c24..18e5e9185de 100644 --- a/lib/banzai/filter/syntax_highlight_filter.rb +++ b/lib/banzai/filter/syntax_highlight_filter.rb @@ -69,7 +69,7 @@ module Banzai end def use_rouge?(language) - %w(math mermaid plantuml).exclude?(language) + %w(math mermaid plantuml suggestion).exclude?(language) end end end diff --git a/lib/banzai/pipeline/gfm_pipeline.rb b/lib/banzai/pipeline/gfm_pipeline.rb index 96bea7ca935..5f13a6d6cde 100644 --- a/lib/banzai/pipeline/gfm_pipeline.rb +++ b/lib/banzai/pipeline/gfm_pipeline.rb @@ -29,6 +29,7 @@ module Banzai Filter::TableOfContentsFilter, Filter::AutolinkFilter, Filter::ExternalLinkFilter, + Filter::SuggestionFilter, *reference_filters, diff --git a/lib/banzai/pipeline/post_process_pipeline.rb b/lib/banzai/pipeline/post_process_pipeline.rb index 63a998a2c1f..7eaad6d7560 100644 --- a/lib/banzai/pipeline/post_process_pipeline.rb +++ b/lib/banzai/pipeline/post_process_pipeline.rb @@ -14,7 +14,8 @@ module Banzai [ Filter::RedactorFilter, Filter::RelativeLinkFilter, - Filter::IssuableStateFilter + Filter::IssuableStateFilter, + Filter::SuggestionFilter ] end diff --git a/lib/banzai/suggestions_parser.rb b/lib/banzai/suggestions_parser.rb new file mode 100644 index 00000000000..09f36635020 --- /dev/null +++ b/lib/banzai/suggestions_parser.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Banzai + module SuggestionsParser + # Returns the content of each suggestion code block. + # + def self.parse(text) + html = Banzai.render(text, project: nil, no_original_data: true) + doc = Nokogiri::HTML(html) + + doc.search('pre.suggestion').map { |node| node.text } + end + end +end diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb index 8ba44dff06f..a85c5386d98 100644 --- a/lib/gitlab/diff/file.rb +++ b/lib/gitlab/diff/file.rb @@ -122,6 +122,16 @@ module Gitlab old_blob_lazy&.itself end + def new_blob_lines_between(from_line, to_line) + return [] unless new_blob + + from_index = from_line - 1 + to_index = to_line - 1 + + new_blob.load_all_data! + new_blob.data.lines[from_index..to_index] + end + def content_sha new_content_sha || old_content_sha end diff --git a/lib/gitlab/diff/line.rb b/lib/gitlab/diff/line.rb index f0c4977fc50..001748afb41 100644 --- a/lib/gitlab/diff/line.rb +++ b/lib/gitlab/diff/line.rb @@ -73,6 +73,10 @@ module Gitlab !meta? end + def suggestible? + !removed? + end + def rich_text @parent_file.try(:highlight_lines!) if @parent_file && !@rich_text diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb index 008e9cd1d24..083c620267a 100644 --- a/lib/gitlab/usage_data.rb +++ b/lib/gitlab/usage_data.rb @@ -85,6 +85,8 @@ module Gitlab releases: count(Release), remote_mirrors: count(RemoteMirror), snippets: count(Snippet), + suggestions: count(Suggestion), + todos: count(Todo), uploads: count(Upload), web_hooks: count(WebHook) }.merge(services_usage).merge(approximate_counts) |