diff options
author | Marin Jankovski <maxlazio@gmail.com> | 2014-10-05 23:04:16 +0400 |
---|---|---|
committer | Marin Jankovski <maxlazio@gmail.com> | 2014-10-05 23:04:16 +0400 |
commit | bb929c2117c8a45620eb37b55d43f5cb8a215572 (patch) | |
tree | e3d57450efa28c0f860d4472285fa8167dd1ea1e /app | |
parent | 43be3fcb833fe522721a7192fffd8d7348b01ffb (diff) | |
parent | 8dce0cd215b657d11b3e183e361fc86ae9314ecd (diff) |
Merge pull request #7933 from mr-vinn/cross-project-markdown
Implement cross-project Markdown references
Diffstat (limited to 'app')
-rw-r--r-- | app/models/concerns/mentionable.rb | 6 | ||||
-rw-r--r-- | app/models/note.rb | 73 |
2 files changed, 73 insertions, 6 deletions
diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb index 71dd2f8c697..5938d9cb28e 100644 --- a/app/models/concerns/mentionable.rb +++ b/app/models/concerns/mentionable.rb @@ -67,8 +67,10 @@ module Mentionable def references(p = project, text = mentionable_text) return [] if text.blank? ext = Gitlab::ReferenceExtractor.new - ext.analyze(text) - (ext.issues_for(p) + ext.merge_requests_for(p) + ext.commits_for(p)).uniq - [local_reference] + ext.analyze(text, p) + (ext.issues_for + + ext.merge_requests_for + + ext.commits_for).uniq - [local_reference] end # Create a cross-reference Note for each GFM reference to another Mentionable found in +mentionable_text+. 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 |