Commit 077f9a4e authored by Alejandro Rodríguez's avatar Alejandro Rodríguez

Implementing special GitLab markdown reference for milestones

Using the syntax proposed in #13829 [project_reference]%(milestone_id | milestone_name)
to get a link to the referred milestone.
parent 2ade37e2
......@@ -74,8 +74,22 @@ class Milestone < ActiveRecord::Base
end
end
def self.reference_prefix
'%'
end
def self.reference_pattern
nil
%r{
(#{Project.reference_pattern})?
#{Regexp.escape(reference_prefix)}
(?:
(?<milestone_id>\d+) | # Integer-based milestone ID, or
(?<milestone_name>
[A-Za-z0-9_-]+ | # String-based single-word milestone title, or
"[^"]+" # String-based multi-word milestone surrounded in quotes
)
)
}x
end
def self.link_reference_pattern
......@@ -86,13 +100,15 @@ class Milestone < ActiveRecord::Base
self.where('due_date > ?', Time.now).reorder(due_date: :asc).first
end
def to_reference(from_project = nil)
escaped_title = self.title.gsub("]", "\\]")
def to_reference(from_project = nil, format: :id)
format_reference = milestone_format_reference(format)
reference = "#{self.class.reference_prefix}#{format_reference}"
h = Gitlab::Routing.url_helpers
url = h.namespace_project_milestone_url(self.project.namespace, self.project, self)
"[#{escaped_title}](#{url})"
if cross_project_reference?(from_project)
project.to_reference + reference
else
reference
end
end
def reference_link_text(from_project = nil)
......@@ -160,4 +176,16 @@ class Milestone < ActiveRecord::Base
issues.where(id: ids).
update_all(["position = CASE #{conditions} ELSE position END", *pairs])
end
private
def milestone_format_reference(format = :id)
raise StandardError, 'Unknown format' unless [:id, :name].include?(format)
if format == :name && !name.include?('"')
%("#{name}")
else
id
end
end
end
......@@ -7,14 +7,36 @@ module Banzai
end
def find_object(project, id)
project.milestones.find_by(iid: id)
project.milestones.find(id)
end
def url_for_object(issue, project)
def references_in(text, pattern = Milestone.reference_pattern)
text.gsub(pattern) do |match|
project = project_from_ref($~[:project])
params = milestone_params($~[:milestone_id].to_i, $~[:milestone_name])
milestone = project.milestones.find_by(params)
if milestone
yield match, milestone.id, $~[:project], $~
else
match
end
end
end
def url_for_object(milestone, project)
h = Gitlab::Routing.url_helpers
h.namespace_project_milestone_url(project.namespace, project, milestone,
only_path: context[:only_path])
end
def milestone_params(id, name)
if name
{ name: name.tr('"', '') }
else
{ id: id }
end
end
end
end
end
......@@ -216,10 +216,13 @@ References should be parseable even inside _<%= merge_request.to_reference %>_ e
#### MilestoneReferenceFilter
- Milestone: <%= milestone.to_reference %>
- Milestone by ID: <%= simple_milestone.to_reference %>
- Milestone by name: <%= Milestone.reference_prefix %><%= simple_milestone.name %>
- Milestone by name in quotes: <%= milestone.to_reference(format: :name) %>
- Milestone in another project: <%= xmilestone.to_reference(project) %>
- Ignored in code: `<%= milestone.to_reference %>`
- Link to milestone by URL: [Milestone](<%= urls.namespace_project_milestone_url(milestone.project.namespace, milestone.project, milestone) %>)
- Ignored in code: `<%= simple_milestone.to_reference %>`
- Ignored in links: [Link to <%= simple_milestone.to_reference %>](#milestone-link)
- Link to milestone by URL: [Milestone](<%= milestone.to_reference %>)
### Task Lists
......
......@@ -63,8 +63,12 @@ class MarkdownFeature
@label ||= create(:label, name: 'awaiting feedback', project: project)
end
def simple_milestone
@simple_milestone ||= create(:milestone, name: 'gfm-milestone', project: project)
end
def milestone
@milestone ||= create(:milestone, project: project)
@milestone ||= create(:milestone, name: 'next goal', project: project)
end
# Cross-references -----------------------------------------------------------
......
......@@ -154,7 +154,7 @@ module MarkdownMatchers
set_default_markdown_messages
match do |actual|
expect(actual).to have_selector('a.gfm.gfm-milestone', count: 3)
expect(actual).to have_selector('a.gfm.gfm-milestone', count: 5)
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment