Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gitlab-ce
Commits
057c8c34
Commit
057c8c34
authored
Mar 24, 2015
by
Vinnie Okada
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into markdown-tags
parents
637ca0b3
b9372c99
Changes
85
Hide whitespace changes
Inline
Side-by-side
Showing
85 changed files
with
829 additions
and
530 deletions
+829
-530
CHANGELOG
CHANGELOG
+13
-2
Gemfile.lock
Gemfile.lock
+2
-2
app/assets/javascripts/calendar.js.coffee
app/assets/javascripts/calendar.js.coffee
+1
-4
app/assets/javascripts/dispatcher.js.coffee
app/assets/javascripts/dispatcher.js.coffee
+1
-0
app/assets/javascripts/merge_request.js.coffee
app/assets/javascripts/merge_request.js.coffee
+9
-0
app/assets/javascripts/project_users_select.js.coffee
app/assets/javascripts/project_users_select.js.coffee
+2
-5
app/assets/stylesheets/generic/calendar.scss
app/assets/stylesheets/generic/calendar.scss
+0
-21
app/assets/stylesheets/pages/diff.scss
app/assets/stylesheets/pages/diff.scss
+5
-5
app/assets/stylesheets/pages/merge_requests.scss
app/assets/stylesheets/pages/merge_requests.scss
+3
-18
app/assets/stylesheets/themes/ui_blue.scss
app/assets/stylesheets/themes/ui_blue.scss
+1
-1
app/controllers/admin/services_controller.rb
app/controllers/admin/services_controller.rb
+3
-1
app/controllers/users_controller.rb
app/controllers/users_controller.rb
+36
-24
app/helpers/issues_helper.rb
app/helpers/issues_helper.rb
+1
-12
app/helpers/projects_helper.rb
app/helpers/projects_helper.rb
+4
-0
app/helpers/search_helper.rb
app/helpers/search_helper.rb
+3
-3
app/mailers/emails/projects.rb
app/mailers/emails/projects.rb
+54
-16
app/models/concerns/taskable.rb
app/models/concerns/taskable.rb
+1
-1
app/models/event.rb
app/models/event.rb
+6
-0
app/models/merge_request.rb
app/models/merge_request.rb
+9
-0
app/models/note.rb
app/models/note.rb
+1
-0
app/models/project_contributions.rb
app/models/project_contributions.rb
+0
-32
app/models/project_services/emails_on_push_service.rb
app/models/project_services/emails_on_push_service.rb
+8
-2
app/models/repository.rb
app/models/repository.rb
+0
-35
app/models/user.rb
app/models/user.rb
+3
-5
app/services/issues/bulk_update_service.rb
app/services/issues/bulk_update_service.rb
+3
-3
app/services/issues/update_service.rb
app/services/issues/update_service.rb
+3
-0
app/services/merge_requests/refresh_service.rb
app/services/merge_requests/refresh_service.rb
+3
-9
app/services/merge_requests/update_service.rb
app/services/merge_requests/update_service.rb
+3
-0
app/views/admin/broadcast_messages/index.html.haml
app/views/admin/broadcast_messages/index.html.haml
+2
-4
app/views/admin/services/_form.html.haml
app/views/admin/services/_form.html.haml
+13
-0
app/views/devise/mailer/confirmation_instructions.html.erb
app/views/devise/mailer/confirmation_instructions.html.erb
+1
-1
app/views/devise/mailer/reset_password_instructions.html.erb
app/views/devise/mailer/reset_password_instructions.html.erb
+1
-1
app/views/devise/mailer/unlock_instructions.html.erb
app/views/devise/mailer/unlock_instructions.html.erb
+1
-1
app/views/devise/passwords/edit.html.haml
app/views/devise/passwords/edit.html.haml
+1
-1
app/views/devise/registrations/edit.html.erb
app/views/devise/registrations/edit.html.erb
+2
-2
app/views/help/ui.html.haml
app/views/help/ui.html.haml
+1
-1
app/views/layouts/_head_panel.html.haml
app/views/layouts/_head_panel.html.haml
+1
-1
app/views/layouts/nav/_project.html.haml
app/views/layouts/nav/_project.html.haml
+12
-10
app/views/notify/repository_push_email.html.haml
app/views/notify/repository_push_email.html.haml
+58
-57
app/views/notify/repository_push_email.text.haml
app/views/notify/repository_push_email.text.haml
+41
-39
app/views/profiles/history.html.haml
app/views/profiles/history.html.haml
+1
-1
app/views/profiles/keys/index.html.haml
app/views/profiles/keys/index.html.haml
+0
-2
app/views/projects/_home_panel.html.haml
app/views/projects/_home_panel.html.haml
+1
-1
app/views/projects/commits/_commit.html.haml
app/views/projects/commits/_commit.html.haml
+1
-1
app/views/projects/diffs/_file.html.haml
app/views/projects/diffs/_file.html.haml
+7
-6
app/views/projects/diffs/_text_file.html.haml
app/views/projects/diffs/_text_file.html.haml
+1
-1
app/views/projects/issues/_issue.html.haml
app/views/projects/issues/_issue.html.haml
+3
-2
app/views/projects/labels/_form.html.haml
app/views/projects/labels/_form.html.haml
+2
-2
app/views/projects/merge_requests/_merge_request.html.haml
app/views/projects/merge_requests/_merge_request.html.haml
+3
-2
app/views/projects/merge_requests/_show.html.haml
app/views/projects/merge_requests/_show.html.haml
+1
-1
app/views/projects/milestones/show.html.haml
app/views/projects/milestones/show.html.haml
+6
-5
app/views/projects/notes/_discussion.html.haml
app/views/projects/notes/_discussion.html.haml
+2
-1
app/views/projects/notes/_note.html.haml
app/views/projects/notes/_note.html.haml
+4
-2
app/views/projects/notes/discussions/_diff.html.haml
app/views/projects/notes/discussions/_diff.html.haml
+7
-7
app/views/snippets/current_user_index.html.haml
app/views/snippets/current_user_index.html.haml
+1
-1
app/views/snippets/index.html.haml
app/views/snippets/index.html.haml
+2
-2
app/views/snippets/show.html.haml
app/views/snippets/show.html.haml
+1
-1
app/views/users/_projects.html.haml
app/views/users/_projects.html.haml
+1
-1
app/views/users/calendar.html.haml
app/views/users/calendar.html.haml
+4
-1
app/views/users/calendar_activities.html.haml
app/views/users/calendar_activities.html.haml
+22
-32
app/views/users/show.html.haml
app/views/users/show.html.haml
+2
-1
app/workers/emails_on_push_worker.rb
app/workers/emails_on_push_worker.rb
+27
-18
config/gitlab.yml.example
config/gitlab.yml.example
+3
-0
config/initializers/1_settings.rb
config/initializers/1_settings.rb
+1
-0
db/migrate/20150324155957_set_incorrect_assignee_id_to_null.rb
...grate/20150324155957_set_incorrect_assignee_id_to_null.rb
+6
-0
db/schema.rb
db/schema.rb
+1
-1
docker/Dockerfile
docker/Dockerfile
+1
-1
features/admin/settings.feature
features/admin/settings.feature
+7
-0
features/steps/admin/settings.rb
features/steps/admin/settings.rb
+29
-0
features/steps/user.rb
features/steps/user.rb
+33
-0
features/user.feature
features/user.feature
+9
-0
lib/api/branches.rb
lib/api/branches.rb
+2
-1
lib/gitlab/backend/grack_auth.rb
lib/gitlab/backend/grack_auth.rb
+31
-14
lib/gitlab/backend/rack_attack_helpers.rb
lib/gitlab/backend/rack_attack_helpers.rb
+31
-0
lib/gitlab/commits_calendar.rb
lib/gitlab/commits_calendar.rb
+0
-41
lib/gitlab/contributions_calendar.rb
lib/gitlab/contributions_calendar.rb
+56
-0
lib/gitlab/ldap/person.rb
lib/gitlab/ldap/person.rb
+0
-1
lib/gitlab/markdown.rb
lib/gitlab/markdown.rb
+3
-2
lib/gitlab/project_search_results.rb
lib/gitlab/project_search_results.rb
+1
-1
spec/controllers/users_controller_spec.rb
spec/controllers/users_controller_spec.rb
+4
-17
spec/helpers/gitlab_markdown_helper_spec.rb
spec/helpers/gitlab_markdown_helper_spec.rb
+11
-0
spec/lib/gitlab/backend/grack_auth_spec.rb
spec/lib/gitlab/backend/grack_auth_spec.rb
+51
-1
spec/lib/gitlab/backend/rack_attack_helpers_spec.rb
spec/lib/gitlab/backend/rack_attack_helpers_spec.rb
+35
-0
spec/mailers/notify_spec.rb
spec/mailers/notify_spec.rb
+96
-2
spec/models/repository_spec.rb
spec/models/repository_spec.rb
+7
-38
No files found.
CHANGELOG
View file @
057c8c34
...
...
@@ -2,12 +2,14 @@ Please view this file on the master branch, on stable branches it's out of date.
v 7.10.0 (unreleased)
- Allow HTML tags in Markdown input
- Include missing events and fix save functionality in admin service template settings form (Stan Hu)
- Fix "Import projects from" button to show the correct instructions (Stan Hu)
- Fix dots in Wiki slugs causing errors (Stan Hu)
- Fix OAuth2 issue importing a new project from GitHub and GitLab (Stan Hu)
- Update poltergeist to version 1.6.0 to support PhantomJS 2.0 (Zeger-Jan van de Weg)
- Fix cross references when usernames, milestones, or project names contain underscores (Stan Hu)
- Disable reference creation for comments surrounded by code/preformatted blocks (Stan Hu)
- Reduce Rack Attack false positives causing 403 errors during HTTP authentication (Stan Hu)
- enable line wrapping per default and remove the checkbox to toggle it (Hannes Rosenögger)
- extend the commit calendar to show the actual commits made on a date (Hannes Rosenögger)
- Fix a link in the patch update guide
...
...
@@ -17,6 +19,7 @@ v 7.10.0 (unreleased)
- Add changelog, license and contribution guide links to project sidebar.
- Improve diff UI
- Fix alignment of navbar toggle button (Cody Mize)
- Fix checkbox rendering for nested task lists
- Identical look of selectboxes in UI
- Move "Import existing repository by URL" option to button.
- Improve error message when save profile has error.
...
...
@@ -28,8 +31,17 @@ v 7.10.0 (unreleased)
- Restrict permissions on backup files
- Improve oauth accounts UI in profile page
- Add ability to unlink connected accounts
- Replace commits calendar with faster contribution calendar that includes issues and merge requests
- Add inifinite scroll to user page activity
- Don't show commit comment button when user is not signed in.
- Don't include system notes in issue/MR comment count.
- Don't mark merge request as updated when merge status relative to target branch changes.
- Link note avatar to user.
v 7.9.0
- Send EmailsOnPush email when branch or tag is created or deleted.
v 7.9.0 (unreleased)
- Add HipChat integration documentation (Stan Hu)
- Update documentation for object_kind field in Webhook push and tag push Webhooks (Stan Hu)
- Fix broken email images (Hannes Rosenögger)
...
...
@@ -146,7 +158,6 @@ v 7.8.0
- Add API endpoint to fetch all changes on a MergeRequest (Jeroen van Baarsen)
- View note image attachments in new tab when clicked instead of downloading them
- Improve sorting logic in UI and API. Explicitly define what sorting method is used by default
- Allow more variations for commit messages closing issues (Julien Bianchi and Hannes Rosenögger)
- Fix overflow at sidebar when have several items
- Add notes for label changes in issue and merge requests
- Show tags in commit view (Hannes Rosenögger)
...
...
@@ -168,7 +179,7 @@ v 7.8.0
- Add a commit calendar to the user profile (Hannes Rosenögger)
- Submit comment on command-enter
- Notify all members of a group when that group is mentioned in a comment, for example: `@gitlab-org` or `@sales`.
- Extend issue clossing pattern to include "Resolve", "Resolves", "Resolved", "Resolving" and "Close"
- Extend issue clossing pattern to include "Resolve", "Resolves", "Resolved", "Resolving" and "Close"
(Julien Bianchi and Hannes Rosenögger)
- Fix long broadcast message cut-off on left sidebar (Visay Keo)
- Add Project Avatars (Steven Thonus and Hannes Rosenögger)
- Password reset token validity increased from 2 hours to 2 days since it is also send on account creation.
...
...
Gemfile.lock
View file @
057c8c34
...
...
@@ -188,7 +188,7 @@ GEM
dotenv (>= 0.7)
thor (>= 0.13.6)
formatador (0.2.4)
gemnasium-gitlab-service (0.2.
5
)
gemnasium-gitlab-service (0.2.
4
)
rugged (~> 0.21)
gemojione (2.0.0)
json
...
...
@@ -516,7 +516,7 @@ GEM
rubyntlm (0.5.0)
rubypants (0.2.0)
rugged (0.21.4)
rugments (1.0.0.beta
5
)
rugments (1.0.0.beta
6
)
safe_yaml (0.9.7)
sanitize (2.1.0)
nokogiri (>= 1.4.4)
...
...
app/assets/javascripts/calendar.js.coffee
View file @
057c8c34
...
...
@@ -7,7 +7,7 @@ class @calendar
constructor
:
(
timestamps
,
starting_year
,
starting_month
,
calendar_activities_path
)
->
cal
=
new
CalHeatMap
()
cal
.
init
itemName
:
[
"co
mmit
"
]
itemName
:
[
"co
ntribution
"
]
data
:
timestamps
start
:
new
Date
(
starting_year
,
starting_month
)
domainLabelFormat
:
"%b"
...
...
@@ -27,7 +27,6 @@ class @calendar
legendCellPadding
:
3
onClick
:
(
date
,
count
)
->
formated_date
=
date
.
getFullYear
()
+
"-"
+
(
date
.
getMonth
()
+
1
)
+
"-"
+
date
.
getDate
()
$
(
".calendar_commit_activity"
).
fadeOut
400
$
.
ajax
url
:
calendar_activities_path
data
:
...
...
@@ -36,6 +35,4 @@ class @calendar
dataType
:
"html"
success
:
(
data
)
->
$
(
".user-calendar-activities"
).
html
data
$
(
".calendar_commit_activity"
).
find
(
".js-toggle-content"
).
hide
()
$
(
".calendar_commit_activity"
).
fadeIn
400
app/assets/javascripts/dispatcher.js.coffee
View file @
057c8c34
...
...
@@ -97,6 +97,7 @@ class Dispatcher
new
ProjectFork
()
when
'users:show'
new
User
()
new
Activities
()
switch
path
.
first
()
when
'admin'
...
...
app/assets/javascripts/merge_request.js.coffee
View file @
057c8c34
...
...
@@ -113,8 +113,14 @@ class @MergeRequest
allowed_states
=
[
"failed"
,
"canceled"
,
"running"
,
"pending"
,
"success"
]
if
state
in
allowed_states
$
(
'.ci_widget.ci-'
+
state
).
show
()
switch
state
when
"failed"
,
"canceled"
@
setMergeButtonClass
(
'btn-danger'
)
when
"running"
,
"pending"
@
setMergeButtonClass
(
'btn-warning'
)
else
$
(
'.ci_widget.ci-error'
).
show
()
@
setMergeButtonClass
(
'btn-danger'
)
showCiCoverage
:
(
coverage
)
->
cov_html
=
$
(
'<span>'
)
...
...
@@ -144,6 +150,9 @@ class @MergeRequest
this
.
$
(
'.merge-in-progress'
).
hide
()
this
.
$
(
'.automerge_widget.already_cannot_be_merged'
).
show
()
setMergeButtonClass
:
(
css_class
)
->
$
(
'.accept_merge_request'
).
removeClass
(
"btn-create"
).
addClass
(
css_class
)
mergeInProgress
:
->
$
.
ajax
type
:
'GET'
...
...
app/assets/javascripts/project_users_select.js.coffee
View file @
057c8c34
...
...
@@ -25,7 +25,7 @@ class @ProjectUsersSelect
initSelection
:
(
element
,
callback
)
->
id
=
$
(
element
).
val
()
if
id
isnt
"
"
if
id
!=
""
&&
id
!=
"-1
"
Api
.
user
(
id
,
callback
)
...
...
@@ -44,10 +44,7 @@ class @ProjectUsersSelect
else
avatar
=
gon
.
default_avatar_url
if
user
.
id
==
''
avatarMarkup
=
''
else
avatarMarkup
=
"<div class='user-image'><img class='avatar s24' src='
#{
avatar
}
'></div>"
avatarMarkup
=
"<div class='user-image'><img class='avatar s24' src='
#{
avatar
}
'></div>"
"<div class='user-result'>
#{
avatarMarkup
}
...
...
app/assets/stylesheets/generic/calendar.scss
View file @
057c8c34
.user-calendar-activities
{
.calendar_commit_activity
{
padding
:
5px
0
0
;
}
.calendar_onclick_hr
{
padding
:
0
;
margin
:
10px
0
;
}
.calendar_commit_date
{
color
:
#999
;
}
.calendar_activity_summary
{
font-size
:
14px
;
}
.str-truncated
{
max-width
:
70%
;
...
...
@@ -31,14 +18,6 @@
background-color
:
#ddd
;
}
}
.commit-row-message
{
color
:
#333
;
&
:hover
{
color
:
#444
;
text-decoration
:
underline
;
}
}
}
/**
* This overwrites the default values of the cal-heatmap gem
...
...
app/assets/stylesheets/pages/diff.scss
View file @
057c8c34
...
...
@@ -15,6 +15,11 @@
word-break
:
break-all
;
margin-right
:
200px
;
display
:
block
;
.file-mode
{
margin-left
:
10px
;
color
:
#777
;
}
}
.diff-btn-group
{
...
...
@@ -34,11 +39,6 @@
font-family
:
$monospace_font
;
font-size
:
smaller
;
}
.file-mode
{
font-family
:
$monospace_font
;
margin-left
:
10px
;
}
}
.diff-content
{
overflow
:
auto
;
...
...
app/assets/stylesheets/pages/merge_requests.scss
View file @
057c8c34
...
...
@@ -137,30 +137,15 @@
background-color
:
#F1FAF1
;
}
&
.ci-pending
{
color
:
#548
;
border-color
:
#548
;
background-color
:
#F4F1FA
;
}
&
.ci-pending
,
&
.ci-running
{
color
:
$gl-warning
;
border-color
:
$gl-warning
;
background-color
:
#FAF5F1
;
}
&
.ci-failed
{
color
:
$gl-danger
;
border-color
:
$gl-danger
;
background-color
:
#FAF1F1
;
}
&
.ci-canceled
{
color
:
$gl-warning
;
border-color
:
$gl-danger
;
background-color
:
#FAF5F1
;
}
&
.ci-failed
,
&
.ci-canceled
,
&
.ci-error
{
color
:
$gl-danger
;
border-color
:
$gl-danger
;
...
...
app/assets/stylesheets/themes/ui_blue.scss
View file @
057c8c34
/**
*
Modern
GitLab UI theme
*
Blue
GitLab UI theme
*/
.ui_blue
{
@include
dark-theme
(
#BECDE9
,
#2980b9
,
#1970a9
,
#096099
);
...
...
app/controllers/admin/services_controller.rb
View file @
057c8c34
...
...
@@ -46,7 +46,9 @@ class Admin::ServicesController < Admin::ApplicationController
:user_key
,
:device
,
:priority
,
:sound
,
:bamboo_url
,
:username
,
:password
,
:build_key
,
:server
,
:teamcity_url
,
:build_type
,
:description
,
:issues_url
,
:new_issue_url
,
:restrict_to_branch
,
:send_from_committer_email
,
:disable_diffs
:send_from_committer_email
,
:disable_diffs
,
:push_events
,
:tag_push_events
,
:note_events
,
:issues_events
,
:merge_requests_events
])
end
end
app/controllers/users_controller.rb
View file @
057c8c34
...
...
@@ -4,10 +4,7 @@ class UsersController < ApplicationController
layout
:determine_layout
def
show
@contributed_projects
=
Project
.
where
(
id:
authorized_projects_ids
&
@user
.
contributed_projects_ids
).
in_group_namespace
.
includes
(
:namespace
).
@contributed_projects
=
contributed_projects
.
joined
(
@user
).
reject
(
&
:forked?
)
@projects
=
@user
.
personal_projects
.
...
...
@@ -16,24 +13,26 @@ class UsersController < ApplicationController
# Collect only groups common for both users
@groups
=
@user
.
groups
&
GroupsFinder
.
new
.
execute
(
current_user
)
# Get user activity feed for projects common for both users
@events
=
@user
.
recent_events
.
where
(
project_id:
authorized_projects_ids
).
with_associations
.
limit
(
30
)
@title
=
@user
.
name
@title_url
=
user_path
(
@user
)
respond_to
do
|
format
|
format
.
html
format
.
atom
{
render
layout:
false
}
format
.
atom
do
load_events
render
layout:
false
end
format
.
json
do
load_events
pager_json
(
"events/_events"
,
@events
.
count
)
end
end
end
def
calendar
projects
=
Project
.
where
(
id:
authorized_projects_ids
&
@user
.
contributed_projects_ids
)
calendar
=
Gitlab
::
CommitsCalendar
.
new
(
projects
,
@user
)
calendar
=
contributions_calendar
@timestamps
=
calendar
.
timestamps
@starting_year
=
calendar
.
starting_year
@starting_month
=
calendar
.
starting_month
...
...
@@ -42,20 +41,13 @@ class UsersController < ApplicationController
end
def
calendar_activities
projects
=
Project
.
where
(
id:
authorized_projects_ids
&
@user
.
contributed_projects_ids
)
@calendar_date
=
Date
.
parse
(
params
[
:date
])
rescue
nil
@events
=
[]
date
=
Date
.
parse
(
params
[
:date
])
rescue
nil
if
date
@calendar_activities
=
Gitlab
::
CommitsCalendar
.
get_commits_for_date
(
projects
,
@user
,
date
)
else
@calendar_activities
=
{}
if
@calendar_date
@events
=
contributions_calendar
.
events_by_date
(
@calendar_date
)
end
# get the total number of unique commits
@commit_count
=
@calendar_activities
.
values
.
flatten
.
map
(
&
:id
).
uniq
.
count
@calendar_date
=
date
render
'calendar_activities'
,
layout:
false
end
...
...
@@ -82,4 +74,24 @@ class UsersController < ApplicationController
@authorized_projects_ids
||=
ProjectsFinder
.
new
.
execute
(
current_user
).
pluck
(
:id
)
end
def
contributed_projects
@contributed_projects
=
Project
.
where
(
id:
authorized_projects_ids
&
@user
.
contributed_projects_ids
).
includes
(
:namespace
)
end
def
contributions_calendar
@contributions_calendar
||=
Gitlab
::
ContributionsCalendar
.
new
(
contributed_projects
.
reject
(
&
:forked?
),
@user
)
end
def
load_events
# Get user activity feed for projects common for both users
@events
=
@user
.
recent_events
.
where
(
project_id:
authorized_projects_ids
).
with_associations
@events
=
@events
.
limit
(
20
).
offset
(
params
[
:offset
]
||
0
)
end
end
app/helpers/issues_helper.rb
View file @
057c8c34
...
...
@@ -58,22 +58,11 @@ module IssuesHelper
end
def
bulk_update_milestone_options
options_for_select
([
'None (backlog)'
])
+
options_for_select
([
[
'None (backlog)'
,
-
1
]
])
+
options_from_collection_for_select
(
project_active_milestones
,
'id'
,
'title'
,
params
[
:milestone_id
])
end
def
bulk_update_assignee_options
(
project
=
@project
)
options_for_select
([
'None (unassigned)'
])
+
options_from_collection_for_select
(
project
.
team
.
members
,
'id'
,
'name'
,
params
[
:assignee_id
])
end
def
assignee_options
(
object
,
project
=
@project
)
options_from_collection_for_select
(
project
.
team
.
members
.
sort_by
(
&
:name
),
'id'
,
'name'
,
object
.
assignee_id
)
end
def
milestone_options
(
object
)
options_from_collection_for_select
(
object
.
project
.
milestones
.
active
,
'id'
,
'title'
,
object
.
milestone_id
)
...
...
app/helpers/projects_helper.rb
View file @
057c8c34
...
...
@@ -146,6 +146,10 @@ module ProjectsHelper
nav_tabs
<<
feature
if
project
.
send
:"
#{
feature
}
_enabled"
end
if
project
.
issues_enabled
||
project
.
merge_requests_enabled
nav_tabs
<<
[
:milestones
,
:labels
]
end
nav_tabs
.
flatten
end
...
...
app/helpers/search_helper.rb
View file @
057c8c34
...
...
@@ -23,9 +23,9 @@ module SearchHelper
# Autocomplete results for various settings pages
def
default_autocomplete
[
{
label:
"
My
Profile settings"
,
url:
profile_path
},
{
label:
"
My
SSH Keys"
,
url:
profile_keys_path
},
{
label:
"
My
Dashboard"
,
url:
root_path
},
{
label:
"Profile settings"
,
url:
profile_path
},
{
label:
"SSH Keys"
,
url:
profile_keys_path
},
{
label:
"Dashboard"
,
url:
root_path
},
{
label:
"Admin Section"
,
url:
admin_root_path
},
]
end
...
...
app/mailers/emails/projects.rb
View file @
057c8c34
...
...
@@ -16,31 +16,69 @@ module Emails
subject:
subject
(
"Project was moved"
))
end
def
repository_push_email
(
project_id
,
recipient
,
author_id
,
branch
,
compare
,
reverse_compare
=
false
,
send_from_committer_email
=
false
,
disable_diffs
=
false
)
def
repository_push_email
(
project_id
,
recipient
,
author_id:
nil
,
ref:
nil
,
action:
nil
,
compare:
nil
,
reverse_compare:
false
,
send_from_committer_email:
false
,
disable_diffs:
false
)
unless
author_id
&&
ref
&&
action
raise
ArgumentError
,
"missing keywords: author_id, ref, action"
end
@project
=
Project
.
find
(
project_id
)
@author
=
User
.
find
(
author_id
)
@reverse_compare
=
reverse_compare
@compare
=
compare
@
commits
=
Commit
.
decorate
(
compare
.
commits
)
@
diffs
=
compare
.
diffs
@
branch
=
Gitlab
::
Git
.
ref_name
(
branch
)
@
ref_name
=
Gitlab
::
Git
.
ref_name
(
ref
)
@
ref_type
=
Gitlab
::
Git
.
tag_ref?
(
ref
)
?
"tag"
:
"branch"
@
action
=
action
@disable_diffs
=
disable_diffs
@subject
=
"[
#{
@project
.
path_with_namespace
}
][
#{
@branch
}
] "
if
@compare
@commits
=
Commit
.
decorate
(
compare
.
commits
)
@diffs
=
compare
.
diffs
end
@action_name
=
case
action
when
:create
"pushed new"
when
:delete
"deleted"
else
"pushed to"
end
@subject
=
"[
#{
@project
.
path_with_namespace
}
]"
@subject
<<
"[
#{
@ref_name
}
]"
if
action
==
:push
@subject
<<
" "
if
action
==
:push
if
@commits
.
length
>
1
@target_url
=
namespace_project_compare_url
(
@project
.
namespace
,
@project
,
from:
Commit
.
new
(
@compare
.
base
),
to:
Commit
.
new
(
@compare
.
head
))
@subject
<<
"Deleted "
if
@reverse_compare
@subject
<<
"
#{
@commits
.
length
}
commits:
#{
@commits
.
first
.
title
}
"
else
@target_url
=
namespace_project_commit_url
(
@project
.
namespace
,
@project
,
@commits
.
first
)
if
@commits
.
length
>
1
@target_url
=
namespace_project_compare_url
(
@project
.
namespace
,
@project
,
from:
Commit
.
new
(
@compare
.
base
),
to:
Commit
.
new
(
@compare
.
head
))
@subject
<<
"Deleted "
if
@reverse_compare
@subject
<<
"
#{
@commits
.
length
}
commits:
#{
@commits
.
first
.
title
}
"
@subject
<<
"Deleted 1 commit: "
if
@reverse_compare
@subject
<<
@commits
.
first
.
title
end
else
@target_url
=
namespace_project_commit_url
(
@project
.
namespace
,
@project
,
@commits
.
first
)
unless
action
==
:delete
@target_url
=
namespace_project_tree_url
(
@project
.
namespace
,
@project
,
@ref_name
)
end
@subject
<<
"Deleted 1 commit: "
if
@reverse_compare
@subject
<<
@commits
.
first
.
title
subject_action
=
@action_name
.
dup
subject_action
[
0
]
=
subject_action
[
0
].
capitalize
@subject
<<
"
#{
subject_action
}
#{
@ref_type
}
#{
@ref_name
}
"
end
@disable_footer
=
true
...
...
app/models/concerns/taskable.rb
View file @
057c8c34
...
...
@@ -5,7 +5,7 @@
# Used by MergeRequest and Issue
module
Taskable
TASK_PATTERN_MD
=
/^(?<bullet> *[*-] *)\[(?<checked>[ xX])\]/
.
freeze
TASK_PATTERN_HTML
=
/^<li>\[(?<checked>[ xX])\]/
.
freeze
TASK_PATTERN_HTML
=
/^<li>
(?<p_tag>\s*<p>)?
\[(?<checked>[ xX])\]/
.
freeze
# Change the state of a task list item for this Taskable. Edit the object's
# description by finding the nth task item and changing its checkbox
...
...
app/models/event.rb
View file @
057c8c34
...
...
@@ -55,6 +55,12 @@ class Event < ActiveRecord::Base
order
(
'id DESC'
).
limit
(
100
).
update_all
(
updated_at:
Time
.
now
)
end
def
contributions
where
(
"action = ? OR (target_type in (?) AND action in (?))"
,
Event
::
PUSHED
,
[
"MergeRequest"
,
"Issue"
],
[
Event
::
CREATED
,
Event
::
CLOSED
,
Event
::
MERGED
])
end
end
def
proper?
...
...
app/models/merge_request.rb
View file @
057c8c34
...
...
@@ -105,6 +105,15 @@ class MergeRequest < ActiveRecord::Base
state
:unchecked
state
:can_be_merged
state
:cannot_be_merged
around_transition
do
|
merge_request
,
transition
,
block
|
merge_request
.
record_timestamps
=
false
begin
block
.
call
ensure
merge_request
.
record_timestamps
=
true
end
end
end
validates
:source_project
,
presence:
true
,
unless: :allow_broken
...
...
app/models/note.rb
View file @
057c8c34
...
...
@@ -48,6 +48,7 @@ class Note < ActiveRecord::Base
scope
:inline
,
->
{
where
(
"line_code IS NOT NULL"
)
}
scope
:not_inline
,
->
{
where
(
line_code:
[
nil
,
''
])
}
scope
:system
,
->
{
where
(
system:
true
)
}
scope
:user
,
->
{
where
(
system:
false
)
}
scope
:common
,
->
{
where
(
noteable_type:
[
""
,
nil
])
}
scope
:fresh
,
->
{
order
(
created_at: :asc
,
id: :asc
)
}
scope
:inc_author_project
,
->
{
includes
(
:project
,
:author
)
}
...
...
app/models/project_contributions.rb
deleted
100644 → 0
View file @
637ca0b3
class
ProjectContributions
attr_reader
:project
,
:user
def
initialize
(
project
,
user
)
@project
,
@user
=
project
,
user
end
def
commits_log
repository
=
project
.
repository
if
!
repository
.
exists?
||
repository
.
empty?
return
{}
end
Rails
.
cache
.
fetch
(
cache_key
)
do
repository
.
commits_per_day_for_user
(
user
)
end
end
def
user_commits_on_date
(
date
)
repository
=
@project
.
repository
if
!
repository
.
exists?
||
repository
.
empty?
return
[]
end
commits
=
repository
.
commits_by_user_on_date_log
(
@user
,
date
)
end
def
cache_key
"
#{
Date
.
today
.
to_s
}
-commits-log-
#{
project
.
id
}
-
#{
user
.
email
}
"
end
end
app/models/project_services/emails_on_push_service.rb
View file @
057c8c34
...
...
@@ -36,13 +36,19 @@ class EmailsOnPushService < Service
end
def
supported_events
%w(push)
%w(push
tag_push
)
end
def
execute
(
push_data
)
return
unless
supported_events
.
include?
(
push_data
[
:object_kind
])
EmailsOnPushWorker
.
perform_async
(
project_id
,
recipients
,
push_data
,
send_from_committer_email?
,
disable_diffs?
)
EmailsOnPushWorker
.
perform_async
(
project_id
,
recipients
,
push_data
,
send_from_committer_email:
send_from_committer_email?
,
disable_diffs:
disable_diffs?
)
end
def
send_from_committer_email?
...
...
app/models/repository.rb
View file @
057c8c34
...
...
@@ -149,41 +149,6 @@ class Repository
end
end
def
timestamps_by_user_log
(
user
)
author_emails
=
'('
+
user
.
all_emails
.
map
{
|
e
|
Regexp
.
escape
(
e
)
}.
join
(
'|'
)
+
')'
args
=
%W(git log -E --author=
#{
author_emails
}
--since=
#{
(
Date
.
today
-
1
.
year
).
to_s
}
--branches --pretty=format:%cd --date=short)
dates
=
Gitlab
::
Popen
.
popen
(
args
,
path_to_repo
).
first
.
split
(
"
\n
"
)
if
dates
.
present?
dates
else
[]
end
end
def
commits_by_user_on_date_log
(
user
,
date
)
# format the date string for git
start_date
=
date
.
strftime
(
"%Y-%m-%d 00:00:00"
)
end_date
=
date
.
strftime
(
"%Y-%m-%d 23:59:59"
)
author_emails
=
'('
+
user
.
all_emails
.
map
{
|
e
|
Regexp
.
escape
(
e
)
}.
join
(
'|'
)
+
')'
args
=
%W(git log -E --author=
#{
author_emails
}
--after=
#{
start_date
.
to_s
}
--until=
#{
end_date
.
to_s
}
--branches --pretty=format:%h)
commits
=
Gitlab
::
Popen
.
popen
(
args
,
path_to_repo
).
first
.
split
(
"
\n
"
)
commits
.
map!
do
|
commit_id
|
commit
(
commit_id
)
end
end
def
commits_per_day_for_user
(
user
)
timestamps_by_user_log
(
user
).
group_by
{
|
commit_date
|
commit_date
}.
inject
({})
do
|
hash
,
(
timestamp_date
,
commits
)
|
hash
[
timestamp_date
]
=
commits
.
count
hash
end
end
def
lookup_cache
@lookup_cache
||=
{}
end
...
...
app/models/user.rb
View file @
057c8c34
...
...
@@ -110,6 +110,7 @@ class User < ActiveRecord::Base
has_many
:notes
,
dependent: :destroy
,
foreign_key: :author_id
has_many
:merge_requests
,
dependent: :destroy
,
foreign_key: :author_id
has_many
:events
,
dependent: :destroy
,
foreign_key: :author_id
,
class_name:
"Event"
has_many
:subscriptions
,
dependent: :destroy
has_many
:recent_events
,
->
{
order
"id DESC"
},
foreign_key: :author_id
,
class_name:
"Event"
has_many
:assigned_issues
,
dependent: :destroy
,
foreign_key: :assignee_id
,
class_name:
"Issue"
has_many
:assigned_merge_requests
,
dependent: :destroy
,
foreign_key: :assignee_id
,
class_name:
"MergeRequest"
...
...
@@ -603,13 +604,10 @@ class User < ActiveRecord::Base
end
def
contributed_projects_ids
Event
.
where
(
author_id:
self
).
Event
.
contributions
.
where
(
author_id:
self
).
where
(
"created_at > ?"
,
Time
.
now
-
1
.
year
).
where
(
"action = :pushed OR (target_type = 'MergeRequest' AND action = :created)"
,
pushed:
Event
::
PUSHED
,
created:
Event
::
CREATED
).
reorder
(
project_id: :desc
).
select
(
:project_id
).
uniq
.
map
(
&
:project_id
)
uniq
.
map
(
&
:project_id
)
end
end
app/services/issues/bulk_update_service.rb
View file @
057c8c34
...
...
@@ -4,9 +4,9 @@ module Issues
issues_ids
=
params
.
delete
(
:issues_ids
).
split
(
","
)
issue_params
=
params
issue_params
.
delete
(
:state_event
)
unless
issue_params
[
:state_event
].
present?
issue_params
.
delete
(
:milestone_id
)
unless
issue_params
[
:milestone_id
].
present?
issue_params
.
delete
(
:assignee_id
)
unless
issue_params
[
:assignee_id
].
present?
issue_params
.
delete
(
:state_event
)
unless
issue_params
[
:state_event
].
present?
issue_params
.
delete
(
:milestone_id
)
unless
issue_params
[
:milestone_id
].
present?
issue_params
.
delete
(
:assignee_id
)
unless
issue_params
[
:assignee_id
].
present?
issues
=
Issue
.
where
(
id:
issues_ids
)
issues
.
each
do
|
issue
|
...
...
app/services/issues/update_service.rb
View file @
057c8c34
...
...
@@ -14,6 +14,9 @@ module Issues
issue
.
update_nth_task
(
params
[
:task_num
].
to_i
,
false
)
end
params
[
:assignee_id
]
=
""
if
params
[
:assignee_id
]
==
"-1"
params
[
:milestone_id
]
=
""
if
params
[
:milestone_id
]
==
"-1"
old_labels
=
issue
.
labels
.
to_a
if
params
.
present?
&&
issue
.
update_attributes
(
params
.
except
(
:state_event
,
...
...
app/services/merge_requests/refresh_service.rb
View file @
057c8c34
...
...
@@ -53,7 +53,7 @@ module MergeRequests
if
merge_request
.
source_branch
==
@branch_name
||
force_push?
merge_request
.
reload_code
update_merge_request
(
merge_request
)
merge_request
.
mark_as_unchecked
else
mr_commit_ids
=
merge_request
.
commits
.
map
(
&
:id
)
push_commit_ids
=
@commits
.
map
(
&
:id
)
...
...
@@ -61,20 +61,14 @@ module MergeRequests
if
matches
.
any?
merge_request
.
reload_code
update_merge_request
(
merge_request
)
merge_request
.
mark_as_unchecked
else
update_merge_request
(
merge_request
)
merge_request
.
mark_as_unchecked
end
end
end
end
def
update_merge_request
(
merge_request
)
MergeRequests
::
UpdateService
.
new
(
merge_request
.
target_project
,
@current_user
,
merge_status:
'unchecked'
).
execute
(
merge_request
)
end
# Add comment about pushing new commits to merge requests
def
comment_mr_with_commits
merge_requests
=
@project
.
origin_merge_requests
.
opened
.
where
(
source_branch:
@branch_name
).
to_a
...
...
app/services/merge_requests/update_service.rb
View file @
057c8c34
...
...
@@ -23,6 +23,9 @@ module MergeRequests
merge_request
.
update_nth_task
(
params
[
:task_num
].
to_i
,
false
)
end
params
[
:assignee_id
]
=
""
if
params
[
:assignee_id
]
==
"-1"
params
[
:milestone_id
]
=
""
if
params
[
:milestone_id
]
==
"-1"
old_labels
=
merge_request
.
labels
.
to_a
if
params
.
present?
&&
merge_request
.
update_attributes
(
...
...
app/views/admin/broadcast_messages/index.html.haml
View file @
057c8c34
...
...
@@ -21,13 +21,11 @@
.form-group.js-toggle-colors-container.hide
=
f
.
label
:color
,
"Background Color"
,
class:
'control-label'
.col-sm-10
=
f
.
text_field
:color
,
placeholder:
"#AA33EE"
,
class:
"form-control"
.light
6 character hex values starting with a # sign.
=
f
.
color_field
:color
,
value:
"#AA33EE"
,
class:
"form-control"
.form-group.js-toggle-colors-container.hide
=
f
.
label
:font
,
"Font Color"
,
class:
'control-label'
.col-sm-10
=
f
.
text_field
:font
,
placeholder:
"#224466"
,
class:
"form-control"
.light
6 character hex values starting with a # sign.
=
f
.
color_field
:font
,
value:
"#224466"
,
class:
"form-control"
.form-group
=
f
.
label
:starts_at
,
class:
'control-label'
.col-sm-10.datetime-controls
...
...
app/views/admin/services/_form.html.haml
View file @
057c8c34
...
...
@@ -14,6 +14,11 @@
=
preserve
do
=
markdown
@service
.
help
.form-group
=
f
.
label
:active
,
"Active"
,
class:
"control-label"
.col-sm-10
=
f
.
check_box
:active
-
if
@service
.
supported_events
.
length
>
1
.form-group
=
f
.
label
:url
,
"Trigger"
,
class:
'control-label'
...
...
@@ -34,6 +39,14 @@
%strong
Tag push events
%p
.light
This url will be triggered when a new tag is pushed to the repository
-
if
@service
.
supported_events
.
include?
(
"note"
)
%div
=
f
.
check_box
:note_events
,
class:
'pull-left'
.prepend-left-20
=
f
.
label
:note_events
,
class:
'list-label'
do
%strong
Comments
%p
.light
This url will be triggered when someone adds a comment
-
if
@service
.
supported_events
.
include?
(
"issue"
)
%div
=
f
.
check_box
:issues_events
,
class:
'pull-left'
...
...
app/views/devise/mailer/confirmation_instructions.html.erb
View file @
057c8c34
...
...
@@ -6,4 +6,4 @@
<p>
You can confirm your account through the link below:
</p>
<%
end
%>
<p>
<%=
link_to
'Confirm
my
account'
,
confirmation_url
(
@resource
,
confirmation_token:
@token
)
%>
</p>
<p>
<%=
link_to
'Confirm
your
account'
,
confirmation_url
(
@resource
,
confirmation_token:
@token
)
%>
</p>
app/views/devise/mailer/reset_password_instructions.html.erb
View file @
057c8c34
...
...
@@ -2,7 +2,7 @@
<p>
Someone has requested a link to change your password, and you can do this through the link below.
</p>
<p>
<%=
link_to
'Change
my
password'
,
edit_password_url
(
@resource
,
reset_password_token:
@token
)
%>
</p>
<p>
<%=
link_to
'Change
your
password'
,
edit_password_url
(
@resource
,
reset_password_token:
@token
)
%>
</p>
<p>
If you didn't request this, please ignore this email.
</p>
<p>
Your password won't change until you access the link above and create a new one.
</p>
app/views/devise/mailer/unlock_instructions.html.erb
View file @
057c8c34
...
...
@@ -4,4 +4,4 @@
<p>
Click the link below to unlock your account:
</p>
<p>
<%=
link_to
'Unlock
my
account'
,
unlock_url
(
@resource
,
unlock_token:
@token
)
%>
</p>
<p>
<%=
link_to
'Unlock
your
account'
,
unlock_url
(
@resource
,
unlock_token:
@token
)
%>
</p>
app/views/devise/passwords/edit.html.haml
View file @
057c8c34
...
...
@@ -11,7 +11,7 @@
%div
=
f
.
password_field
:password_confirmation
,
class:
"form-control bottom"
,
placeholder:
"Confirm new password"
,
required:
true
.clearfix
=
f
.
submit
"Change
my
password"
,
class:
"btn btn-primary"
=
f
.
submit
"Change
your
password"
,
class:
"btn btn-primary"
.clearfix.prepend-top-20
%p
...
...
app/views/devise/registrations/edit.html.erb
View file @
057c8c34
...
...
@@ -21,8 +21,8 @@
<div>
<%=
f
.
submit
"Update"
,
class:
"input_button"
%>
</div>
<%
end
%>
<h3>
Cancel
my
account
</h3>
<h3>
Cancel
your
account
</h3>
<p>
Unhappy?
<%=
link_to
"Cancel
my
account"
,
registration_path
(
resource_name
),
data:
{
confirm:
"Are you sure?"
},
method: :delete
%>
.
</p>
<p>
Unhappy?
<%=
link_to
"Cancel
your
account"
,
registration_path
(
resource_name
),
data:
{
confirm:
"Are you sure?"
},
method: :delete
%>
.
</p>
<%=
link_to
"Back"
,
:back
%>
app/views/help/ui.html.haml
View file @
057c8c34
...
...
@@ -53,7 +53,7 @@
%code
.panel .well-list
.panel.panel-default
.panel-heading
My
list
.panel-heading
Your
list
%ul
.well-list
%li
One item
...
...
app/views/layouts/_head_panel.html.haml
View file @
057c8c34
...
...
@@ -25,7 +25,7 @@
=
link_to
explore_root_path
,
title:
"Explore"
,
class:
'has_bottom_tooltip'
,
'data-original-title'
=>
'Public area'
do
%i
.fa.fa-globe
%li
=
link_to
user_snippets_path
(
current_user
),
title:
"
My snippets"
,
class:
'has_bottom_tooltip'
,
'data-original-title'
=>
'My
snippets'
do
=
link_to
user_snippets_path
(
current_user
),
title:
"
Your snippets"
,
class:
'has_bottom_tooltip'
,
'data-original-title'
=>
'Your
snippets'
do
%i
.fa.fa-clipboard
-
if
current_user
.
is_admin?
%li
...
...
app/views/layouts/nav/_project.html.haml
View file @
057c8c34
...
...
@@ -44,11 +44,12 @@
%span
Graphs
=
nav_link
(
controller: :milestones
)
do
=
link_to
namespace_project_milestones_path
(
@project
.
namespace
,
@project
),
title:
'Milestones'
do
%i
.fa.fa-clock-o
%span
Milestones
-
if
project_nav_tab?
:milestones
=
nav_link
(
controller: :milestones
)
do
=
link_to
namespace_project_milestones_path
(
@project
.
namespace
,
@project
),
title:
'Milestones'
do
%i
.fa.fa-clock-o
%span
Milestones
-
if
project_nav_tab?
:issues
=
nav_link
(
controller: :issues
)
do
...
...
@@ -67,11 +68,12 @@
Merge Requests
%span
.count.merge_counter
=
@project
.
merge_requests
.
opened
.
count
=
nav_link
(
controller: :labels
)
do
=
link_to
namespace_project_labels_path
(
@project
.
namespace
,
@project
),
title:
'Labels'
do
%i
.fa.fa-tags
%span
Labels
-
if
project_nav_tab?
:labels
=
nav_link
(
controller: :labels
)
do
=
link_to
namespace_project_labels_path
(
@project
.
namespace
,
@project
),
title:
'Labels'
do
%i
.fa.fa-tags
%span
Labels
-
if
project_nav_tab?
:wiki
=
nav_link
(
controller: :wikis
)
do
...
...
app/views/notify/repository_push_email.html.haml
View file @
057c8c34
%h3
#{
@author
.
name
}
pushed to
#{
@branch
}
at
#{
link_to
@project
.
name_with_namespace
,
namespace_project_url
(
@project
.
namespace
,
@project
)
}
%h3
#{
@author
.
name
}
#{
@action_name
}
#{
@ref_type
}
#{
@ref_name
}
at
#{
link_to
@project
.
name_with_namespace
,
namespace_project_url
(
@project
.
namespace
,
@project
)
}
-
if
@reverse_compare
%p
%strong
WARNING:
The push did not contain any new commits, but force pushed to delete the commits and changes below.
-
if
@compare
-
if
@reverse_compare
%p
%strong
WARNING:
The push did not contain any new commits, but force pushed to delete the commits and changes below.
%h4
=
@reverse_compare
?
"Deleted commits:"
:
"Commits:"
%h4
=
@reverse_compare
?
"Deleted commits:"
:
"Commits:"
%ul
-
@commits
.
each
do
|
commit
|
%li
%strong
#{
link_to
commit
.
short_id
,
namespace_project_commit_url
(
@project
.
namespace
,
@project
,
commit
)
}
%div
%span
by
#{
commit
.
author_name
}
%i
at
#{
commit
.
committed_date
.
strftime
(
"%Y-%m-%dT%H:%M:%SZ"
)
}
%pre
.commit-message
=
commit
.
safe_message
%ul
-
@commits
.
each
do
|
commit
|
%li
%strong
#{
link_to
commit
.
short_id
,
namespace_project_commit_url
(
@project
.
namespace
,
@project
,
commit
)
}
%div
%span
by
#{
commit
.
author_name
}
%i
at
#{
commit
.
committed_date
.
strftime
(
"%Y-%m-%dT%H:%M:%SZ"
)
}
%pre
.commit-message
=
commit
.
safe_message
%h4
#{
pluralize
@diffs
.
count
,
"changed file"
}
:
%h4
#{
pluralize
@diffs
.
count
,
"changed file"
}
:
%ul
-
@diffs
.
each_with_index
do
|
diff
,
i
|
%li
.file-stats
%a
{
href:
"#{@target_url if @disable_diffs}#diff-#{i}"
}
-
if
diff
.
deleted_file
%span
.deleted-file
−
%ul
-
@diffs
.
each_with_index
do
|
diff
,
i
|
%li
.file-stats
%a
{
href:
"#{@target_url if @disable_diffs}#diff-#{i}"
}
-
if
diff
.
deleted_file
%span
.deleted-file
−
=
diff
.
old_path
-
elsif
diff
.
renamed_file
=
diff
.
old_path
-
elsif
diff
.
renamed_file
=
diff
.
old_path
→
=
diff
.
new_path
-
elsif
diff
.
new_file
%span
.new-file
+
→
=
diff
.
new_path
-
else
=
diff
.
new_path
-
unless
@disable_diffs
%h4
Changes:
-
@diffs
.
each_with_index
do
|
diff
,
i
|
%li
{
id:
"diff-#{i}"
}
%a
{
href:
@target_url
+
"#diff-#{i}"
}
-
if
diff
.
deleted_file
%strong
=
diff
.
old_path
deleted
-
elsif
diff
.
renamed_file
%strong
=
diff
.
old_path
→
%strong
-
elsif
diff
.
new_file
%span
.new-file
+
=
diff
.
new_path
-
else
=
diff
.
new_path
-
else
%strong
=
diff
.
new_path
%hr
%pre
=
color_email_diff
(
diff
.
diff
)
%br
-
if
@compare
.
timeout
%h5
Huge diff. To prevent performance issues changes are hidden
-
unless
@disable_diffs
%h4
Changes:
-
@diffs
.
each_with_index
do
|
diff
,
i
|
%li
{
id:
"diff-#{i}"
}
%a
{
href:
@target_url
+
"#diff-#{i}"
}
-
if
diff
.
deleted_file
%strong
=
diff
.
old_path
deleted
-
elsif
diff
.
renamed_file
%strong
=
diff
.
old_path
→
%strong
=
diff
.
new_path
-
else
%strong
=
diff
.
new_path
%hr
%pre
=
color_email_diff
(
diff
.
diff
)
%br
-
if
@compare
.
timeout
%h5
Huge diff. To prevent performance issues changes are hidden
app/views/notify/repository_push_email.text.haml
View file @
057c8c34
#{
@author
.
name
}
pushed to
#{
@branch
}
at
#{
@project
.
name_with_namespace
}
\
\
-
if
@reverse_compare
WARNING: The push did not contain any new commits, but force pushed to delete the commits and changes below.
#{
@author
.
name
}
#{
@action_name
}
#{
@ref_type
}
#{
@ref_name
}
at
#{
@project
.
name_with_namespace
}
-
if
@compare
\
\
=
@reverse_compare
?
"Deleted commits:"
:
"Commits:"
-
@commits
.
each
do
|
commit
|
#{
commit
.
short_id
}
by
#{
commit
.
author_name
}
at
#{
commit
.
committed_date
.
strftime
(
"%Y-%m-%dT%H:%M:%SZ"
)
}
#{
commit
.
safe_message
}
\- - - - -
\
\
#{
pluralize
@diffs
.
count
,
"changed file"
}
:
\
-
@diffs
.
each
do
|
diff
|
-
if
diff
.
deleted_file
\- −
#{
diff
.
old_path
}
-
elsif
diff
.
renamed_file
\-
#{
diff
.
old_path
}
→
#{
diff
.
new_path
}
-
elsif
diff
.
new_file
\- +
#{
diff
.
new_path
}
-
else
\-
#{
diff
.
new_path
}
-
unless
@disable_diffs
-
if
@reverse_compare
WARNING: The push did not contain any new commits, but force pushed to delete the commits and changes below.
\
\
=
@reverse_compare
?
"Deleted commits:"
:
"Commits:"
-
@commits
.
each
do
|
commit
|
#{
commit
.
short_id
}
by
#{
commit
.
author_name
}
at
#{
commit
.
committed_date
.
strftime
(
"%Y-%m-%dT%H:%M:%SZ"
)
}
#{
commit
.
safe_message
}
\- - - - -
\
\
#{
pluralize
@diffs
.
count
,
"changed file"
}
:
\
Changes:
-
@diffs
.
each
do
|
diff
|
\
\=====================================
-
if
diff
.
deleted_file
#{
diff
.
old_path
}
deleted
\- −
#{
diff
.
old_path
}
-
elsif
diff
.
renamed_file
#{
diff
.
old_path
}
→
#{
diff
.
new_path
}
\-
#{
diff
.
old_path
}
→
#{
diff
.
new_path
}
-
elsif
diff
.
new_file
\- +
#{
diff
.
new_path
}
-
else
=
diff
.
new_path
\=====================================
!=
diff
.
diff
-
if
@compare
.
timeout
\
\
Huge diff. To prevent performance issues it was hidden
\
\
View it on GitLab:
#{
@target_url
}
\-
#{
diff
.
new_path
}
-
unless
@disable_diffs
\
\
Changes:
-
@diffs
.
each
do
|
diff
|
\
\=====================================
-
if
diff
.
deleted_file
#{
diff
.
old_path
}
deleted
-
elsif
diff
.
renamed_file
#{
diff
.
old_path
}
→
#{
diff
.
new_path
}
-
else
=
diff
.
new_path
\=====================================
!=
diff
.
diff
-
if
@compare
.
timeout
\
\
Huge diff. To prevent performance issues it was hidden
-
if
@target_url
\
\
View it on GitLab:
#{
@target_url
}
app/views/profiles/history.html.haml
View file @
057c8c34
%h3
.page-title
My
Account History
Your
Account History
%p
.light
All events created by your account are listed below.
%hr
...
...
app/views/profiles/keys/index.html.haml
View file @
057c8c34
...
...
@@ -3,8 +3,6 @@
.pull-right
=
link_to
"Add SSH Key"
,
new_profile_key_path
,
class:
"btn btn-new"
%p
.light
My SSH keys:
#{
@keys
.
count
}
%br
Before you can add an SSH key you need to
=
link_to
"generate it."
,
help_page_path
(
"ssh"
,
"README"
)
%hr
...
...
app/views/projects/_home_panel.html.haml
View file @
057c8c34
...
...
@@ -19,7 +19,7 @@
.fork-buttons
-
if
current_user
&&
can?
(
current_user
,
:fork_project
,
@project
)
&&
@project
.
namespace
!=
current_user
.
namespace
-
if
current_user
.
already_forked?
(
@project
)
&&
current_user
.
manageable_namespaces
.
size
<
2
=
link_to
namespace_project_path
(
current_user
,
current_user
.
fork_of
(
@project
)),
title:
'Go to
my
fork'
do
=
link_to
namespace_project_path
(
current_user
,
current_user
.
fork_of
(
@project
)),
title:
'Go to
your
fork'
do
=
link_to_toggle_fork
-
else
=
link_to
new_namespace_project_fork_path
(
@project
.
namespace
,
@project
),
title:
"Fork project"
do
...
...
app/views/projects/commits/_commit.html.haml
View file @
057c8c34
...
...
@@ -13,7 +13,7 @@
-
note_count
=
@note_counts
.
fetch
(
commit
.
id
,
0
)
-
else
-
notes
=
project
.
notes
.
for_commit_id
(
commit
.
id
)
-
note_count
=
notes
.
count
-
note_count
=
notes
.
user
.
count
-
if
note_count
>
0
%span
.light
...
...
app/views/projects/diffs/_file.html.haml
View file @
057c8c34
...
...
@@ -13,12 +13,13 @@
-
submodule_item
=
project
.
repository
.
blob_at
(
@commit
.
id
,
diff_file
.
file_path
)
=
submodule_link
(
submodule_item
,
@commit
.
id
)
-
else
-
if
diff_file
.
renamed_file
%span
=
"
#{
diff_file
.
old_path
}
renamed to
#{
diff_file
.
new_path
}
"
-
else
%span
=
diff_file
.
new_path
-
if
diff_file
.
mode_changed?
%span
.file-mode
=
"
#{
diff_file
.
diff
.
a_mode
}
→
#{
diff_file
.
diff
.
b_mode
}
"
%span
-
if
diff_file
.
renamed_file
=
"
#{
diff_file
.
old_path
}
renamed to
#{
diff_file
.
new_path
}
"
-
else
=
diff_file
.
new_path
-
if
diff_file
.
mode_changed?
%span
.file-mode
=
"
#{
diff_file
.
diff
.
a_mode
}
→
#{
diff_file
.
diff
.
b_mode
}
"
.diff-btn-group
-
if
blob
.
text?
...
...
app/views/projects/diffs/_text_file.html.haml
View file @
057c8c34
...
...
@@ -16,7 +16,7 @@
-
else
%td
.old_line
=
link_to
raw
(
type
==
"new"
?
" "
:
line_old
),
"#
#{
line_code
}
"
,
id:
line_code
-
if
@comments_allowed
-
if
@comments_allowed
&&
can?
(
current_user
,
:write_note
,
@project
)
=
link_to_new_diff_note
(
line_code
)
%td
.new_line
{
data:
{
linenumber:
line
.
new_pos
}}
=
link_to
raw
(
type
==
"old"
?
" "
:
line
.
new_pos
)
,
"#
#{
line_code
}
"
,
id:
line_code
...
...
app/views/projects/issues/_issue.html.haml
View file @
057c8c34
...
...
@@ -10,11 +10,12 @@
-
if
issue
.
closed?
%span
CLOSED
-
if
issue
.
notes
.
any?
-
note_count
=
issue
.
notes
.
user
.
count
-
if
note_count
>
0
%span
%i
.fa.fa-comments
=
issue
.
notes
.
count
=
note_
count
.issue-info
=
link_to
"#
#{
issue
.
iid
}
"
,
issue_path
(
issue
),
class:
"light"
...
...
app/views/projects/labels/_form.html.haml
View file @
057c8c34
...
...
@@ -16,9 +16,9 @@
.col-sm-10
.input-group
.input-group-addon.label-color-preview
=
f
.
color_field
:color
,
placeholder
:
"#AA33EE"
,
class:
"form-control"
=
f
.
color_field
:color
,
value
:
"#AA33EE"
,
class:
"form-control"
.help-block
6 character hex values starting with a # sign
.
Choose any color
.
%br
Or you can choose one of suggested colors below
...
...
app/views/projects/merge_requests/_merge_request.html.haml
View file @
057c8c34
...
...
@@ -16,11 +16,12 @@
%span
.label-branch
<
%i
.fa.fa-code-fork
%span
=
merge_request
.
target_branch
-
if
merge_request
.
notes
.
any?
-
note_count
=
merge_request
.
mr_and_commit_notes
.
user
.
count
-
if
note_count
>
0
&
nbsp
;
%span
%i
.fa.fa-comments
=
merge_request
.
mr_and_commit_notes
.
count
=
note_
count
.merge-request-info
=
link_to
"#
#{
merge_request
.
iid
}
"
,
merge_request_path
(
merge_request
),
class:
"light"
-
if
merge_request
.
assignee
...
...
app/views/projects/merge_requests/_show.html.haml
View file @
057c8c34
...
...
@@ -40,7 +40,7 @@
=
link_to
merge_request_path
(
@merge_request
)
do
%i
.fa.fa-comments
Discussion
%span
.badge
=
@merge_request
.
mr_and_commit_notes
.
count
%span
.badge
=
@merge_request
.
mr_and_commit_notes
.
user
.
count
%li
.commits-tab
{
data:
{
action:
'commits'
}}
=
link_to
merge_request_path
(
@merge_request
),
title:
'Commits'
do
%i
.fa.fa-history
...
...
app/views/projects/milestones/show.html.haml
View file @
057c8c34
...
...
@@ -60,11 +60,12 @@
Participants
%span
.badge
=
@users
.
count
.pull-right
=
link_to
new_namespace_project_issue_path
(
@project
.
namespace
,
@project
,
issue:
{
milestone_id:
@milestone
.
id
}),
class:
"btn btn-grouped"
,
title:
"New Issue"
do
%i
.fa.fa-plus
New Issue
=
link_to
'Browse Issues'
,
namespace_project_issues_path
(
@milestone
.
project
.
namespace
,
@milestone
.
project
,
milestone_id:
@milestone
.
id
),
class:
"btn edit-milestone-link btn-grouped"
-
if
@project
.
issues_enabled
.pull-right
=
link_to
new_namespace_project_issue_path
(
@project
.
namespace
,
@project
,
issue:
{
milestone_id:
@milestone
.
id
}),
class:
"btn btn-grouped"
,
title:
"New Issue"
do
%i
.fa.fa-plus
New Issue
=
link_to
'Browse Issues'
,
namespace_project_issues_path
(
@milestone
.
project
.
namespace
,
@milestone
.
project
,
milestone_id:
@milestone
.
id
),
class:
"btn edit-milestone-link btn-grouped"
.tab-content
.tab-pane.active
#tab-issues
...
...
app/views/projects/notes/_discussion.html.haml
View file @
057c8c34
...
...
@@ -2,7 +2,8 @@
.timeline-entry
.timeline-entry-inner
.timeline-icon
=
image_tag
avatar_icon
(
note
.
author_email
),
class:
"avatar s40"
=
link_to
user_path
(
note
.
author
)
do
=
image_tag
avatar_icon
(
note
.
author_email
),
class:
"avatar s40"
.timeline-content
-
if
note
.
for_merge_request?
-
if
note
.
outdated?
...
...
app/views/projects/notes/_note.html.haml
View file @
057c8c34
...
...
@@ -4,7 +4,8 @@
-
if
note
.
system
%span
.fa.fa-circle
-
else
=
image_tag
avatar_icon
(
note
.
author_email
),
class:
"avatar s40"
=
link_to
user_path
(
note
.
author
)
do
=
image_tag
avatar_icon
(
note
.
author_email
),
class:
"avatar s40"
.timeline-content
.note-header
.note-actions
...
...
@@ -21,7 +22,8 @@
%i
.fa.fa-trash-o.cred
Remove
-
if
note
.
system
=
image_tag
avatar_icon
(
note
.
author_email
),
class:
"avatar s16"
=
link_to
user_path
(
note
.
author
)
do
=
image_tag
avatar_icon
(
note
.
author_email
),
class:
"avatar s16"
=
link_to_member
(
@project
,
note
.
author
,
avatar:
false
)
%span
.author-username
=
'@'
+
note
.
author
.
username
...
...
app/views/projects/notes/discussions/_diff.html.haml
View file @
057c8c34
...
...
@@ -2,13 +2,13 @@
-
if
diff
.diff-file
.diff-header
-
if
diff
.
deleted_file
%span
=
diff
.
old_path
-
else
%span
=
diff
.
new_path
-
if
diff
.
a_mode
&&
diff
.
b_mode
&&
diff
.
a_mode
!=
diff
.
b_mode
%span
.file-mode
=
"
#{
diff
.
a_mode
}
→
#{
diff
.
b_mode
}
"
%br
/
%span
-
if
diff
.
deleted_file
=
diff
.
old_path
-
else
=
diff
.
new_path
-
if
diff
.
a_mode
&&
diff
.
b_mode
&&
diff
.
a_mode
!=
diff
.
b_mode
%span
.file-mode
=
"
#{
diff
.
a_mode
}
→
#{
diff
.
b_mode
}
"
.diff-content
%table
-
note
.
truncated_diff_lines
.
each
do
|
line
|
...
...
app/views/snippets/current_user_index.html.haml
View file @
057c8c34
%h3
.page-title
My
Snippets
Your
Snippets
.pull-right
=
link_to
new_snippet_path
,
class:
"btn btn-new btn-grouped"
,
title:
"New Snippet"
do
Add new snippet
...
...
app/views/snippets/index.html.haml
View file @
057c8c34
...
...
@@ -2,12 +2,12 @@
Public snippets
.pull-right
-
if
current_user
=
link_to
new_snippet_path
,
class:
"btn btn-new btn-grouped"
,
title:
"New Snippet"
do
Add new snippet
=
link_to
user_snippets_path
(
current_user
),
class:
"btn btn-grouped"
do
My
snippets
Your
snippets
%p
.light
Public snippets created by you and other users are listed here
...
...
app/views/snippets/show.html.haml
View file @
057c8c34
...
...
@@ -23,7 +23,7 @@
.back-link
-
if
@snippet
.
author
==
current_user
=
link_to
user_snippets_path
(
current_user
)
do
←
my
snippets
←
your
snippets
-
else
=
link_to
snippets_path
do
←
discover snippets
...
...
app/views/users/_projects.html.haml
View file @
057c8c34
-
if
@contributed_projects
.
present?
.panel.panel-default
.panel.panel-default
.contributed-projects
.panel-heading
Projects contributed to
=
render
'shared/projects_list'
,
projects:
@contributed_projects
.
sort_by
(
&
:star_count
).
reverse
,
...
...
app/views/users/calendar.html.haml
View file @
057c8c34
%h4
Commits calendar
%h4
Contributions calendar
.pull-right
%small
Issues, merge requests and push events
#cal-heatmap
.calendar
:javascript
new
calendar
(
...
...
app/views/users/calendar_activities.html.haml
View file @
057c8c34
.calendar_commit_activity
%hr
%h4
Commit Activity
%strong
-
if
@commit_count
==
0
no
-
else
=
@commit_count
%span
.calendar_commit_date
unique
=
'commit'
.
pluralize
(
@commit_count
)
on
=
@calendar_date
.
strftime
(
"%b %d, %Y"
)
rescue
''
-
unless
@commit_count
==
0
%hr
-
@calendar_activities
.
each
do
|
project
,
commits
|
-
next
if
commits
.
empty?
%div
.js-toggle-container
%h4
.prepend-top-20
%span
.light
Contributions for
%strong
#{
@calendar_date
.
to_s
(
:short
)
}
%ul
.bordered-list
-
@events
.
sort_by
(
&
:created_at
).
each
do
|
event
|
%li
%span
.light
%i
.fa.fa-clock-o
=
event
.
created_at
.
to_s
(
:time
)
-
if
event
.
push?
#{
event
.
action_name
}
#{
event
.
ref_type
}
#{
event
.
ref_name
}
-
else
=
event_action_name
(
event
)
-
if
event
.
target
%strong
=
link_to
"#
#{
event
.
target_iid
}
"
,
[
event
.
project
.
namespace
.
becomes
(
Namespace
),
event
.
project
,
event
.
target
]
at
%strong
=
pluralize
(
commits
.
count
,
'commit'
)
in project
=
link_to
project
.
name_with_namespace
,
project_path
(
project
)
%a
.text-expander.js-toggle-button
…
%hr
%div
.js-toggle-content
-
commits
.
each
do
|
commit
|
%span
.monospace
=
commit
.
committed_date
.
strftime
(
"%H:%M"
)
=
link_to
commit
.
short_id
,
namespace_project_commit_path
(
project
.
namespace
,
project
,
commit
),
class:
"commit_short_id"
=
link_to
commit
.
message
,
namespace_project_commit_path
(
project
.
namespace
,
project
,
commit
),
class:
"commit-row-message str-truncated"
%br
%hr
-
if
event
.
project
=
link_to_project
event
.
project
-
else
=
event
.
project_name
app/views/users/show.html.haml
View file @
057c8c34
...
...
@@ -40,7 +40,8 @@
%strong
%i
.fa.fa-rss
=
render
@events
.content_list
=
spinner
%aside
.col-md-4
=
render
'profile'
,
user:
@user
=
render
'projects'
...
...
app/workers/emails_on_push_worker.rb
View file @
057c8c34
class
EmailsOnPushWorker
include
Sidekiq
::
Worker
def
perform
(
project_id
,
recipients
,
push_data
,
send_from_committer_email
=
false
,
disable_diffs
=
false
)
def
perform
(
project_id
,
recipients
,
push_data
,
send_from_committer_email
:
false
,
disable_diffs:
false
)
project
=
Project
.
find
(
project_id
)
before_sha
=
push_data
[
"before"
]
after_sha
=
push_data
[
"after"
]
branch
=
push_data
[
"ref"
]
ref
=
push_data
[
"ref"
]
author_id
=
push_data
[
"user_id"
]
if
Gitlab
::
Git
.
blank_ref?
(
before_sha
)
||
Gitlab
::
Git
.
blank_ref?
(
after_sha
)
# skip if new branch was pushed or branch was removed
return
true
end
action
=
if
Gitlab
::
Git
.
blank_ref?
(
before_sha
)
:create
elsif
Gitlab
::
Git
.
blank_ref?
(
after_sha
)
:delete
else
:push
end
compare
=
Gitlab
::
Git
::
Compare
.
new
(
project
.
repository
.
raw_repository
,
before_sha
,
after_sha
)
compare
=
nil
reverse_compare
=
false
if
action
==
:push
compare
=
Gitlab
::
Git
::
Compare
.
new
(
project
.
repository
.
raw_repository
,
before_sha
,
after_sha
)
return
false
if
compare
.
same
return
false
if
compare
.
same
if
compare
.
commits
.
empty?
compare
=
Gitlab
::
Git
::
Compare
.
new
(
project
.
repository
.
raw_repository
,
after_sha
,
before_sha
)
if
compare
.
commits
.
empty?
compare
=
Gitlab
::
Git
::
Compare
.
new
(
project
.
repository
.
raw_repository
,
after_sha
,
before_sha
)
reverse_compare
=
true
reverse_compare
=
true
return
false
if
compare
.
commits
.
empty?
return
false
if
compare
.
commits
.
empty?
end
end
recipients
.
split
(
" "
).
each
do
|
recipient
|
Notify
.
repository_push_email
(
project_id
,
recipient
,
author_id
,
branch
,
compare
,
reverse_compare
,
send_from_committer_email
,
disable_diffs
author_id:
author_id
,
ref:
ref
,
action:
action
,
compare:
compare
,
reverse_compare:
reverse_compare
,
send_from_committer_email:
send_from_committer_email
,
disable_diffs:
disable_diffs
).
deliver
end
ensure
...
...
config/gitlab.yml.example
View file @
057c8c34
...
...
@@ -285,6 +285,9 @@ production: &base
rack_attack:
git_basic_auth:
# Rack Attack IP banning enabled
# enabled: true
#
# Whitelist requests from 127.0.0.1 for web proxies (NGINX/Apache) with incorrect headers
# ip_whitelist: ["127.0.0.1"]
#
...
...
config/initializers/1_settings.rb
View file @
057c8c34
...
...
@@ -183,6 +183,7 @@ Settings['extra'] ||= Settingslogic.new({})
#
Settings
[
'rack_attack'
]
||=
Settingslogic
.
new
({})
Settings
.
rack_attack
[
'git_basic_auth'
]
||=
Settingslogic
.
new
({})
Settings
.
rack_attack
.
git_basic_auth
[
'enabled'
]
=
true
if
Settings
.
rack_attack
.
git_basic_auth
[
'enabled'
].
nil?
Settings
.
rack_attack
.
git_basic_auth
[
'ip_whitelist'
]
||=
%w{127.0.0.1}
Settings
.
rack_attack
.
git_basic_auth
[
'maxretry'
]
||=
10
Settings
.
rack_attack
.
git_basic_auth
[
'findtime'
]
||=
1
.
minute
...
...
db/migrate/20150324155957_set_incorrect_assignee_id_to_null.rb
0 → 100644
View file @
057c8c34
class
SetIncorrectAssigneeIdToNull
<
ActiveRecord
::
Migration
def
up
execute
"UPDATE issues SET assignee_id = NULL WHERE assignee_id = -1"
execute
"UPDATE merge_requests SET assignee_id = NULL WHERE assignee_id = -1"
end
end
db/schema.rb
View file @
057c8c34
...
...
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord
::
Schema
.
define
(
version:
2015032
023443
7
)
do
ActiveRecord
::
Schema
.
define
(
version:
2015032
415595
7
)
do
# These are extensions that must be enabled in order to support this database
enable_extension
"plpgsql"
...
...
docker/Dockerfile
View file @
057c8c34
...
...
@@ -11,7 +11,7 @@ RUN apt-get update -q \
# If the Omnibus package version below is outdated please contribute a merge request to update it.
# If you run GitLab Enterprise Edition point it to a location where you have downloaded it.
RUN
TMP_FILE
=
$(
mktemp
)
;
\
wget
-q
-O
$TMP_FILE
https://downloads-packages.s3.amazonaws.com/ubuntu-14.04/gitlab_7.
8.3-omnibus
-1_amd64.deb
\
wget
-q
-O
$TMP_FILE
https://downloads-packages.s3.amazonaws.com/ubuntu-14.04/gitlab_7.
9.0-omnibus.2
-1_amd64.deb
\
&&
dpkg
-i
$TMP_FILE
\
&&
rm
-f
$TMP_FILE
...
...
features/admin/settings.feature
View file @
057c8c34
...
...
@@ -7,3 +7,10 @@ Feature: Admin Settings
Scenario
:
Change application settings
When
I modify settings and save form
Then
I should see application settings saved
Scenario
:
Change Slack Service Template settings
When
I click on
"Service Templates"
And
I click on
"Slack"
service
Then
I check all events and submit form
And
I should see service template settings saved
And
I should see all checkboxes checked
features/steps/admin/settings.rb
View file @
057c8c34
...
...
@@ -15,4 +15,33 @@ class Spinach::Features::AdminSettings < Spinach::FeatureSteps
current_application_settings
.
home_page_url
.
should
==
'https://about.gitlab.com/'
page
.
should
have_content
'Application settings saved successfully'
end
step
'I click on "Service Templates"'
do
click_link
'Service Templates'
end
step
'I click on "Slack" service'
do
click_link
'Slack'
end
step
'I check all events and submit form'
do
page
.
check
(
'Active'
)
page
.
check
(
'Push events'
)
page
.
check
(
'Tag push events'
)
page
.
check
(
'Comments'
)
page
.
check
(
'Issues events'
)
page
.
check
(
'Merge Request events'
)
fill_in
'Webhook'
,
with:
"http://localhost"
click_on
'Save'
end
step
'I should see service template settings saved'
do
page
.
should
have_content
'Application settings saved successfully'
end
step
'I should see all checkboxes checked'
do
all
(
'input[type=checkbox]'
).
each
do
|
checkbox
|
checkbox
.
should
be_checked
end
end
end
features/steps/user.rb
View file @
057c8c34
...
...
@@ -7,4 +7,37 @@ class Spinach::Features::User < Spinach::FeatureSteps
step
'I should see user "John Doe" page'
do
expect
(
title
).
to
match
(
/^\s*John Doe/
)
end
step
'"John Doe" has contributions'
do
user
=
User
.
find_by
(
name:
'John Doe'
)
project
=
contributed_project
# Issue controbution
issue_params
=
{
title:
'Bug in old browser'
}
Issues
::
CreateService
.
new
(
project
,
user
,
issue_params
).
execute
# Push code contribution
push_params
=
{
project:
project
,
action:
Event
::
PUSHED
,
author_id:
user
.
id
,
data:
{
commit_count:
3
}
}
Event
.
create
(
push_params
)
end
step
'I should see contributed projects'
do
within
'.contributed-projects'
do
page
.
should
have_content
(
@contributed_project
.
name
)
end
end
step
'I should see contributions calendar'
do
page
.
should
have_css
(
'.cal-heatmap-container'
)
end
def
contributed_project
@contributed_project
||=
create
(
:project
,
:public
)
end
end
features/user.feature
View file @
057c8c34
...
...
@@ -67,3 +67,12 @@ Feature: User
And
I should see project
"Enterprise"
And
I should not see project
"Internal"
And
I should not see project
"Community"
@javascript
Scenario
:
"John Doe" contribution profile
Given
I sign in as a user
And
"John Doe"
has contributions
When
I visit user
"John Doe"
page
Then
I should see user
"John Doe"
page
And
I should see contributed projects
And
I should see contributions calendar
lib/api/branches.rb
View file @
057c8c34
require
'mime/types'
require
'uri'
module
API
# Projects API
...
...
@@ -103,7 +104,7 @@ module API
delete
":id/repository/branches/:branch"
do
authorize_push_project
result
=
DeleteBranchService
.
new
(
user_project
,
current_user
).
execute
(
params
[
:branch
]
)
execute
(
URI
.
unescape
(
params
[
:branch
])
)
if
result
[
:status
]
==
:success
{
...
...
lib/gitlab/backend/grack_auth.rb
View file @
057c8c34
require_relative
'rack_attack_helpers'
require_relative
'shell_env'
module
Grack
...
...
@@ -85,25 +86,41 @@ module Grack
user
=
oauth_access_token_check
(
login
,
password
)
end
return
user
if
user
.
present?
# At this point, we know the credentials were wrong. We let Rack::Attack
# know there was a failed authentication attempt from this IP. This
# information is stored in the Rails cache (Redis) and will be used by
# the Rack::Attack middleware to decide whether to block requests from
# this IP.
# If the user authenticated successfully, we reset the auth failure count
# from Rack::Attack for that IP. A client may attempt to authenticate
# with a username and blank password first, and only after it receives
# a 401 error does it present a password. Resetting the count prevents
# false positives from occurring.
#
# Otherwise, we let Rack::Attack know there was a failed authentication
# attempt from this IP. This information is stored in the Rails cache
# (Redis) and will be used by the Rack::Attack middleware to decide
# whether to block requests from this IP.
config
=
Gitlab
.
config
.
rack_attack
.
git_basic_auth
Rack
::
Attack
::
Allow2Ban
.
filter
(
@request
.
ip
,
config
)
do
# Unless the IP is whitelisted, return true so that Allow2Ban
# increments the counter (stored in Rails.cache) for the IP
if
config
.
ip_whitelist
.
include?
(
@request
.
ip
)
false
if
config
.
enabled
if
user
# A successful login will reset the auth failure count from this IP
Rack
::
Attack
::
Allow2Ban
.
reset
(
@request
.
ip
,
config
)
else
true
banned
=
Rack
::
Attack
::
Allow2Ban
.
filter
(
@request
.
ip
,
config
)
do
# Unless the IP is whitelisted, return true so that Allow2Ban
# increments the counter (stored in Rails.cache) for the IP
if
config
.
ip_whitelist
.
include?
(
@request
.
ip
)
false
else
true
end
end
if
banned
Rails
.
logger
.
info
"IP
#{
@request
.
ip
}
failed to login "
\
"as
#{
login
}
but has been temporarily banned from Git auth"
end
end
end
nil
# No user was found
user
end
def
authorized_request?
...
...
lib/gitlab/backend/rack_attack_helpers.rb
0 → 100644
View file @
057c8c34
# rack-attack v4.2.0 doesn't yet support clearing of keys.
# Taken from https://github.com/kickstarter/rack-attack/issues/113
class
Rack::Attack::Allow2Ban
def
self
.
reset
(
discriminator
,
options
)
findtime
=
options
[
:findtime
]
or
raise
ArgumentError
,
"Must pass findtime option"
cache
.
reset_count
(
"
#{
key_prefix
}
:count:
#{
discriminator
}
"
,
findtime
)
cache
.
delete
(
"
#{
key_prefix
}
:ban:
#{
discriminator
}
"
)
end
end
class
Rack::Attack::Cache
def
reset_count
(
unprefixed_key
,
period
)
epoch_time
=
Time
.
now
.
to_i
# Add 1 to expires_in to avoid timing error: http://git.io/i1PHXA
expires_in
=
period
-
(
epoch_time
%
period
)
+
1
key
=
"
#{
(
epoch_time
/
period
).
to_i
}
:
#{
unprefixed_key
}
"
delete
(
key
)
end
def
delete
(
unprefixed_key
)
store
.
delete
(
"
#{
prefix
}
:
#{
unprefixed_key
}
"
)
end
end
class
Rack::Attack::StoreProxy::RedisStoreProxy
def
delete
(
key
,
options
=
{})
self
.
del
(
key
)
rescue
Redis
::
BaseError
end
end
lib/gitlab/commits_calendar.rb
deleted
100644 → 0
View file @
637ca0b3
module
Gitlab
class
CommitsCalendar
attr_reader
:timestamps
def
initialize
(
projects
,
user
)
@timestamps
=
{}
date_timestamps
=
[]
projects
.
reject
(
&
:forked?
).
each
do
|
project
|
date_timestamps
<<
ProjectContributions
.
new
(
project
,
user
).
commits_log
end
# Sumarrize commits from all projects per days
date_timestamps
=
date_timestamps
.
inject
do
|
collection
,
date
|
collection
.
merge
(
date
)
{
|
k
,
old_v
,
new_v
|
old_v
+
new_v
}
end
date_timestamps
||=
[]
date_timestamps
.
each
do
|
date
,
commits
|
timestamp
=
Date
.
parse
(
date
).
to_time
.
to_i
.
to_s
rescue
nil
@timestamps
[
timestamp
]
=
commits
if
timestamp
end
end
def
self
.
get_commits_for_date
(
projects
,
user
,
date
)
user_commits
=
{}
projects
.
reject
(
&
:forked?
).
each
do
|
project
|
user_commits
[
project
]
=
ProjectContributions
.
new
(
project
,
user
).
user_commits_on_date
(
date
)
end
user_commits
end
def
starting_year
(
Time
.
now
-
1
.
year
).
strftime
(
"%Y"
)
end
def
starting_month
Date
.
today
.
strftime
(
"%m"
).
to_i
end
end
end
lib/gitlab/contributions_calendar.rb
0 → 100644
View file @
057c8c34
module
Gitlab
class
ContributionsCalendar
attr_reader
:timestamps
,
:projects
,
:user
def
initialize
(
projects
,
user
)
@projects
=
projects
@user
=
user
end
def
timestamps
return
@timestamps
if
@timestamps
.
present?
@timestamps
=
{}
date_from
=
1
.
year
.
ago
date_to
=
Date
.
today
events
=
Event
.
reorder
(
nil
).
contributions
.
where
(
author_id:
user
.
id
).
where
(
"created_at > ?"
,
date_from
).
where
(
project_id:
projects
).
group
(
'date(created_at)'
).
select
(
'date(created_at), count(id) as total_amount'
).
map
(
&
:attributes
)
dates
=
(
1
.
year
.
ago
.
to_date
..
(
Date
.
today
+
1
.
day
)).
to_a
dates
.
each
do
|
date
|
date_id
=
date
.
to_time
.
to_i
.
to_s
@timestamps
[
date_id
]
=
0
day_events
=
events
.
find
{
|
day_events
|
day_events
[
"date"
]
==
date
}
if
day_events
@timestamps
[
date_id
]
=
day_events
[
"total_amount"
]
end
end
@timestamps
end
def
events_by_date
(
date
)
events
=
Event
.
contributions
.
where
(
author_id:
user
.
id
).
where
(
"created_at > ? AND created_at < ?"
,
date
.
beginning_of_day
,
date
.
end_of_day
).
where
(
project_id:
projects
)
events
.
select
do
|
event
|
event
.
push?
||
event
.
issue?
||
event
.
merge_request?
end
end
def
starting_year
(
Time
.
now
-
1
.
year
).
strftime
(
"%Y"
)
end
def
starting_month
Date
.
today
.
strftime
(
"%m"
).
to_i
end
end
end
lib/gitlab/ldap/person.rb
View file @
057c8c34
...
...
@@ -14,7 +14,6 @@ module Gitlab
end
def
self
.
find_by_dn
(
dn
,
adapter
)
dn
=
Net
::
LDAP
::
Filter
.
escape
(
dn
)
adapter
.
user
(
'dn'
,
dn
)
end
...
...
lib/gitlab/markdown.rb
View file @
057c8c34
...
...
@@ -368,11 +368,12 @@ module Gitlab
# ActiveSupport::SafeBuffer, hence the `String.new`
String
.
new
(
text
).
gsub
(
Taskable
::
TASK_PATTERN_HTML
)
do
checked
=
$LAST_MATCH_INFO
[
:checked
].
downcase
==
'x'
p_tag
=
$LAST_MATCH_INFO
[
:p_tag
]
if
checked
"
#{
li_tag
}#{
checked_box
}
"
"
#{
li_tag
}#{
p_tag
}#{
checked_box
}
"
else
"
#{
li_tag
}#{
unchecked_box
}
"
"
#{
li_tag
}#{
p_tag
}#{
unchecked_box
}
"
end
end
end
...
...
lib/gitlab/project_search_results.rb
View file @
057c8c34
...
...
@@ -67,7 +67,7 @@ module Gitlab
end
def
notes
Note
.
where
(
project_id:
limit_project_ids
).
search
(
query
).
order
(
'updated_at DESC'
)
Note
.
where
(
project_id:
limit_project_ids
).
user
.
search
(
query
).
order
(
'updated_at DESC'
)
end
def
limit_project_ids
...
...
spec/controllers/users_controller_spec.rb
View file @
057c8c34
...
...
@@ -25,34 +25,21 @@ describe UsersController do
end
describe
'GET #calendar_activities'
do
include
RepoHelpers
let
(
:project
)
{
create
(
:project
)
}
let
(
:calendar_user
)
{
create
(
:user
,
email:
sample_commit
.
author_email
)
}
let
(
:commit1
)
{
'0ed8c6c6752e8c6ea63e7b92a517bf5ac1209c80'
}
let
(
:commit2
)
{
'7d3b0f7cff5f37573aea97cebfd5692ea1689924'
}
let!
(
:project
)
{
create
(
:project
)
}
let!
(
:user
)
{
create
(
:user
)
}
before
do
allow_any_instance_of
(
User
).
to
receive
(
:contributed_projects_ids
).
and_return
([
project
.
id
])
project
.
team
<<
[
user
,
:developer
]
end
it
'assigns @commit_count'
do
get
:calendar_activities
,
username:
calendar_user
.
username
,
date:
'2014-07-31'
expect
(
assigns
(
:commit_count
)).
to
eq
(
2
)
end
it
'assigns @calendar_date'
do
get
:calendar_activities
,
username:
calendar_
user
.
username
,
date:
'2014-07-31'
get
:calendar_activities
,
username:
user
.
username
,
date:
'2014-07-31'
expect
(
assigns
(
:calendar_date
)).
to
eq
(
Date
.
parse
(
'2014-07-31'
))
end
it
'assigns @calendar_activities'
do
get
:calendar_activities
,
username:
calendar_user
.
username
,
date:
'2014-07-31'
expect
(
assigns
(
:calendar_activities
).
values
.
flatten
.
map
(
&
:id
)).
to
eq
([
commit1
,
commit2
])
end
it
'renders calendar_activities'
do
get
:calendar_activities
,
username:
calendar_
user
.
username
get
:calendar_activities
,
username:
user
.
username
expect
(
response
).
to
render_template
(
'calendar_activities'
)
end
end
...
...
spec/helpers/gitlab_markdown_helper_spec.rb
View file @
057c8c34
...
...
@@ -847,6 +847,17 @@ EOT
)
end
it
'should render checkboxes for nested tasks'
do
rendered_text
=
markdown
(
@source_text_asterisk
,
parse_tasks:
true
)
expect
(
rendered_text
).
to
match
(
/<input.*checkbox.*valid unchecked nested task/
)
expect
(
rendered_text
).
to
match
(
/<input.*checkbox.*valid checked nested task/
)
end
it
'should not be confused by whitespace before bullets'
do
rendered_text_asterisk
=
markdown
(
@source_text_asterisk
,
parse_tasks:
true
)
...
...
spec/lib/gitlab/backend/grack_auth_spec.rb
View file @
057c8c34
...
...
@@ -6,7 +6,7 @@ describe Grack::Auth do
let
(
:app
)
{
lambda
{
|
env
|
[
200
,
{},
"Success!"
]
}
}
let!
(
:auth
)
{
Grack
::
Auth
.
new
(
app
)
}
let
(
:env
)
{
let
(
:env
)
{
{
"rack.input"
=>
""
,
"REQUEST_METHOD"
=>
"GET"
,
...
...
@@ -85,6 +85,17 @@ describe Grack::Auth do
it
"responds with status 401"
do
expect
(
status
).
to
eq
(
401
)
end
context
"when the user is IP banned"
do
before
do
expect
(
Rack
::
Attack
::
Allow2Ban
).
to
receive
(
:filter
).
and_return
(
true
)
allow_any_instance_of
(
Rack
::
Request
).
to
receive
(
:ip
).
and_return
(
'1.2.3.4'
)
end
it
"responds with status 401"
do
expect
(
status
).
to
eq
(
401
)
end
end
end
context
"when authentication succeeds"
do
...
...
@@ -109,10 +120,49 @@ describe Grack::Auth do
end
context
"when the user isn't blocked"
do
before
do
expect
(
Rack
::
Attack
::
Allow2Ban
).
to
receive
(
:reset
)
end
it
"responds with status 200"
do
expect
(
status
).
to
eq
(
200
)
end
end
context
"when blank password attempts follow a valid login"
do
let
(
:options
)
{
Gitlab
.
config
.
rack_attack
.
git_basic_auth
}
let
(
:maxretry
)
{
options
[
:maxretry
]
-
1
}
let
(
:ip
)
{
'1.2.3.4'
}
before
do
allow_any_instance_of
(
Rack
::
Request
).
to
receive
(
:ip
).
and_return
(
ip
)
Rack
::
Attack
::
Allow2Ban
.
reset
(
ip
,
options
)
end
after
do
Rack
::
Attack
::
Allow2Ban
.
reset
(
ip
,
options
)
end
def
attempt_login
(
include_password
)
password
=
include_password
?
user
.
password
:
""
env
[
"HTTP_AUTHORIZATION"
]
=
ActionController
::
HttpAuthentication
::
Basic
.
encode_credentials
(
user
.
username
,
password
)
Grack
::
Auth
.
new
(
app
)
auth
.
call
(
env
).
first
end
it
"repeated attempts followed by successful attempt"
do
for
n
in
0
..
maxretry
do
expect
(
attempt_login
(
false
)).
to
eq
(
401
)
end
expect
(
attempt_login
(
true
)).
to
eq
(
200
)
expect
(
Rack
::
Attack
::
Allow2Ban
.
send
(
:banned?
,
ip
)).
to
eq
(
nil
)
for
n
in
0
..
maxretry
do
expect
(
attempt_login
(
false
)).
to
eq
(
401
)
end
end
end
end
context
"when the user doesn't have access to the project"
do
...
...
spec/lib/gitlab/backend/rack_attack_helpers_spec.rb
0 → 100644
View file @
057c8c34
require
"spec_helper"
describe
'RackAttackHelpers'
do
describe
'reset'
do
let
(
:discriminator
)
{
'test-key'
}
let
(
:maxretry
)
{
5
}
let
(
:period
)
{
1
.
minute
}
let
(
:options
)
{
{
findtime:
period
,
bantime:
60
,
maxretry:
maxretry
}
}
def
do_filter
for
i
in
1
..
maxretry
-
1
do
status
=
Rack
::
Attack
::
Allow2Ban
.
filter
(
discriminator
,
options
)
{
true
}
expect
(
status
).
to
eq
(
false
)
end
end
def
do_reset
Rack
::
Attack
::
Allow2Ban
.
reset
(
discriminator
,
options
)
end
before
do
do_reset
end
after
do
do_reset
end
it
'user is not banned after n - 1 retries'
do
do_filter
do_reset
do_filter
end
end
end
spec/mailers/notify_spec.rb
View file @
057c8c34
...
...
@@ -640,6 +640,100 @@ describe Notify do
end
end
describe
'email on push for a created branch'
do
let
(
:example_site_path
)
{
root_path
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:tree_path
)
{
namespace_project_tree_path
(
project
.
namespace
,
project
,
"master"
)
}
subject
{
Notify
.
repository_push_email
(
project
.
id
,
'devs@company.name'
,
author_id:
user
.
id
,
ref:
'refs/heads/master'
,
action: :create
)
}
it
'is sent as the author'
do
sender
=
subject
.
header
[
:from
].
addrs
[
0
]
expect
(
sender
.
display_name
).
to
eq
(
user
.
name
)
expect
(
sender
.
address
).
to
eq
(
gitlab_sender
)
end
it
'is sent to recipient'
do
is_expected
.
to
deliver_to
'devs@company.name'
end
it
'has the correct subject'
do
is_expected
.
to
have_subject
/Pushed new branch master/
end
it
'contains a link to the branch'
do
is_expected
.
to
have_body_text
/
#{
tree_path
}
/
end
end
describe
'email on push for a created tag'
do
let
(
:example_site_path
)
{
root_path
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:tree_path
)
{
namespace_project_tree_path
(
project
.
namespace
,
project
,
"v1.0"
)
}
subject
{
Notify
.
repository_push_email
(
project
.
id
,
'devs@company.name'
,
author_id:
user
.
id
,
ref:
'refs/tags/v1.0'
,
action: :create
)
}
it
'is sent as the author'
do
sender
=
subject
.
header
[
:from
].
addrs
[
0
]
expect
(
sender
.
display_name
).
to
eq
(
user
.
name
)
expect
(
sender
.
address
).
to
eq
(
gitlab_sender
)
end
it
'is sent to recipient'
do
is_expected
.
to
deliver_to
'devs@company.name'
end
it
'has the correct subject'
do
is_expected
.
to
have_subject
/Pushed new tag v1\.0/
end
it
'contains a link to the tag'
do
is_expected
.
to
have_body_text
/
#{
tree_path
}
/
end
end
describe
'email on push for a deleted branch'
do
let
(
:example_site_path
)
{
root_path
}
let
(
:user
)
{
create
(
:user
)
}
subject
{
Notify
.
repository_push_email
(
project
.
id
,
'devs@company.name'
,
author_id:
user
.
id
,
ref:
'refs/heads/master'
,
action: :delete
)
}
it
'is sent as the author'
do
sender
=
subject
.
header
[
:from
].
addrs
[
0
]
expect
(
sender
.
display_name
).
to
eq
(
user
.
name
)
expect
(
sender
.
address
).
to
eq
(
gitlab_sender
)
end
it
'is sent to recipient'
do
is_expected
.
to
deliver_to
'devs@company.name'
end
it
'has the correct subject'
do
is_expected
.
to
have_subject
/Deleted branch master/
end
end
describe
'email on push for a deleted tag'
do
let
(
:example_site_path
)
{
root_path
}
let
(
:user
)
{
create
(
:user
)
}
subject
{
Notify
.
repository_push_email
(
project
.
id
,
'devs@company.name'
,
author_id:
user
.
id
,
ref:
'refs/tags/v1.0'
,
action: :delete
)
}
it
'is sent as the author'
do
sender
=
subject
.
header
[
:from
].
addrs
[
0
]
expect
(
sender
.
display_name
).
to
eq
(
user
.
name
)
expect
(
sender
.
address
).
to
eq
(
gitlab_sender
)
end
it
'is sent to recipient'
do
is_expected
.
to
deliver_to
'devs@company.name'
end
it
'has the correct subject'
do
is_expected
.
to
have_subject
/Deleted tag v1\.0/
end
end
describe
'email on push with multiple commits'
do
let
(
:example_site_path
)
{
root_path
}
let
(
:user
)
{
create
(
:user
)
}
...
...
@@ -648,7 +742,7 @@ describe Notify do
let
(
:diff_path
)
{
namespace_project_compare_path
(
project
.
namespace
,
project
,
from:
Commit
.
new
(
compare
.
base
),
to:
Commit
.
new
(
compare
.
head
))
}
let
(
:send_from_committer_email
)
{
false
}
subject
{
Notify
.
repository_push_email
(
project
.
id
,
'devs@company.name'
,
user
.
id
,
'master'
,
compare
,
false
,
send_from_committer_email
)
}
subject
{
Notify
.
repository_push_email
(
project
.
id
,
'devs@company.name'
,
author_id:
user
.
id
,
ref:
'refs/heads/master'
,
action: :push
,
compare:
compare
,
reverse_compare:
false
,
send_from_committer_email:
send_from_committer_email
)
}
it
'is sent as the author'
do
sender
=
subject
.
header
[
:from
].
addrs
[
0
]
...
...
@@ -736,7 +830,7 @@ describe Notify do
let
(
:commits
)
{
Commit
.
decorate
(
compare
.
commits
)
}
let
(
:diff_path
)
{
namespace_project_commit_path
(
project
.
namespace
,
project
,
commits
.
first
)
}
subject
{
Notify
.
repository_push_email
(
project
.
id
,
'devs@company.name'
,
user
.
id
,
'master'
,
compare
)
}
subject
{
Notify
.
repository_push_email
(
project
.
id
,
'devs@company.name'
,
author_id:
user
.
id
,
ref:
'refs/heads/master'
,
action: :push
,
compare:
compare
)
}
it
'is sent as the author'
do
sender
=
subject
.
header
[
:from
].
addrs
[
0
]
...
...
spec/models/repository_spec.rb
View file @
057c8c34
...
...
@@ -13,47 +13,16 @@ describe Repository do
it
{
is_expected
.
not_to
include
(
'fix'
)
}
end
describe
:last_commit_for_path
do
subject
{
repository
.
last_commit_for_path
(
sample_commit
.
id
,
'.gitignore'
).
id
}
it
{
is_expected
.
to
eq
(
'c1acaa58bbcbc3eafe538cb8274ba387047b69f8'
)
}
end
context
:timestamps_by_user_log
do
before
do
Date
.
stub
(
:today
).
and_return
(
Date
.
new
(
2015
,
03
,
01
))
end
describe
'single e-mail for user'
do
let
(
:user
)
{
create
(
:user
,
email:
sample_commit
.
author_email
)
}
subject
{
repository
.
timestamps_by_user_log
(
user
)
}
describe
:tag_names_contains
do
subject
{
repository
.
tag_names_contains
(
sample_commit
.
id
)
}
it
{
is_expected
.
to
eq
([
'2014-08-06'
,
'2014-07-31'
,
'2014-07-31'
])
}
end
describe
'multiple emails for user'
do
let
(
:email_alias
)
{
create
(
:email
,
email:
another_sample_commit
.
author_email
)
}
let
(
:user
)
{
create
(
:user
,
email:
sample_commit
.
author_email
,
emails:
[
email_alias
])
}
subject
{
repository
.
timestamps_by_user_log
(
user
)
}
it
{
is_expected
.
to
eq
([
'2015-01-10'
,
'2014-08-06'
,
'2014-07-31'
,
'2014-07-31'
])
}
end
it
{
is_expected
.
to
include
(
'v1.1.0'
)
}
it
{
is_expected
.
not_to
include
(
'v1.0.0'
)
}
end
context
:commits_by_user_on_date_log
do
describe
'single e-mail for user'
do
let
(
:user
)
{
create
(
:user
,
email:
sample_commit
.
author_email
)
}
let
(
:commit1
)
{
'0ed8c6c6752e8c6ea63e7b92a517bf5ac1209c80'
}
let
(
:commit2
)
{
'7d3b0f7cff5f37573aea97cebfd5692ea1689924'
}
subject
{
repository
.
commits_by_user_on_date_log
(
user
,
Date
.
new
(
2014
,
07
,
31
))
}
describe
:last_commit_for_path
do
subject
{
repository
.
last_commit_for_path
(
sample_commit
.
id
,
'.gitignore'
).
id
}
it
'contains the exepected commits'
do
expect
(
subject
.
flatten
.
map
(
&
:id
)).
to
eq
([
commit1
,
commit2
])
end
end
it
{
is_expected
.
to
eq
(
'c1acaa58bbcbc3eafe538cb8274ba387047b69f8'
)
}
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment