Skip to content
Snippets Groups Projects
Commit 2c46c452 authored by Vinnie Okada's avatar Vinnie Okada
Browse files

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.
parent 7edc1439
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -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
 
Loading
Loading
Loading
Loading
@@ -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
[]
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
@@ -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
Loading
Loading
@@ -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
 
Loading
Loading
@@ -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
 
Loading
Loading
@@ -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
 
Loading
Loading
@@ -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
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment