Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2016-03-17 17:14:32 +0300
committerDouwe Maan <douwe@gitlab.com>2016-03-17 17:14:32 +0300
commitcf2e3ff6f985c1ffdab9b795d79f792d3ea115fa (patch)
tree74e94840970e7fcdcc810482cba3bf27d2e83f31 /app
parent4874c549c618db98888cfa5adc84543d872f655f (diff)
parent9337406671755ebd9175866cd86f1d6da4265d49 (diff)
Merge branch 'new-branch-button-issue' into 'master'
New branch button on issues Creates a button which creates a branch for you, referencing the original issue in the branch name. When creating the MR the text `Closes #iid` is appended to the description field. The button; with styling ![Screenshot_from_2016-02-13_17-28-54](/uploads/9595fbfef88c10a499829beaa3db11c1/Screenshot_from_2016-02-13_17-28-54.png) Links to the related branches on the issue ![Screenshot_from_2016-02-13_17-31-48](/uploads/ee7a78754eb5e2389f8671771bb59af9/Screenshot_from_2016-02-13_17-31-48.png) Styled like the MR links ![Screenshot_from_2016-02-13_17-31-53](/uploads/c60130333a650a16f51b014aeb1458c3/Screenshot_from_2016-02-13_17-31-53.png) Please provide input on the following; the CI repo on the GDK had the following happening with the current way I implemented the matching: ![Screenshot_from_2016-02-14_08-57-19](/uploads/35e7a3687a0fa801aba1ad66305ab2ff/Screenshot_from_2016-02-14_08-57-19.png) Closes #3886 cc @DouweM See merge request !2808
Diffstat (limited to 'app')
-rw-r--r--app/assets/stylesheets/pages/issues.scss2
-rw-r--r--app/controllers/projects/branches_controller.rb21
-rw-r--r--app/controllers/projects/issues_controller.rb1
-rw-r--r--app/models/issue.rb31
-rw-r--r--app/services/merge_requests/build_service.rb15
-rw-r--r--app/services/system_note_service.rb12
-rw-r--r--app/views/projects/issues/_merge_requests.html.haml2
-rw-r--r--app/views/projects/issues/_new_branch.html.haml5
-rw-r--r--app/views/projects/issues/_related_branches.html.haml15
-rw-r--r--app/views/projects/issues/show.html.haml2
10 files changed, 96 insertions, 10 deletions
diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss
index 73718ff511a..7ac4bc468d6 100644
--- a/app/assets/stylesheets/pages/issues.scss
+++ b/app/assets/stylesheets/pages/issues.scss
@@ -49,7 +49,7 @@ form.edit-issue {
margin: 0;
}
-.merge-requests-title {
+.merge-requests-title, .related-branches-title {
font-size: 16px;
font-weight: 600;
}
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index 4db3b3bf23d..43ea717cbd2 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -9,7 +9,7 @@ class Projects::BranchesController < Projects::ApplicationController
@sort = params[:sort] || 'name'
@branches = @repository.branches_sorted_by(@sort)
@branches = Kaminari.paginate_array(@branches).page(params[:page]).per(PER_PAGE)
-
+
@max_commits = @branches.reduce(0) do |memo, branch|
diverging_commit_counts = repository.diverging_commit_counts(branch)
[memo, diverging_commit_counts[:behind], diverging_commit_counts[:ahead]].max
@@ -23,11 +23,15 @@ class Projects::BranchesController < Projects::ApplicationController
def create
branch_name = sanitize(strip_tags(params[:branch_name]))
branch_name = Addressable::URI.unescape(branch_name)
- ref = sanitize(strip_tags(params[:ref]))
- ref = Addressable::URI.unescape(ref)
+
result = CreateBranchService.new(project, current_user).
execute(branch_name, ref)
+ if params[:issue_iid]
+ issue = @project.issues.find_by(iid: params[:issue_iid])
+ SystemNoteService.new_issue_branch(issue, @project, current_user, branch_name) if issue
+ end
+
if result[:status] == :success
@branch = result[:branch]
redirect_to namespace_project_tree_path(@project.namespace, @project,
@@ -49,4 +53,15 @@ class Projects::BranchesController < Projects::ApplicationController
format.js { render status: status[:return_code] }
end
end
+
+ private
+
+ def ref
+ if params[:ref]
+ ref_escaped = sanitize(strip_tags(params[:ref]))
+ Addressable::URI.unescape(ref_escaped)
+ else
+ @project.default_branch
+ end
+ end
end
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index b0a03ee45cc..aa7a178dcf4 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -65,6 +65,7 @@ class Projects::IssuesController < Projects::ApplicationController
@notes = @issue.notes.nonawards.with_associations.fresh
@noteable = @issue
@merge_requests = @issue.referenced_merge_requests(current_user)
+ @related_branches = @issue.related_branches - @merge_requests.map(&:source_branch)
respond_with(@issue)
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 5f58c0508fd..2447f860c5a 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -87,11 +87,21 @@ class Issue < ActiveRecord::Base
end
def referenced_merge_requests(current_user = nil)
- Gitlab::ReferenceExtractor.lazily do
- [self, *notes].flat_map do |note|
- note.all_references(current_user).merge_requests
- end
- end.sort_by(&:iid)
+ @referenced_merge_requests ||= {}
+ @referenced_merge_requests[current_user] ||= begin
+ Gitlab::ReferenceExtractor.lazily do
+ [self, *notes].flat_map do |note|
+ note.all_references(current_user).merge_requests
+ end
+ end.sort_by(&:iid).uniq
+ end
+ end
+
+ def related_branches
+ return [] if self.project.empty_repo?
+ self.project.repository.branch_names.select do |branch|
+ branch =~ /\A#{iid}-(?!\d+-stable)/i
+ end
end
# Reset issue events cache
@@ -120,4 +130,15 @@ class Issue < ActiveRecord::Base
note.all_references(current_user).merge_requests
end.uniq.select { |mr| mr.open? && mr.closes_issue?(self) }
end
+
+ def to_branch_name
+ "#{iid}-#{title.parameterize}"
+ end
+
+ def can_be_worked_on?(current_user)
+ !self.closed? &&
+ !self.project.forked? &&
+ self.related_branches.empty? &&
+ self.closed_by_merge_requests(current_user).empty?
+ end
end
diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb
index 954746a39a5..fa34753c4fd 100644
--- a/app/services/merge_requests/build_service.rb
+++ b/app/services/merge_requests/build_service.rb
@@ -47,6 +47,21 @@ module MergeRequests
merge_request.title = merge_request.source_branch.titleize.humanize
end
+ # When your branch name starts with an iid followed by a dash this pattern will
+ # be interpreted as the use wants to close that issue on this project
+ # Pattern example: 112-fix-mep-mep
+ # Will lead to appending `Closes #112` to the description
+ if match = merge_request.source_branch.match(/\A(\d+)-/)
+ iid = match[1]
+ closes_issue = "Closes ##{iid}"
+
+ if merge_request.description.present?
+ merge_request.description << closes_issue.prepend("\n")
+ else
+ merge_request.description = closes_issue
+ end
+ end
+
merge_request
end
diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb
index 58a861ee08e..f09b77c4a57 100644
--- a/app/services/system_note_service.rb
+++ b/app/services/system_note_service.rb
@@ -207,6 +207,18 @@ class SystemNoteService
create_note(noteable: noteable, project: project, author: author, note: body)
end
+ # Called when a branch is created from the 'new branch' button on a issue
+ # Example note text:
+ #
+ # "Started branch `201-issue-branch-button`"
+ def self.new_issue_branch(issue, project, author, branch)
+ h = Gitlab::Application.routes.url_helpers
+ link = h.namespace_project_compare_url(project.namespace, project, from: project.default_branch, to: branch)
+
+ body = "Started branch [`#{branch}`](#{link})"
+ create_note(noteable: issue, project: project, author: author, note: body)
+ end
+
# Called when a Mentionable references a Noteable
#
# noteable - Noteable object being referenced
diff --git a/app/views/projects/issues/_merge_requests.html.haml b/app/views/projects/issues/_merge_requests.html.haml
index d9868ad1f0a..d6b38b327ff 100644
--- a/app/views/projects/issues/_merge_requests.html.haml
+++ b/app/views/projects/issues/_merge_requests.html.haml
@@ -1,4 +1,4 @@
--if @merge_requests.any?
+- if @merge_requests.any?
%h2.merge-requests-title
= pluralize(@merge_requests.count, 'Related Merge Request')
%ul.unstyled-list
diff --git a/app/views/projects/issues/_new_branch.html.haml b/app/views/projects/issues/_new_branch.html.haml
new file mode 100644
index 00000000000..e66e4669d48
--- /dev/null
+++ b/app/views/projects/issues/_new_branch.html.haml
@@ -0,0 +1,5 @@
+- if current_user && can?(current_user, :push_code, @project) && @issue.can_be_worked_on?(current_user)
+ .pull-right
+ = link_to namespace_project_branches_path(@project.namespace, @project, branch_name: @issue.to_branch_name, issue_iid: @issue.iid), method: :post, class: 'btn', title: @issue.to_branch_name do
+ = icon('code-fork')
+ New Branch
diff --git a/app/views/projects/issues/_related_branches.html.haml b/app/views/projects/issues/_related_branches.html.haml
new file mode 100644
index 00000000000..b10cd03515f
--- /dev/null
+++ b/app/views/projects/issues/_related_branches.html.haml
@@ -0,0 +1,15 @@
+- if @related_branches.any?
+ %h2.related-branches-title
+ = pluralize(@related_branches.count, 'Related Branch')
+ %ul.unstyled-list
+ - @related_branches.each do |branch|
+ %li
+ - sha = @project.repository.find_branch(branch).target
+ - ci_commit = @project.ci_commit(sha) if sha
+ - if ci_commit
+ %span.related-branch-ci-status
+ = render_ci_status(ci_commit)
+ %span.related-branch-info
+ %strong
+ = link_to namespace_project_compare_path(@project.namespace, @project, from: @project.default_branch, to: branch), class: "label-branch" do
+ = branch
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index 0242276cd84..1e8308277cc 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -70,8 +70,10 @@
.merge-requests
= render 'merge_requests'
+ = render 'related_branches'
.content-block.content-block-small
+ = render 'new_branch'
= render 'votes/votes_block', votable: @issue
.row