summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2015-08-04 16:42:36 +0200
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2015-08-04 16:42:36 +0200
commitb48b07044b919c07de34434aea7cdba13d7c38a6 (patch)
tree5a6d9d8de1048280a595825aa5f47464455ad670 /app
parentc17f5d06aa4a55a8446928ea6b690ae8e09ce237 (diff)
parent326b827ce39f998ce75f58e9f649e6b50623f1aa (diff)
downloadgitlab-ce-b48b07044b919c07de34434aea7cdba13d7c38a6.tar.gz
Merge branch 'master' into drop-satellites
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Diffstat (limited to 'app')
-rw-r--r--app/assets/images/auth_buttons/bitbucket_64.png (renamed from app/assets/images/authbuttons/bitbucket_64.png)bin2163 -> 2163 bytes
-rw-r--r--app/assets/images/auth_buttons/github_64.pngbin0 -> 2625 bytes
-rw-r--r--app/assets/images/auth_buttons/gitlab_64.pngbin0 -> 2849 bytes
-rw-r--r--app/assets/images/auth_buttons/google_64.png (renamed from app/assets/images/authbuttons/google_64.png)bin5281 -> 5281 bytes
-rw-r--r--app/assets/images/auth_buttons/twitter_64.png (renamed from app/assets/images/authbuttons/twitter_64.png)bin4835 -> 4835 bytes
-rw-r--r--app/assets/images/authbuttons/github_64.pngbin4196 -> 0 bytes
-rw-r--r--app/assets/images/authbuttons/gitlab_64.pngbin6559 -> 0 bytes
-rw-r--r--app/assets/javascripts/application.js.coffee7
-rw-r--r--app/assets/javascripts/diff.js.coffee4
-rw-r--r--app/assets/javascripts/dispatcher.js.coffee5
-rw-r--r--app/assets/javascripts/line_highlighter.js.coffee2
-rw-r--r--app/assets/javascripts/merge_request.js.coffee12
-rw-r--r--app/assets/javascripts/merge_request_tabs.js.coffee10
-rw-r--r--app/assets/javascripts/notes.js.coffee3
-rw-r--r--app/assets/stylesheets/base/mixins.scss2
-rw-r--r--app/assets/stylesheets/generic/common.scss2
-rw-r--r--app/assets/stylesheets/generic/typography.scss4
-rw-r--r--app/assets/stylesheets/pages/diff.scss11
-rw-r--r--app/assets/stylesheets/pages/notes.scss4
-rw-r--r--app/assets/stylesheets/pages/projects.scss9
-rw-r--r--app/controllers/application_controller.rb6
-rw-r--r--app/controllers/groups/application_controller.rb6
-rw-r--r--app/controllers/groups/group_members_controller.rb4
-rw-r--r--app/controllers/groups_controller.rb6
-rw-r--r--app/controllers/import/bitbucket_controller.rb1
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb5
-rw-r--r--app/controllers/projects/milestones_controller.rb7
-rw-r--r--app/controllers/projects/network_controller.rb4
-rw-r--r--app/controllers/projects/refs_controller.rb6
-rw-r--r--app/controllers/projects/tree_controller.rb4
-rw-r--r--app/controllers/projects_controller.rb10
-rw-r--r--app/controllers/sessions_controller.rb2
-rw-r--r--app/helpers/auth_helper.rb50
-rw-r--r--app/helpers/blob_helper.rb8
-rw-r--r--app/helpers/emails_helper.rb4
-rw-r--r--app/helpers/oauth_helper.rb34
-rw-r--r--app/helpers/profile_helper.rb13
-rw-r--r--app/helpers/projects_helper.rb67
-rw-r--r--app/models/ability.rb63
-rw-r--r--app/models/application_setting.rb5
-rw-r--r--app/models/audit_event.rb14
-rw-r--r--app/models/concerns/issuable.rb10
-rw-r--r--app/models/group.rb6
-rw-r--r--app/models/project.rb18
-rw-r--r--app/models/project_services/gitlab_ci_service.rb8
-rw-r--r--app/models/repository.rb58
-rw-r--r--app/models/security_event.rb14
-rw-r--r--app/models/user.rb5
-rw-r--r--app/services/git_push_service.rb2
-rw-r--r--app/services/git_tag_push_service.rb6
-rw-r--r--app/services/issuable_base_service.rb6
-rw-r--r--app/services/issues/base_service.rb4
-rw-r--r--app/services/merge_requests/base_service.rb6
-rw-r--r--app/services/projects/create_service.rb2
-rw-r--r--app/views/admin/groups/show.html.haml34
-rw-r--r--app/views/admin/identities/_form.html.haml3
-rw-r--r--app/views/admin/identities/_identity.html.haml2
-rw-r--r--app/views/devise/sessions/_new_base.html.haml2
-rw-r--r--app/views/devise/sessions/_new_ldap.html.haml2
-rw-r--r--app/views/devise/shared/_omniauth_box.html.haml8
-rw-r--r--app/views/devise/shared/_signin_box.html.haml2
-rw-r--r--app/views/events/_event.html.haml15
-rw-r--r--app/views/explore/projects/_project.html.haml2
-rw-r--r--app/views/groups/group_members/_group_member.html.haml2
-rw-r--r--app/views/groups/group_members/index.html.haml2
-rw-r--r--app/views/layouts/notify.html.haml2
-rw-r--r--app/views/profiles/accounts/show.html.haml14
-rw-r--r--app/views/profiles/keys/_form.html.haml7
-rw-r--r--app/views/profiles/two_factor_auths/new.html.haml2
-rw-r--r--app/views/projects/blob/diff.html.haml2
-rw-r--r--app/views/projects/diffs/_text_file.html.haml3
-rw-r--r--app/views/projects/diffs/_warning.html.haml2
-rw-r--r--app/views/projects/issues/_issue.html.haml73
-rw-r--r--app/views/projects/merge_requests/_show.html.haml16
-rw-r--r--app/views/projects/merge_requests/branch_from.js.haml1
-rw-r--r--app/views/projects/merge_requests/branch_to.js.haml1
-rw-r--r--app/views/projects/merge_requests/widget/open/_missing_branch.html.haml6
-rw-r--r--app/views/projects/milestones/_milestone.html.haml4
-rw-r--r--app/views/projects/milestones/show.html.haml3
-rw-r--r--app/views/projects/network/show.html.haml6
-rw-r--r--app/views/projects/notes/_edit_form.html.haml5
-rw-r--r--app/views/projects/notes/_form.html.haml14
-rw-r--r--app/views/projects/notes/_hints.html.haml9
-rw-r--r--app/views/projects/notes/_note.html.haml7
-rw-r--r--app/views/projects/refs/logs_tree.js.haml8
-rw-r--r--app/views/projects/show.html.haml27
-rw-r--r--app/views/projects/tree/_tree.html.haml2
-rw-r--r--app/views/projects/wikis/show.html.haml6
-rw-r--r--app/views/shared/issuable/_context.html.haml4
-rw-r--r--app/views/shared/issuable/_form.html.haml4
-rw-r--r--app/workers/project_cache_worker.rb15
-rw-r--r--app/workers/repository_import_worker.rb2
92 files changed, 550 insertions, 308 deletions
diff --git a/app/assets/images/authbuttons/bitbucket_64.png b/app/assets/images/auth_buttons/bitbucket_64.png
index 4b90a57bc7d..4b90a57bc7d 100644
--- a/app/assets/images/authbuttons/bitbucket_64.png
+++ b/app/assets/images/auth_buttons/bitbucket_64.png
Binary files differ
diff --git a/app/assets/images/auth_buttons/github_64.png b/app/assets/images/auth_buttons/github_64.png
new file mode 100644
index 00000000000..182a1a3f734
--- /dev/null
+++ b/app/assets/images/auth_buttons/github_64.png
Binary files differ
diff --git a/app/assets/images/auth_buttons/gitlab_64.png b/app/assets/images/auth_buttons/gitlab_64.png
new file mode 100644
index 00000000000..99a40583b3a
--- /dev/null
+++ b/app/assets/images/auth_buttons/gitlab_64.png
Binary files differ
diff --git a/app/assets/images/authbuttons/google_64.png b/app/assets/images/auth_buttons/google_64.png
index fb64f8bee68..fb64f8bee68 100644
--- a/app/assets/images/authbuttons/google_64.png
+++ b/app/assets/images/auth_buttons/google_64.png
Binary files differ
diff --git a/app/assets/images/authbuttons/twitter_64.png b/app/assets/images/auth_buttons/twitter_64.png
index e3bd9169a34..e3bd9169a34 100644
--- a/app/assets/images/authbuttons/twitter_64.png
+++ b/app/assets/images/auth_buttons/twitter_64.png
Binary files differ
diff --git a/app/assets/images/authbuttons/github_64.png b/app/assets/images/authbuttons/github_64.png
deleted file mode 100644
index dc7c03d1005..00000000000
--- a/app/assets/images/authbuttons/github_64.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/authbuttons/gitlab_64.png b/app/assets/images/authbuttons/gitlab_64.png
deleted file mode 100644
index 31281a19444..00000000000
--- a/app/assets/images/authbuttons/gitlab_64.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee
index 8b041c490d8..bb0a0c51fd4 100644
--- a/app/assets/javascripts/application.js.coffee
+++ b/app/assets/javascripts/application.js.coffee
@@ -164,9 +164,10 @@ $ ->
$('.account-box').hover -> $(@).toggleClass('hover')
# Commit show suppressed diff
- $(".diff-content").on "click", ".supp_diff_link", ->
- $(@).next('table').show()
- $(@).remove()
+ $(document).on 'click', '.diff-content .js-show-suppressed-diff', ->
+ $container = $(@).parent()
+ $container.next('table').show()
+ $container.remove()
$('.navbar-toggle').on 'click', ->
$('.header-content .title').toggle()
diff --git a/app/assets/javascripts/diff.js.coffee b/app/assets/javascripts/diff.js.coffee
index 069f91c30e1..6d9b364cb8d 100644
--- a/app/assets/javascripts/diff.js.coffee
+++ b/app/assets/javascripts/diff.js.coffee
@@ -31,6 +31,10 @@ class @Diff
bottom: unfoldBottom
offset: offset
unfold: unfold
+ # indent is used to compensate for single space indent to fit
+ # '+' and '-' prepended to diff lines,
+ # see https://gitlab.com/gitlab-org/gitlab-ce/issues/707
+ indent: 1
$.get(link, params, (response) =>
target.parent().replaceWith(response)
diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee
index 2ab148bc296..81e73799271 100644
--- a/app/assets/javascripts/dispatcher.js.coffee
+++ b/app/assets/javascripts/dispatcher.js.coffee
@@ -128,7 +128,10 @@ class Dispatcher
shortcut_handler = new ShortcutsNavigation()
new ZenMode()
new DropzoneInput($('.wiki-form'))
- when 'snippets', 'labels', 'graphs'
+ when 'snippets'
+ shortcut_handler = new ShortcutsNavigation()
+ new ZenMode() if path[2] == 'show'
+ when 'labels', 'graphs'
shortcut_handler = new ShortcutsNavigation()
when 'project_members', 'deploy_keys', 'hooks', 'services', 'protected_branches'
shortcut_handler = new ShortcutsNavigation()
diff --git a/app/assets/javascripts/line_highlighter.js.coffee b/app/assets/javascripts/line_highlighter.js.coffee
index a8b3c1fa33e..e604e6025c2 100644
--- a/app/assets/javascripts/line_highlighter.js.coffee
+++ b/app/assets/javascripts/line_highlighter.js.coffee
@@ -70,7 +70,7 @@ class @LineHighlighter
@clearHighlight()
- lineNumber = $(event.target).data('line-number')
+ lineNumber = $(event.target).closest('a').data('line-number')
current = @hashToRange(@_hash)
unless current[0] && event.shiftKey
diff --git a/app/assets/javascripts/merge_request.js.coffee b/app/assets/javascripts/merge_request.js.coffee
index 7462975bd3d..b21cb7904b5 100644
--- a/app/assets/javascripts/merge_request.js.coffee
+++ b/app/assets/javascripts/merge_request.js.coffee
@@ -15,9 +15,7 @@ class @MergeRequest
this.$('.show-all-commits').on 'click', =>
this.showAllCommits()
- # `MergeRequests#new` has no tab-persisting or lazy-loading behavior
- unless @opts.action == 'new'
- new MergeRequestTabs(@opts)
+ @initTabs()
# Prevent duplicate event bindings
@disableTaskList()
@@ -29,6 +27,14 @@ class @MergeRequest
$: (selector) ->
this.$el.find(selector)
+ initTabs: ->
+ if @opts.action != 'new'
+ # `MergeRequests#new` has no tab-persisting or lazy-loading behavior
+ new MergeRequestTabs(@opts)
+ else
+ # Show the first tab (Commits)
+ $('.merge-request-tabs a[data-toggle="tab"]:first').tab('show')
+
showAllCommits: ->
this.$('.first-commits').remove()
this.$('.all-commits').removeClass 'hide'
diff --git a/app/assets/javascripts/merge_request_tabs.js.coffee b/app/assets/javascripts/merge_request_tabs.js.coffee
index a132a0a9dcc..19a07b6a033 100644
--- a/app/assets/javascripts/merge_request_tabs.js.coffee
+++ b/app/assets/javascripts/merge_request_tabs.js.coffee
@@ -49,12 +49,6 @@ class @MergeRequestTabs
# Store the `location` object, allowing for easier stubbing in tests
@_location = location
- switch @opts.action
- when 'commits'
- @commitsLoaded = true
- when 'diffs'
- @diffsLoaded = true
-
@bindEvents()
@activateTab(@opts.action)
@@ -102,7 +96,7 @@ class @MergeRequestTabs
action = 'notes' if action == 'show'
# Remove a trailing '/commits' or '/diffs'
- new_state = @_location.pathname.replace(/\/(commits|diffs)\/?$/, '')
+ new_state = @_location.pathname.replace(/\/(commits|diffs)(\.html)?\/?$/, '')
# Append the new action if we're on a tab other than 'notes'
unless action == 'notes'
@@ -133,7 +127,7 @@ class @MergeRequestTabs
return if @diffsLoaded
@_get
- url: "#{source}.json"
+ url: "#{source}.json" + @_location.search
success: (data) =>
document.getElementById('diffs').innerHTML = data.html
@diffsLoaded = true
diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee
index 1c05a2b9fe8..0021d17d85e 100644
--- a/app/assets/javascripts/notes.js.coffee
+++ b/app/assets/javascripts/notes.js.coffee
@@ -10,7 +10,6 @@ class @Notes
constructor: (notes_url, note_ids, last_fetched_at, view) ->
@notes_url = notes_url
- @notes_url = gon.relative_url_root + @notes_url if gon.relative_url_root?
@note_ids = note_ids
@last_fetched_at = last_fetched_at
@view = view
@@ -298,7 +297,7 @@ class @Notes
note.find(".note-header").hide()
base_form = note.find(".note-edit-form")
form = base_form.clone().insertAfter(base_form)
- form.addClass('current-note-edit-form')
+ form.addClass('current-note-edit-form gfm-form')
form.find('.div-dropzone').remove()
# Show the attachment delete link
diff --git a/app/assets/stylesheets/base/mixins.scss b/app/assets/stylesheets/base/mixins.scss
index d64e79170b9..7beef1845ef 100644
--- a/app/assets/stylesheets/base/mixins.scss
+++ b/app/assets/stylesheets/base/mixins.scss
@@ -70,7 +70,7 @@
font-family: $monospace_font;
white-space: pre;
word-wrap: normal;
- padding: 0;
+ padding: 1px 2px;
}
kbd {
diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss
index 961ac793de2..d36530169a9 100644
--- a/app/assets/stylesheets/generic/common.scss
+++ b/app/assets/stylesheets/generic/common.scss
@@ -184,7 +184,7 @@ li.note {
}
}
-.supp_diff_link,
+.show-suppressed-diff,
.show-all-commits {
cursor: pointer;
}
diff --git a/app/assets/stylesheets/generic/typography.scss b/app/assets/stylesheets/generic/typography.scss
index 2db4213159a..34b4ee3e17e 100644
--- a/app/assets/stylesheets/generic/typography.scss
+++ b/app/assets/stylesheets/generic/typography.scss
@@ -38,6 +38,10 @@ code {
}
}
+a > code {
+ color: $link-color;
+}
+
/**
* Wiki typography
*
diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss
index af6ea58382f..1557c243db5 100644
--- a/app/assets/stylesheets/pages/diff.scss
+++ b/app/assets/stylesheets/pages/diff.scss
@@ -65,6 +65,17 @@
color: #777;
}
+ .suppressed-container {
+ padding: ($padding-base-vertical + 5px) $padding-base-horizontal;
+ text-align: center;
+
+ // "Changes suppressed. Click to show." link
+ .show-suppressed-diff {
+ font-size: 110%;
+ font-weight: bold;
+ }
+ }
+
table {
width: 100%;
font-family: $monospace_font;
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index 4da65b28743..85c828ec1ad 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -37,7 +37,7 @@ ul.notes {
font-size: 13px;
a {
- @extend .cgray;
+ @extend .cgray;
&:hover {
text-decoration: underline;
@@ -105,6 +105,8 @@ ul.notes {
}
hr {
+ // Darken 'whitesmoke' a bit to make it more visible in note bodies
+ border-color: darken(#F5F5F5, 8%);
margin: 10px 0;
}
}
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 5f415f2d78f..21d958db80c 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -297,6 +297,15 @@ table.table.protected-branches-list tr.no-border {
ul.nav-pills { display:inline-block; }
li { display:inline; }
a { float:left; }
+
+ li.missing a {
+ color: #bbb;
+ border: 1px dashed #ccc;
+
+ &:hover {
+ background-color: #FAFAFA;
+ }
+ }
}
pre.light-well {
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 362b03e0d5e..3ce8dbc9407 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -299,14 +299,14 @@ class ApplicationController < ActionController::Base
end
def github_import_enabled?
- OauthHelper.enabled_oauth_providers.include?(:github)
+ Gitlab::OAuth::Provider.enabled?(:github)
end
def gitlab_import_enabled?
- OauthHelper.enabled_oauth_providers.include?(:gitlab)
+ Gitlab::OAuth::Provider.enabled?(:gitlab)
end
def bitbucket_import_enabled?
- OauthHelper.enabled_oauth_providers.include?(:bitbucket) && Gitlab::BitbucketImport.public_key.present?
+ Gitlab::OAuth::Provider.enabled?(:bitbucket) && Gitlab::BitbucketImport.public_key.present?
end
end
diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb
index 4df9d1b7533..6878d4bc07e 100644
--- a/app/controllers/groups/application_controller.rb
+++ b/app/controllers/groups/application_controller.rb
@@ -18,4 +18,10 @@ class Groups::ApplicationController < ApplicationController
return render_404
end
end
+
+ def authorize_admin_group_member!
+ unless can?(current_user, :admin_group_member, group)
+ return render_403
+ end
+ end
end
diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb
index 040255f08e6..91518c44a98 100644
--- a/app/controllers/groups/group_members_controller.rb
+++ b/app/controllers/groups/group_members_controller.rb
@@ -5,6 +5,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
# Authorize
before_action :authorize_read_group!
before_action :authorize_admin_group!, except: [:index, :leave]
+ before_action :authorize_admin_group_member!, only: [:create, :resend_invite]
def index
@project = @group.projects.find(params[:project_id]) if params[:project_id]
@@ -28,6 +29,9 @@ class Groups::GroupMembersController < Groups::ApplicationController
def update
@member = @group.group_members.find(params[:id])
+
+ return render_403 unless can?(current_user, :update_group_member, @member)
+
@member.update_attributes(member_params)
end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 901c1cdddcb..279c6ef0f4d 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -24,7 +24,7 @@ class GroupsController < Groups::ApplicationController
if @group.save
@group.add_owner(current_user)
- redirect_to @group, notice: 'Group was successfully created.'
+ redirect_to @group, notice: "Group '#{@group.name}' was successfully created."
else
render action: "new"
end
@@ -75,7 +75,7 @@ class GroupsController < Groups::ApplicationController
def update
if @group.update_attributes(group_params)
- redirect_to edit_group_path(@group), notice: 'Group was successfully updated.'
+ redirect_to edit_group_path(@group), notice: "Group '#{@group.name}' was successfully updated."
else
render action: "edit"
end
@@ -84,7 +84,7 @@ class GroupsController < Groups::ApplicationController
def destroy
DestroyGroupService.new(@group, current_user).execute
- redirect_to root_path, notice: 'Group was removed.'
+ redirect_to root_path, alert: "Group '#{@group.name} was deleted."
end
protected
diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb
index ca78a4aaa8e..af0b841f0b7 100644
--- a/app/controllers/import/bitbucket_controller.rb
+++ b/app/controllers/import/bitbucket_controller.rb
@@ -3,6 +3,7 @@ class Import::BitbucketController < Import::BaseController
before_action :bitbucket_auth, except: :callback
rescue_from OAuth::Error, with: :bitbucket_unauthorized
+ rescue_from Gitlab::BitbucketImport::Client::Unauthorized, with: :bitbucket_unauthorized
def callback
request_token = session.delete(:oauth_request_token)
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index fd51b380da2..523264b8ea9 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -72,10 +72,11 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
end
end
rescue Gitlab::OAuth::SignupDisabledError => e
- message = "Signing in using your #{oauth['provider']} account without a pre-existing GitLab account is not allowed."
+ label = Gitlab::OAuth::Provider.label_for(oauth['provider'])
+ message = "Signing in using your #{label} account without a pre-existing GitLab account is not allowed."
if current_application_settings.signup_enabled?
- message << " Create a GitLab account first, and then connect it to your #{oauth['provider']} account."
+ message << " Create a GitLab account first, and then connect it to your #{label} account."
end
flash[:notice] = message
diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb
index 61689488d13..9efe9704d1e 100644
--- a/app/controllers/projects/milestones_controller.rb
+++ b/app/controllers/projects/milestones_controller.rb
@@ -64,7 +64,12 @@ class Projects::MilestonesController < Projects::ApplicationController
end
def destroy
- return access_denied! unless can?(current_user, :admin_milestone, @milestone)
+ return access_denied! unless can?(current_user, :admin_milestone, @project)
+
+ update_params = { milestone: nil }
+ @milestone.issues.each do |issue|
+ Issues::UpdateService.new(@project, current_user, update_params).execute(issue)
+ end
@milestone.destroy
diff --git a/app/controllers/projects/network_controller.rb b/app/controllers/projects/network_controller.rb
index 06aef91cadd..b181c47baec 100644
--- a/app/controllers/projects/network_controller.rb
+++ b/app/controllers/projects/network_controller.rb
@@ -7,6 +7,10 @@ class Projects::NetworkController < Projects::ApplicationController
before_action :authorize_download_code!
def show
+
+ @url = namespace_project_network_path(@project.namespace, @project, @ref, @options.merge(format: :json))
+ @commit_url = namespace_project_commit_path(@project.namespace, @project, 'ae45ca32').gsub("ae45ca32", "%s")
+
respond_to do |format|
format.html
diff --git a/app/controllers/projects/refs_controller.rb b/app/controllers/projects/refs_controller.rb
index d83561cf32a..6080c849c8d 100644
--- a/app/controllers/projects/refs_controller.rb
+++ b/app/controllers/projects/refs_controller.rb
@@ -1,5 +1,6 @@
class Projects::RefsController < Projects::ApplicationController
include ExtractsPath
+ include TreeHelper
before_action :require_non_empty_project
before_action :assign_ref_vars
@@ -60,6 +61,11 @@ class Projects::RefsController < Projects::ApplicationController
}
end
+ if @logs.present?
+ @log_url = namespace_project_tree_url(@project.namespace, @project, tree_join(@ref, @path || '/'))
+ @more_log_url = logs_file_namespace_project_ref_path(@project.namespace, @project, @ref, @path || '', offset: (@offset + @limit))
+ end
+
respond_to do |format|
format.html { render_404 }
format.js
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index b659e15f242..92e4bc16d9d 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -7,13 +7,15 @@ class Projects::TreeController < Projects::ApplicationController
before_action :authorize_download_code!
def show
+ return not_found! unless @repository.commit(@ref)
+
if tree.entries.empty?
if @repository.blob_at(@commit.id, @path)
redirect_to(
namespace_project_blob_path(@project.namespace, @project,
File.join(@ref, @path))
) and return
- else
+ elsif @path.present?
return not_found!
end
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index b191819a117..dafc11d0707 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -1,6 +1,6 @@
class ProjectsController < ApplicationController
prepend_before_filter :render_go_import, only: [:show]
- skip_before_action :authenticate_user!, only: [:show]
+ skip_before_action :authenticate_user!, only: [:show, :activity]
before_action :project, except: [:new, :create]
before_action :repository, except: [:new, :create]
@@ -24,7 +24,7 @@ class ProjectsController < ApplicationController
if @project.saved?
redirect_to(
project_path(@project),
- notice: 'Project was successfully created.'
+ notice: "Project '#{@project.name}' was successfully created."
)
else
render 'new'
@@ -36,11 +36,11 @@ class ProjectsController < ApplicationController
respond_to do |format|
if status
- flash[:notice] = 'Project was successfully updated.'
+ flash[:notice] = "Project '#{@project.name}' was successfully updated."
format.html do
redirect_to(
edit_project_path(@project),
- notice: 'Project was successfully updated.'
+ notice: "Project '#{@project.name}' was successfully updated."
)
end
format.js
@@ -100,7 +100,7 @@ class ProjectsController < ApplicationController
return access_denied! unless can?(current_user, :remove_project, @project)
::Projects::DestroyService.new(@project, current_user, {}).execute
- flash[:alert] = 'Project deleted.'
+ flash[:alert] = "Project '#{@project.name}' was deleted."
if request.referer.include?('/admin')
redirect_to admin_namespaces_projects_path
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 89629bc0581..796cbe4c58c 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -90,7 +90,7 @@ class SessionsController < Devise::SessionsController
# Prevent alert from popping up on the first page shown after authentication.
flash[:alert] = nil
- redirect_to omniauth_authorize_path(:user, provider.to_sym)
+ redirect_to user_omniauth_authorize_path(provider.to_sym)
end
def valid_otp_attempt?(user)
diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb
new file mode 100644
index 00000000000..0e7a37b4cc6
--- /dev/null
+++ b/app/helpers/auth_helper.rb
@@ -0,0 +1,50 @@
+module AuthHelper
+ PROVIDERS_WITH_ICONS = %w(twitter github gitlab bitbucket google_oauth2).freeze
+ FORM_BASED_PROVIDERS = [/\Aldap/, 'kerberos'].freeze
+
+ def ldap_enabled?
+ Gitlab.config.ldap.enabled
+ end
+
+ def provider_has_icon?(name)
+ PROVIDERS_WITH_ICONS.include?(name.to_s)
+ end
+
+ def auth_providers
+ Gitlab::OAuth::Provider.providers
+ end
+
+ def label_for_provider(name)
+ Gitlab::OAuth::Provider.label_for(name)
+ end
+
+ def form_based_provider?(name)
+ FORM_BASED_PROVIDERS.any? { |pattern| pattern === name.to_s }
+ end
+
+ def form_based_providers
+ auth_providers.select { |provider| form_based_provider?(provider) }
+ end
+
+ def button_based_providers
+ auth_providers.reject { |provider| form_based_provider?(provider) }
+ end
+
+ def provider_image_tag(provider, size = 64)
+ label = label_for_provider(provider)
+
+ if provider_has_icon?(provider)
+ file_name = "#{provider.to_s.split('_').first}_#{size}.png"
+
+ image_tag(image_path("auth_buttons/#{file_name}"), alt: label, title: "Sign in with #{label}")
+ else
+ label
+ end
+ end
+
+ def auth_active?(provider)
+ current_user.identities.exists?(provider: provider.to_s)
+ end
+
+ extend self
+end
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 50df3801703..77d99140c43 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -1,6 +1,6 @@
module BlobHelper
def highlight(blob_name, blob_content, nowrap: false, continue: false)
- @formatter ||= Rugments::Formatters::HTML.new(
+ @formatter ||= Rouge::Formatters::HTMLGitlab.new(
nowrap: nowrap,
cssclass: 'code highlight',
lineanchors: true,
@@ -8,11 +8,11 @@ module BlobHelper
)
begin
- @lexer ||= Rugments::Lexer.guess(filename: blob_name, source: blob_content).new
+ @lexer ||= Rouge::Lexer.guess(filename: blob_name, source: blob_content).new
result = @formatter.format(@lexer.lex(blob_content, continue: continue)).html_safe
rescue
- lexer = Rugments::Lexers::PlainText
- result = @formatter.format(lexer.lex(blob_content)).html_safe
+ @lexer = Rouge::Lexers::PlainText
+ result = @formatter.format(@lexer.lex(blob_content)).html_safe
end
result
diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb
index 128de18bc47..45788ba95ac 100644
--- a/app/helpers/emails_helper.rb
+++ b/app/helpers/emails_helper.rb
@@ -31,8 +31,8 @@ module EmailsHelper
end
def color_email_diff(diffcontent)
- formatter = Rugments::Formatters::HTML.new(cssclass: "highlight", inline_theme: :github)
- lexer = Rugments::Lexers::Diff.new
+ formatter = Rouge::Formatters::HTML.new(css_class: 'highlight', inline_theme: 'github')
+ lexer = Rouge::Lexers::Diff
raw formatter.format(lexer.lex(diffcontent))
end
diff --git a/app/helpers/oauth_helper.rb b/app/helpers/oauth_helper.rb
deleted file mode 100644
index 2fdca13ed40..00000000000
--- a/app/helpers/oauth_helper.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-module OauthHelper
- def ldap_enabled?
- Gitlab.config.ldap.enabled
- end
-
- def default_providers
- [:twitter, :github, :gitlab, :bitbucket, :google_oauth2, :ldap]
- end
-
- def enabled_oauth_providers
- Devise.omniauth_providers
- end
-
- def enabled_social_providers
- enabled_oauth_providers.select do |name|
- [:saml, :twitter, :gitlab, :github, :bitbucket, :google_oauth2].include?(name.to_sym)
- end
- end
-
- def additional_providers
- enabled_oauth_providers.reject{|provider| provider.to_s.starts_with?('ldap')}
- end
-
- def oauth_image_tag(provider, size = 64)
- file_name = "#{provider.to_s.split('_').first}_#{size}.png"
- image_tag(image_path("authbuttons/#{file_name}"), alt: "Sign in with #{provider.to_s.titleize}")
- end
-
- def oauth_active?(provider)
- current_user.identities.exists?(provider: provider.to_s)
- end
-
- extend self
-end
diff --git a/app/helpers/profile_helper.rb b/app/helpers/profile_helper.rb
deleted file mode 100644
index 780c7cd5133..00000000000
--- a/app/helpers/profile_helper.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-module ProfileHelper
- def show_profile_username_tab?
- current_user.can_change_username?
- end
-
- def show_profile_social_tab?
- enabled_social_providers.any?
- end
-
- def show_profile_remove_tab?
- signup_enabled?
- end
-end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 78f24dbd7ef..f5b78533896 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -131,8 +131,12 @@ module ProjectsHelper
nav_tabs << :snippets
end
+ if can?(current_user, :read_label, project)
+ nav_tabs << :labels
+ end
+
if can?(current_user, :read_milestone, project)
- nav_tabs << [:milestones, :labels]
+ nav_tabs << :milestones
end
nav_tabs.flatten
@@ -180,7 +184,43 @@ module ProjectsHelper
end
end
- def contribution_guide_url(project)
+ def add_contribution_guide_path(project)
+ if project && !project.repository.contribution_guide
+ namespace_project_new_blob_path(
+ project.namespace,
+ project,
+ project.default_branch,
+ file_name: "CONTRIBUTING.md",
+ commit_message: "Add contribution guide"
+ )
+ end
+ end
+
+ def add_changelog_path(project)
+ if project && !project.repository.changelog
+ namespace_project_new_blob_path(
+ project.namespace,
+ project,
+ project.default_branch,
+ file_name: "CHANGELOG",
+ commit_message: "Add changelog"
+ )
+ end
+ end
+
+ def add_license_path(project)
+ if project && !project.repository.license
+ namespace_project_new_blob_path(
+ project.namespace,
+ project,
+ project.default_branch,
+ file_name: "LICENSE",
+ commit_message: "Add license"
+ )
+ end
+ end
+
+ def contribution_guide_path(project)
if project && contribution_guide = project.repository.contribution_guide
namespace_project_blob_path(
project.namespace,
@@ -191,7 +231,7 @@ module ProjectsHelper
end
end
- def changelog_url(project)
+ def changelog_path(project)
if project && changelog = project.repository.changelog
namespace_project_blob_path(
project.namespace,
@@ -202,7 +242,7 @@ module ProjectsHelper
end
end
- def license_url(project)
+ def license_path(project)
if project && license = project.repository.license
namespace_project_blob_path(
project.namespace,
@@ -213,7 +253,7 @@ module ProjectsHelper
end
end
- def version_url(project)
+ def version_path(project)
if project && version = project.repository.version
namespace_project_blob_path(
project.namespace,
@@ -274,6 +314,21 @@ module ProjectsHelper
end
def readme_cache_key
- [@project.id, @project.commit.sha, "readme"].join('-')
+ sha = @project.commit.try(:sha) || 'nil'
+ [@project.id, sha, "readme"].join('-')
+ end
+
+ def round_commit_count(project)
+ count = project.commit_count
+
+ if count > 10000
+ '10000+'
+ elsif count > 5000
+ '5000+'
+ elsif count > 1000
+ '1000+'
+ else
+ count
+ end
end
end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index d3631d49ec6..f8e5afa9b01 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -31,10 +31,11 @@ class Ability
end
if project && project.public?
- [
+ rules = [
:read_project,
:read_wiki,
:read_issue,
+ :read_label,
:read_milestone,
:read_project_snippet,
:read_project_member,
@@ -42,6 +43,8 @@ class Ability
:read_note,
:download_code
]
+
+ rules - project_disabled_features_rules(project)
else
group = if subject.kind_of?(Group)
subject
@@ -102,28 +105,7 @@ class Ability
rules -= project_archived_rules
end
- unless project.issues_enabled
- rules -= named_abilities('issue')
- end
-
- unless project.merge_requests_enabled
- rules -= named_abilities('merge_request')
- end
-
- unless project.issues_enabled or project.merge_requests_enabled
- rules -= named_abilities('label')
- rules -= named_abilities('milestone')
- end
-
- unless project.snippets_enabled
- rules -= named_abilities('project_snippet')
- end
-
- unless project.wiki_enabled
- rules -= named_abilities('wiki')
- end
-
- rules
+ rules - project_disabled_features_rules(project)
end
end
@@ -158,12 +140,13 @@ class Ability
:create_project_snippet,
:update_issue,
:admin_issue,
- :admin_label,
+ :admin_label
]
end
def project_dev_rules
project_report_rules + [
+ :admin_merge_request,
:create_merge_request,
:create_wiki,
:push_code
@@ -205,6 +188,33 @@ class Ability
]
end
+ def project_disabled_features_rules(project)
+ rules = []
+
+ unless project.issues_enabled
+ rules += named_abilities('issue')
+ end
+
+ unless project.merge_requests_enabled
+ rules += named_abilities('merge_request')
+ end
+
+ unless project.issues_enabled or project.merge_requests_enabled
+ rules += named_abilities('label')
+ rules += named_abilities('milestone')
+ end
+
+ unless project.snippets_enabled
+ rules += named_abilities('project_snippet')
+ end
+
+ unless project.wiki_enabled
+ rules += named_abilities('wiki')
+ end
+
+ rules
+ end
+
def group_abilities(user, group)
rules = []
@@ -223,7 +233,8 @@ class Ability
if group.has_owner?(user) || user.admin?
rules.push(*[
:admin_group,
- :admin_namespace
+ :admin_namespace,
+ :admin_group_member
])
end
@@ -285,7 +296,7 @@ class Ability
rules = []
target_user = subject.user
group = subject.group
- can_manage = group_abilities(user, group).include?(:admin_group)
+ can_manage = group_abilities(user, group).include?(:admin_group_member)
if can_manage && (user != target_user)
rules << :update_group_member
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index fee52694099..6d1ad82a262 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -14,13 +14,14 @@
# default_branch_protection :integer default(2)
# twitter_sharing_enabled :boolean default(TRUE)
# restricted_visibility_levels :text
+# version_check_enabled :boolean default(TRUE)
# max_attachment_size :integer default(10), not null
-# session_expire_delay :integer default(10080), not null
# default_project_visibility :integer
# default_snippet_visibility :integer
# restricted_signup_domains :text
-# user_oauth_applications :bool default(TRUE)
+# user_oauth_applications :boolean default(TRUE)
# after_sign_out_path :string(255)
+# session_expire_delay :integer default(10080), not null
#
class ApplicationSetting < ActiveRecord::Base
diff --git a/app/models/audit_event.rb b/app/models/audit_event.rb
index 967ffd46db0..0ed0dd98a59 100644
--- a/app/models/audit_event.rb
+++ b/app/models/audit_event.rb
@@ -1,3 +1,17 @@
+# == Schema Information
+#
+# Table name: audit_events
+#
+# id :integer not null, primary key
+# author_id :integer not null
+# type :string(255) not null
+# entity_id :integer not null
+# entity_type :string(255) not null
+# details :text
+# created_at :datetime
+# updated_at :datetime
+#
+
class AuditEvent < ActiveRecord::Base
serialize :details, Hash
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 97846b06d72..c21e7fd0e3b 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -159,6 +159,16 @@ module Issuable
end
end
+ # Convert this Issuable class name to a format usable by Ability definitions
+ #
+ # Examples:
+ #
+ # issuable.class # => MergeRequest
+ # issuable.to_ability_name # => "merge_request"
+ def to_ability_name
+ self.class.to_s.underscore
+ end
+
private
def filter_superceded_votes(votes, notes)
diff --git a/app/models/group.rb b/app/models/group.rb
index 051c672cb33..cfb8faa1491 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -56,6 +56,12 @@ class Group < Namespace
name
end
+ def avatar_url(size = nil)
+ if avatar.present?
+ [gitlab_config.url, avatar.url].join
+ end
+ end
+
def owners
@owners ||= group_members.owners.map(&:user)
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 8481a149e21..4628f478ca6 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -21,12 +21,13 @@
# import_url :string(255)
# visibility_level :integer default(0), not null
# archived :boolean default(FALSE), not null
+# avatar :string(255)
# import_status :string(255)
# repository_size :float default(0.0)
# star_count :integer default(0), not null
# import_type :string(255)
# import_source :string(255)
-# avatar :string(255)
+# commit_count :integer default(0)
#
require 'carrierwave/orm/activerecord'
@@ -36,7 +37,6 @@ class Project < ActiveRecord::Base
include Gitlab::ConfigHelper
include Gitlab::ShellAdapter
include Gitlab::VisibilityLevel
- include Rails.application.routes.url_helpers
include Referable
include Sortable
@@ -316,7 +316,7 @@ class Project < ActiveRecord::Base
end
def web_url
- [gitlab_config.url, path_with_namespace].join('/')
+ Rails.application.routes.url_helpers.namespace_project_url(self.namespace, self)
end
def web_url_without_protocol
@@ -433,7 +433,7 @@ class Project < ActiveRecord::Base
if avatar.present?
[gitlab_config.url, avatar.url].join
elsif avatar_in_git
- [gitlab_config.url, namespace_project_avatar_path(namespace, self)].join
+ Rails.application.routes.url_helpers.namespace_project_avatar_url(namespace, self)
end
end
@@ -563,7 +563,7 @@ class Project < ActiveRecord::Base
end
def http_url_to_repo
- [gitlab_config.url, '/', path_with_namespace, '.git'].join('')
+ "#{web_url}.git"
end
# Check if current branch name is marked as protected in the system
@@ -672,6 +672,10 @@ class Project < ActiveRecord::Base
update_attribute(:repository_size, repository.size)
end
+ def update_commit_count
+ update_attribute(:commit_count, repository.commit_count)
+ end
+
def forks_count
ForkedProjectLink.where(forked_from_project_id: self.id).count
end
@@ -689,14 +693,14 @@ class Project < ActiveRecord::Base
if gitlab_shell.fork_repository(forked_from_project.path_with_namespace, self.namespace.path)
true
else
- errors.add(:base, 'Failed to fork repository')
+ errors.add(:base, 'Failed to fork repository via gitlab-shell')
false
end
else
if gitlab_shell.add_repository(path_with_namespace)
true
else
- errors.add(:base, 'Failed to create repository')
+ errors.add(:base, 'Failed to create repository via gitlab-shell')
false
end
end
diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb
index 0ea866fdb4a..ecdcd48ae60 100644
--- a/app/models/project_services/gitlab_ci_service.rb
+++ b/app/models/project_services/gitlab_ci_service.rb
@@ -22,8 +22,12 @@ class GitlabCiService < CiService
API_PREFIX = "api/v1"
prop_accessor :project_url, :token
- validates :project_url, presence: true, if: :activated?
- validates :token, presence: true, if: :activated?
+ validates :project_url,
+ presence: true,
+ format: { with: /\A#{URI.regexp(%w(http https))}\z/, message: "should be a valid url" }, if: :activated?
+ validates :token,
+ presence: true,
+ format: { with: /\A([A-Za-z0-9]+)\z/ }, if: :activated?
after_save :compose_service_hook, if: :activated?
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 41666bd6e38..46efbede2a2 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -94,18 +94,6 @@ class Repository
gitlab_shell.rm_tag(path_with_namespace, tag_name)
end
- def round_commit_count
- if commit_count > 10000
- '10000+'
- elsif commit_count > 5000
- '5000+'
- elsif commit_count > 1000
- '1000+'
- else
- commit_count
- end
- end
-
def branch_names
cache.fetch(:branch_names) { raw_repository.branch_names }
end
@@ -130,28 +118,29 @@ class Repository
cache.fetch(:size) { raw_repository.size }
end
+ def cache_keys
+ %i(size branch_names tag_names commit_count
+ readme version contribution_guide changelog license)
+ end
+
+ def build_cache
+ cache_keys.each do |key|
+ unless cache.exist?(key)
+ send(key)
+ end
+ end
+ end
+
def expire_cache
- %i(size branch_names tag_names commit_count graph_log
- readme version contribution_guide changelog license).each do |key|
+ cache_keys.each do |key|
cache.expire(key)
end
end
- def graph_log
- cache.fetch(:graph_log) do
- commits = raw_repository.log(limit: 6000, skip_merges: true,
- ref: root_ref)
-
- commits.map do |rugged_commit|
- commit = Gitlab::Git::Commit.new(rugged_commit)
-
- {
- author_name: commit.author_name,
- author_email: commit.author_email,
- additions: commit.stats.additions,
- deletions: commit.stats.deletions,
- }
- end
+ def rebuild_cache
+ cache_keys.each do |key|
+ cache.expire(key)
+ send(key)
end
end
@@ -463,8 +452,7 @@ class Repository
filename = nil
startline = 0
- lines = result.lines
- lines.each_with_index do |line, index|
+ result.each_line.each_with_index do |line, index|
if line =~ /^.*:.*:\d+:/
ref, filename, startline = line.split(':')
startline = startline.to_i - index
@@ -472,11 +460,11 @@ class Repository
end
end
- data = lines.map do |line|
- line.sub(ref, '').sub(filename, '').sub(/^:-\d+-/, '').sub(/^::\d+:/, '')
- end
+ data = ""
- data = data.join("")
+ result.each_line do |line|
+ data << line.sub(ref, '').sub(filename, '').sub(/^:-\d+-/, '').sub(/^::\d+:/, '')
+ end
OpenStruct.new(
filename: filename,
diff --git a/app/models/security_event.rb b/app/models/security_event.rb
index d131c11cb6c..68c00adad59 100644
--- a/app/models/security_event.rb
+++ b/app/models/security_event.rb
@@ -1,2 +1,16 @@
+# == Schema Information
+#
+# Table name: audit_events
+#
+# id :integer not null, primary key
+# author_id :integer not null
+# type :string(255) not null
+# entity_id :integer not null
+# entity_type :string(255) not null
+# details :text
+# created_at :datetime
+# updated_at :datetime
+#
+
class SecurityEvent < AuditEvent
end
diff --git a/app/models/user.rb b/app/models/user.rb
index fb330ff7185..2beefb1d614 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -57,6 +57,7 @@
# otp_backup_codes :text
# public_email :string(255) default(""), not null
# dashboard :integer default(0)
+# project_view :integer default(0)
#
require 'carrierwave/orm/activerecord'
@@ -274,6 +275,10 @@ class User < ActiveRecord::Base
value: login.to_s.downcase).first
end
+ def find_by_username!(username)
+ find_by!('lower(username) = ?', username.downcase)
+ end
+
def by_username_or_id(name_or_id)
where('users.username = ? OR users.id = ?', name_or_id.to_s, name_or_id.to_i).first
end
diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb
index 3a5a52e6f55..81535450ac1 100644
--- a/app/services/git_push_service.rb
+++ b/app/services/git_push_service.rb
@@ -19,7 +19,6 @@ class GitPushService
@project, @user = project, user
project.repository.expire_cache
- project.update_repository_size
if push_remove_branch?(ref, newrev)
@push_commits = []
@@ -59,6 +58,7 @@ class GitPushService
EventCreateService.new.push(project, user, @push_data)
project.execute_hooks(@push_data.dup, :push_hooks)
project.execute_services(@push_data.dup, :push_hooks)
+ ProjectCacheWorker.perform_async(project.id)
end
protected
diff --git a/app/services/git_tag_push_service.rb b/app/services/git_tag_push_service.rb
index 075a6118da2..1cc42b0b0ad 100644
--- a/app/services/git_tag_push_service.rb
+++ b/app/services/git_tag_push_service.rb
@@ -2,15 +2,15 @@ class GitTagPushService
attr_accessor :project, :user, :push_data
def execute(project, user, oldrev, newrev, ref)
- @project, @user = project, user
+ project.repository.expire_cache
+ @project, @user = project, user
@push_data = build_push_data(oldrev, newrev, ref)
EventCreateService.new.push(project, user, @push_data)
project.execute_hooks(@push_data.dup, :tag_push_hooks)
project.execute_services(@push_data.dup, :tag_push_hooks)
-
- project.repository.expire_cache
+ ProjectCacheWorker.perform_async(project.id)
true
end
diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb
index f1ef5ca84fe..15b3825f96a 100644
--- a/app/services/issuable_base_service.rb
+++ b/app/services/issuable_base_service.rb
@@ -27,8 +27,10 @@ class IssuableBaseService < BaseService
old_branch, new_branch)
end
- def filter_params
- unless can?(current_user, :admin_issue, project)
+ def filter_params(issuable_ability_name = :issue)
+ ability = :"admin_#{issuable_ability_name}"
+
+ unless can?(current_user, ability, project)
params.delete(:milestone_id)
params.delete(:label_ids)
params.delete(:assignee_id)
diff --git a/app/services/issues/base_service.rb b/app/services/issues/base_service.rb
index c3ca04a4343..770f32de944 100644
--- a/app/services/issues/base_service.rb
+++ b/app/services/issues/base_service.rb
@@ -10,6 +10,10 @@ module Issues
private
+ def filter_params
+ super(:issue)
+ end
+
def execute_hooks(issue, action = 'open')
issue_data = hook_data(issue, action)
issue.project.execute_hooks(issue_data, :issue_hooks)
diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb
index e455fe95791..7b306a8a531 100644
--- a/app/services/merge_requests/base_service.rb
+++ b/app/services/merge_requests/base_service.rb
@@ -20,5 +20,11 @@ module MergeRequests
merge_request.project.execute_services(merge_data, :merge_request_hooks)
end
end
+
+ private
+
+ def filter_params
+ super(:merge_request)
+ end
end
end
diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb
index 011f6f6145e..b35aed005da 100644
--- a/app/services/projects/create_service.rb
+++ b/app/services/projects/create_service.rb
@@ -85,6 +85,8 @@ module Projects
@project.create_wiki if @project.wiki_enabled?
+ @project.build_missing_services
+
event_service.create_project(@project, current_user)
system_hook_service.execute_hooks_for(@project, :create)
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index 187314872de..296497a4cd4 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -51,21 +51,22 @@
= paginate @projects, param_name: 'projects_page', theme: 'gitlab'
.col-md-6
- .panel.panel-default
- .panel-heading
- Add user(s) to the group:
- .panel-body.form-holder
- %p.light
- Read more about project permissions
- %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink"
+ - if can?(current_user, :admin_group_member, @group)
+ .panel.panel-default
+ .panel-heading
+ Add user(s) to the group:
+ .panel-body.form-holder
+ %p.light
+ Read more about project permissions
+ %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink"
- = form_tag members_update_admin_group_path(@group), id: "new_project_member", class: "bulk_import", method: :put do
- %div
- = users_select_tag(:user_ids, multiple: true, email_user: true, scope: :all)
- %div.prepend-top-10
- = select_tag :access_level, options_for_select(GroupMember.access_level_roles), class: "project-access-select select2"
- %hr
- = button_tag 'Add users to group', class: "btn btn-create"
+ = form_tag members_update_admin_group_path(@group), id: "new_project_member", class: "bulk_import", method: :put do
+ %div
+ = users_select_tag(:user_ids, multiple: true, email_user: true, scope: :all)
+ %div.prepend-top-10
+ = select_tag :access_level, options_for_select(GroupMember.access_level_roles), class: "project-access-select select2"
+ %hr
+ = button_tag 'Add users to group', class: "btn btn-create"
.panel.panel-default
.panel-heading
%h3.panel-title
@@ -86,7 +87,8 @@
(invited)
%span.pull-right.light
= member.human_access
- = link_to group_group_member_path(@group, member), data: { confirm: remove_user_from_group_message(@group, member) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from group' do
- %i.fa.fa-minus.fa-inverse
+ - if can?(current_user, :destroy_group_member, member)
+ = link_to group_group_member_path(@group, member), data: { confirm: remove_user_from_group_message(@group, member) }, method: :delete, remote: true, class: "btn-xs btn btn-remove", title: 'Remove user from group' do
+ %i.fa.fa-minus.fa-inverse
.panel-footer
= paginate @members, param_name: 'members_page', theme: 'gitlab'
diff --git a/app/views/admin/identities/_form.html.haml b/app/views/admin/identities/_form.html.haml
index 0525552ebf8..3a788558226 100644
--- a/app/views/admin/identities/_form.html.haml
+++ b/app/views/admin/identities/_form.html.haml
@@ -8,7 +8,8 @@
.form-group
= f.label :provider, class: 'control-label'
.col-sm-10
- = f.select :provider, Gitlab::OAuth::Provider.names, { allow_blank: false }, class: 'form-control'
+ - values = Gitlab::OAuth::Provider.providers.map { |name| ["#{Gitlab::OAuth::Provider.label_for(name)} (#{name})", name] }
+ = f.select :provider, values, { allow_blank: false }, class: 'form-control'
.form-group
= f.label :extern_uid, "Identifier", class: 'control-label'
.col-sm-10
diff --git a/app/views/admin/identities/_identity.html.haml b/app/views/admin/identities/_identity.html.haml
index 671c4fbc677..7362d904b94 100644
--- a/app/views/admin/identities/_identity.html.haml
+++ b/app/views/admin/identities/_identity.html.haml
@@ -1,6 +1,6 @@
%tr
%td
- = identity.provider
+ = "#{Gitlab::OAuth::Provider.label_for(identity.provider)} (#{identity.provider})"
%td
= identity.extern_uid
%td
diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml
index 54a39726771..9f5520603cd 100644
--- a/app/views/devise/sessions/_new_base.html.haml
+++ b/app/views/devise/sessions/_new_base.html.haml
@@ -1,5 +1,5 @@
= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
- = f.text_field :login, class: "form-control top", placeholder: "Username or Email", autofocus: "autofocus"
+ = f.text_field :login, class: "form-control top", placeholder: "Username or Email", autofocus: "autofocus", autocapitalize: "off", autocorrect: "off"
= f.password_field :password, class: "form-control bottom", placeholder: "Password"
- if devise_mapping.rememberable?
.remember-me.checkbox
diff --git a/app/views/devise/sessions/_new_ldap.html.haml b/app/views/devise/sessions/_new_ldap.html.haml
index 6ec741e4882..689cd6ed665 100644
--- a/app/views/devise/sessions/_new_ldap.html.haml
+++ b/app/views/devise/sessions/_new_ldap.html.haml
@@ -6,4 +6,4 @@
%label{for: "remember_me"}
= check_box_tag :remember_me, '1', false, id: 'remember_me'
%span Remember me
- = button_tag "#{server['label']} Sign in", class: "btn-save btn"
+ = button_tag "Sign in", class: "btn-save btn"
diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml
index f8ba9d80ae8..ecf680e7b23 100644
--- a/app/views/devise/shared/_omniauth_box.html.haml
+++ b/app/views/devise/shared/_omniauth_box.html.haml
@@ -1,10 +1,8 @@
%p
%span.light
Sign in with &nbsp;
- - providers = additional_providers
+ - providers = button_based_providers
- providers.each do |provider|
%span.light
- - if default_providers.include?(provider)
- = link_to oauth_image_tag(provider), omniauth_authorize_path(resource_name, provider), method: :post, class: 'oauth-image-link'
- - else
- = link_to provider.to_s.titleize, omniauth_authorize_path(resource_name, provider), method: :post, class: "btn", "data-no-turbolink" => "true"
+ - has_icon = provider_has_icon?(provider)
+ = link_to provider_image_tag(provider), user_omniauth_authorize_path(provider), method: :post, class: (has_icon ? 'oauth-image-link' : 'btn'), "data-no-turbolink" => "true"
diff --git a/app/views/devise/shared/_signin_box.html.haml b/app/views/devise/shared/_signin_box.html.haml
index c76574db457..bb5e479697d 100644
--- a/app/views/devise/shared/_signin_box.html.haml
+++ b/app/views/devise/shared/_signin_box.html.haml
@@ -6,7 +6,7 @@
.login-heading
%h3 Sign in
.login-body
- - if ldap_enabled?
+ - if form_based_providers.any?
%ul.nav.nav-tabs
- @ldap_servers.each_with_index do |server, i|
%li{class: (:active if i.zero?)}
diff --git a/app/views/events/_event.html.haml b/app/views/events/_event.html.haml
index b8409f64665..5ab5ffc238c 100644
--- a/app/views/events/_event.html.haml
+++ b/app/views/events/_event.html.haml
@@ -8,11 +8,10 @@
= image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:''
= render "events/event/created_project", event: event
- else
- = cache event do
- = image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:''
- - if event.push?
- = render "events/event/push", event: event
- - elsif event.commented?
- = render "events/event/note", event: event
- - else
- = render "events/event/common", event: event
+ = image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:''
+ - if event.push?
+ = render "events/event/push", event: event
+ - elsif event.commented?
+ = render "events/event/note", event: event
+ - else
+ = render "events/event/common", event: event
diff --git a/app/views/explore/projects/_project.html.haml b/app/views/explore/projects/_project.html.haml
index d65fb529373..d769c91545d 100644
--- a/app/views/explore/projects/_project.html.haml
+++ b/app/views/explore/projects/_project.html.haml
@@ -14,7 +14,7 @@
.repo-info
- unless project.empty_repo?
- = link_to pluralize(project.repository.round_commit_count, 'commit'), namespace_project_commits_path(project.namespace, project, project.default_branch)
+ = link_to pluralize(round_commit_count(project), 'commit'), namespace_project_commits_path(project.namespace, project, project.default_branch)
&middot;
= link_to pluralize(project.repository.branch_names.count, 'branch'), namespace_project_branches_path(project.namespace, project)
&middot;
diff --git a/app/views/groups/group_members/_group_member.html.haml b/app/views/groups/group_members/_group_member.html.haml
index b460e0ff59e..acc7f8b28c2 100644
--- a/app/views/groups/group_members/_group_member.html.haml
+++ b/app/views/groups/group_members/_group_member.html.haml
@@ -24,7 +24,7 @@
= link_to member.created_by.name, user_path(member.created_by)
= time_ago_with_tooltip(member.created_at)
- - if show_controls && can?(current_user, :admin_group, @group)
+ - if show_controls && can?(current_user, :admin_group_member, member)
= link_to resend_invite_group_group_member_path(@group, member), method: :post, class: "btn-xs btn", title: 'Resend invite' do
Resend invite
diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml
index a70d1ff0697..dba395cc8fa 100644
--- a/app/views/groups/group_members/index.html.haml
+++ b/app/views/groups/group_members/index.html.haml
@@ -17,7 +17,7 @@
= search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input' }
= button_tag 'Search', class: 'btn'
- - if current_user && current_user.can?(:admin_group, @group)
+ - if current_user && current_user.can?(:admin_group_member, @group)
.pull-right
= button_tag class: 'btn btn-new js-toggle-button', type: 'button' do
Add members
diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml
index ee1b57278b6..c8662a15adb 100644
--- a/app/views/layouts/notify.html.haml
+++ b/app/views/layouts/notify.html.haml
@@ -33,7 +33,7 @@
= yield
%div.footer{style: "margin-top: 10px;"}
%p
- \—
+ &mdash;
%br
- if @target_url
#{link_to "View it on GitLab", @target_url}
diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml
index 378dfa2dce0..767fe2e0e9a 100644
--- a/app/views/profiles/accounts/show.html.haml
+++ b/app/views/profiles/accounts/show.html.haml
@@ -59,22 +59,22 @@
%div
= link_to 'Enable Two-factor Authentication', new_profile_two_factor_auth_path, class: 'btn btn-success'
- - if show_profile_social_tab?
+ - if button_based_providers.any?
.panel.panel-default
.panel-heading
Connected Accounts
.panel-body
.oauth-buttons.append-bottom-10
%p Click on icon to activate signin with one of the following services
- - enabled_social_providers.each do |provider|
+ - button_based_providers.each do |provider|
.btn-group
- = link_to oauth_image_tag(provider), omniauth_authorize_path(User, provider),
- method: :post, class: "btn btn-lg #{'active' if oauth_active?(provider)}"
- - if oauth_active?(provider)
+ = link_to provider_image_tag(provider), user_omniauth_authorize_path(provider), method: :post, class: "btn btn-lg #{'active' if auth_active?(provider)}", "data-no-turbolink" => "true"
+
+ - if auth_active?(provider)
= link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'btn btn-lg' do
= icon('close')
- - if show_profile_username_tab?
+ - if current_user.can_change_username?
.panel.panel-warning.update-username
.panel-heading
Change Username
@@ -94,7 +94,7 @@
%div
= f.submit 'Save username', class: "btn btn-warning"
- - if show_profile_remove_tab?
+ - if signup_enabled?
.panel.panel-danger.remove-account
.panel-heading
Remove account
diff --git a/app/views/profiles/keys/_form.html.haml b/app/views/profiles/keys/_form.html.haml
index f905417f0e2..b76a5b636ac 100644
--- a/app/views/profiles/keys/_form.html.haml
+++ b/app/views/profiles/keys/_form.html.haml
@@ -7,13 +7,12 @@
%li= msg
.form-group
- = f.label :title, class: 'control-label'
- .col-sm-10= f.text_field :title, class: "form-control"
- .form-group
= f.label :key, class: 'control-label'
.col-sm-10
= f.text_area :key, class: "form-control", rows: 8
-
+ .form-group
+ = f.label :title, class: 'control-label'
+ .col-sm-10= f.text_field :title, class: "form-control"
.form-actions
= f.submit 'Add key', class: "btn btn-create"
diff --git a/app/views/profiles/two_factor_auths/new.html.haml b/app/views/profiles/two_factor_auths/new.html.haml
index 74268c9bde2..92dc58c10d7 100644
--- a/app/views/profiles/two_factor_auths/new.html.haml
+++ b/app/views/profiles/two_factor_auths/new.html.haml
@@ -5,7 +5,7 @@
Download the Google Authenticator application from App Store for iOS or Google
Play for Android and scan this code.
- More information is available in the #{link_to('documentation', help_page_path('workflow', 'two_factor_authentication'))}.
+ More information is available in the #{link_to('documentation', help_page_path('profile', 'two_factor_authentication'))}.
%hr
diff --git a/app/views/projects/blob/diff.html.haml b/app/views/projects/blob/diff.html.haml
index 84742608986..f3b01ff3288 100644
--- a/app/views/projects/blob/diff.html.haml
+++ b/app/views/projects/blob/diff.html.haml
@@ -11,7 +11,7 @@
%td.old_line.diff-line-num{data: {linenumber: line_old}}
= link_to raw(line_old), "#"
%td.new_line= link_to raw(line_new) , "#"
- %td.line_content.noteable_line= line
+ %td.line_content.noteable_line= ' ' * @form.indent + line
- if @form.unfold? && @form.bottom? && @form.to < @blob.loc
%tr.line_holder{ id: @form.to }
diff --git a/app/views/projects/diffs/_text_file.html.haml b/app/views/projects/diffs/_text_file.html.haml
index ed4c601bcdb..977ca423f75 100644
--- a/app/views/projects/diffs/_text_file.html.haml
+++ b/app/views/projects/diffs/_text_file.html.haml
@@ -1,6 +1,7 @@
- too_big = diff_file.diff_lines.count > Commit::DIFF_SAFE_LINES
- if too_big
- %a.supp_diff_link Changes suppressed. Click to show
+ .suppressed-container
+ %a.show-suppressed-diff.js-show-suppressed-diff Changes suppressed. Click to show.
%table.text-file{class: "#{'hide' if too_big}"}
- last_line = 0
diff --git a/app/views/projects/diffs/_warning.html.haml b/app/views/projects/diffs/_warning.html.haml
index f99bc9a85eb..caed0e69dc8 100644
--- a/app/views/projects/diffs/_warning.html.haml
+++ b/app/views/projects/diffs/_warning.html.haml
@@ -3,7 +3,7 @@
Too many changes to show.
.pull-right
- unless diff_hard_limit_enabled?
- = link_to "Reload with full diff", url_for(params.merge(force_show_diff: true, format: nil)), class: "btn btn-sm btn-warning"
+ = link_to "Reload with full diff", url_for(params.merge(force_show_diff: true, format: :html)), class: "btn btn-sm btn-warning"
- if current_controller?(:commit) or current_controller?(:merge_requests)
- if current_controller?(:commit)
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index 1b45bb1af0c..b6910c8f796 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -3,43 +3,42 @@
.issue-check
= check_box_tag dom_id(issue,"selected"), nil, false, 'data-id' => issue.id, class: "selected_issue"
- = cache issue do
- .issue-title
- %span.issue-title-text
- = link_to_gfm issue.title, issue_path(issue), class: "row_title"
- .issue-labels
- - issue.labels.each do |label|
- = link_to_label(label, project: issue.project)
- .pull-right.light
- - if issue.closed?
- %span
- CLOSED
- - if issue.assignee
- = link_to_member(@project, issue.assignee, name: false)
- - note_count = issue.notes.user.count
- - if note_count > 0
- &nbsp;
- %span
- %i.fa.fa-comments
- = note_count
- - else
- &nbsp;
- %span.issue-no-comments
- %i.fa.fa-comments
- = 0
-
- .issue-info
- = "#{issue.to_reference} opened #{time_ago_with_tooltip(issue.created_at, placement: 'bottom')} by #{link_to_member(@project, issue.author, avatar: false)}".html_safe
- - if issue.votes_count > 0
- = render 'votes/votes_inline', votable: issue
- - if issue.milestone
+ .issue-title
+ %span.issue-title-text
+ = link_to_gfm issue.title, issue_path(issue), class: "row_title"
+ .issue-labels
+ - issue.labels.each do |label|
+ = link_to_label(label, project: issue.project)
+ .pull-right.light
+ - if issue.closed?
+ %span
+ CLOSED
+ - if issue.assignee
+ = link_to_member(@project, issue.assignee, name: false)
+ - note_count = issue.notes.user.count
+ - if note_count > 0
&nbsp;
%span
- %i.fa.fa-clock-o
- = issue.milestone.title
- - if issue.tasks?
- %span.task-status
- = issue.task_status
+ %i.fa.fa-comments
+ = note_count
+ - else
+ &nbsp;
+ %span.issue-no-comments
+ %i.fa.fa-comments
+ = 0
+
+ .issue-info
+ = "#{issue.to_reference} opened #{time_ago_with_tooltip(issue.created_at, placement: 'bottom')} by #{link_to_member(@project, issue.author, avatar: false)}".html_safe
+ - if issue.votes_count > 0
+ = render 'votes/votes_inline', votable: issue
+ - if issue.milestone
+ &nbsp;
+ %span
+ %i.fa.fa-clock-o
+ = issue.milestone.title
+ - if issue.tasks?
+ %span.task-status
+ = issue.task_status
- .pull-right.issue-updated-at
- %small updated #{time_ago_with_tooltip(issue.updated_at, placement: 'bottom', html_class: 'issue_update_ago')}
+ .pull-right.issue-updated-at
+ %small updated #{time_ago_with_tooltip(issue.updated_at, placement: 'bottom', html_class: 'issue_update_ago')}
diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml
index b6d9b135c70..c57eee14143 100644
--- a/app/views/projects/merge_requests/_show.html.haml
+++ b/app/views/projects/merge_requests/_show.html.haml
@@ -31,6 +31,16 @@
%li= link_to "Email Patches", merge_request_path(@merge_request, format: :patch)
%li= link_to "Plain Diff", merge_request_path(@merge_request, format: :diff)
+ - if @merge_request.open? and @merge_request.source_branch_exists?
+ .append-bottom-20
+ .slead
+ %span
+ Fetch the branch with
+ %strong.label-branch<
+ git fetch
+ \ #{@merge_request.source_project.http_url_to_repo}
+ \ #{@merge_request.source_branch}
+
= render "projects/merge_requests/show/how_to_merge"
= render "projects/merge_requests/widget/show.html.haml"
@@ -56,11 +66,9 @@
#notes.notes.tab-pane.voting_notes
= render "projects/merge_requests/discussion"
#commits.commits.tab-pane
- - if current_page?(action: 'commits')
- = render "projects/merge_requests/show/commits"
+ - # This tab is always loaded via AJAX
#diffs.diffs.tab-pane
- - if current_page?(action: 'diffs')
- = render "projects/merge_requests/show/diffs"
+ - # This tab is always loaded via AJAX
.mr-loading-status
= spinner
diff --git a/app/views/projects/merge_requests/branch_from.js.haml b/app/views/projects/merge_requests/branch_from.js.haml
index 8372afa61b5..9210798f39c 100644
--- a/app/views/projects/merge_requests/branch_from.js.haml
+++ b/app/views/projects/merge_requests/branch_from.js.haml
@@ -1,2 +1,3 @@
:plain
$(".mr_source_commit").html("#{commit_to_html(@commit, @source_project, false)}");
+ $('.js-timeago').timeago()
diff --git a/app/views/projects/merge_requests/branch_to.js.haml b/app/views/projects/merge_requests/branch_to.js.haml
index f7ede0ded53..32fe2d535f3 100644
--- a/app/views/projects/merge_requests/branch_to.js.haml
+++ b/app/views/projects/merge_requests/branch_to.js.haml
@@ -1,2 +1,3 @@
:plain
$(".mr_target_commit").html("#{commit_to_html(@commit, @target_project, false)}");
+ $('.js-timeago').timeago()
diff --git a/app/views/projects/merge_requests/widget/open/_missing_branch.html.haml b/app/views/projects/merge_requests/widget/open/_missing_branch.html.haml
index 423fcd48e25..1c565bae80a 100644
--- a/app/views/projects/merge_requests/widget/open/_missing_branch.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_missing_branch.html.haml
@@ -6,9 +6,11 @@
%span.label.label-inverse= @merge_request.source_branch
does not exist in
%span.label.label-info= @merge_request.source_project_path
+ %br
+ %strong Please close this merge request and open a new merge request to change source branches.
- else
%span.label.label-inverse= @merge_request.target_branch
does not exist in
%span.label.label-info= @merge_request.target_project_path
- %br
- %strong Please close this merge request or change branches with existing one
+ %br
+ %strong Please close this merge request or change to another target branch.
diff --git a/app/views/projects/milestones/_milestone.html.haml b/app/views/projects/milestones/_milestone.html.haml
index 14a0580f966..2ce5358fa74 100644
--- a/app/views/projects/milestones/_milestone.html.haml
+++ b/app/views/projects/milestones/_milestone.html.haml
@@ -5,6 +5,10 @@
%i.fa.fa-pencil-square-o
Edit
= link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-sm btn-close"
+ = link_to namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-sm btn-remove" do
+ %i.fa.fa-trash-o
+ Remove
+
%h4
= link_to_gfm truncate(milestone.title, length: 100), namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone)
- if milestone.expired? and not milestone.closed?
diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml
index 5947498e379..7b1681df336 100644
--- a/app/views/projects/milestones/show.html.haml
+++ b/app/views/projects/milestones/show.html.haml
@@ -19,6 +19,9 @@
= link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, @milestone, milestone: {state_event: :close }), method: :put, class: "btn btn-close btn-grouped"
- else
= link_to 'Reopen Milestone', namespace_project_milestone_path(@project.namespace, @project, @milestone, milestone: {state_event: :activate }), method: :put, class: "btn btn-reopen btn-grouped"
+ = link_to namespace_project_milestone_path(@project.namespace, @project, @milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-grouped btn-remove" do
+ %i.fa.fa-trash-o
+ Remove
%hr
- if @milestone.issues.any? && @milestone.can_be_closed?
diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml
index a88cf167511..52b5b8b877e 100644
--- a/app/views/projects/network/show.html.haml
+++ b/app/views/projects/network/show.html.haml
@@ -17,9 +17,9 @@
:javascript
network_graph = new Network({
- url: '#{namespace_project_network_path(@project.namespace, @project, @ref, @options.merge(format: :json))}',
- commit_url: '#{namespace_project_commit_path(@project.namespace, @project, 'ae45ca32').gsub("ae45ca32", "%s")}',
- ref: '#{@ref}',
+ url: "#{escape_javascript(@url)}",
+ commit_url: "#{escape_javascript(@commit_url)}",
+ ref: "#{escape_javascript(@ref)}",
commit_id: '#{@commit.id}'
})
new ShortcutsNetwork(network_graph.branch_graph)
diff --git a/app/views/projects/notes/_edit_form.html.haml b/app/views/projects/notes/_edit_form.html.haml
index 7472b33bb53..8f7d2e84c70 100644
--- a/app/views/projects/notes/_edit_form.html.haml
+++ b/app/views/projects/notes/_edit_form.html.haml
@@ -3,10 +3,7 @@
= note_target_fields(note)
= render layout: 'projects/md_preview', locals: { preview_class: 'note-text' } do
= render 'projects/zen', f: f, attr: :note, classes: 'note_text js-note-text js-task-list-field'
-
- .comment-hints.clearfix
- .pull-left #{link_to 'Markdown ', help_page_path('markdown', 'markdown'),{ target: '_blank', tabindex: -1 }}
- .pull-right #{link_to 'Attach a file', '#', class: 'markdown-selector', tabindex: -1 }
+ = render 'projects/notes/hints'
.note-form-actions
.buttons
diff --git a/app/views/projects/notes/_form.html.haml b/app/views/projects/notes/_form.html.haml
index 64f98741d45..3be8f44b282 100644
--- a/app/views/projects/notes/_form.html.haml
+++ b/app/views/projects/notes/_form.html.haml
@@ -8,18 +8,8 @@
= f.hidden_field :noteable_type
= render layout: 'projects/md_preview', locals: { preview_class: "note-text", referenced_users: true } do
- = render 'projects/zen', f: f, attr: :note,
- classes: 'note_text js-note-text'
-
- .comment-hints.clearfix
- .pull-left
- = link_to "Markdown ", help_page_path("markdown", "markdown"),{ target: '_blank', tabindex: -1 }
- tip:
- = random_markdown_tip
- .pull-right
- = link_to '#', class: 'markdown-selector', tabindex: -1 do
- Attach a file
- = icon('paperclip')
+ = render 'projects/zen', f: f, attr: :note, classes: 'note_text js-note-text'
+ = render 'projects/notes/hints'
.error-alert
.note-form-actions
diff --git a/app/views/projects/notes/_hints.html.haml b/app/views/projects/notes/_hints.html.haml
new file mode 100644
index 00000000000..6e7929bdab0
--- /dev/null
+++ b/app/views/projects/notes/_hints.html.haml
@@ -0,0 +1,9 @@
+.comment-hints.clearfix
+ .pull-left
+ = link_to 'Markdown', help_page_path('markdown', 'markdown'), target: '_blank', tabindex: -1
+ tip:
+ = random_markdown_tip
+ .pull-right
+ = link_to '#', class: 'markdown-selector', tabindex: -1 do
+ = icon('paperclip')
+ Attach a file
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index 5478a887f91..4a1009686c6 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -56,10 +56,9 @@
.note-body{class: note_editable?(note) ? 'js-task-list-container' : ''}
- = cache [note, 'markdown'] do
- .note-text
- = preserve do
- = markdown(note.note, {no_header_anchors: true})
+ .note-text
+ = preserve do
+ = markdown(note.note, {no_header_anchors: true})
= render 'projects/notes/edit_form', note: note
- if note.attachment.url
diff --git a/app/views/projects/refs/logs_tree.js.haml b/app/views/projects/refs/logs_tree.js.haml
index 35c15cf3a9e..db7f244d002 100644
--- a/app/views/projects/refs/logs_tree.js.haml
+++ b/app/views/projects/refs/logs_tree.js.haml
@@ -11,9 +11,11 @@
- if @logs.present?
:plain
var current_url = location.href.replace(/\/?$/, '/');
- var log_url = '#{namespace_project_tree_url(@project.namespace, @project, tree_join(@ref, @path || '/'))}'.replace(/\/?$/, '/');
+ var log_url = "#{escape_javascript(@log_url)}".replace(/\/?$/, '/');
+
if(current_url == log_url) {
- // Load 10 more commit log for each file in tree
+ // Load more commit logs 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))}');
+ var url = "#{escape_javascript(@more_log_url)}";
+ ajaxGet(url);
}
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index 98d9053eb1d..4577b84ab89 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -6,33 +6,50 @@
= render 'shared/no_ssh'
= render 'shared/no_password'
-= render 'projects/last_push'
+- if prefer_readme?
+ = render 'projects/last_push'
+
= render "home_panel"
.project-stats
%ul.nav.nav-pills
%li
= link_to namespace_project_commits_path(@project.namespace, @project, @ref || @repository.root_ref) do
- = pluralize(number_with_delimiter(@repository.commit_count), 'commit')
+ = pluralize(number_with_delimiter(@project.commit_count), 'commit')
%li
= link_to namespace_project_branches_path(@project.namespace, @project) do
= pluralize(number_with_delimiter(@repository.branch_names.count), 'branch')
%li
= link_to namespace_project_tags_path(@project.namespace, @project) do
= pluralize(number_with_delimiter(@repository.tag_names.count), 'tag')
+
- if @repository.changelog
%li
- = link_to changelog_url(@project) do
+ = link_to changelog_path(@project) do
Changelog
- if @repository.license
%li
- = link_to license_url(@project) do
+ = link_to license_path(@project) do
License
- if @repository.contribution_guide
%li
- = link_to contribution_guide_url(@project) do
+ = link_to contribution_guide_path(@project) do
Contribution guide
+ - if current_user && can_push_branch?(@project, @project.default_branch)
+ - unless @repository.changelog
+ %li.missing
+ = link_to add_changelog_path(@project) do
+ Add Changelog
+ - unless @repository.license
+ %li.missing
+ = link_to add_license_path(@project) do
+ Add License
+ - unless @repository.contribution_guide
+ %li.missing
+ = link_to add_contribution_guide_path(@project) do
+ Add Contribution guide
+
- if @project.archived?
.text-warning.center.prepend-top-20
%p
diff --git a/app/views/projects/tree/_tree.html.haml b/app/views/projects/tree/_tree.html.haml
index d304690d162..5048154cb2f 100644
--- a/app/views/projects/tree/_tree.html.haml
+++ b/app/views/projects/tree/_tree.html.haml
@@ -49,5 +49,5 @@
:javascript
// Load last commit log for each file in tree
$('#tree-slider').waitForImages(function() {
- ajaxGet('#{@logs_path}');
+ ajaxGet("#{escape_javascript(@logs_path)}");
});
diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml
index 83cd4c66672..5c4dd7f91ae 100644
--- a/app/views/projects/wikis/show.html.haml
+++ b/app/views/projects/wikis/show.html.haml
@@ -3,6 +3,10 @@
%h3.page-title
= @page.title
= render 'main_links'
+
+.wiki-last-edit-by
+ Last edited by #{@page.commit.author.name} #{time_ago_with_tooltip(@page.commit.authored_date)}
+
- if @page.historical?
.warning_message
This is an old version of this page.
@@ -16,6 +20,6 @@
= render_wiki_content(@page)
%hr
-
.wiki-last-edit-by
Last edited by #{@page.commit.author.name} #{time_ago_with_tooltip(@page.commit.authored_date)}
+
diff --git a/app/views/shared/issuable/_context.html.haml b/app/views/shared/issuable/_context.html.haml
index 46990895d33..19e8c31975b 100644
--- a/app/views/shared/issuable/_context.html.haml
+++ b/app/views/shared/issuable/_context.html.haml
@@ -8,7 +8,7 @@
- else
none
.issuable-context-selectbox
- - if can?(current_user, :admin_issue, @project)
+ - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
= users_select_tag("#{issuable.class.table_name.singularize}[assignee_id]", placeholder: 'Select assignee', class: 'custom-form-control js-select2 js-assignee', selected: issuable.assignee_id, project: @target_project, null_user: true)
%div.prepend-top-20.clearfix
@@ -24,7 +24,7 @@
- else
none
.issuable-context-selectbox
- - if can?(current_user, :admin_issue, @project)
+ - if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
= f.select(:milestone_id, milestone_options(issuable), { include_blank: 'Select milestone' }, {class: 'select2 select2-compact js-select2 js-milestone'})
= hidden_field_tag :issuable_context
= f.submit class: 'btn hide'
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index e434e1b6b98..ac8c1936c9e 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -38,7 +38,7 @@
.clearfix
.error-alert
%hr
-- if can?(current_user, :admin_issue, @project)
+- if can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
.form-group
.issue-assignee
= f.label :assignee_id, class: 'control-label' do
@@ -100,7 +100,7 @@
= link_to 'Change branches', mr_change_branches_path(@merge_request)
.form-actions
- - if !issuable.project.empty_repo? && (guide_url = contribution_guide_url(issuable.project)) && !issuable.persisted?
+ - if !issuable.project.empty_repo? && (guide_url = contribution_guide_path(issuable.project)) && !issuable.persisted?
%p
Please review the
%strong #{link_to 'guidelines for contribution', guide_url}
diff --git a/app/workers/project_cache_worker.rb b/app/workers/project_cache_worker.rb
new file mode 100644
index 00000000000..55cb6af232e
--- /dev/null
+++ b/app/workers/project_cache_worker.rb
@@ -0,0 +1,15 @@
+class ProjectCacheWorker
+ include Sidekiq::Worker
+
+ sidekiq_options queue: :default
+
+ def perform(project_id)
+ project = Project.find(project_id)
+ project.update_repository_size
+ project.update_commit_count
+
+ if project.repository.root_ref
+ project.repository.build_cache
+ end
+ end
+end
diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb
index 4e14e4883bb..b546f8777e1 100644
--- a/app/workers/repository_import_worker.rb
+++ b/app/workers/repository_import_worker.rb
@@ -27,7 +27,7 @@ class RepositoryImportWorker
project.import_finish
project.save
- project.update_repository_size
+ ProjectCacheWorker.perform_async(project.id)
Gitlab::BitbucketImport::KeyDeleter.new(project).execute if project.import_type == 'bitbucket'
end
end