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:
-rw-r--r--app/services/issues/move_service.rb7
-rw-r--r--lib/banzai/filter/reference_unfold_filter.rb42
-rw-r--r--lib/banzai/pipeline/reference_unfold_pipeline.rb21
-rw-r--r--lib/gitlab/gfm/reference_unfolder.rb31
-rw-r--r--lib/gitlab/reference_extractor.rb8
-rw-r--r--spec/lib/banzai/pipeline/reference_unfold_pipeline_spec.rb62
-rw-r--r--spec/lib/gitlab/gfm/reference_unfolder_spec.rb43
-rw-r--r--spec/lib/gitlab/reference_extractor_spec.rb12
8 files changed, 95 insertions, 131 deletions
diff --git a/app/services/issues/move_service.rb b/app/services/issues/move_service.rb
index a9448af4699..de12ea5c172 100644
--- a/app/services/issues/move_service.rb
+++ b/app/services/issues/move_service.rb
@@ -83,11 +83,8 @@ module Issues
def rewrite_references(noteable)
content = noteable_content(noteable).dup
- context = { pipeline: :reference_unfold,
- project: @project_old, new_project: @project_new }
-
- new_content = Banzai.render_result(content, context)
- new_content[:output].to_s
+ unfolder = Gitlab::Gfm::ReferenceUnfolder.new(content, @project_old)
+ unfolder.unfold(@project_new)
end
def noteable_content(noteable)
diff --git a/lib/banzai/filter/reference_unfold_filter.rb b/lib/banzai/filter/reference_unfold_filter.rb
deleted file mode 100644
index 70a485ba2ae..00000000000
--- a/lib/banzai/filter/reference_unfold_filter.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-require 'html/pipeline/filter'
-
-module Banzai
- module Filter
- ##
- # Filter than unfolds local references.
- #
- #
- class ReferenceUnfoldFilter < HTML::Pipeline::Filter
- def initialize(*)
- super
-
- unless result[:references].is_a?(Hash)
- raise StandardError, 'References not processed!'
- end
-
- @text = context[:text].dup
- @new_project = context[:new_project]
- @referables = result[:references].values.flatten
- end
-
- def call
- @referables.each do |referable|
- next unless referable.respond_to?(:to_reference)
-
- pattern = /#{Regexp.escape(referable.to_reference)}/
- @text.gsub!(pattern, referable.to_reference(@new_project))
- end
-
- @text
- end
-
- private
-
- def validate
- needs :project
- needs :new_project
- needs :text
- end
- end
- end
-end
diff --git a/lib/banzai/pipeline/reference_unfold_pipeline.rb b/lib/banzai/pipeline/reference_unfold_pipeline.rb
deleted file mode 100644
index 597bf7befd1..00000000000
--- a/lib/banzai/pipeline/reference_unfold_pipeline.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-module Banzai
- module Pipeline
- class ReferenceUnfoldPipeline < BasePipeline
- def self.filters
- FullPipeline.filters +
- [Filter::ReferenceGathererFilter,
- Filter::ReferenceUnfoldFilter]
- end
-
- def self.call(text, context = {})
- context = context.merge(text: text)
- super
- end
-
- class << self
- alias_method :to_document, :call
- alias_method :to_html, :call
- end
- end
- end
-end
diff --git a/lib/gitlab/gfm/reference_unfolder.rb b/lib/gitlab/gfm/reference_unfolder.rb
new file mode 100644
index 00000000000..4969e8ebe85
--- /dev/null
+++ b/lib/gitlab/gfm/reference_unfolder.rb
@@ -0,0 +1,31 @@
+module Gitlab
+ module Gfm
+ ##
+ # Class than unfolds local references in text.
+ #
+ #
+ class ReferenceUnfolder
+ def initialize(text, project)
+ @text = text
+ @project = project
+ end
+
+ def unfold(from_project)
+ referables.each_with_object(@text.dup) do |referable, text|
+ next unless referable.respond_to?(:to_reference)
+
+ pattern = /#{Regexp.escape(referable.to_reference)}/
+ text.gsub!(pattern, referable.to_reference(from_project))
+ end
+ end
+
+ private
+
+ def referables
+ extractor = Gitlab::ReferenceExtractor.new(@project)
+ extractor.analyze(@text)
+ extractor.all
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb
index 4d830aa45e1..8c698d43bef 100644
--- a/lib/gitlab/reference_extractor.rb
+++ b/lib/gitlab/reference_extractor.rb
@@ -1,6 +1,7 @@
module Gitlab
# Extract possible GFM references from an arbitrary String for further processing.
class ReferenceExtractor < Banzai::ReferenceExtractor
+ REFERABLES = %i(user issue label milestone merge_request snippet commit commit_range)
attr_accessor :project, :current_user, :author
def initialize(project, current_user = nil, author = nil)
@@ -17,7 +18,7 @@ module Gitlab
super(text, context.merge(project: project))
end
- %i(user label milestone merge_request snippet commit commit_range).each do |type|
+ REFERABLES.each do |type|
define_method("#{type}s") do
@references[type] ||= references(type, reference_context)
end
@@ -31,6 +32,11 @@ module Gitlab
end
end
+ def all
+ REFERABLES.each { |referable| send(referable.to_s.pluralize) }
+ @references.values.flatten
+ end
+
private
def reference_context
diff --git a/spec/lib/banzai/pipeline/reference_unfold_pipeline_spec.rb b/spec/lib/banzai/pipeline/reference_unfold_pipeline_spec.rb
deleted file mode 100644
index c02dc5a2c2c..00000000000
--- a/spec/lib/banzai/pipeline/reference_unfold_pipeline_spec.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-require 'spec_helper'
-
-describe Banzai::Pipeline::ReferenceUnfoldPipeline do
- let(:text) { 'some text' }
- let(:old_project) { create(:project) }
- let(:new_project) { create(:project) }
- let(:pipeline_context) do
- { project: old_project, new_project: new_project }
- end
-
- let(:result) do
- described_class.to_document(text, pipeline_context)
- end
-
- context 'invalid initializers' do
- subject { -> { result } }
-
- context 'project context is missing' do
- let(:pipeline_context) { { new_project: new_project } }
- it { is_expected.to raise_error ArgumentError, /Missing context keys/ }
- end
-
- context 'new project context is missing' do
- let(:pipeline_context) { { project: old_project } }
- it { is_expected.to raise_error ArgumentError, /Missing context keys/ }
- end
- end
-
- context 'multiple issues and merge requests referenced' do
- subject { result[:output] }
-
- let!(:issue_first) { create(:issue, project: old_project) }
- let!(:issue_second) { create(:issue, project: old_project) }
- let!(:merge_request) { create(:merge_request, source_project: old_project) }
-
- context 'plain text description' do
- let(:text) { 'Description that references #1, #2 and !1' }
-
- it { is_expected.to include issue_first.to_reference(new_project) }
- it { is_expected.to include issue_second.to_reference(new_project) }
- it { is_expected.to include merge_request.to_reference(new_project) }
- end
-
- context 'description with ignored elements' do
- let(:text) do
- "Hi. This references #1, but not `#2`\n" +
- '<pre>and not !1</pre>'
- end
-
- it { is_expected.to include issue_first.to_reference(new_project) }
- it { is_expected.to_not include issue_second.to_reference(new_project) }
- it { is_expected.to_not include merge_request.to_reference(new_project) }
- end
-
- context 'description ambigous elements' do
- let(:url) { 'http://gitlab.com/#1' }
- let(:text) { "This references #1, but not #{url}" }
-
- it { is_expected.to include url }
- end
- end
-end
diff --git a/spec/lib/gitlab/gfm/reference_unfolder_spec.rb b/spec/lib/gitlab/gfm/reference_unfolder_spec.rb
new file mode 100644
index 00000000000..4f8b960350c
--- /dev/null
+++ b/spec/lib/gitlab/gfm/reference_unfolder_spec.rb
@@ -0,0 +1,43 @@
+require 'spec_helper'
+
+describe Gitlab::Gfm::ReferenceUnfolder do
+ let(:text) { 'some text' }
+ let(:old_project) { create(:project) }
+ let(:new_project) { create(:project) }
+
+ describe '#unfold' do
+ subject { described_class.new(text, old_project).unfold(new_project) }
+
+ context 'multiple issues and merge requests referenced' do
+ let!(:issue_first) { create(:issue, project: old_project) }
+ let!(:issue_second) { create(:issue, project: old_project) }
+ let!(:merge_request) { create(:merge_request, source_project: old_project) }
+
+ context 'plain text description' do
+ let(:text) { 'Description that references #1, #2 and !1' }
+
+ it { is_expected.to include issue_first.to_reference(new_project) }
+ it { is_expected.to include issue_second.to_reference(new_project) }
+ it { is_expected.to include merge_request.to_reference(new_project) }
+ end
+
+ context 'description with ignored elements' do
+ let(:text) do
+ "Hi. This references #1, but not `#2`\n" +
+ '<pre>and not !1</pre>'
+ end
+
+ it { is_expected.to include issue_first.to_reference(new_project) }
+ it { is_expected.to_not include issue_second.to_reference(new_project) }
+ it { is_expected.to_not include merge_request.to_reference(new_project) }
+ end
+
+ context 'description ambigous elements' do
+ let(:url) { 'http://gitlab.com/#1' }
+ let(:text) { "This references #1, but not #{url}" }
+
+ it { is_expected.to include url }
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb
index 7d963795e17..78ab162e5d6 100644
--- a/spec/lib/gitlab/reference_extractor_spec.rb
+++ b/spec/lib/gitlab/reference_extractor_spec.rb
@@ -122,4 +122,16 @@ describe Gitlab::ReferenceExtractor, lib: true do
expect(extracted).to match_array([issue])
end
end
+
+ describe '#all' do
+ let(:issue) { create(:issue, project: project) }
+ let(:label) { create(:label, project: project) }
+ let(:text) { "Ref. #{issue.to_reference} and #{label.to_reference}" }
+
+ before { subject.analyze(text) }
+
+ it 'returns all referables' do
+ expect(subject.all).to match_array([issue, label])
+ end
+ end
end