diff options
| author | Vinnie Okada <vokada@mrvinn.com> | 2014-10-03 00:48:35 -0500 |
|---|---|---|
| committer | Vinnie Okada <vokada@mrvinn.com> | 2014-10-03 12:30:20 -0500 |
| commit | 088987e2dd4b7ad8d62ebd34448dbe194df7812d (patch) | |
| tree | b06d59aed2f34ffdb2f7740dcf858409c7b837ee /app/models/note.rb | |
| parent | 2c46c4523fc8aa41cb60e4840af16fdd595f7dd2 (diff) | |
| download | gitlab-ce-088987e2dd4b7ad8d62ebd34448dbe194df7812d.tar.gz | |
Make Mentionables work for cross-project refs
Add a note to merge requests and issues when they're mentioned by a
merge request, issue, or commit in another project.
Diffstat (limited to 'app/models/note.rb')
| -rw-r--r-- | app/models/note.rb | 73 |
1 files changed, 69 insertions, 4 deletions
diff --git a/app/models/note.rb b/app/models/note.rb index fa5fdea4eb0..0c1d792ca9a 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -70,13 +70,17 @@ class Note < ActiveRecord::Base ) end - # +noteable+ was referenced from +mentioner+, by including GFM in either +mentioner+'s description or an associated Note. - # Create a system Note associated with +noteable+ with a GFM back-reference to +mentioner+. + # +noteable+ was referenced from +mentioner+, by including GFM in either + # +mentioner+'s description or an associated Note. + # Create a system Note associated with +noteable+ with a GFM back-reference + # to +mentioner+. def create_cross_reference_note(noteable, mentioner, author, project) + gfm_reference = mentioner_gfm_ref(noteable, mentioner, project) + note_options = { project: project, author: author, - note: "_mentioned in #{mentioner.gfm_reference}_", + note: "_mentioned in #{gfm_reference}_", system: true } @@ -163,12 +167,73 @@ class Note < ActiveRecord::Base # Determine whether or not a cross-reference note already exists. def cross_reference_exists?(noteable, mentioner) - where(noteable_id: noteable.id, system: true, note: "_mentioned in #{mentioner.gfm_reference}_").any? + gfm_reference = mentioner_gfm_ref(noteable, mentioner) + + where(['noteable_id = ? and system = ? and note like ?', + noteable.id, true, "_mentioned in #{gfm_reference}_"]).any? end def search(query) where("note like :query", query: "%#{query}%") end + + private + + # Prepend the mentioner's namespaced project path to the GFM reference for + # cross-project references. For same-project references, return the + # unmodified GFM reference. + def mentioner_gfm_ref(noteable, mentioner, project = nil) + if mentioner.is_a?(Commit) + if project.nil? + return mentioner.gfm_reference.sub('commit ', 'commit %') + else + mentioning_project = project + end + else + mentioning_project = mentioner.project + end + + noteable_project_id = noteable_project_id(noteable, mentioning_project) + + full_gfm_reference(mentioning_project, noteable_project_id, mentioner) + end + + # Return the ID of the project that +noteable+ belongs to, or nil if + # +noteable+ is a commit and is not part of the project that owns + # +mentioner+. + def noteable_project_id(noteable, mentioning_project) + if noteable.is_a?(Commit) + if mentioning_project.repository.commit(noteable.id) + # The noteable commit belongs to the mentioner's project + mentioning_project.id + else + nil + end + else + noteable.project.id + end + end + + # Return the +mentioner+ GFM reference. If the mentioner and noteable + # projects are not the same, add the mentioning project's path to the + # returned value. + def full_gfm_reference(mentioning_project, noteable_project_id, mentioner) + if mentioning_project.id == noteable_project_id + mentioner.gfm_reference + else + if mentioner.is_a?(Commit) + mentioner.gfm_reference.sub( + /(commit )/, + "\\1#{mentioning_project.path_with_namespace}@" + ) + else + mentioner.gfm_reference.sub( + /(issue |merge request )/, + "\\1#{mentioning_project.path_with_namespace}" + ) + end + end + end end def commit_author |
