Commit 6b04a5f9108c640f638afa8055e2a5b60f926d5a

Authored by Marin Jankovski
Committed by Dmitriy Zaporozhets
1 parent 1f1c59b6

Add support for Jira ticket mentions in format JIRA-123.

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>

Conflicts:
	CHANGELOG-EE
doc/integration/external-issue-tracker.md
... ... @@ -2,8 +2,8 @@ GitLab has a great issue tracker but you can also use an external issue tracker
2 2  
3 3 - the 'Issues' link on the GitLab project pages takes you to the appropriate JIRA issue index;
4 4 - clicking 'New issue' on the project dashboard creates a new JIRA issue;
5   -- To reference JIRA issue PROJECT-1234 in comments, use syntax #PROJECT-1234. Commit messages get turned into HTML links to the corresponding JIRA issue.
  5 +- To reference JIRA issue PROJECT-1234 in comments, use syntax PROJECT-1234. Commit messages get turned into HTML links to the corresponding JIRA issue.
6 6  
7 7 ![jira screenshot](jira-integration-points.png)
8 8  
9   -You can configure the integration in the gitlab.yml configuration file.
10 9 \ No newline at end of file
  10 +You can configure the integration in the gitlab.yml configuration file.
... ...
lib/gitlab/markdown.rb
... ... @@ -98,6 +98,7 @@ module Gitlab
98 98 (?<prefix>\W)? # Prefix
99 99 ( # Reference
100 100 @(?<user>[a-zA-Z][a-zA-Z0-9_\-\.]*) # User name
  101 + |(?<issue>([A-Z\-]+-)\d+) # JIRA Issue ID
101 102 |\#(?<issue>([a-zA-Z\-]+-)?\d+) # Issue ID
102 103 |!(?<merge_request>\d+) # MR ID
103 104 |\$(?<snippet>\d+) # Snippet ID
... ... @@ -172,11 +173,15 @@ module Gitlab
172 173 end
173 174  
174 175 def reference_issue(identifier)
175   - if @project.issue_exists? identifier
176   - url = url_for_issue(identifier)
177   - title = title_for_issue(identifier)
  176 + if @project.used_default_issues_tracker? || !external_issues_tracker_enabled?
  177 + if @project.issue_exists? identifier
  178 + url = url_for_issue(identifier)
  179 + title = title_for_issue(identifier)
178 180  
179   - link_to("##{identifier}", url, html_options.merge(title: "Issue: #{title}", class: "gfm gfm-issue #{html_options[:class]}"))
  181 + link_to("##{identifier}", url, html_options.merge(title: "Issue: #{title}", class: "gfm gfm-issue #{html_options[:class]}"))
  182 + end
  183 + else
  184 + reference_jira_issue(identifier) if @project.issues_tracker == "jira"
180 185 end
181 186 end
182 187  
... ... @@ -197,5 +202,12 @@ module Gitlab
197 202 link_to(identifier, project_commit_url(@project, commit), html_options.merge(title: commit.link_title, class: "gfm gfm-commit #{html_options[:class]}"))
198 203 end
199 204 end
  205 +
  206 + def reference_jira_issue(identifier)
  207 + url = url_for_issue(identifier)
  208 + title = Gitlab.config.issues_tracker[@project.issues_tracker]["title"]
  209 +
  210 + link_to("#{identifier}", url, html_options.merge(title: "Issue in #{title}", class: "gfm gfm-issue #{html_options[:class]}"))
  211 + end
200 212 end
201 213 end
... ...
spec/helpers/gitlab_markdown_helper_spec.rb
... ... @@ -181,6 +181,52 @@ describe GitlabMarkdownHelper do
181 181 include_examples 'referenced object'
182 182 end
183 183  
  184 + describe "referencing a Jira issue" do
  185 + let(:actual) { "Reference to JIRA-#{issue.iid}" }
  186 + let(:expected) { "http://jira.example/browse/JIRA-#{issue.iid}" }
  187 + let(:reference) { "JIRA-#{issue.iid}" }
  188 +
  189 + before do
  190 + hash = { "jira" => { "title" => "JIRA tracker", "issues_url" => "http://jira.example/browse/:id" } }
  191 + Gitlab.config.stub(:issues_tracker).and_return(hash)
  192 + @project.stub(:issues_tracker).and_return("jira")
  193 + @project.stub(:issues_tracker_id).and_return("JIRA")
  194 + end
  195 +
  196 + it "should link using a valid id" do
  197 + gfm(actual).should match(expected)
  198 + end
  199 +
  200 + it "should link with adjacent text" do
  201 + # Wrap the reference in parenthesis
  202 + gfm(actual.gsub(reference, "(#{reference})")).should match(expected)
  203 +
  204 + # Append some text to the end of the reference
  205 + gfm(actual.gsub(reference, "#{reference}, right?")).should match(expected)
  206 + end
  207 +
  208 + it "should keep whitespace intact" do
  209 + actual = "Referenced #{reference} already."
  210 + expected = /Referenced <a.+>[^\s]+<\/a> already/
  211 + gfm(actual).should match(expected)
  212 + end
  213 +
  214 + it "should not link with an invalid id" do
  215 + # Modify the reference string so it's still parsed, but is invalid
  216 + invalid_reference = actual.gsub(/(\d+)$/, "r45")
  217 + gfm(invalid_reference).should == invalid_reference
  218 + end
  219 +
  220 + it "should include a title attribute" do
  221 + title = "Issue in JIRA tracker"
  222 + gfm(actual).should match(/title="#{title}"/)
  223 + end
  224 +
  225 + it "should include standard gfm classes" do
  226 + gfm(actual).should match(/class="\s?gfm gfm-issue\s?"/)
  227 + end
  228 + end
  229 +
184 230 describe "referencing a merge request" do
185 231 let(:object) { merge_request }
186 232 let(:reference) { "!#{merge_request.iid}" }
... ...
spec/lib/gitlab/reference_extractor_spec.rb
... ... @@ -11,6 +11,12 @@ describe Gitlab::ReferenceExtractor do
11 11 subject.issues.should == ["1234"]
12 12 end
13 13  
  14 + it 'extracts JIRA issue references' do
  15 + Gitlab.config.gitlab.stub(:issues_tracker).and_return("jira")
  16 + subject.analyze "this one talks about issue JIRA-1234"
  17 + subject.issues.should == ["JIRA-1234"]
  18 + end
  19 +
14 20 it 'extracts merge request references' do
15 21 subject.analyze "and here's !43, a merge request"
16 22 subject.merge_requests.should == ["43"]
... ...