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:
authorVinnie Okada <vokada@mrvinn.com>2014-10-02 22:26:39 +0400
committerVinnie Okada <vokada@mrvinn.com>2014-10-03 21:30:20 +0400
commit2c46c4523fc8aa41cb60e4840af16fdd595f7dd2 (patch)
treeb178ae204f78e40aff7611b70a3a025f6e7befa9
parent7edc1439fe11e396bb6327a3f50aca5dfe3c411c (diff)
Track projects in ReferenceExtractor
Store both the project and identifier of extracted references. This prevents `ReferenceExtractor` from returning objects in the wrong project for cross-project references.
-rw-r--r--app/models/concerns/mentionable.rb2
-rw-r--r--lib/gitlab/closing_issue_extractor.rb2
-rw-r--r--lib/gitlab/reference_extractor.rb52
-rw-r--r--spec/lib/gitlab/reference_extractor_spec.rb52
4 files changed, 62 insertions, 46 deletions
diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb
index 71dd2f8c697..8c31cdd12d0 100644
--- a/app/models/concerns/mentionable.rb
+++ b/app/models/concerns/mentionable.rb
@@ -67,7 +67,7 @@ module Mentionable
def references(p = project, text = mentionable_text)
return [] if text.blank?
ext = Gitlab::ReferenceExtractor.new
- ext.analyze(text)
+ ext.analyze(text, p)
(ext.issues_for(p) + ext.merge_requests_for(p) + ext.commits_for(p)).uniq - [local_reference]
end
diff --git a/lib/gitlab/closing_issue_extractor.rb b/lib/gitlab/closing_issue_extractor.rb
index 90f1370c209..401e6e047b1 100644
--- a/lib/gitlab/closing_issue_extractor.rb
+++ b/lib/gitlab/closing_issue_extractor.rb
@@ -6,7 +6,7 @@ module Gitlab
md = ISSUE_CLOSING_REGEX.match(message)
if md
extractor = Gitlab::ReferenceExtractor.new
- extractor.analyze(md[0])
+ extractor.analyze(md[0], project)
extractor.issues_for(project)
else
[]
diff --git a/lib/gitlab/reference_extractor.rb b/lib/gitlab/reference_extractor.rb
index d2f02f712ce..99165950aef 100644
--- a/lib/gitlab/reference_extractor.rb
+++ b/lib/gitlab/reference_extractor.rb
@@ -9,51 +9,63 @@ module Gitlab
@users, @issues, @merge_requests, @snippets, @commits = [], [], [], [], []
end
- def analyze(string)
- parse_references(string.dup)
+ def analyze(string, project)
+ parse_references(string.dup, project)
end
# Given a valid project, resolve the extracted identifiers of the requested type to
# model objects.
def users_for(project)
- users.map do |identifier|
- project.users.where(username: identifier).first
+ users.map do |entry|
+ project.users.where(username: entry[:id]).first
end.reject(&:nil?)
end
- def issues_for(project)
- issues.map do |identifier|
- project.issues.where(iid: identifier).first
+ def issues_for(project = nil)
+ issues.map do |entry|
+ if should_lookup?(project, entry[:project])
+ entry[:project].issues.where(iid: entry[:id]).first
+ end
end.reject(&:nil?)
end
- def merge_requests_for(project)
- merge_requests.map do |identifier|
- project.merge_requests.where(iid: identifier).first
+ def merge_requests_for(project = nil)
+ merge_requests.map do |entry|
+ if should_lookup?(project, entry[:project])
+ entry[:project].merge_requests.where(iid: entry[:id]).first
+ end
end.reject(&:nil?)
end
def snippets_for(project)
- snippets.map do |identifier|
- project.snippets.where(id: identifier).first
+ snippets.map do |entry|
+ project.snippets.where(id: entry[:id]).first
end.reject(&:nil?)
end
- def commits_for(project)
- repo = project.repository
- return [] if repo.nil?
-
- commits.map do |identifier|
- repo.commit(identifier)
+ def commits_for(project = nil)
+ commits.map do |entry|
+ repo = entry[:project].repository if entry[:project]
+ if should_lookup?(project, entry[:project])
+ repo.commit(entry[:id]) if repo
+ end
end.reject(&:nil?)
end
private
- def reference_link(type, identifier, _, _)
+ def reference_link(type, identifier, project, _)
# Append identifier to the appropriate collection.
- send("#{type}s") << identifier
+ send("#{type}s") << { project: project, id: identifier }
+ end
+
+ def should_lookup?(project, entry_project)
+ if entry_project.nil?
+ false
+ else
+ project.nil? || project.id == entry_project.id
+ end
end
end
end
diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb
index 99fed27c796..23867df39dd 100644
--- a/spec/lib/gitlab/reference_extractor_spec.rb
+++ b/spec/lib/gitlab/reference_extractor_spec.rb
@@ -2,45 +2,48 @@ require 'spec_helper'
describe Gitlab::ReferenceExtractor do
it 'extracts username references' do
- subject.analyze "this contains a @user reference"
- subject.users.should == ["user"]
+ subject.analyze('this contains a @user reference', nil)
+ subject.users.should == [{ project: nil, id: 'user' }]
end
it 'extracts issue references' do
- subject.analyze "this one talks about issue #1234"
- subject.issues.should == ["1234"]
+ subject.analyze('this one talks about issue #1234', nil)
+ subject.issues.should == [{ project: nil, id: '1234' }]
end
it 'extracts JIRA issue references' do
- Gitlab.config.gitlab.stub(:issues_tracker).and_return("jira")
- subject.analyze "this one talks about issue JIRA-1234"
- subject.issues.should == ["JIRA-1234"]
+ Gitlab.config.gitlab.stub(:issues_tracker).and_return('jira')
+ subject.analyze('this one talks about issue JIRA-1234', nil)
+ subject.issues.should == [{ project: nil, id: 'JIRA-1234' }]
end
it 'extracts merge request references' do
- subject.analyze "and here's !43, a merge request"
- subject.merge_requests.should == ["43"]
+ subject.analyze("and here's !43, a merge request", nil)
+ subject.merge_requests.should == [{ project: nil, id: '43' }]
end
it 'extracts snippet ids' do
- subject.analyze "snippets like $12 get extracted as well"
- subject.snippets.should == ["12"]
+ subject.analyze('snippets like $12 get extracted as well', nil)
+ subject.snippets.should == [{ project: nil, id: '12' }]
end
it 'extracts commit shas' do
- subject.analyze "commit shas 98cf0ae3 are pulled out as Strings"
- subject.commits.should == ["98cf0ae3"]
+ subject.analyze('commit shas 98cf0ae3 are pulled out as Strings', nil)
+ subject.commits.should == [{ project: nil, id: '98cf0ae3' }]
end
it 'extracts multiple references and preserves their order' do
- subject.analyze "@me and @you both care about this"
- subject.users.should == ["me", "you"]
+ subject.analyze('@me and @you both care about this', nil)
+ subject.users.should == [
+ { project: nil, id: 'me' },
+ { project: nil, id: 'you' }
+ ]
end
it 'leaves the original note unmodified' do
- text = "issue #123 is just the worst, @user"
- subject.analyze text
- text.should == "issue #123 is just the worst, @user"
+ text = 'issue #123 is just the worst, @user'
+ subject.analyze(text, nil)
+ text.should == 'issue #123 is just the worst, @user'
end
it 'handles all possible kinds of references' do
@@ -59,7 +62,7 @@ describe Gitlab::ReferenceExtractor do
project.team << [@u_foo, :reporter]
project.team << [@u_bar, :guest]
- subject.analyze "@foo, @baduser, @bar, and @offteam"
+ subject.analyze('@foo, @baduser, @bar, and @offteam', project)
subject.users_for(project).should == [@u_foo, @u_bar]
end
@@ -67,7 +70,7 @@ describe Gitlab::ReferenceExtractor do
@i0 = create(:issue, project: project)
@i1 = create(:issue, project: project)
- subject.analyze "##{@i0.iid}, ##{@i1.iid}, and #999."
+ subject.analyze("##{@i0.iid}, ##{@i1.iid}, and #999.", project)
subject.issues_for(project).should == [@i0, @i1]
end
@@ -75,7 +78,7 @@ describe Gitlab::ReferenceExtractor do
@m0 = create(:merge_request, source_project: project, target_project: project, source_branch: 'aaa')
@m1 = create(:merge_request, source_project: project, target_project: project, source_branch: 'bbb')
- subject.analyze "!999, !#{@m1.iid}, and !#{@m0.iid}."
+ subject.analyze("!999, !#{@m1.iid}, and !#{@m0.iid}.", project)
subject.merge_requests_for(project).should == [@m1, @m0]
end
@@ -84,14 +87,15 @@ describe Gitlab::ReferenceExtractor do
@s1 = create(:project_snippet, project: project)
@s2 = create(:project_snippet)
- subject.analyze "$#{@s0.id}, $999, $#{@s2.id}, $#{@s1.id}"
+ subject.analyze("$#{@s0.id}, $999, $#{@s2.id}, $#{@s1.id}", project)
subject.snippets_for(project).should == [@s0, @s1]
end
it 'accesses valid commits' do
- commit = project.repository.commit("master")
+ commit = project.repository.commit('master')
- subject.analyze "this references commits #{commit.sha[0..6]} and 012345"
+ subject.analyze("this references commits #{commit.sha[0..6]} and 012345",
+ project)
extracted = subject.commits_for(project)
extracted.should have(1).item
extracted[0].sha.should == commit.sha