Add `reference_pattern` to Referable models
This commit is contained in:
		
							parent
							
								
									94af050117
								
							
						
					
					
						commit
						b88da58cb6
					
				|  | @ -62,6 +62,19 @@ class Commit | |||
|     (self.class === other) && (raw == other.raw) | ||||
|   end | ||||
| 
 | ||||
|   def self.reference_prefix | ||||
|     '@' | ||||
|   end | ||||
| 
 | ||||
|   # Pattern used to extract commit references from text | ||||
|   # | ||||
|   # The SHA can be between 6 and 40 hex characters. | ||||
|   # | ||||
|   # This pattern supports cross-project references. | ||||
|   def self.reference_pattern | ||||
|     %r{(?:#{Project.reference_pattern}#{reference_prefix})?(?<commit>\h{6,40})} | ||||
|   end | ||||
| 
 | ||||
|   def to_reference(from_project = nil) | ||||
|     if cross_project_reference?(from_project) | ||||
|       "#{project.to_reference}@#{id}" | ||||
|  |  | |||
|  | @ -29,10 +29,24 @@ class CommitRange | |||
|   # See `exclude_start?` | ||||
|   attr_reader :exclude_start | ||||
| 
 | ||||
|   # The beginning and ending SHA sums can be between 6 and 40 hex characters, | ||||
|   # and the range selection can be double- or triple-dot. | ||||
|   # The beginning and ending SHAs can be between 6 and 40 hex characters, and | ||||
|   # the range notation can be double- or triple-dot. | ||||
|   PATTERN = /\h{6,40}\.{2,3}\h{6,40}/ | ||||
| 
 | ||||
|   def self.reference_prefix | ||||
|     '@' | ||||
|   end | ||||
| 
 | ||||
|   # Pattern used to extract commit range references from text | ||||
|   # | ||||
|   # This pattern supports cross-project references. | ||||
|   def self.reference_pattern | ||||
|     %r{ | ||||
|       (?:#{Project.reference_pattern}#{reference_prefix})? | ||||
|       (?<commit_range>#{PATTERN}) | ||||
|     }x | ||||
|   end | ||||
| 
 | ||||
|   # Initialize a CommitRange | ||||
|   # | ||||
|   # range_string - The String commit range. | ||||
|  |  | |||
|  | @ -35,6 +35,16 @@ module Referable | |||
|     def reference_prefix | ||||
|       '' | ||||
|     end | ||||
| 
 | ||||
|     # Regexp pattern used to match references to this object | ||||
|     # | ||||
|     # This must be overridden by the including class. | ||||
|     # | ||||
|     # Returns Regexp | ||||
|     def reference_pattern | ||||
|       raise NotImplementedError, | ||||
|         %Q{#{self} does not implement "reference_pattern"} | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   private | ||||
|  |  | |||
|  | @ -9,10 +9,6 @@ class ExternalIssue | |||
|     @issue_identifier.to_s | ||||
|   end | ||||
| 
 | ||||
|   def to_reference(_from_project = nil) | ||||
|     id | ||||
|   end | ||||
| 
 | ||||
|   def id | ||||
|     @issue_identifier.to_s | ||||
|   end | ||||
|  | @ -32,4 +28,13 @@ class ExternalIssue | |||
|   def project | ||||
|     @project | ||||
|   end | ||||
| 
 | ||||
|   # Pattern used to extract `JIRA-123` issue references from text | ||||
|   def self.reference_pattern | ||||
|     %r{(?<issue>([A-Z\-]+-)\d+)} | ||||
|   end | ||||
| 
 | ||||
|   def to_reference(_from_project = nil) | ||||
|     id | ||||
|   end | ||||
| end | ||||
|  |  | |||
|  | @ -40,7 +40,11 @@ class Group < Namespace | |||
|     end | ||||
| 
 | ||||
|     def reference_prefix | ||||
|       '@' | ||||
|       User.reference_prefix | ||||
|     end | ||||
| 
 | ||||
|     def reference_pattern | ||||
|       User.reference_pattern | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|  |  | |||
|  | @ -50,12 +50,22 @@ class Issue < ActiveRecord::Base | |||
|     state :closed | ||||
|   end | ||||
| 
 | ||||
|   def hook_attrs | ||||
|     attributes | ||||
|   end | ||||
| 
 | ||||
|   def self.reference_prefix | ||||
|     '#' | ||||
|   end | ||||
| 
 | ||||
|   def hook_attrs | ||||
|     attributes | ||||
|   # Pattern used to extract `#123` issue references from text | ||||
|   # | ||||
|   # This pattern supports cross-project references. | ||||
|   def self.reference_pattern | ||||
|     %r{ | ||||
|       #{Project.reference_pattern}? | ||||
|       #{Regexp.escape(reference_prefix)}(?<issue>\d+) | ||||
|     }x | ||||
|   end | ||||
| 
 | ||||
|   def to_reference(from_project = nil) | ||||
|  |  | |||
|  | @ -40,6 +40,22 @@ class Label < ActiveRecord::Base | |||
|     '~' | ||||
|   end | ||||
| 
 | ||||
|   # Pattern used to extract label references from text | ||||
|   # | ||||
|   # TODO (rspeicher): Limit to double quotes (meh) or disallow single quotes in label names (bad). | ||||
|   def self.reference_pattern | ||||
|     %r{ | ||||
|       #{reference_prefix} | ||||
|       (?: | ||||
|         (?<label_id>\d+)   | # Integer-based label ID, or | ||||
|         (?<label_name> | ||||
|           [A-Za-z0-9_-]+   | # String-based single-word label title | ||||
|           ['"][^&\?,]+['"]   # String-based multi-word label surrounded in quotes | ||||
|         ) | ||||
|       ) | ||||
|     }x | ||||
|   end | ||||
| 
 | ||||
|   # Returns the String necessary to reference this Label in Markdown | ||||
|   # | ||||
|   # format - Symbol format to use (default: :id, optional: :name) | ||||
|  |  | |||
|  | @ -140,6 +140,16 @@ class MergeRequest < ActiveRecord::Base | |||
|     '!' | ||||
|   end | ||||
| 
 | ||||
|   # Pattern used to extract `!123` merge request references from text | ||||
|   # | ||||
|   # This pattern supports cross-project references. | ||||
|   def self.reference_pattern | ||||
|     %r{ | ||||
|       #{Project.reference_pattern}? | ||||
|       #{Regexp.escape(reference_prefix)}(?<merge_request>\d+) | ||||
|     }x | ||||
|   end | ||||
| 
 | ||||
|   def to_reference(from_project = nil) | ||||
|     reference = "#{self.class.reference_prefix}#{iid}" | ||||
| 
 | ||||
|  |  | |||
|  | @ -248,6 +248,11 @@ class Project < ActiveRecord::Base | |||
|         order_by(method) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     def reference_pattern | ||||
|       name_pattern = Gitlab::Regex::NAMESPACE_REGEX_STR | ||||
|       %r{(?<project>#{name_pattern}/#{name_pattern})} | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def team | ||||
|  |  | |||
|  | @ -56,6 +56,16 @@ class Snippet < ActiveRecord::Base | |||
|     '$' | ||||
|   end | ||||
| 
 | ||||
|   # Pattern used to extract `$123` snippet references from text | ||||
|   # | ||||
|   # This pattern supports cross-project references. | ||||
|   def self.reference_pattern | ||||
|     %r{ | ||||
|       #{Project.reference_pattern}? | ||||
|       #{Regexp.escape(reference_prefix)}(?<snippet>\d+) | ||||
|     }x | ||||
|   end | ||||
| 
 | ||||
|   def to_reference(from_project = nil) | ||||
|     reference = "#{self.class.reference_prefix}#{id}" | ||||
| 
 | ||||
|  |  | |||
|  | @ -253,6 +253,14 @@ class User < ActiveRecord::Base | |||
|     def reference_prefix | ||||
|       '@' | ||||
|     end | ||||
| 
 | ||||
|     # Pattern used to extract `@user` user references from text | ||||
|     def reference_pattern | ||||
|       %r{ | ||||
|         #{Regexp.escape(reference_prefix)} | ||||
|         (?<user>#{Gitlab::Regex::NAMESPACE_REGEX_STR}) | ||||
|       }x | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   # | ||||
|  |  | |||
|  | @ -19,7 +19,7 @@ module Gitlab | |||
|       # | ||||
|       # Returns a String replaced with the return of the block. | ||||
|       def self.references_in(text) | ||||
|         text.gsub(COMMIT_RANGE_PATTERN) do |match| | ||||
|         text.gsub(CommitRange.reference_pattern) do |match| | ||||
|           yield match, $~[:commit_range], $~[:project] | ||||
|         end | ||||
|       end | ||||
|  | @ -30,13 +30,8 @@ module Gitlab | |||
|         @commit_map = {} | ||||
|       end | ||||
| 
 | ||||
|       # Pattern used to extract commit range references from text | ||||
|       # | ||||
|       # This pattern supports cross-project references. | ||||
|       COMMIT_RANGE_PATTERN = /(#{PROJECT_PATTERN}@)?(?<commit_range>#{CommitRange::PATTERN})/ | ||||
| 
 | ||||
|       def call | ||||
|         replace_text_nodes_matching(COMMIT_RANGE_PATTERN) do |content| | ||||
|         replace_text_nodes_matching(CommitRange.reference_pattern) do |content| | ||||
|           commit_range_link_filter(content) | ||||
|         end | ||||
|       end | ||||
|  |  | |||
|  | @ -19,20 +19,13 @@ module Gitlab | |||
|       # | ||||
|       # Returns a String replaced with the return of the block. | ||||
|       def self.references_in(text) | ||||
|         text.gsub(COMMIT_PATTERN) do |match| | ||||
|         text.gsub(Commit.reference_pattern) do |match| | ||||
|           yield match, $~[:commit], $~[:project] | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       # Pattern used to extract commit references from text | ||||
|       # | ||||
|       # The SHA1 sum can be between 6 and 40 hex characters. | ||||
|       # | ||||
|       # This pattern supports cross-project references. | ||||
|       COMMIT_PATTERN = /(#{PROJECT_PATTERN}@)?(?<commit>\h{6,40})/ | ||||
| 
 | ||||
|       def call | ||||
|         replace_text_nodes_matching(COMMIT_PATTERN) do |content| | ||||
|         replace_text_nodes_matching(Commit.reference_pattern) do |content| | ||||
|           commit_link_filter(content) | ||||
|         end | ||||
|       end | ||||
|  |  | |||
|  | @ -3,9 +3,6 @@ module Gitlab | |||
|     # Common methods for ReferenceFilters that support an optional cross-project | ||||
|     # reference. | ||||
|     module CrossProjectReference | ||||
|       NAMING_PATTERN  = Gitlab::Regex::NAMESPACE_REGEX_STR | ||||
|       PROJECT_PATTERN = "(?<project>#{NAMING_PATTERN}/#{NAMING_PATTERN})" | ||||
| 
 | ||||
|       # Given a cross-project reference string, get the Project record | ||||
|       # | ||||
|       # Defaults to value of `context[:project]` if: | ||||
|  |  | |||
|  | @ -16,19 +16,16 @@ module Gitlab | |||
|       # | ||||
|       # Returns a String replaced with the return of the block. | ||||
|       def self.references_in(text) | ||||
|         text.gsub(ISSUE_PATTERN) do |match| | ||||
|         text.gsub(ExternalIssue.reference_pattern) do |match| | ||||
|           yield match, $~[:issue] | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       # Pattern used to extract `JIRA-123` issue references from text | ||||
|       ISSUE_PATTERN = /(?<issue>([A-Z\-]+-)\d+)/ | ||||
| 
 | ||||
|       def call | ||||
|         # Early return if the project isn't using an external tracker | ||||
|         return doc if project.nil? || project.default_issues_tracker? | ||||
| 
 | ||||
|         replace_text_nodes_matching(ISSUE_PATTERN) do |content| | ||||
|         replace_text_nodes_matching(ExternalIssue.reference_pattern) do |content| | ||||
|           issue_link_filter(content) | ||||
|         end | ||||
|       end | ||||
|  |  | |||
|  | @ -20,18 +20,13 @@ module Gitlab | |||
|       # | ||||
|       # Returns a String replaced with the return of the block. | ||||
|       def self.references_in(text) | ||||
|         text.gsub(ISSUE_PATTERN) do |match| | ||||
|         text.gsub(Issue.reference_pattern) do |match| | ||||
|           yield match, $~[:issue].to_i, $~[:project] | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       # Pattern used to extract `#123` issue references from text | ||||
|       # | ||||
|       # This pattern supports cross-project references. | ||||
|       ISSUE_PATTERN = /#{PROJECT_PATTERN}?\#(?<issue>([a-zA-Z\-]+-)?\d+)/ | ||||
| 
 | ||||
|       def call | ||||
|         replace_text_nodes_matching(ISSUE_PATTERN) do |content| | ||||
|         replace_text_nodes_matching(Issue.reference_pattern) do |content| | ||||
|           issue_link_filter(content) | ||||
|         end | ||||
|       end | ||||
|  |  | |||
|  | @ -15,26 +15,13 @@ module Gitlab | |||
|       # | ||||
|       # Returns a String replaced with the return of the block. | ||||
|       def self.references_in(text) | ||||
|         text.gsub(LABEL_PATTERN) do |match| | ||||
|         text.gsub(Label.reference_pattern) do |match| | ||||
|           yield match, $~[:label_id].to_i, $~[:label_name] | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       # Pattern used to extract label references from text | ||||
|       # | ||||
|       # TODO (rspeicher): Limit to double quotes (meh) or disallow single quotes in label names (bad). | ||||
|       LABEL_PATTERN = %r{ | ||||
|         ~( | ||||
|           (?<label_id>\d+)   | # Integer-based label ID, or | ||||
|           (?<label_name> | ||||
|             [A-Za-z0-9_-]+   | # String-based single-word label title | ||||
|             ['"][^&\?,]+['"]   # String-based multi-word label surrounded in quotes | ||||
|           ) | ||||
|         ) | ||||
|       }x | ||||
| 
 | ||||
|       def call | ||||
|         replace_text_nodes_matching(LABEL_PATTERN) do |content| | ||||
|         replace_text_nodes_matching(Label.reference_pattern) do |content| | ||||
|           label_link_filter(content) | ||||
|         end | ||||
|       end | ||||
|  |  | |||
|  | @ -20,18 +20,13 @@ module Gitlab | |||
|       # | ||||
|       # Returns a String replaced with the return of the block. | ||||
|       def self.references_in(text) | ||||
|         text.gsub(MERGE_REQUEST_PATTERN) do |match| | ||||
|         text.gsub(MergeRequest.reference_pattern) do |match| | ||||
|           yield match, $~[:merge_request].to_i, $~[:project] | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       # Pattern used to extract `!123` merge request references from text | ||||
|       # | ||||
|       # This pattern supports cross-project references. | ||||
|       MERGE_REQUEST_PATTERN = /#{PROJECT_PATTERN}?!(?<merge_request>\d+)/ | ||||
| 
 | ||||
|       def call | ||||
|         replace_text_nodes_matching(MERGE_REQUEST_PATTERN) do |content| | ||||
|         replace_text_nodes_matching(MergeRequest.reference_pattern) do |content| | ||||
|           merge_request_link_filter(content) | ||||
|         end | ||||
|       end | ||||
|  |  | |||
|  | @ -20,18 +20,13 @@ module Gitlab | |||
|       # | ||||
|       # Returns a String replaced with the return of the block. | ||||
|       def self.references_in(text) | ||||
|         text.gsub(SNIPPET_PATTERN) do |match| | ||||
|         text.gsub(Snippet.reference_pattern) do |match| | ||||
|           yield match, $~[:snippet].to_i, $~[:project] | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       # Pattern used to extract `$123` snippet references from text | ||||
|       # | ||||
|       # This pattern supports cross-project references. | ||||
|       SNIPPET_PATTERN = /#{PROJECT_PATTERN}?\$(?<snippet>\d+)/ | ||||
| 
 | ||||
|       def call | ||||
|         replace_text_nodes_matching(SNIPPET_PATTERN) do |content| | ||||
|         replace_text_nodes_matching(Snippet.reference_pattern) do |content| | ||||
|           snippet_link_filter(content) | ||||
|         end | ||||
|       end | ||||
|  |  | |||
|  | @ -16,16 +16,13 @@ module Gitlab | |||
|       # | ||||
|       # Returns a String replaced with the return of the block. | ||||
|       def self.references_in(text) | ||||
|         text.gsub(USER_PATTERN) do |match| | ||||
|         text.gsub(User.reference_pattern) do |match| | ||||
|           yield match, $~[:user] | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       # Pattern used to extract `@user` user references from text | ||||
|       USER_PATTERN = /@(?<user>#{Gitlab::Regex::NAMESPACE_REGEX_STR})/ | ||||
| 
 | ||||
|       def call | ||||
|         replace_text_nodes_matching(USER_PATTERN) do |content| | ||||
|         replace_text_nodes_matching(User.reference_pattern) do |content| | ||||
|           user_link_filter(content) | ||||
|         end | ||||
|       end | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue