Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce

Conflicts:
	lib/gitlab/markdown.rb
This commit is contained in:
Marin Jankovski 2015-03-31 19:03:54 -07:00
commit d77f333f9c
21 changed files with 263 additions and 101 deletions

View File

@ -49,6 +49,9 @@ v 7.10.0 (unreleased)
- Improve file icons rendering on tree (Sullivan Sénéchal)
- API: Add pagination to project events
- Get issue links in notification mail to work again.
- Don't show commit comment button when user is not signed in.
- Fix admin user projects lists.
- Don't leak private group existence by redirecting from namespace controller to group controller.
v 7.9.0
- Send EmailsOnPush email when branch or tag is created or deleted.

View File

@ -100,6 +100,8 @@ class Dispatcher
when 'users:show'
new User()
new Activities()
when 'admin:users:show'
new ProjectsList()
switch path.first()
when 'admin'

View File

@ -9,12 +9,8 @@ class @Issue
if $("a.btn-close").length
$("li.task-list-item input:checkbox").prop("disabled", false)
$(".task-list-item input:checkbox").on(
"click"
null
"issue"
updateTaskState
)
$('.task-list-item input:checkbox').off('change')
$('.task-list-item input:checkbox').change('issue', updateTaskState)
$('.issue-details').waitForImages ->
$('.issuable-affix').affix offset:

View File

@ -81,12 +81,8 @@ class @MergeRequest
this.$('.remove_source_branch_in_progress').hide()
this.$('.remove_source_branch_widget.failed').show()
$(".task-list-item input:checkbox").on(
"click"
null
"merge_request"
updateTaskState
)
$('.task-list-item input:checkbox').off('change')
$('.task-list-item input:checkbox').change('merge_request', updateTaskState)
activateTab: (action) ->
this.$('.merge-request-tabs li').removeClass 'active'

View File

@ -246,7 +246,7 @@ li.note {
.milestone {
&.milestone-closed {
background: #eee;
background: #f9f9f9;
}
.progress {
margin-bottom: 0;

View File

@ -4,14 +4,22 @@ class NamespacesController < ApplicationController
def show
namespace = Namespace.find_by(path: params[:id])
unless namespace
return render_404
if namespace
if namespace.is_a?(Group)
group = namespace
else
user = namespace.owner
end
end
if namespace.type == "Group"
redirect_to group_path(namespace)
if user
redirect_to user_path(user)
elsif group && can?(current_user, :read_group, group)
redirect_to group_path(group)
elsif current_user.nil?
authenticate_user!
else
redirect_to user_path(namespace.owner)
render_404
end
end
end

View File

@ -29,6 +29,10 @@ module GitlabRoutingHelper
namespace_project_merge_request_path(entity.project.namespace, entity.project, entity, *args)
end
def milestone_path(entity, *args)
namespace_project_milestone_path(entity.project.namespace, entity.project, entity, *args)
end
def project_url(project, *args)
namespace_project_url(project.namespace, project, *args)
end

View File

@ -52,7 +52,7 @@ module Mentionable
if identifier == "all"
users.push(*project.team.members.flatten)
elsif namespace = Namespace.find_by(path: identifier)
if namespace.type == "Group"
if namespace.is_a?(Group)
users.push(*namespace.users)
else
users << namespace.owner

View File

@ -0,0 +1,20 @@
%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) }
%h4
= link_to_gfm truncate(milestone.title, length: 100), dashboard_milestone_path(milestone.safe_title, title: milestone.title)
.row
.col-sm-6
= link_to dashboard_milestone_path(milestone.safe_title, title: milestone.title) do
= pluralize milestone.issue_count, 'Issue'
&nbsp;
= link_to dashboard_milestone_path(milestone.safe_title, title: milestone.title) do
= pluralize milestone.merge_requests_count, 'Merge Request'
&nbsp;
%span.light #{milestone.percent_complete}% complete
.col-sm-6
= milestone_progress_bar(milestone)
%div
- milestone.milestones.each do |milestone|
= link_to milestone_path(milestone) do
%span.label.label-gray
= milestone.project.name_with_namespace

View File

@ -16,23 +16,5 @@
.nothing-here-block No milestones to show
- else
- @dashboard_milestones.each do |milestone|
%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) }
%h4
= link_to_gfm truncate(milestone.title, length: 100), dashboard_milestone_path(milestone.safe_title, title: milestone.title)
%div
%div
= link_to dashboard_milestone_path(milestone.safe_title, title: milestone.title) do
= pluralize milestone.issue_count, 'Issue'
&nbsp;
= link_to dashboard_milestone_path(milestone.safe_title, title: milestone.title) do
= pluralize milestone.merge_requests_count, 'Merge Request'
&nbsp;
%span.light #{milestone.percent_complete}% complete
= milestone_progress_bar(milestone)
%div
%br
- milestone.milestones.each do |milestone|
= link_to namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone) do
%span.label.label-default
= milestone.project.name_with_namespace
= render 'milestone', milestone: milestone
= paginate @dashboard_milestones, theme: "gitlab"

View File

@ -0,0 +1,25 @@
%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) }
.pull-right
- if can?(current_user, :manage_group, @group)
- if milestone.closed?
= link_to 'Reopen Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-sm btn-grouped btn-reopen"
- else
= link_to 'Close Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-sm btn-close"
%h4
= link_to_gfm truncate(milestone.title, length: 100), group_milestone_path(@group, milestone.safe_title, title: milestone.title)
.row
.col-sm-6
= link_to group_milestone_path(@group, milestone.safe_title, title: milestone.title) do
= pluralize milestone.issue_count, 'Issue'
&nbsp;
= link_to group_milestone_path(@group, milestone.safe_title, title: milestone.title) do
= pluralize milestone.merge_requests_count, 'Merge Request'
&nbsp;
%span.light #{milestone.percent_complete}% complete
.col-sm-6
= milestone_progress_bar(milestone)
%div
- milestone.milestones.each do |milestone|
= link_to milestone_path(milestone) do
%span.label.label-gray
= milestone.project.name

View File

@ -18,29 +18,5 @@
.nothing-here-block No milestones to show
- else
- @group_milestones.each do |milestone|
%li{class: "milestone milestone-#{milestone.closed? ? 'closed' : 'open'}", id: dom_id(milestone.milestones.first) }
.pull-right
- if can?(current_user, :manage_group, @group)
- if milestone.closed?
= link_to 'Reopen Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :activate }), method: :put, class: "btn btn-sm btn-grouped btn-reopen"
- else
= link_to 'Close Milestone', group_milestone_path(@group, milestone.safe_title, title: milestone.title, milestone: {state_event: :close }), method: :put, class: "btn btn-sm btn-close"
%h4
= link_to_gfm truncate(milestone.title, length: 100), group_milestone_path(@group, milestone.safe_title, title: milestone.title)
%div
%div
= link_to group_milestone_path(@group, milestone.safe_title, title: milestone.title) do
= pluralize milestone.issue_count, 'Issue'
&nbsp;
= link_to group_milestone_path(@group, milestone.safe_title, title: milestone.title) do
= pluralize milestone.merge_requests_count, 'Merge Request'
&nbsp;
%span.light #{milestone.percent_complete}% complete
= milestone_progress_bar(milestone)
%div
%br
- milestone.milestones.each do |milestone|
= link_to namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone) do
%span.label.label-default
= milestone.project.name
= render 'milestone', milestone: milestone
= paginate @group_milestones, theme: "gitlab"

View File

@ -11,16 +11,14 @@
%span.cred (Expired)
%small
= milestone.expires_at
- if milestone.is_empty?
%span.muted Empty
- else
%div
%div
= link_to namespace_project_issues_path(milestone.project.namespace, milestone.project, milestone_id: milestone.id) do
= pluralize milestone.issues.count, 'Issue'
&nbsp;
= link_to namespace_project_merge_requests_path(milestone.project.namespace, milestone.project, milestone_id: milestone.id) do
= pluralize milestone.merge_requests.count, 'Merge Request'
&nbsp;
%span.light #{milestone.percent_complete}% complete
.row
.col-sm-6
= link_to namespace_project_issues_path(milestone.project.namespace, milestone.project, milestone_id: milestone.id) do
= pluralize milestone.issues.count, 'Issue'
&nbsp;
= link_to namespace_project_merge_requests_path(milestone.project.namespace, milestone.project, milestone_id: milestone.id) do
= pluralize milestone.merge_requests.count, 'Merge Request'
&nbsp;
%span.light #{milestone.percent_complete}% complete
.col-sm-6
= milestone_progress_bar(milestone)

View File

@ -15,5 +15,5 @@
if(current_url == log_url) {
// Load 10 more commit log for each file in tree
// if we still on the same page
ajaxGet('#{logs_file_namespace_project_ref_path(@project.namespace, @project, @ref, @path || '/', offset: (@offset + @limit))}');
ajaxGet('#{logs_file_namespace_project_ref_path(@project.namespace, @project, @ref, @path || '', offset: (@offset + @limit))}');
}

View File

@ -1,13 +1,13 @@
- if @contributed_projects.present?
- if local_assigns.has_key?(:contributed_projects) && contributed_projects.present?
.panel.panel-default.contributed-projects
.panel-heading Projects contributed to
= render 'shared/projects_list',
projects: @contributed_projects.sort_by(&:star_count).reverse,
projects: contributed_projects.sort_by(&:star_count).reverse,
projects_limit: 5, stars: true, avatar: false
- if @projects.present?
- if local_assigns.has_key?(:projects) && projects.present?
.panel.panel-default
.panel-heading Personal projects
= render 'shared/projects_list',
projects: @projects.sort_by(&:star_count).reverse,
projects: projects.sort_by(&:star_count).reverse,
projects_limit: 10, stars: true, avatar: false

View File

@ -44,7 +44,7 @@
= spinner
%aside.col-md-4
= render 'profile', user: @user
= render 'projects'
= render 'projects', projects: @projects, contributed_projects: @contributed_projects
:coffeescript
$(".user-calendar").load("#{user_calendar_path}")

View File

@ -66,8 +66,8 @@ production: &base
# If a commit message matches this regular expression, all issues referenced from the matched text will be closed.
# This happens when the commit is pushed or merged into the default branch of a project.
# When not specified the default issue_closing_pattern as specified below will be used.
# Tip: you can test your closing pattern at http://rubular.com
# issue_closing_pattern: '((?:[Cc]los(?:e[sd]|ing)|[Ff]ix(?:e[sd]|ing)?) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)'
# Tip: you can test your closing pattern at http://rubular.com.
# issue_closing_pattern: '((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)'
## Default project features settings
default_projects_features:

View File

@ -1,5 +1,36 @@
# Issue closing pattern
By default you can close issues from commit messages by saying 'Closes #12' or 'Fixed #101'.
If a commit message matches the regular expression below, all issues referenced from
the matched text will be closed. This happens when the commit is pushed or merged
into the default branch of a project.
If you want to customize the message please do so in [gitlab.yml](https://gitlab.com/gitlab-org/gitlab-ce/blob/73b92f85bcd6c213b845cc997843a969cf0906cf/config/gitlab.yml.example#L73)
When not specified, the default issue_closing_pattern as shown below will be used:
```bash
((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)
```
For example:
```
git commit -m "Awesome commit message (Fix #20, Fixes #21 and Closes #22). This commit is also related to #17 and fixes #18, #19 and #23."
```
will close `#20`, `#21`, `#22`, `#18`, `#19` and `#23`, but `#17` won't be closed
as it does not match the pattern. It also works with multiline commit messages.
Tip: you can test this closing pattern at [http://rubular.com][1]. Use this site
to test your own patterns.
## Change the pattern
For Omnibus installs you can change the default pattern in `/etc/gitlab/gitlab.rb`:
```
issue_closing_pattern: '((?:[Cc]los(?:e[sd]|ing)|[Ff]ix(?:e[sd]|ing)?) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)'
```
For manual installs you can customize the pattern in [gitlab.yml][0].
[0]: https://gitlab.com/gitlab-org/gitlab-ce/blob/40c3675372320febf5264061c9bcd63db2dfd13c/config/gitlab.yml.example#L65
[1]: http://rubular.com/r/Xmbexed1OJ

View File

@ -1,5 +1,4 @@
require 'mime/types'
require 'uri'
module API
# Projects API
@ -101,10 +100,11 @@ module API
# branch (required) - The name of the branch
# Example Request:
# DELETE /projects/:id/repository/branches/:branch
delete ":id/repository/branches/:branch" do
delete ":id/repository/branches/:branch",
requirements: { branch: /.*/ } do
authorize_push_project
result = DeleteBranchService.new(user_project, current_user).
execute(URI.unescape(params[:branch]))
execute(params[:branch])
if result[:status] == :success
{

View File

@ -121,7 +121,7 @@ module Gitlab
markdown_pipeline = HTML::Pipeline::Gitlab.new(filters).pipeline
result = markdown_pipeline.call(text, markdown_context)
save_options = 0
if options[:xhtml]
save_options |= Nokogiri::XML::Node::SaveOptions::AS_XHTML
@ -244,18 +244,18 @@ module Gitlab
if identifier == "all"
link_to(
"@all",
namespace_project_url(project.namespace, project, only_path: options[:reference_only_path]),
"@all",
namespace_project_url(project.namespace, project, only_path: options[:reference_only_path]),
link_options
)
elsif namespace = Namespace.find_by(path: identifier)
url =
if namespace.type == "Group"
if namespace.is_a?(Group)
group_url(identifier, only_path: options[:reference_only_path])
else
else
user_url(identifier, only_path: options[:reference_only_path])
end
link_to("@#{identifier}", url, link_options)
end
end
@ -300,7 +300,7 @@ module Gitlab
class: "gfm gfm-merge_request #{html_options[:class]}"
)
url = namespace_project_merge_request_url(project.namespace, project,
merge_request,
merge_request,
only_path: options[:reference_only_path])
link_to("#{prefix_text}!#{identifier}", url, link_options)
end
@ -314,7 +314,7 @@ module Gitlab
)
link_to(
"$#{identifier}",
namespace_project_snippet_url(project.namespace, project, snippet,
namespace_project_snippet_url(project.namespace, project, snippet,
only_path: options[:reference_only_path]),
link_options
)
@ -330,7 +330,7 @@ module Gitlab
prefix_text = "#{prefix_text}@" if prefix_text
link_to(
"#{prefix_text}#{identifier}",
namespace_project_commit_url( project.namespace, project, commit,
namespace_project_commit_url( project.namespace, project, commit,
only_path: options[:reference_only_path]),
link_options
)
@ -343,8 +343,8 @@ module Gitlab
inclusive = identifier !~ /\.{3}/
from_id << "^" if inclusive
if project.valid_repo? &&
from = project.repository.commit(from_id) &&
if project.valid_repo? &&
from = project.repository.commit(from_id) &&
to = project.repository.commit(to_id)
link_options = html_options.merge(
@ -355,8 +355,8 @@ module Gitlab
link_to(
"#{prefix_text}#{identifier}",
namespace_project_compare_url(project.namespace, project,
from: from_id, to: to_id,
namespace_project_compare_url(project.namespace, project,
from: from_id, to: to_id,
only_path: options[:reference_only_path]),
link_options
)

View File

@ -0,0 +1,121 @@
require 'spec_helper'
describe NamespacesController do
let!(:user) { create(:user, avatar: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")) }
describe "GET show" do
context "when the namespace belongs to a user" do
let!(:other_user) { create(:user) }
it "redirects to the user's page" do
get :show, id: other_user.username
expect(response).to redirect_to(user_path(other_user))
end
end
context "when the namespace belongs to a group" do
let!(:group) { create(:group) }
let!(:project) { create(:project, namespace: group) }
context "when the group has public projects" do
before do
project.update_attribute(:visibility_level, Project::PUBLIC)
end
context "when not signed in" do
it "redirects to the group's page" do
get :show, id: group.path
expect(response).to redirect_to(group_path(group))
end
end
context "when signed in" do
before do
sign_in(user)
end
it "redirects to the group's page" do
get :show, id: group.path
expect(response).to redirect_to(group_path(group))
end
end
end
context "when the project doesn't have public projects" do
context "when not signed in" do
it "redirects to the sign in page" do
get :show, id: group.path
expect(response).to redirect_to(new_user_session_path)
end
end
context "when signed in" do
before do
sign_in(user)
end
context "when the user has access to the project" do
before do
project.team << [user, :master]
end
context "when the user is blocked" do
before do
user.block
project.team << [user, :master]
end
it "redirects to the sign in page" do
get :show, id: group.path
expect(response).to redirect_to(new_user_session_path)
end
end
context "when the user isn't blocked" do
it "redirects to the group's page" do
get :show, id: group.path
expect(response).to redirect_to(group_path(group))
end
end
end
context "when the user doesn't have access to the project" do
it "responds with status 404" do
get :show, id: group.path
expect(response.status).to eq(404)
end
end
end
end
end
context "when the namespace doesn't exist" do
context "when signed in" do
before do
sign_in(user)
end
it "responds with status 404" do
get :show, id: "doesntexist"
expect(response.status).to eq(404)
end
end
context "when not signed in" do
it "redirects to the sign in page" do
get :show, id: "doesntexist"
expect(response).to redirect_to(new_user_session_path)
end
end
end
end
end