From b88da58cb6272a86b6df2e4efe392f10e689a6b2 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 14 May 2015 16:59:39 -0400 Subject: Add `reference_pattern` to Referable models --- app/models/commit.rb | 13 +++++++++++++ app/models/commit_range.rb | 18 ++++++++++++++++-- app/models/concerns/referable.rb | 10 ++++++++++ app/models/external_issue.rb | 13 +++++++++---- app/models/group.rb | 6 +++++- app/models/issue.rb | 14 ++++++++++++-- app/models/label.rb | 16 ++++++++++++++++ app/models/merge_request.rb | 10 ++++++++++ app/models/project.rb | 5 +++++ app/models/snippet.rb | 10 ++++++++++ app/models/user.rb | 8 ++++++++ 11 files changed, 114 insertions(+), 9 deletions(-) (limited to 'app/models') diff --git a/app/models/commit.rb b/app/models/commit.rb index 085f4e6398f..2c244fc0410 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -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})?(?\h{6,40})} + end + def to_reference(from_project = nil) if cross_project_reference?(from_project) "#{project.to_reference}@#{id}" diff --git a/app/models/commit_range.rb b/app/models/commit_range.rb index fb1f6d09be6..86fc9eb01a3 100644 --- a/app/models/commit_range.rb +++ b/app/models/commit_range.rb @@ -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})? + (?#{PATTERN}) + }x + end + # Initialize a CommitRange # # range_string - The String commit range. diff --git a/app/models/concerns/referable.rb b/app/models/concerns/referable.rb index b41df301c3f..e3c1c6d268e 100644 --- a/app/models/concerns/referable.rb +++ b/app/models/concerns/referable.rb @@ -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 diff --git a/app/models/external_issue.rb b/app/models/external_issue.rb index 6fda4a2ab77..49f6c95e045 100644 --- a/app/models/external_issue.rb +++ b/app/models/external_issue.rb @@ -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{(?([A-Z\-]+-)\d+)} + end + + def to_reference(_from_project = nil) + id + end end diff --git a/app/models/group.rb b/app/models/group.rb index 33d72e0d9ee..b4e908c5602 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -40,7 +40,11 @@ class Group < Namespace end def reference_prefix - '@' + User.reference_prefix + end + + def reference_pattern + User.reference_pattern end end diff --git a/app/models/issue.rb b/app/models/issue.rb index 31803b57b3f..ea6b9329b07 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -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)}(?\d+) + }x end def to_reference(from_project = nil) diff --git a/app/models/label.rb b/app/models/label.rb index 013e6bf5978..8980049cef8 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -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} + (?: + (?\d+) | # Integer-based label ID, or + (? + [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) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 60b0ce6c018..6c90d09b866 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -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)}(?\d+) + }x + end + def to_reference(from_project = nil) reference = "#{self.class.reference_prefix}#{iid}" diff --git a/app/models/project.rb b/app/models/project.rb index c943114449a..3c9f0dad28b 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -248,6 +248,11 @@ class Project < ActiveRecord::Base order_by(method) end end + + def reference_pattern + name_pattern = Gitlab::Regex::NAMESPACE_REGEX_STR + %r{(?#{name_pattern}/#{name_pattern})} + end end def team diff --git a/app/models/snippet.rb b/app/models/snippet.rb index 8c3167833aa..d1619071f49 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -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)}(?\d+) + }x + end + def to_reference(from_project = nil) reference = "#{self.class.reference_prefix}#{id}" diff --git a/app/models/user.rb b/app/models/user.rb index f546dc015c2..50ca4bc5acc 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -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)} + (?#{Gitlab::Regex::NAMESPACE_REGEX_STR}) + }x + end end # -- cgit v1.2.3