From 228007dfbcd8f97c66c1802f3b69abd7d02c7d26 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Fri, 12 Feb 2016 19:42:25 +0100 Subject: [PATCH] new-branch-button --- CHANGELOG | 2 ++ app/assets/stylesheets/pages/issues.scss | 5 +++++ app/controllers/projects/branches_controller.rb | 16 +++++++++++++--- app/controllers/projects/issues_controller.rb | 1 + app/models/issue.rb | 14 ++++++++++++++ app/services/merge_requests/build_service.rb | 11 +++++++++++ .../projects/issues/_merge_requests.html.haml | 2 +- app/views/projects/issues/_new_branch.html.haml | 5 +++++ .../projects/issues/_related_branches.html.haml | 15 +++++++++++++++ app/views/projects/issues/show.html.haml | 2 ++ spec/models/issue_spec.rb | 12 ++++++++++++ 11 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 app/views/projects/issues/_new_branch.html.haml create mode 100644 app/views/projects/issues/_related_branches.html.haml diff --git a/CHANGELOG b/CHANGELOG index 7f076f70c7c..fe65e7b34fc 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -175,6 +175,8 @@ v 8.5.0 - Add label description (Nuttanart Pornprasitsakul) - Show label row when filtering issues or merge requests by label (Nuttanart Pornprasitsakul) - Add Todos + - User project limit is reached notice is hidden if the projects limit is zero + - New branch button appears on issues where applicable (Zeger-Jan van de Weg) v 8.4.5 - No CE-specific changes diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 1b686c58eaf..5f1810cbaf6 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -49,6 +49,11 @@ form.edit-issue { margin: 0; } +.related-branches-title { + font-size: 16px; + font-weight: 600; +} + .merge-requests-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..cf68f50b1f9 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,8 +23,7 @@ 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) @@ -49,4 +48,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..243d9a5db62 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -94,6 +94,10 @@ class Issue < ActiveRecord::Base end.sort_by(&:iid) end + def related_branches + self.project.repository.branch_names.select { |branch| /\A#{iid}-/ =~ branch } + end + # Reset issue events cache # # Since we do cache @event we need to reset cache in special cases: @@ -120,4 +124,14 @@ 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}"[0,25] + end + + def new_branch_button?(current_user) + !self.closed? && + referenced_merge_requests(current_user).empty? && + related_branches.empty? + end end diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb index 954746a39a5..8f1b735b8df 100644 --- a/app/services/merge_requests/build_service.rb +++ b/app/services/merge_requests/build_service.rb @@ -47,6 +47,17 @@ 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 merge_request.source_branch =~ /\A\d+-/ + closes_issue = "Closes ##{Regexp.last_match(0)[0...-1]}" + closes_issue.prepend("\n") if merge_request.description.present? + + merge_request.description << closes_issue + end + merge_request end 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..4d5fa61a91a --- /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.new_branch_button?(current_user) + .pull-right + = link_to namespace_project_branches_path(@project.namespace, @project, branch_name: @issue.to_branch_name), method: :post, class: 'btn' 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..56387661989 --- /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) 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 diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index 7f44ca2f7db..d572a71cf46 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -140,4 +140,16 @@ describe Issue, models: true do it_behaves_like 'a Taskable' do let(:subject) { create :issue } end + + describe "#to_branch_name" do + let(:issue) { build(:issue, title: 'a' * 30) } + + it "is expected not to exceed 25 chars" do + expect(issue.to_branch_name.length).to eq 25 + end + + it "starts with the issue iid" do + expect(issue.to_branch_name).to match /\A#{issue.iid}-a+\z/ + end + end end