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
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
d37cf642
Commit
d37cf642
authored
Oct 21, 2015
by
Douwe Maan
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into hanloong/gitlab-ce-add-dates-snippets-show
parents
d9944fdb
35618a3d
Changes
162
Hide whitespace changes
Inline
Side-by-side
Showing
162 changed files
with
1994 additions
and
904 deletions
+1994
-904
CHANGELOG
CHANGELOG
+19
-0
app/assets/stylesheets/framework/blocks.scss
app/assets/stylesheets/framework/blocks.scss
+45
-0
app/assets/stylesheets/framework/files.scss
app/assets/stylesheets/framework/files.scss
+4
-0
app/assets/stylesheets/framework/typography.scss
app/assets/stylesheets/framework/typography.scss
+0
-1
app/assets/stylesheets/pages/issues.scss
app/assets/stylesheets/pages/issues.scss
+5
-0
app/assets/stylesheets/pages/notes.scss
app/assets/stylesheets/pages/notes.scss
+4
-1
app/assets/stylesheets/pages/profile.scss
app/assets/stylesheets/pages/profile.scss
+6
-0
app/assets/stylesheets/pages/projects.scss
app/assets/stylesheets/pages/projects.scss
+1
-1
app/assets/stylesheets/pages/tree.scss
app/assets/stylesheets/pages/tree.scss
+0
-8
app/controllers/abuse_reports_controller.rb
app/controllers/abuse_reports_controller.rb
+4
-0
app/controllers/admin/application_settings_controller.rb
app/controllers/admin/application_settings_controller.rb
+1
-0
app/controllers/admin/broadcast_messages_controller.rb
app/controllers/admin/broadcast_messages_controller.rb
+1
-1
app/controllers/admin/hooks_controller.rb
app/controllers/admin/hooks_controller.rb
+1
-1
app/controllers/admin/users_controller.rb
app/controllers/admin/users_controller.rb
+17
-9
app/controllers/application_controller.rb
app/controllers/application_controller.rb
+4
-0
app/controllers/ci/projects_controller.rb
app/controllers/ci/projects_controller.rb
+8
-3
app/controllers/import/github_controller.rb
app/controllers/import/github_controller.rb
+0
-4
app/controllers/import/google_code_controller.rb
app/controllers/import/google_code_controller.rb
+3
-3
app/controllers/invites_controller.rb
app/controllers/invites_controller.rb
+2
-2
app/controllers/profiles/notifications_controller.rb
app/controllers/profiles/notifications_controller.rb
+1
-1
app/controllers/profiles_controller.rb
app/controllers/profiles_controller.rb
+1
-1
app/controllers/projects/ci_services_controller.rb
app/controllers/projects/ci_services_controller.rb
+1
-1
app/controllers/projects/ci_web_hooks_controller.rb
app/controllers/projects/ci_web_hooks_controller.rb
+1
-1
app/controllers/projects/compare_controller.rb
app/controllers/projects/compare_controller.rb
+2
-1
app/controllers/projects/deploy_keys_controller.rb
app/controllers/projects/deploy_keys_controller.rb
+1
-1
app/controllers/projects/hooks_controller.rb
app/controllers/projects/hooks_controller.rb
+1
-1
app/controllers/projects/issues_controller.rb
app/controllers/projects/issues_controller.rb
+8
-1
app/controllers/projects/merge_requests_controller.rb
app/controllers/projects/merge_requests_controller.rb
+5
-2
app/controllers/projects/milestones_controller.rb
app/controllers/projects/milestones_controller.rb
+1
-5
app/controllers/projects/notes_controller.rb
app/controllers/projects/notes_controller.rb
+2
-2
app/controllers/projects/project_members_controller.rb
app/controllers/projects/project_members_controller.rb
+2
-1
app/controllers/projects/services_controller.rb
app/controllers/projects/services_controller.rb
+2
-2
app/controllers/projects_controller.rb
app/controllers/projects_controller.rb
+28
-2
app/finders/issuable_finder.rb
app/finders/issuable_finder.rb
+71
-43
app/helpers/diff_helper.rb
app/helpers/diff_helper.rb
+2
-1
app/helpers/gitlab_markdown_helper.rb
app/helpers/gitlab_markdown_helper.rb
+16
-5
app/helpers/issues_helper.rb
app/helpers/issues_helper.rb
+4
-0
app/helpers/preferences_helper.rb
app/helpers/preferences_helper.rb
+4
-4
app/helpers/projects_helper.rb
app/helpers/projects_helper.rb
+5
-1
app/mailers/abuse_report_mailer.rb
app/mailers/abuse_report_mailer.rb
+12
-0
app/models/ability.rb
app/models/ability.rb
+2
-1
app/models/application_setting.rb
app/models/application_setting.rb
+4
-0
app/models/commit.rb
app/models/commit.rb
+10
-6
app/models/concerns/issuable.rb
app/models/concerns/issuable.rb
+6
-3
app/models/concerns/mentionable.rb
app/models/concerns/mentionable.rb
+13
-7
app/models/concerns/participable.rb
app/models/concerns/participable.rb
+19
-13
app/models/issue.rb
app/models/issue.rb
+10
-0
app/models/merge_request.rb
app/models/merge_request.rb
+17
-5
app/models/merge_request_diff.rb
app/models/merge_request_diff.rb
+4
-0
app/models/milestone.rb
app/models/milestone.rb
+32
-0
app/models/note.rb
app/models/note.rb
+2
-2
app/models/repository.rb
app/models/repository.rb
+9
-15
app/models/user.rb
app/models/user.rb
+10
-7
app/services/archive_repository_service.rb
app/services/archive_repository_service.rb
+1
-1
app/services/git_push_service.rb
app/services/git_push_service.rb
+1
-1
app/services/merge_requests/post_merge_service.rb
app/services/merge_requests/post_merge_service.rb
+10
-0
app/views/abuse_report_mailer/notify.html.haml
app/views/abuse_report_mailer/notify.html.haml
+11
-0
app/views/abuse_report_mailer/notify.text.haml
app/views/abuse_report_mailer/notify.text.haml
+5
-0
app/views/admin/application_settings/_form.html.haml
app/views/admin/application_settings/_form.html.haml
+6
-0
app/views/admin/users/_profile.html.haml
app/views/admin/users/_profile.html.haml
+0
-0
app/views/admin/users/show.html.haml
app/views/admin/users/show.html.haml
+1
-1
app/views/ci/projects/index.html.haml
app/views/ci/projects/index.html.haml
+20
-0
app/views/events/_event_issue.atom.haml
app/views/events/_event_issue.atom.haml
+1
-2
app/views/events/_event_merge_request.atom.haml
app/views/events/_event_merge_request.atom.haml
+1
-2
app/views/events/_event_note.atom.haml
app/views/events/_event_note.atom.haml
+1
-1
app/views/events/_event_push.atom.haml
app/views/events/_event_push.atom.haml
+1
-1
app/views/layouts/notify.html.haml
app/views/layouts/notify.html.haml
+4
-0
app/views/notify/_note_message.html.haml
app/views/notify/_note_message.html.haml
+1
-1
app/views/notify/new_issue_email.html.haml
app/views/notify/new_issue_email.html.haml
+1
-1
app/views/notify/new_merge_request_email.html.haml
app/views/notify/new_merge_request_email.html.haml
+1
-1
app/views/profiles/preferences/show.html.haml
app/views/profiles/preferences/show.html.haml
+2
-2
app/views/projects/_activity.html.haml
app/views/projects/_activity.html.haml
+0
-1
app/views/projects/_files.html.haml
app/views/projects/_files.html.haml
+6
-0
app/views/projects/_readme.html.haml
app/views/projects/_readme.html.haml
+7
-8
app/views/projects/activity.html.haml
app/views/projects/activity.html.haml
+2
-0
app/views/projects/blob/_blob.html.haml
app/views/projects/blob/_blob.html.haml
+17
-14
app/views/projects/blob/show.html.haml
app/views/projects/blob/show.html.haml
+0
-3
app/views/projects/buttons/_notifications.html.haml
app/views/projects/buttons/_notifications.html.haml
+19
-13
app/views/projects/ci_services/index.html.haml
app/views/projects/ci_services/index.html.haml
+1
-1
app/views/projects/diffs/_diffs.html.haml
app/views/projects/diffs/_diffs.html.haml
+2
-2
app/views/projects/diffs/_file.html.haml
app/views/projects/diffs/_file.html.haml
+2
-2
app/views/projects/edit.html.haml
app/views/projects/edit.html.haml
+17
-1
app/views/projects/issues/_closed_by_box.html.haml
app/views/projects/issues/_closed_by_box.html.haml
+3
-0
app/views/projects/issues/show.html.haml
app/views/projects/issues/show.html.haml
+2
-1
app/views/projects/merge_requests/widget/_heading.html.haml
app/views/projects/merge_requests/widget/_heading.html.haml
+36
-37
app/views/projects/remove_fork.js.haml
app/views/projects/remove_fork.js.haml
+2
-0
app/views/projects/show.html.haml
app/views/projects/show.html.haml
+4
-11
app/views/projects/tree/_blob_item.html.haml
app/views/projects/tree/_blob_item.html.haml
+1
-1
app/views/projects/tree/_readme.html.haml
app/views/projects/tree/_readme.html.haml
+3
-3
app/views/projects/tree/_tree_content.html.haml
app/views/projects/tree/_tree_content.html.haml
+1
-34
app/views/projects/tree/_tree_header.html.haml
app/views/projects/tree/_tree_header.html.haml
+32
-0
app/views/projects/tree/_tree_item.html.haml
app/views/projects/tree/_tree_item.html.haml
+1
-1
app/views/projects/tree/show.html.haml
app/views/projects/tree/show.html.haml
+4
-4
app/views/shared/_clone_panel.html.haml
app/views/shared/_clone_panel.html.haml
+2
-2
app/views/users/calendar.html.haml
app/views/users/calendar.html.haml
+2
-4
app/views/users/show.html.haml
app/views/users/show.html.haml
+57
-33
app/workers/repository_archive_cache_worker.rb
app/workers/repository_archive_cache_worker.rb
+9
-0
app/workers/repository_archive_worker.rb
app/workers/repository_archive_worker.rb
+0
-43
config/routes.rb
config/routes.rb
+1
-0
db/fixtures/development/05_users.rb
db/fixtures/development/05_users.rb
+2
-2
db/fixtures/development/07_milestones.rb
db/fixtures/development/07_milestones.rb
+1
-1
db/fixtures/development/09_issues.rb
db/fixtures/development/09_issues.rb
+1
-1
db/fixtures/development/12_snippets.rb
db/fixtures/development/12_snippets.rb
+1
-1
db/migrate/20151008143519_add_admin_notification_email_setting.rb
...te/20151008143519_add_admin_notification_email_setting.rb
+5
-0
db/migrate/20151019111551_fix_build_tags.rb
db/migrate/20151019111551_fix_build_tags.rb
+5
-0
db/migrate/20151019111703_fail_build_without_names.rb
db/migrate/20151019111703_fail_build_without_names.rb
+5
-0
db/migrate/20151020173516_ci_limits_to_mysql.rb
db/migrate/20151020173516_ci_limits_to_mysql.rb
+9
-0
db/migrate/20151020173906_add_ci_builds_index_for_status.rb
db/migrate/20151020173906_add_ci_builds_index_for_status.rb
+5
-0
db/migrate/limits_to_mysql.rb
db/migrate/limits_to_mysql.rb
+0
-4
db/schema.rb
db/schema.rb
+3
-1
doc/update/8.0-to-8.1.md
doc/update/8.0-to-8.1.md
+34
-4
doc/update/patch_versions.md
doc/update/patch_versions.md
+1
-3
features/steps/abuse_reports.rb
features/steps/abuse_reports.rb
+1
-1
features/steps/project/project.rb
features/steps/project/project.rb
+2
-2
lib/api/projects.rb
lib/api/projects.rb
+2
-2
lib/gitlab/markdown.rb
lib/gitlab/markdown.rb
+77
-41
lib/gitlab/markdown/commit_range_reference_filter.rb
lib/gitlab/markdown/commit_range_reference_filter.rb
+13
-3
lib/gitlab/markdown/commit_reference_filter.rb
lib/gitlab/markdown/commit_reference_filter.rb
+17
-7
lib/gitlab/markdown/cross_project_reference.rb
lib/gitlab/markdown/cross_project_reference.rb
+2
-9
lib/gitlab/markdown/external_issue_reference_filter.rb
lib/gitlab/markdown/external_issue_reference_filter.rb
+2
-1
lib/gitlab/markdown/issue_reference_filter.rb
lib/gitlab/markdown/issue_reference_filter.rb
+5
-3
lib/gitlab/markdown/label_reference_filter.rb
lib/gitlab/markdown/label_reference_filter.rb
+5
-3
lib/gitlab/markdown/merge_request_reference_filter.rb
lib/gitlab/markdown/merge_request_reference_filter.rb
+5
-3
lib/gitlab/markdown/redactor_filter.rb
lib/gitlab/markdown/redactor_filter.rb
+40
-0
lib/gitlab/markdown/reference_filter.rb
lib/gitlab/markdown/reference_filter.rb
+44
-27
lib/gitlab/markdown/reference_gatherer_filter.rb
lib/gitlab/markdown/reference_gatherer_filter.rb
+63
-0
lib/gitlab/markdown/snippet_reference_filter.rb
lib/gitlab/markdown/snippet_reference_filter.rb
+5
-3
lib/gitlab/markdown/user_reference_filter.rb
lib/gitlab/markdown/user_reference_filter.rb
+29
-16
lib/gitlab/reference_extractor.rb
lib/gitlab/reference_extractor.rb
+20
-8
lib/tasks/gitlab/check.rake
lib/tasks/gitlab/check.rake
+1
-1
spec/benchmarks/lib/gitlab/markdown/reference_filter_spec.rb
spec/benchmarks/lib/gitlab/markdown/reference_filter_spec.rb
+41
-0
spec/benchmarks/models/milestone_spec.rb
spec/benchmarks/models/milestone_spec.rb
+17
-0
spec/controllers/abuse_reports_controller_spec.rb
spec/controllers/abuse_reports_controller_spec.rb
+72
-0
spec/controllers/admin/users_controller_spec.rb
spec/controllers/admin/users_controller_spec.rb
+26
-0
spec/controllers/import/github_controller_spec.rb
spec/controllers/import/github_controller_spec.rb
+1
-1
spec/controllers/invites_controller_spec.rb
spec/controllers/invites_controller_spec.rb
+33
-0
spec/controllers/projects/services_controller_spec.rb
spec/controllers/projects/services_controller_spec.rb
+32
-15
spec/controllers/projects_controller_spec.rb
spec/controllers/projects_controller_spec.rb
+74
-0
spec/features/markdown_spec.rb
spec/features/markdown_spec.rb
+1
-1
spec/features/projects_spec.rb
spec/features/projects_spec.rb
+25
-4
spec/helpers/gitlab_markdown_helper_spec.rb
spec/helpers/gitlab_markdown_helper_spec.rb
+15
-12
spec/helpers/issues_helper_spec.rb
spec/helpers/issues_helper_spec.rb
+10
-0
spec/lib/gitlab/closing_issue_extractor_spec.rb
spec/lib/gitlab/closing_issue_extractor_spec.rb
+5
-5
spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb
...lib/gitlab/markdown/commit_range_reference_filter_spec.rb
+32
-38
spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
+30
-36
spec/lib/gitlab/markdown/cross_project_reference_spec.rb
spec/lib/gitlab/markdown/cross_project_reference_spec.rb
+8
-28
spec/lib/gitlab/markdown/issue_reference_filter_spec.rb
spec/lib/gitlab/markdown/issue_reference_filter_spec.rb
+35
-41
spec/lib/gitlab/markdown/label_reference_filter_spec.rb
spec/lib/gitlab/markdown/label_reference_filter_spec.rb
+13
-5
spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb
...ib/gitlab/markdown/merge_request_reference_filter_spec.rb
+30
-36
spec/lib/gitlab/markdown/redactor_filter_spec.rb
spec/lib/gitlab/markdown/redactor_filter_spec.rb
+91
-0
spec/lib/gitlab/markdown/reference_gatherer_filter_spec.rb
spec/lib/gitlab/markdown/reference_gatherer_filter_spec.rb
+89
-0
spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
+29
-35
spec/lib/gitlab/markdown/user_reference_filter_spec.rb
spec/lib/gitlab/markdown/user_reference_filter_spec.rb
+18
-37
spec/lib/gitlab/reference_extractor_spec.rb
spec/lib/gitlab/reference_extractor_spec.rb
+7
-7
spec/models/concerns/issuable_spec.rb
spec/models/concerns/issuable_spec.rb
+0
-1
spec/models/issue_spec.rb
spec/models/issue_spec.rb
+37
-0
spec/models/milestone_spec.rb
spec/models/milestone_spec.rb
+28
-0
spec/requests/api/projects_spec.rb
spec/requests/api/projects_spec.rb
+32
-18
spec/services/archive_repository_service_spec.rb
spec/services/archive_repository_service_spec.rb
+1
-1
spec/support/filter_spec_helper.rb
spec/support/filter_spec_helper.rb
+8
-15
spec/support/markdown_feature.rb
spec/support/markdown_feature.rb
+13
-19
spec/support/mentionable_shared_examples.rb
spec/support/mentionable_shared_examples.rb
+2
-0
No files found.
CHANGELOG
View file @
d37cf642
Please view this file on the master branch, on stable branches it's out of date.
Please view this file on the master branch, on stable branches it's out of date.
v 8.2.0 (unreleased)
v 8.2.0 (unreleased)
- Ensure MySQL CI limits DB migrations occur after the fields have been created (Stan Hu)
- Improved performance of replacing references in comments
- Fix duplicate repositories in GitHub import page (Stan Hu)
- Redirect to a default path if HTTP_REFERER is not set (Stan Hu)
- Show last project commit to default branch on project home page
- Show last project commit to default branch on project home page
- Highlight comment based on anchor in URL
- Highlight comment based on anchor in URL
- Adds ability to remove the forked relationship from project settings screen. (Han Loong Liauw)
- Improved performance of sorting milestone issues
- Allow users to select the Files view as default project view (Cristian Bica)
v 8.1.0 (unreleased)
v 8.1.0 (unreleased)
- Send an email to admin email when a user is reported for spam (Jonathan Rochkind)
- Show notifications button when user is member of group rather than project (Grzegorz Bizon)
- Fix bug preventing mentioned issued from being closed when MR is merged using fast-forward merge.
- Fix nonatomic database update potentially causing project star counts to go negative (Stan Hu)
- Fix error preventing displaying of commit data for a directory with a leading dot (Stan Hu)
- Fix error preventing displaying of commit data for a directory with a leading dot (Stan Hu)
- Speed up load times of issue detail pages by roughly 1.5x
- Speed up load times of issue detail pages by roughly 1.5x
- If a merge request is to close an issue, show this on the issue page (Zeger-Jan van de Weg)
- Add a system note and update relevant merge requests when a branch is deleted or re-added (Stan Hu)
- Add a system note and update relevant merge requests when a branch is deleted or re-added (Stan Hu)
- Make diff file view easier to use on mobile screens (Stan Hu)
- Make diff file view easier to use on mobile screens (Stan Hu)
- Improved performance of finding users by username or Email address
- Improved performance of finding users by username or Email address
...
@@ -69,6 +81,13 @@ v 8.1.0 (unreleased)
...
@@ -69,6 +81,13 @@ v 8.1.0 (unreleased)
- Only render 404 page from /public
- Only render 404 page from /public
- Hide passwords from services API (Alex Lossent)
- Hide passwords from services API (Alex Lossent)
- Fix: Images cannot show when projects' path was changed
- Fix: Images cannot show when projects' path was changed
- Let gitlab-git-http-server generate and serve 'git archive' downloads
- Optimize query when filtering on issuables (Zeger-Jan van de Weg)
- Fix padding of outdated discussion item.
v 8.0.5
- Correct lookup-by-email for LDAP logins
- Fix loading spinner sometimes not being hidden on Merge Request tab switches
v 8.0.4
v 8.0.4
- Fix Message-ID header to be RFC 2111-compliant to prevent e-mails being dropped (Stan Hu)
- Fix Message-ID header to be RFC 2111-compliant to prevent e-mails being dropped (Stan Hu)
...
...
app/assets/stylesheets/framework/blocks.scss
View file @
d37cf642
...
@@ -65,3 +65,48 @@
...
@@ -65,3 +65,48 @@
line-height
:
42px
;
line-height
:
42px
;
}
}
}
}
.cover-block
{
text-align
:
center
;
background
:
#f7f8fa
;
margin
:
-
$gl-padding
;
margin-bottom
:
0
;
padding
:
44px
$gl-padding
;
border-bottom
:
1px
solid
$border-color
;
position
:
relative
;
.avatar-holder
{
margin-bottom
:
16px
;
.avatar
,
.identicon
{
margin
:
0
auto
;
float
:
none
;
}
.identicon
{
@include
border-radius
(
50%
);
}
}
.cover-title
{
color
:
$gl-header-color
;
margin
:
0
;
font-size
:
23px
;
font-weight
:
normal
;
margin
:
16px
0
5px
0
;
color
:
#4c4e54
;
font-size
:
23px
;
line-height
:
1
.1
;
}
.cover-desc
{
padding
:
0
$gl-padding
;
color
:
$gl-text-color
;
}
.cover-controls
{
position
:
absolute
;
top
:
10px
;
right
:
10px
;
}
}
app/assets/stylesheets/framework/files.scss
View file @
d37cf642
...
@@ -10,6 +10,10 @@
...
@@ -10,6 +10,10 @@
border-bottom
:
1px
solid
#E7E9EE
;
border-bottom
:
1px
solid
#E7E9EE
;
margin-bottom
:
1em
;
margin-bottom
:
1em
;
&
.readme-holder
{
border-bottom
:
0
;
}
table
{
table
{
@extend
.table
;
@extend
.table
;
}
}
...
...
app/assets/stylesheets/framework/typography.scss
View file @
d37cf642
...
@@ -18,7 +18,6 @@
...
@@ -18,7 +18,6 @@
font-family
:
$monospace_font
;
font-family
:
$monospace_font
;
white-space
:
pre
;
white-space
:
pre
;
word-wrap
:
normal
;
word-wrap
:
normal
;
padding
:
1px
2px
;
}
}
kbd
{
kbd
{
...
...
app/assets/stylesheets/pages/issues.scss
View file @
d37cf642
...
@@ -132,6 +132,11 @@ form.edit-issue {
...
@@ -132,6 +132,11 @@ form.edit-issue {
}
}
}
}
.issue-closed-by-widget
{
padding
:
16px
0
;
margin
:
0px
;
}
.issue-form
.select2-container
{
.issue-form
.select2-container
{
width
:
250px
!
important
;
width
:
250px
!
important
;
}
}
app/assets/stylesheets/pages/notes.scss
View file @
d37cf642
...
@@ -30,7 +30,6 @@ ul.notes {
...
@@ -30,7 +30,6 @@ ul.notes {
.discussion-header
,
.discussion-header
,
.note-header
{
.note-header
{
@extend
.cgray
;
@extend
.cgray
;
padding-bottom
:
15px
;
a
:hover
{
a
:hover
{
text-decoration
:
none
;
text-decoration
:
none
;
...
@@ -75,6 +74,10 @@ ul.notes {
...
@@ -75,6 +74,10 @@ ul.notes {
}
}
}
}
.discussion-body
{
padding-top
:
15px
;
}
.discussion
{
.discussion
{
overflow
:
hidden
;
overflow
:
hidden
;
display
:
block
;
display
:
block
;
...
...
app/assets/stylesheets/pages/profile.scss
View file @
d37cf642
...
@@ -47,3 +47,9 @@
...
@@ -47,3 +47,9 @@
}
}
}
}
}
}
.calendar-hint
{
margin-top
:
-12px
;
float
:
right
;
font-size
:
12px
;
}
app/assets/stylesheets/pages/projects.scss
View file @
d37cf642
...
@@ -544,5 +544,5 @@ pre.light-well {
...
@@ -544,5 +544,5 @@ pre.light-well {
}
}
.project-show-readme
.readme-holder
{
.project-show-readme
.readme-holder
{
padding
:
7px
;
border-top
:
0
;
}
}
app/assets/stylesheets/pages/tree.scss
View file @
d37cf642
...
@@ -4,14 +4,6 @@
...
@@ -4,14 +4,6 @@
margin-right
:
-
$gl-padding
;
margin-right
:
-
$gl-padding
;
}
}
.tree_progress
{
display
:
none
;
margin
:
20px
;
&
.loading
{
display
:
block
;
}
}
.tree-table
{
.tree-table
{
margin-bottom
:
0
;
margin-bottom
:
0
;
...
...
app/controllers/abuse_reports_controller.rb
View file @
d37cf642
...
@@ -9,6 +9,10 @@ class AbuseReportsController < ApplicationController
...
@@ -9,6 +9,10 @@ class AbuseReportsController < ApplicationController
@abuse_report
.
reporter
=
current_user
@abuse_report
.
reporter
=
current_user
if
@abuse_report
.
save
if
@abuse_report
.
save
if
current_application_settings
.
admin_notification_email
.
present?
AbuseReportMailer
.
delay
.
notify
(
@abuse_report
.
id
)
end
message
=
"Thank you for your report. A GitLab administrator will look into it shortly."
message
=
"Thank you for your report. A GitLab administrator will look into it shortly."
redirect_to
root_path
,
notice:
message
redirect_to
root_path
,
notice:
message
else
else
...
...
app/controllers/admin/application_settings_controller.rb
View file @
d37cf642
...
@@ -55,6 +55,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
...
@@ -55,6 +55,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:default_snippet_visibility
,
:default_snippet_visibility
,
:restricted_signup_domains_raw
,
:restricted_signup_domains_raw
,
:version_check_enabled
,
:version_check_enabled
,
:admin_notification_email
,
:user_oauth_applications
,
:user_oauth_applications
,
restricted_visibility_levels:
[],
restricted_visibility_levels:
[],
import_sources:
[]
import_sources:
[]
...
...
app/controllers/admin/broadcast_messages_controller.rb
View file @
d37cf642
...
@@ -19,7 +19,7 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController
...
@@ -19,7 +19,7 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController
BroadcastMessage
.
find
(
params
[
:id
]).
destroy
BroadcastMessage
.
find
(
params
[
:id
]).
destroy
respond_to
do
|
format
|
respond_to
do
|
format
|
format
.
html
{
redirect_
to
:back
}
format
.
html
{
redirect_
back_or_default
(
default:
{
action:
'index'
})
}
format
.
js
{
render
nothing:
true
}
format
.
js
{
render
nothing:
true
}
end
end
end
end
...
...
app/controllers/admin/hooks_controller.rb
View file @
d37cf642
...
@@ -35,7 +35,7 @@ class Admin::HooksController < Admin::ApplicationController
...
@@ -35,7 +35,7 @@ class Admin::HooksController < Admin::ApplicationController
}
}
@hook
.
execute
(
data
,
'system_hooks'
)
@hook
.
execute
(
data
,
'system_hooks'
)
redirect_
to
:back
redirect_
back_or_default
end
end
def
hook_params
def
hook_params
...
...
app/controllers/admin/users_controller.rb
View file @
d37cf642
...
@@ -33,33 +33,33 @@ class Admin::UsersController < Admin::ApplicationController
...
@@ -33,33 +33,33 @@ class Admin::UsersController < Admin::ApplicationController
def
block
def
block
if
user
.
block
if
user
.
block
redirect_
to
:back
,
notice:
"Successfully blocked"
redirect_
back_or_admin_user
(
notice:
"Successfully blocked"
)
else
else
redirect_
to
:back
,
alert:
"Error occurred. User was not blocked"
redirect_
back_or_admin_user
(
alert:
"Error occurred. User was not blocked"
)
end
end
end
end
def
unblock
def
unblock
if
user
.
activate
if
user
.
activate
redirect_
to
:back
,
notice:
"Successfully unblocked"
redirect_
back_or_admin_user
(
notice:
"Successfully unblocked"
)
else
else
redirect_
to
:back
,
alert:
"Error occurred. User was not unblocked"
redirect_
back_or_admin_user
(
alert:
"Error occurred. User was not unblocked"
)
end
end
end
end
def
unlock
def
unlock
if
user
.
unlock_access!
if
user
.
unlock_access!
redirect_
to
:back
,
alert:
"Successfully unlocked"
redirect_
back_or_admin_user
(
alert:
"Successfully unlocked"
)
else
else
redirect_
to
:back
,
alert:
"Error occurred. User was not unlocked"
redirect_
back_or_admin_user
(
alert:
"Error occurred. User was not unlocked"
)
end
end
end
end
def
confirm
def
confirm
if
user
.
confirm
if
user
.
confirm
redirect_
to
:back
,
notice:
"Successfully confirmed"
redirect_
back_or_admin_user
(
notice:
"Successfully confirmed"
)
else
else
redirect_
to
:back
,
alert:
"Error occurred. User was not confirmed"
redirect_
back_or_admin_user
(
alert:
"Error occurred. User was not confirmed"
)
end
end
end
end
...
@@ -138,7 +138,7 @@ class Admin::UsersController < Admin::ApplicationController
...
@@ -138,7 +138,7 @@ class Admin::UsersController < Admin::ApplicationController
user
.
update_secondary_emails!
user
.
update_secondary_emails!
respond_to
do
|
format
|
respond_to
do
|
format
|
format
.
html
{
redirect_
to
:back
,
notice:
"Successfully removed email."
}
format
.
html
{
redirect_
back_or_admin_user
(
notice:
"Successfully removed email."
)
}
format
.
js
{
render
nothing:
true
}
format
.
js
{
render
nothing:
true
}
end
end
end
end
...
@@ -157,4 +157,12 @@ class Admin::UsersController < Admin::ApplicationController
...
@@ -157,4 +157,12 @@ class Admin::UsersController < Admin::ApplicationController
:projects_limit
,
:can_create_group
,
:admin
,
:key_id
:projects_limit
,
:can_create_group
,
:admin
,
:key_id
)
)
end
end
def
redirect_back_or_admin_user
(
options
=
{})
redirect_back_or_default
(
default:
default_route
,
options:
options
)
end
def
default_route
[
:admin
,
@user
]
end
end
end
app/controllers/application_controller.rb
View file @
d37cf642
...
@@ -33,6 +33,10 @@ class ApplicationController < ActionController::Base
...
@@ -33,6 +33,10 @@ class ApplicationController < ActionController::Base
render_404
render_404
end
end
def
redirect_back_or_default
(
default:
root_path
,
options:
{})
redirect_to
request
.
referer
.
present?
?
:back
:
default
,
options
end
protected
protected
# From https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example
# From https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example
...
...
app/controllers/ci/projects_controller.rb
View file @
d37cf642
module
Ci
module
Ci
class
ProjectsController
<
Ci
::
ApplicationController
class
ProjectsController
<
Ci
::
ApplicationController
before_action
:project
before_action
:project
,
except:
[
:index
]
before_action
:authenticate_user!
,
except:
[
:build
,
:badge
]
before_action
:authenticate_user!
,
except:
[
:
index
,
:
build
,
:badge
]
before_action
:authorize_access_project!
,
except:
[
:badge
]
before_action
:authorize_access_project!
,
except:
[
:
index
,
:
badge
]
before_action
:authorize_manage_project!
,
only:
[
:toggle_shared_runners
,
:dumped_yaml
]
before_action
:authorize_manage_project!
,
only:
[
:toggle_shared_runners
,
:dumped_yaml
]
before_action
:no_cache
,
only:
[
:badge
]
before_action
:no_cache
,
only:
[
:badge
]
protect_from_forgery
protect_from_forgery
def
show
# Temporary compatibility with CI badges pointing to CI project page
redirect_to
namespace_project_path
(
project
.
gl_project
.
namespace
,
project
.
gl_project
)
end
# Project status badge
# Project status badge
# Image with build status for sha or ref
# Image with build status for sha or ref
def
badge
def
badge
...
...
app/controllers/import/github_controller.rb
View file @
d37cf642
...
@@ -11,10 +11,6 @@ class Import::GithubController < Import::BaseController
...
@@ -11,10 +11,6 @@ class Import::GithubController < Import::BaseController
def
status
def
status
@repos
=
client
.
repos
@repos
=
client
.
repos
client
.
orgs
.
each
do
|
org
|
@repos
+=
client
.
org_repos
(
org
.
login
)
end
@already_added_projects
=
current_user
.
created_projects
.
where
(
import_type:
"github"
)
@already_added_projects
=
current_user
.
created_projects
.
where
(
import_type:
"github"
)
already_added_projects_names
=
@already_added_projects
.
pluck
(
:import_source
)
already_added_projects_names
=
@already_added_projects
.
pluck
(
:import_source
)
...
...
app/controllers/import/google_code_controller.rb
View file @
d37cf642
...
@@ -10,18 +10,18 @@ class Import::GoogleCodeController < Import::BaseController
...
@@ -10,18 +10,18 @@ class Import::GoogleCodeController < Import::BaseController
dump_file
=
params
[
:dump_file
]
dump_file
=
params
[
:dump_file
]
unless
dump_file
.
respond_to?
(
:read
)
unless
dump_file
.
respond_to?
(
:read
)
return
redirect_
to
:back
,
alert:
"You need to upload a Google Takeout archive."
return
redirect_
back_or_default
(
options:
{
alert:
"You need to upload a Google Takeout archive."
})
end
end
begin
begin
dump
=
JSON
.
parse
(
dump_file
.
read
)
dump
=
JSON
.
parse
(
dump_file
.
read
)
rescue
rescue
return
redirect_
to
:back
,
alert:
"The uploaded file is not a valid Google Takeout archive."
return
redirect_
back_or_default
(
options:
{
alert:
"The uploaded file is not a valid Google Takeout archive."
})
end
end
client
=
Gitlab
::
GoogleCodeImport
::
Client
.
new
(
dump
)
client
=
Gitlab
::
GoogleCodeImport
::
Client
.
new
(
dump
)
unless
client
.
valid?
unless
client
.
valid?
return
redirect_
to
:back
,
alert:
"The uploaded file is not a valid Google Takeout archive."
return
redirect_
back_or_default
(
options:
{
alert:
"The uploaded file is not a valid Google Takeout archive."
})
end
end
session
[
:google_code_dump
]
=
dump
session
[
:google_code_dump
]
=
dump
...
...
app/controllers/invites_controller.rb
View file @
d37cf642
...
@@ -14,7 +14,7 @@ class InvitesController < ApplicationController
...
@@ -14,7 +14,7 @@ class InvitesController < ApplicationController
redirect_to
path
,
notice:
"You have been granted
#{
member
.
human_access
}
access to
#{
label
}
."
redirect_to
path
,
notice:
"You have been granted
#{
member
.
human_access
}
access to
#{
label
}
."
else
else
redirect_
to
:back
,
alert:
"The invitation could not be accepted."
redirect_
back_or_default
(
options:
{
alert:
"The invitation could not be accepted."
})
end
end
end
end
...
@@ -31,7 +31,7 @@ class InvitesController < ApplicationController
...
@@ -31,7 +31,7 @@ class InvitesController < ApplicationController
redirect_to
path
,
notice:
"You have declined the invitation to join
#{
label
}
."
redirect_to
path
,
notice:
"You have declined the invitation to join
#{
label
}
."
else
else
redirect_
to
:back
,
alert:
"The invitation could not be declined."
redirect_
back_or_default
(
options:
{
alert:
"The invitation could not be declined."
})
end
end
end
end
...
...
app/controllers/profiles/notifications_controller.rb
View file @
d37cf642
...
@@ -29,7 +29,7 @@ class Profiles::NotificationsController < Profiles::ApplicationController
...
@@ -29,7 +29,7 @@ class Profiles::NotificationsController < Profiles::ApplicationController
flash
[
:alert
]
=
"Failed to save new settings"
flash
[
:alert
]
=
"Failed to save new settings"
end
end
redirect_
to
:back
redirect_
back_or_default
(
default:
profile_notifications_path
)
end
end
format
.
js
format
.
js
...
...
app/controllers/profiles_controller.rb
View file @
d37cf642
...
@@ -26,7 +26,7 @@ class ProfilesController < Profiles::ApplicationController
...
@@ -26,7 +26,7 @@ class ProfilesController < Profiles::ApplicationController
end
end
respond_to
do
|
format
|
respond_to
do
|
format
|
format
.
html
{
redirect_
to
:back
}
format
.
html
{
redirect_
back_or_default
(
default:
{
action:
'show'
})
}
end
end
end
end
...
...
app/controllers/projects/ci_services_controller.rb
View file @
d37cf642
...
@@ -30,7 +30,7 @@ class Projects::CiServicesController < Projects::ApplicationController
...
@@ -30,7 +30,7 @@ class Projects::CiServicesController < Projects::ApplicationController
message
=
{
alert:
'We tried to test the service but error occurred'
}
message
=
{
alert:
'We tried to test the service but error occurred'
}
end
end
redirect_
to
:back
,
message
redirect_
back_or_default
(
options:
message
)
end
end
private
private
...
...
app/controllers/projects/ci_web_hooks_controller.rb
View file @
d37cf642
...
@@ -24,7 +24,7 @@ class Projects::CiWebHooksController < Projects::ApplicationController
...
@@ -24,7 +24,7 @@ class Projects::CiWebHooksController < Projects::ApplicationController
def
test
def
test
Ci
::
TestHookService
.
new
.
execute
(
hook
,
current_user
)
Ci
::
TestHookService
.
new
.
execute
(
hook
,
current_user
)
redirect_
to
:back
redirect_
back_or_default
(
default:
{
action:
'index'
})
end
end
def
destroy
def
destroy
...
...
app/controllers/projects/compare_controller.rb
View file @
d37cf642
...
@@ -17,9 +17,10 @@ class Projects::CompareController < Projects::ApplicationController
...
@@ -17,9 +17,10 @@ class Projects::CompareController < Projects::ApplicationController
execute
(
@project
,
head_ref
,
@project
,
base_ref
)
execute
(
@project
,
head_ref
,
@project
,
base_ref
)
if
compare_result
if
compare_result
@commits
=
compare_result
.
commits
@commits
=
Commit
.
decorate
(
compare_result
.
commits
,
@project
)
@diffs
=
compare_result
.
diffs
@diffs
=
compare_result
.
diffs
@commit
=
@commits
.
last
@commit
=
@commits
.
last
@first_commit
=
@commits
.
first
@line_notes
=
[]
@line_notes
=
[]
end
end
end
end
...
...
app/controllers/projects/deploy_keys_controller.rb
View file @
d37cf642
...
@@ -46,7 +46,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
...
@@ -46,7 +46,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
def
disable
def
disable
@project
.
deploy_keys_projects
.
find_by
(
deploy_key_id:
params
[
:id
]).
destroy
@project
.
deploy_keys_projects
.
find_by
(
deploy_key_id:
params
[
:id
]).
destroy
redirect_
to
:back
redirect_
back_or_default
(
default:
{
action:
'index'
})
end
end
protected
protected
...
...
app/controllers/projects/hooks_controller.rb
View file @
d37cf642
...
@@ -37,7 +37,7 @@ class Projects::HooksController < Projects::ApplicationController
...
@@ -37,7 +37,7 @@ class Projects::HooksController < Projects::ApplicationController
flash
[
:alert
]
=
'Hook execution failed. Ensure the project has commits.'
flash
[
:alert
]
=
'Hook execution failed. Ensure the project has commits.'
end
end
redirect_
to
:back
redirect_
back_or_default
(
default:
{
action:
'index'
})
end
end
def
destroy
def
destroy
...
...
app/controllers/projects/issues_controller.rb
View file @
d37cf642
...
@@ -14,6 +14,9 @@ class Projects::IssuesController < Projects::ApplicationController
...
@@ -14,6 +14,9 @@ class Projects::IssuesController < Projects::ApplicationController
# Allow issues bulk update
# Allow issues bulk update
before_action
:authorize_admin_issues!
,
only:
[
:bulk_update
]
before_action
:authorize_admin_issues!
,
only:
[
:bulk_update
]
# Cross-reference merge requests
before_action
:closed_by_merge_requests
,
only:
[
:show
]
respond_to
:html
respond_to
:html
def
index
def
index
...
@@ -103,7 +106,7 @@ class Projects::IssuesController < Projects::ApplicationController
...
@@ -103,7 +106,7 @@ class Projects::IssuesController < Projects::ApplicationController
def
bulk_update
def
bulk_update
result
=
Issues
::
BulkUpdateService
.
new
(
project
,
current_user
,
bulk_update_params
).
execute
result
=
Issues
::
BulkUpdateService
.
new
(
project
,
current_user
,
bulk_update_params
).
execute
redirect_
to
:back
,
notice:
"
#{
result
[
:count
]
}
issues updated"
redirect_
back_or_default
(
default:
{
action:
'index'
},
options:
{
notice:
"
#{
result
[
:count
]
}
issues updated"
})
end
end
def
toggle_subscription
def
toggle_subscription
...
@@ -112,6 +115,10 @@ class Projects::IssuesController < Projects::ApplicationController
...
@@ -112,6 +115,10 @@ class Projects::IssuesController < Projects::ApplicationController
render
nothing:
true
render
nothing:
true
end
end
def
closed_by_merge_requests
@closed_by_merge_requests
||=
@issue
.
closed_by_merge_requests
(
current_user
)
end
protected
protected
def
issue
def
issue
...
...
app/controllers/projects/merge_requests_controller.rb
View file @
d37cf642
...
@@ -56,6 +56,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
...
@@ -56,6 +56,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
def
diffs
def
diffs
@commit
=
@merge_request
.
last_commit
@commit
=
@merge_request
.
last_commit
@first_commit
=
@merge_request
.
first_commit
@comments_allowed
=
@reply_allowed
=
true
@comments_allowed
=
@reply_allowed
=
true
@comments_target
=
{
@comments_target
=
{
noteable_type:
'MergeRequest'
,
noteable_type:
'MergeRequest'
,
...
@@ -89,7 +91,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
...
@@ -89,7 +91,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@target_project
=
merge_request
.
target_project
@target_project
=
merge_request
.
target_project
@source_project
=
merge_request
.
source_project
@source_project
=
merge_request
.
source_project
@commits
=
@merge_request
.
compare_commits
@commits
=
@merge_request
.
compare_commits
@commit
=
@merge_request
.
compare_commits
.
last
@commit
=
@merge_request
.
last_commit
@first_commit
=
@merge_request
.
first_commit
@diffs
=
@merge_request
.
compare_diffs
@diffs
=
@merge_request
.
compare_diffs
@note_counts
=
Note
.
where
(
commit_id:
@commits
.
map
(
&
:id
)).
@note_counts
=
Note
.
where
(
commit_id:
@commits
.
map
(
&
:id
)).
group
(
:commit_id
).
count
group
(
:commit_id
).
count
...
@@ -259,7 +262,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
...
@@ -259,7 +262,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@commits
=
@merge_request
.
commits
@commits
=
@merge_request
.
commits
@merge_request_diff
=
@merge_request
.
merge_request_diff
@merge_request_diff
=
@merge_request
.
merge_request_diff
if
@merge_request
.
locked_long_ago?
if
@merge_request
.
locked_long_ago?
@merge_request
.
unlock_mr
@merge_request
.
unlock_mr
@merge_request
.
close
@merge_request
.
close
...
...
app/controllers/projects/milestones_controller.rb
View file @
d37cf642
...
@@ -75,11 +75,7 @@ class Projects::MilestonesController < Projects::ApplicationController
...
@@ -75,11 +75,7 @@ class Projects::MilestonesController < Projects::ApplicationController
end
end
def
sort_issues
def
sort_issues
@issues
=
@milestone
.
issues
.
where
(
id:
params
[
'sortable_issue'
])
@milestone
.
sort_issues
(
params
[
'sortable_issue'
].
map
(
&
:to_i
))
@issues
.
each
do
|
issue
|
issue
.
position
=
params
[
'sortable_issue'
].
index
(
issue
.
id
.
to_s
)
+
1
issue
.
save
end
render
json:
{
saved:
true
}
render
json:
{
saved:
true
}
end
end
...
...
app/controllers/projects/notes_controller.rb
View file @
d37cf642
...
@@ -25,7 +25,7 @@ class Projects::NotesController < Projects::ApplicationController
...
@@ -25,7 +25,7 @@ class Projects::NotesController < Projects::ApplicationController
respond_to
do
|
format
|
respond_to
do
|
format
|
format
.
json
{
render_note_json
(
@note
)
}
format
.
json
{
render_note_json
(
@note
)
}
format
.
html
{
redirect_
to
:back
}
format
.
html
{
redirect_
back_or_default
}
end
end
end
end
...
@@ -34,7 +34,7 @@ class Projects::NotesController < Projects::ApplicationController
...
@@ -34,7 +34,7 @@ class Projects::NotesController < Projects::ApplicationController
respond_to
do
|
format
|
respond_to
do
|
format
|
format
.
json
{
render_note_json
(
@note
)
}
format
.
json
{
render_note_json
(
@note
)
}
format
.
html
{
redirect_
to
:back
}
format
.
html
{
redirect_
back_or_default
}
end
end
end
end
...
...
app/controllers/projects/project_members_controller.rb
View file @
d37cf642
...
@@ -72,7 +72,8 @@ class Projects::ProjectMembersController < Projects::ApplicationController
...
@@ -72,7 +72,8 @@ class Projects::ProjectMembersController < Projects::ApplicationController
def
leave
def
leave
if
@project
.
namespace
==
current_user
.
namespace
if
@project
.
namespace
==
current_user
.
namespace
return
redirect_to
(
:back
,
alert:
'You can not leave your own project. Transfer or delete the project.'
)
message
=
'You can not leave your own project. Transfer or delete the project.'
return
redirect_back_or_default
(
default:
{
action:
'index'
},
options:
{
alert:
message
})
end
end
@project
.
project_members
.
find_by
(
user_id:
current_user
).
destroy
@project
.
project_members
.
find_by
(
user_id:
current_user
).
destroy
...
...
app/controllers/projects/services_controller.rb
View file @
d37cf642
...
@@ -12,7 +12,7 @@ class Projects::ServicesController < Projects::ApplicationController
...
@@ -12,7 +12,7 @@ class Projects::ServicesController < Projects::ApplicationController
# Parameters to ignore if no value is specified
# Parameters to ignore if no value is specified
FILTER_BLANK_PARAMS
=
[
:password
]
FILTER_BLANK_PARAMS
=
[
:password
]
# Authorize
# Authorize
before_action
:authorize_admin_project!
before_action
:authorize_admin_project!
before_action
:service
,
only:
[
:edit
,
:update
,
:test
]
before_action
:service
,
only:
[
:edit
,
:update
,
:test
]
...
@@ -52,7 +52,7 @@ class Projects::ServicesController < Projects::ApplicationController
...
@@ -52,7 +52,7 @@ class Projects::ServicesController < Projects::ApplicationController
message
=
{
alert:
error_message
}
message
=
{
alert:
error_message
}
end
end
redirect_
to
:back
,
message
redirect_
back_or_default
(
options:
message
)
end
end
private
private
...
...
app/controllers/projects_controller.rb
View file @
d37cf642
class
ProjectsController
<
ApplicationController
class
ProjectsController
<
ApplicationController
include
ExtractsPath
prepend_before_filter
:render_go_import
,
only:
[
:show
]
prepend_before_filter
:render_go_import
,
only:
[
:show
]
skip_before_action
:authenticate_user!
,
only:
[
:show
,
:activity
]
skip_before_action
:authenticate_user!
,
only:
[
:show
,
:activity
]
before_action
:project
,
except:
[
:new
,
:create
]
before_action
:project
,
except:
[
:new
,
:create
]
before_action
:repository
,
except:
[
:new
,
:create
]
before_action
:repository
,
except:
[
:new
,
:create
]
before_action
:assign_ref_vars
,
:tree
,
only:
[
:show
],
if: :repo_exists?
# Authorize
# Authorize
before_action
:authorize_admin_project!
,
only:
[
:edit
,
:update
,
:destroy
,
:transfer
,
:archive
,
:unarchive
]
before_action
:authorize_admin_project!
,
only:
[
:edit
,
:update
]
before_action
:event_filter
,
only:
[
:show
,
:activity
]
before_action
:event_filter
,
only:
[
:show
,
:activity
]
layout
:determine_layout
layout
:determine_layout
...
@@ -56,6 +59,8 @@ class ProjectsController < ApplicationController
...
@@ -56,6 +59,8 @@ class ProjectsController < ApplicationController
end
end
def
transfer
def
transfer
return
access_denied!
unless
can?
(
current_user
,
:change_namespace
,
@project
)
namespace
=
Namespace
.
find_by
(
id:
params
[
:new_namespace_id
])
namespace
=
Namespace
.
find_by
(
id:
params
[
:new_namespace_id
])
::
Projects
::
TransferService
.
new
(
project
,
current_user
).
execute
(
namespace
)
::
Projects
::
TransferService
.
new
(
project
,
current_user
).
execute
(
namespace
)
...
@@ -64,6 +69,15 @@ class ProjectsController < ApplicationController
...
@@ -64,6 +69,15 @@ class ProjectsController < ApplicationController
end
end
end
end
def
remove_fork
return
access_denied!
unless
can?
(
current_user
,
:remove_fork_project
,
@project
)
if
@project
.
forked?
@project
.
forked_project_link
.
destroy
flash
[
:notice
]
=
'The fork relationship has been removed.'
end
end
def
activity
def
activity
respond_to
do
|
format
|
respond_to
do
|
format
|
format
.
html
format
.
html
...
@@ -87,7 +101,7 @@ class ProjectsController < ApplicationController
...
@@ -87,7 +101,7 @@ class ProjectsController < ApplicationController
render
'projects/empty'
render
'projects/empty'
else
else
if
current_user
if
current_user
@membership
=
@project
.
project_member_by_id
(
current_user
.
id
)
@membership
=
@project
.
team
.
find_member
(
current_user
.
id
)
end
end
render
:show
render
:show
...
@@ -139,6 +153,7 @@ class ProjectsController < ApplicationController
...
@@ -139,6 +153,7 @@ class ProjectsController < ApplicationController
def
archive
def
archive
return
access_denied!
unless
can?
(
current_user
,
:archive_project
,
@project
)
return
access_denied!
unless
can?
(
current_user
,
:archive_project
,
@project
)
@project
.
archive!
@project
.
archive!
respond_to
do
|
format
|
respond_to
do
|
format
|
...
@@ -148,6 +163,7 @@ class ProjectsController < ApplicationController
...
@@ -148,6 +163,7 @@ class ProjectsController < ApplicationController
def
unarchive
def
unarchive
return
access_denied!
unless
can?
(
current_user
,
:archive_project
,
@project
)
return
access_denied!
unless
can?
(
current_user
,
:archive_project
,
@project
)
@project
.
unarchive!
@project
.
unarchive!
respond_to
do
|
format
|
respond_to
do
|
format
|
...
@@ -225,4 +241,14 @@ class ProjectsController < ApplicationController
...
@@ -225,4 +241,14 @@ class ProjectsController < ApplicationController
render
"go_import"
,
layout:
false
render
"go_import"
,
layout:
false
end
end
def
repo_exists?
project
.
repository_exists?
&&
!
project
.
empty_repo?
end
# Override get_id from ExtractsPath, which returns the branch and file path
# for the blob/tree, which in this case is just the root of the default branch.
def
get_id
project
.
repository
.
root_ref
end
end
end
app/finders/issuable_finder.rb
View file @
d37cf642
...
@@ -53,15 +53,36 @@ class IssuableFinder
...
@@ -53,15 +53,36 @@ class IssuableFinder
end
end
end
end
def
project?
params
[
:project_id
].
present?
end
def
project
def
project
return
@project
if
defined?
(
@project
)
return
@project
if
defined?
(
@project
)
@project
=
if
project?
if
params
[
:project_id
].
present?
@project
=
Project
.
find
(
params
[
:project_id
])
Project
.
find
(
params
[
:project_id
])
else
unless
Ability
.
abilities
.
allowed?
(
current_user
,
:read_project
,
@project
)
nil
@project
=
nil
end
end
else
@project
=
nil
end
@project
end
def
projects
return
@projects
if
defined?
(
@projects
)
if
project?
project
elsif
current_user
&&
params
[
:authorized_only
].
presence
&&
!
current_user_related?
current_user
.
authorized_projects
else
ProjectsFinder
.
new
.
execute
(
current_user
)
end
end
end
def
search
def
search
...
@@ -72,7 +93,7 @@ class IssuableFinder
...
@@ -72,7 +93,7 @@ class IssuableFinder
params
[
:milestone_title
].
present?
params
[
:milestone_title
].
present?
end
end
def
no_milestones
?
def
filter_by_no_milestone
?
milestones?
&&
params
[
:milestone_title
]
==
Milestone
::
None
.
title
milestones?
&&
params
[
:milestone_title
]
==
Milestone
::
None
.
title
end
end
...
@@ -81,12 +102,22 @@ class IssuableFinder
...
@@ -81,12 +102,22 @@ class IssuableFinder
@milestones
=
@milestones
=
if
milestones?
if
milestones?
Milestone
.
where
(
title:
params
[
:milestone_title
])
scope
=
Milestone
.
where
(
project_id:
projects
)
scope
.
where
(
title:
params
[
:milestone_title
])
else
else
nil
nil
end
end
end
end
def
labels?
params
[
:label_name
].
present?
end
def
filter_by_no_label?
labels?
&&
params
[
:label_name
]
==
Label
::
None
.
title
end
def
assignee?
def
assignee?
params
[
:assignee_id
].
present?
params
[
:assignee_id
].
present?
end
end
...
@@ -120,19 +151,7 @@ class IssuableFinder
...
@@ -120,19 +151,7 @@ class IssuableFinder
private
private
def
init_collection
def
init_collection
table_name
=
klass
.
table_name
klass
.
all
if
project
if
Ability
.
abilities
.
allowed?
(
current_user
,
:read_project
,
project
)
project
.
send
(
table_name
)
else
[]
end
elsif
current_user
&&
params
[
:authorized_only
].
presence
&&
!
current_user_related?
klass
.
of_projects
(
current_user
.
authorized_projects
).
references
(
:project
)
else
klass
.
of_projects
(
ProjectsFinder
.
new
.
execute
(
current_user
)).
references
(
:project
)
end
end
end
def
by_scope
(
items
)
def
by_scope
(
items
)
...
@@ -170,7 +189,12 @@ class IssuableFinder
...
@@ -170,7 +189,12 @@ class IssuableFinder
end
end
def
by_project
(
items
)
def
by_project
(
items
)
items
=
items
.
of_projects
(
project
.
id
)
if
project
items
=
if
projects
items
.
of_projects
(
projects
).
references
(
:project
)
else
items
.
none
end
items
items
end
end
...
@@ -185,18 +209,6 @@ class IssuableFinder
...
@@ -185,18 +209,6 @@ class IssuableFinder
items
.
sort
(
params
[
:sort
])
items
.
sort
(
params
[
:sort
])
end
end
def
by_milestone
(
items
)
if
milestones?
if
no_milestones?
items
=
items
.
where
(
milestone_id:
[
-
1
,
nil
])
else
items
=
items
.
where
(
milestone_id:
milestones
.
try
(
:pluck
,
:id
))
end
end
items
end
def
by_assignee
(
items
)
def
by_assignee
(
items
)
if
assignee?
if
assignee?
items
=
items
.
where
(
assignee_id:
assignee
.
try
(
:id
))
items
=
items
.
where
(
assignee_id:
assignee
.
try
(
:id
))
...
@@ -213,20 +225,36 @@ class IssuableFinder
...
@@ -213,20 +225,36 @@ class IssuableFinder
items
items
end
end
def
by_label
(
items
)
def
by_milestone
(
items
)
if
params
[
:label_name
].
present?
if
milestones?
if
params
[
:label_name
]
==
Label
::
None
.
title
if
filter_by_no_milestone?
item_ids
=
LabelLink
.
where
(
target_type:
klass
.
name
).
pluck
(
:target_id
)
items
=
items
.
where
(
milestone_id:
[
-
1
,
nil
])
else
items
=
items
.
joins
(
:milestone
).
where
(
milestones:
{
title:
params
[
:milestone_title
]
})
if
projects
items
=
items
.
where
(
milestones:
{
project_id:
projects
})
end
end
end
items
end
items
=
items
.
where
(
'id NOT IN (?)'
,
item_ids
)
def
by_label
(
items
)
if
labels?
if
filter_by_no_label?
items
=
items
.
joins
(
"LEFT OUTER JOIN label_links ON label_links.target_type = '
#{
klass
.
name
}
' AND label_links.target_id =
#{
klass
.
table_name
}
.id"
).
where
(
label_links:
{
id:
nil
})
else
else
label_names
=
params
[
:label_name
].
split
(
","
)
label_names
=
params
[
:label_name
].
split
(
","
)
item_ids
=
LabelLink
.
joins
(
:label
).
items
=
items
.
joins
(
:labels
).
where
(
labels:
{
title:
label_names
})
where
(
'labels.title in (?)'
,
label_names
).
where
(
target_type:
klass
.
name
).
pluck
(
:target_id
)
items
=
items
.
where
(
id:
item_ids
)
if
projects
items
=
items
.
where
(
labels:
{
project_id:
projects
})
end
end
end
end
end
...
...
app/helpers/diff_helper.rb
View file @
d37cf642
...
@@ -170,7 +170,8 @@ module DiffHelper
...
@@ -170,7 +170,8 @@ module DiffHelper
def
commit_for_diff
(
diff
)
def
commit_for_diff
(
diff
)
if
diff
.
deleted_file
if
diff
.
deleted_file
@merge_request
?
@merge_request
.
commits
.
last
:
@commit
.
parents
.
first
first_commit
=
@first_commit
||
@commit
first_commit
.
parent
else
else
@commit
@commit
end
end
...
...
app/helpers/gitlab_markdown_helper.rb
View file @
d37cf642
...
@@ -19,7 +19,8 @@ module GitlabMarkdownHelper
...
@@ -19,7 +19,8 @@ module GitlabMarkdownHelper
escape_once
(
body
)
escape_once
(
body
)
end
end
gfm_body
=
Gitlab
::
Markdown
.
gfm
(
escaped_body
,
project:
@project
,
current_user:
current_user
)
user
=
current_user
if
defined?
(
current_user
)
gfm_body
=
Gitlab
::
Markdown
.
gfm
(
escaped_body
,
project:
@project
,
current_user:
user
)
fragment
=
Nokogiri
::
HTML
::
DocumentFragment
.
parse
(
gfm_body
)
fragment
=
Nokogiri
::
HTML
::
DocumentFragment
.
parse
(
gfm_body
)
if
fragment
.
children
.
size
==
1
&&
fragment
.
children
[
0
].
name
==
'a'
if
fragment
.
children
.
size
==
1
&&
fragment
.
children
[
0
].
name
==
'a'
...
@@ -45,29 +46,39 @@ module GitlabMarkdownHelper
...
@@ -45,29 +46,39 @@ module GitlabMarkdownHelper
end
end
def
markdown
(
text
,
context
=
{})
def
markdown
(
text
,
context
=
{})
return
""
unless
text
.
present?
context
.
reverse_merge!
(
context
.
reverse_merge!
(
current_user:
current_user
,
path:
@path
,
path:
@path
,
pipeline: :default
,
project:
@project
,
project:
@project
,
project_wiki:
@project_wiki
,
project_wiki:
@project_wiki
,
ref:
@ref
ref:
@ref
)
)
Gitlab
::
Markdown
.
render
(
text
,
context
)
user
=
current_user
if
defined?
(
current_user
)
html
=
Gitlab
::
Markdown
.
render
(
text
,
context
)
Gitlab
::
Markdown
.
post_process
(
html
,
pipeline:
context
[
:pipeline
],
project:
@project
,
user:
user
)
end
end
# TODO (rspeicher): Remove all usages of this helper and just call `markdown`
# TODO (rspeicher): Remove all usages of this helper and just call `markdown`
# with a custom pipeline depending on the content being rendered
# with a custom pipeline depending on the content being rendered
def
gfm
(
text
,
options
=
{})
def
gfm
(
text
,
options
=
{})
return
""
unless
text
.
present?
options
.
reverse_merge!
(
options
.
reverse_merge!
(
current_user:
current_user
,
path:
@path
,
path:
@path
,
pipeline: :default
,
project:
@project
,
project:
@project
,
project_wiki:
@project_wiki
,
project_wiki:
@project_wiki
,
ref:
@ref
ref:
@ref
)
)
Gitlab
::
Markdown
.
gfm
(
text
,
options
)
user
=
current_user
if
defined?
(
current_user
)
html
=
Gitlab
::
Markdown
.
gfm
(
text
,
options
)
Gitlab
::
Markdown
.
post_process
(
html
,
pipeline:
options
[
:pipeline
],
project:
@project
,
user:
user
)
end
end
def
asciidoc
(
text
)
def
asciidoc
(
text
)
...
...
app/helpers/issues_helper.rb
View file @
d37cf642
...
@@ -83,6 +83,10 @@ module IssuesHelper
...
@@ -83,6 +83,10 @@ module IssuesHelper
end
end
end
end
def
merge_requests_sentence
(
merge_requests
)
merge_requests
.
map
(
&
:to_reference
).
to_sentence
(
last_word_connector:
', or '
)
end
# Required for Gitlab::Markdown::IssueReferenceFilter
# Required for Gitlab::Markdown::IssueReferenceFilter
module_function
:url_for_issue
module_function
:url_for_issue
end
end
app/helpers/preferences_helper.rb
View file @
d37cf642
...
@@ -34,7 +34,8 @@ module PreferencesHelper
...
@@ -34,7 +34,8 @@ module PreferencesHelper
def
project_view_choices
def
project_view_choices
[
[
[
'Readme (default)'
,
:readme
],
[
'Readme (default)'
,
:readme
],
[
'Activity view'
,
:activity
]
[
'Activity view'
,
:activity
],
[
'Files view'
,
:files
]
]
]
end
end
...
@@ -46,8 +47,7 @@ module PreferencesHelper
...
@@ -46,8 +47,7 @@ module PreferencesHelper
Gitlab
::
ColorSchemes
.
for_user
(
current_user
).
css_class
Gitlab
::
ColorSchemes
.
for_user
(
current_user
).
css_class
end
end
def
prefer_readme?
def
default_project_view
!
current_user
||
current_user
?
current_user
.
project_view
:
'readme'
current_user
.
project_view
==
'readme'
end
end
end
end
app/helpers/projects_helper.rb
View file @
d37cf642
...
@@ -70,6 +70,10 @@ module ProjectsHelper
...
@@ -70,6 +70,10 @@ module ProjectsHelper
"You are going to transfer
#{
project
.
name_with_namespace
}
to another owner. Are you ABSOLUTELY sure?"
"You are going to transfer
#{
project
.
name_with_namespace
}
to another owner. Are you ABSOLUTELY sure?"
end
end
def
remove_fork_project_message
(
project
)
"You are going to remove the fork relationship to source project
#{
@project
.
forked_from_project
.
name_with_namespace
}
. Are you ABSOLUTELY sure?"
end
def
project_nav_tabs
def
project_nav_tabs
@nav_tabs
||=
get_project_nav_tabs
(
@project
,
current_user
)
@nav_tabs
||=
get_project_nav_tabs
(
@project
,
current_user
)
end
end
...
@@ -113,7 +117,7 @@ module ProjectsHelper
...
@@ -113,7 +117,7 @@ module ProjectsHelper
nav_tabs
<<
:merge_requests
nav_tabs
<<
:merge_requests
end
end
if
can?
(
current_user
,
:read_build
,
project
)
if
project
.
gitlab_ci?
&&
can?
(
current_user
,
:read_build
,
project
)
nav_tabs
<<
:builds
nav_tabs
<<
:builds
end
end
...
...
app/mailers/abuse_report_mailer.rb
0 → 100644
View file @
d37cf642
class
AbuseReportMailer
<
BaseMailer
include
Gitlab
::
CurrentSettings
def
notify
(
abuse_report_id
)
@abuse_report
=
AbuseReport
.
find
(
abuse_report_id
)
mail
(
to:
current_application_settings
.
admin_notification_email
,
subject:
"
#{
@abuse_report
.
user
.
name
}
(
#{
@abuse_report
.
user
.
username
}
) was reported for abuse"
)
end
end
app/models/ability.rb
View file @
d37cf642
...
@@ -189,7 +189,8 @@ class Ability
...
@@ -189,7 +189,8 @@ class Ability
:change_visibility_level
,
:change_visibility_level
,
:rename_project
,
:rename_project
,
:remove_project
,
:remove_project
,
:archive_project
:archive_project
,
:remove_fork_project
]
]
end
end
...
...
app/models/application_setting.rb
View file @
d37cf642
...
@@ -44,6 +44,10 @@ class ApplicationSetting < ActiveRecord::Base
...
@@ -44,6 +44,10 @@ class ApplicationSetting < ActiveRecord::Base
allow_blank:
true
,
allow_blank:
true
,
format:
{
with:
/\A
#{
URI
.
regexp
(
%w(http https)
)
}
\z/
,
message:
"should be a valid url"
}
format:
{
with:
/\A
#{
URI
.
regexp
(
%w(http https)
)
}
\z/
,
message:
"should be a valid url"
}
validates
:admin_notification_email
,
allow_blank:
true
,
email:
true
validates_each
:restricted_visibility_levels
do
|
record
,
attr
,
value
|
validates_each
:restricted_visibility_levels
do
|
record
,
attr
,
value
|
unless
value
.
nil?
unless
value
.
nil?
value
.
each
do
|
level
|
value
.
each
do
|
level
|
...
...
app/models/commit.rb
View file @
d37cf642
...
@@ -2,13 +2,13 @@ class Commit
...
@@ -2,13 +2,13 @@ class Commit
extend
ActiveModel
::
Naming
extend
ActiveModel
::
Naming
include
ActiveModel
::
Conversion
include
ActiveModel
::
Conversion
include
Mentionable
include
Participable
include
Participable
include
Mentionable
include
Referable
include
Referable
include
StaticModel
include
StaticModel
attr_mentionable
:safe_message
attr_mentionable
:safe_message
participant
:author
,
:committer
,
:notes
,
:mentioned_users
participant
:author
,
:committer
,
:notes
attr_accessor
:project
attr_accessor
:project
...
@@ -164,6 +164,14 @@ class Commit
...
@@ -164,6 +164,14 @@ class Commit
@committer
||=
User
.
find_by_any_email
(
committer_email
)
@committer
||=
User
.
find_by_any_email
(
committer_email
)
end
end
def
parents
@parents
||=
parent_ids
.
map
{
|
id
|
project
.
commit
(
id
)
}
end
def
parent
@parent
||=
project
.
commit
(
self
.
parent_id
)
if
self
.
parent_id
end
def
notes
def
notes
project
.
notes
.
for_commit_id
(
self
.
id
)
project
.
notes
.
for_commit_id
(
self
.
id
)
end
end
...
@@ -181,10 +189,6 @@ class Commit
...
@@ -181,10 +189,6 @@ class Commit
@raw
.
short_id
(
7
)
@raw
.
short_id
(
7
)
end
end
def
parents
@parents
||=
Commit
.
decorate
(
super
,
project
)
end
def
ci_commit
def
ci_commit
project
.
ci_commit
(
sha
)
project
.
ci_commit
(
sha
)
end
end
...
...
app/models/concerns/issuable.rb
View file @
d37cf642
...
@@ -6,8 +6,8 @@
...
@@ -6,8 +6,8 @@
#
#
module
Issuable
module
Issuable
extend
ActiveSupport
::
Concern
extend
ActiveSupport
::
Concern
include
Mentionable
include
Participable
include
Participable
include
Mentionable
included
do
included
do
belongs_to
:author
,
class_name:
"User"
belongs_to
:author
,
class_name:
"User"
...
@@ -47,8 +47,7 @@ module Issuable
...
@@ -47,8 +47,7 @@ module Issuable
prefix:
true
prefix:
true
attr_mentionable
:title
,
:description
attr_mentionable
:title
,
:description
participant
:author
,
:assignee
,
:notes_with_associations
participant
:author
,
:assignee
,
:notes_with_associations
,
:mentioned_users
end
end
module
ClassMethods
module
ClassMethods
...
@@ -86,6 +85,10 @@ module Issuable
...
@@ -86,6 +85,10 @@ module Issuable
assignee_id_changed?
assignee_id_changed?
end
end
def
open?
opened?
||
reopened?
end
#
#
# Votes
# Votes
#
#
...
...
app/models/concerns/mentionable.rb
View file @
d37cf642
...
@@ -20,6 +20,12 @@ module Mentionable
...
@@ -20,6 +20,12 @@ module Mentionable
end
end
end
end
included
do
if
self
<
Participable
participant
->
(
current_user
)
{
mentioned_users
(
current_user
,
load_lazy_references:
false
)
}
end
end
# Returns the text used as the body of a Note when this object is referenced
# Returns the text used as the body of a Note when this object is referenced
#
#
# By default this will be the class name and the result of calling
# By default this will be the class name and the result of calling
...
@@ -41,22 +47,22 @@ module Mentionable
...
@@ -41,22 +47,22 @@ module Mentionable
self
self
end
end
def
all_references
(
current_user
=
self
.
author
,
text
=
self
.
mentionable_text
)
def
all_references
(
current_user
=
self
.
author
,
text
=
self
.
mentionable_text
,
load_lazy_references:
true
)
ext
=
Gitlab
::
ReferenceExtractor
.
new
(
self
.
project
,
current_user
)
ext
=
Gitlab
::
ReferenceExtractor
.
new
(
self
.
project
,
current_user
,
load_lazy_references:
load_lazy_references
)
ext
.
analyze
(
text
)
ext
.
analyze
(
text
)
ext
ext
end
end
def
mentioned_users
(
current_user
=
nil
)
def
mentioned_users
(
current_user
=
nil
,
load_lazy_references:
true
)
all_references
(
current_user
).
users
.
uniq
all_references
(
current_user
,
load_lazy_references:
load_lazy_references
).
users
end
end
# Extract GFM references to other Mentionables from this Mentionable. Always excludes its #local_reference.
# Extract GFM references to other Mentionables from this Mentionable. Always excludes its #local_reference.
def
referenced_mentionables
(
current_user
=
self
.
author
,
text
=
self
.
mentionable_text
)
def
referenced_mentionables
(
current_user
=
self
.
author
,
text
=
self
.
mentionable_text
,
load_lazy_references:
true
)
return
[]
if
text
.
blank?
return
[]
if
text
.
blank?
refs
=
all_references
(
current_user
,
text
)
refs
=
all_references
(
current_user
,
text
,
load_lazy_references:
load_lazy_references
)
(
refs
.
issues
+
refs
.
merge_requests
+
refs
.
commits
)
.
uniq
-
[
local_reference
]
(
refs
.
issues
+
refs
.
merge_requests
+
refs
.
commits
)
-
[
local_reference
]
end
end
# Create a cross-reference Note for each GFM reference to another Mentionable found in +mentionable_text+.
# Create a cross-reference Note for each GFM reference to another Mentionable found in +mentionable_text+.
...
...
app/models/concerns/participable.rb
View file @
d37cf642
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
#
#
# # ...
# # ...
#
#
# participant :author, :assignee, :
mentioned_users, :notes
# participant :author, :assignee, :
notes, ->(current_user) { mentioned_users(current_user) }
# end
# end
#
#
# issue = Issue.last
# issue = Issue.last
...
@@ -27,7 +27,7 @@ module Participable
...
@@ -27,7 +27,7 @@ module Participable
module
ClassMethods
module
ClassMethods
def
participant
(
*
attrs
)
def
participant
(
*
attrs
)
participant_attrs
.
concat
(
attrs
.
map
(
&
:to_s
)
)
participant_attrs
.
concat
(
attrs
)
end
end
def
participant_attrs
def
participant_attrs
...
@@ -37,33 +37,39 @@ module Participable
...
@@ -37,33 +37,39 @@ module Participable
# Be aware that this method makes a lot of sql queries.
# Be aware that this method makes a lot of sql queries.
# Save result into variable if you are going to reuse it inside same request
# Save result into variable if you are going to reuse it inside same request
def
participants
(
current_user
=
self
.
author
)
def
participants
(
current_user
=
self
.
author
,
load_lazy_references:
true
)
self
.
class
.
participant_attrs
.
flat_map
do
|
attr
|
participants
=
self
.
class
.
participant_attrs
.
flat_map
do
|
attr
|
meth
=
method
(
attr
)
value
=
value
=
if
meth
.
arity
==
1
||
meth
.
arity
==
-
1
if
attr
.
respond_to?
(
:call
)
meth
.
call
(
current_use
r
)
instance_exec
(
current_user
,
&
att
r
)
else
else
meth
.
call
send
(
attr
)
end
end
participants_for
(
value
,
current_user
)
participants_for
(
value
,
current_user
)
end
.
compact
.
uniq
.
select
do
|
user
|
end
.
compact
.
uniq
user
.
can?
(
:read_project
,
self
.
project
)
if
load_lazy_references
participants
=
Gitlab
::
Markdown
::
ReferenceFilter
::
LazyReference
.
load
(
participants
).
uniq
participants
.
select!
do
|
user
|
user
.
can?
(
:read_project
,
project
)
end
end
end
participants
end
end
private
private
def
participants_for
(
value
,
current_user
=
nil
)
def
participants_for
(
value
,
current_user
=
nil
)
case
value
case
value
when
User
when
User
,
Gitlab
::
Markdown
::
ReferenceFilter
::
LazyReference
[
value
]
[
value
]
when
Enumerable
,
ActiveRecord
::
Relation
when
Enumerable
,
ActiveRecord
::
Relation
value
.
flat_map
{
|
v
|
participants_for
(
v
,
current_user
)
}
value
.
flat_map
{
|
v
|
participants_for
(
v
,
current_user
)
}
when
Participable
when
Participable
value
.
participants
(
current_user
)
value
.
participants
(
current_user
,
load_lazy_references:
false
)
end
end
end
end
end
end
app/models/issue.rb
View file @
d37cf642
...
@@ -95,4 +95,14 @@ class Issue < ActiveRecord::Base
...
@@ -95,4 +95,14 @@ class Issue < ActiveRecord::Base
def
source_project
def
source_project
project
project
end
end
# From all notes on this issue, we'll select the system notes about linked
# merge requests. Of those, the MRs closing `self` are returned.
def
closed_by_merge_requests
(
current_user
=
nil
)
return
[]
unless
open
?
notes
.
system
.
flat_map
do
|
note
|
note
.
all_references
(
current_user
).
merge_requests
end
.
uniq
.
select
{
|
mr
|
mr
.
open?
&&
mr
.
closes_issue?
(
self
)
}
end
end
end
app/models/merge_request.rb
View file @
d37cf642
...
@@ -40,7 +40,7 @@ class MergeRequest < ActiveRecord::Base
...
@@ -40,7 +40,7 @@ class MergeRequest < ActiveRecord::Base
after_create
:create_merge_request_diff
after_create
:create_merge_request_diff
after_update
:update_merge_request_diff
after_update
:update_merge_request_diff
delegate
:commits
,
:diffs
,
:last_commit
,
:last_commit_short_sha
,
to: :merge_request_diff
,
prefix:
nil
delegate
:commits
,
:diffs
,
to: :merge_request_diff
,
prefix:
nil
# When this attribute is true some MR validation is ignored
# When this attribute is true some MR validation is ignored
# It allows us to close or modify broken merge requests
# It allows us to close or modify broken merge requests
...
@@ -157,6 +157,18 @@ class MergeRequest < ActiveRecord::Base
...
@@ -157,6 +157,18 @@ class MergeRequest < ActiveRecord::Base
reference
reference
end
end
def
last_commit
merge_request_diff
?
merge_request_diff
.
last_commit
:
compare_commits
.
last
end
def
first_commit
merge_request_diff
?
merge_request_diff
.
first_commit
:
compare_commits
.
first
end
def
last_commit_short_sha
last_commit
.
short_id
end
def
validate_branches
def
validate_branches
if
target_project
==
source_project
&&
target_branch
==
source_branch
if
target_project
==
source_project
&&
target_branch
==
source_branch
errors
.
add
:branch_conflict
,
"You can not use same project/branch for source and target"
errors
.
add
:branch_conflict
,
"You can not use same project/branch for source and target"
...
@@ -222,10 +234,6 @@ class MergeRequest < ActiveRecord::Base
...
@@ -222,10 +234,6 @@ class MergeRequest < ActiveRecord::Base
self
.
target_project
.
events
.
where
(
target_id:
self
.
id
,
target_type:
"MergeRequest"
,
action:
Event
::
CLOSED
).
last
self
.
target_project
.
events
.
where
(
target_id:
self
.
id
,
target_type:
"MergeRequest"
,
action:
Event
::
CLOSED
).
last
end
end
def
open?
opened?
||
reopened?
end
def
work_in_progress?
def
work_in_progress?
!!
(
title
=~
/\A\[?WIP\]?:? /i
)
!!
(
title
=~
/\A\[?WIP\]?:? /i
)
end
end
...
@@ -294,6 +302,10 @@ class MergeRequest < ActiveRecord::Base
...
@@ -294,6 +302,10 @@ class MergeRequest < ActiveRecord::Base
target_project
target_project
end
end
def
closes_issue?
(
issue
)
closes_issues
.
include?
(
issue
)
end
# Return the set of issues that will be closed if this merge request is accepted.
# Return the set of issues that will be closed if this merge request is accepted.
def
closes_issues
(
current_user
=
self
.
author
)
def
closes_issues
(
current_user
=
self
.
author
)
if
target_branch
==
project
.
default_branch
if
target_branch
==
project
.
default_branch
...
...
app/models/merge_request_diff.rb
View file @
d37cf642
...
@@ -55,6 +55,10 @@ class MergeRequestDiff < ActiveRecord::Base
...
@@ -55,6 +55,10 @@ class MergeRequestDiff < ActiveRecord::Base
commits
.
first
commits
.
first
end
end
def
first_commit
commits
.
last
end
def
last_commit_short_sha
def
last_commit_short_sha
@last_commit_short_sha
||=
last_commit
.
short_id
@last_commit_short_sha
||=
last_commit
.
short_id
end
end
...
...
app/models/milestone.rb
View file @
d37cf642
...
@@ -105,4 +105,36 @@ class Milestone < ActiveRecord::Base
...
@@ -105,4 +105,36 @@ class Milestone < ActiveRecord::Base
def
author_id
def
author_id
nil
nil
end
end
# Sorts the issues for the given IDs.
#
# This method runs a single SQL query using a CASE statement to update the
# position of all issues in the current milestone (scoped to the list of IDs).
#
# Given the ids [10, 20, 30] this method produces a SQL query something like
# the following:
#
# UPDATE issues
# SET position = CASE
# WHEN id = 10 THEN 1
# WHEN id = 20 THEN 2
# WHEN id = 30 THEN 3
# ELSE position
# END
# WHERE id IN (10, 20, 30);
#
# This method expects that the IDs given in `ids` are already Fixnums.
def
sort_issues
(
ids
)
pairs
=
[]
ids
.
each_with_index
do
|
id
,
index
|
pairs
<<
id
pairs
<<
index
+
1
end
conditions
=
'WHEN id = ? THEN ? '
*
ids
.
length
issues
.
where
(
id:
ids
).
update_all
([
"position = CASE
#{
conditions
}
ELSE position END"
,
*
pairs
])
end
end
end
app/models/note.rb
View file @
d37cf642
...
@@ -22,14 +22,14 @@ require 'carrierwave/orm/activerecord'
...
@@ -22,14 +22,14 @@ require 'carrierwave/orm/activerecord'
require
'file_size_validator'
require
'file_size_validator'
class
Note
<
ActiveRecord
::
Base
class
Note
<
ActiveRecord
::
Base
include
Mentionable
include
Gitlab
::
CurrentSettings
include
Gitlab
::
CurrentSettings
include
Participable
include
Participable
include
Mentionable
default_value_for
:system
,
false
default_value_for
:system
,
false
attr_mentionable
:note
attr_mentionable
:note
participant
:author
,
:mentioned_users
participant
:author
belongs_to
:project
belongs_to
:project
belongs_to
:noteable
,
polymorphic:
true
belongs_to
:noteable
,
polymorphic:
true
...
...
app/models/repository.rb
View file @
d37cf642
...
@@ -8,6 +8,14 @@ class Repository
...
@@ -8,6 +8,14 @@ class Repository
attr_accessor
:raw_repository
,
:path_with_namespace
,
:project
attr_accessor
:raw_repository
,
:path_with_namespace
,
:project
def
self
.
clean_old_archives
repository_downloads_path
=
Gitlab
.
config
.
gitlab
.
repository_downloads_path
return
unless
File
.
directory?
(
repository_downloads_path
)
Gitlab
::
Popen
.
popen
(
%W(find
#{
repository_downloads_path
}
-not -path
#{
repository_downloads_path
}
-mmin +120 -delete)
)
end
def
initialize
(
path_with_namespace
,
default_branch
=
nil
,
project
=
nil
)
def
initialize
(
path_with_namespace
,
default_branch
=
nil
,
project
=
nil
)
@path_with_namespace
=
path_with_namespace
@path_with_namespace
=
path_with_namespace
@project
=
project
@project
=
project
...
@@ -269,14 +277,6 @@ class Repository
...
@@ -269,14 +277,6 @@ class Repository
end
end
# Remove archives older than 2 hours
# Remove archives older than 2 hours
def
clean_old_archives
repository_downloads_path
=
Gitlab
.
config
.
gitlab
.
repository_downloads_path
return
unless
File
.
directory?
(
repository_downloads_path
)
Gitlab
::
Popen
.
popen
(
%W(find
#{
repository_downloads_path
}
-not -path
#{
repository_downloads_path
}
-mmin +120 -delete)
)
end
def
branches_sorted_by
(
value
)
def
branches_sorted_by
(
value
)
case
value
case
value
when
'recently_updated'
when
'recently_updated'
...
@@ -312,13 +312,7 @@ class Repository
...
@@ -312,13 +312,7 @@ class Repository
end
end
def
blob_for_diff
(
commit
,
diff
)
def
blob_for_diff
(
commit
,
diff
)
file
=
blob_at
(
commit
.
id
,
diff
.
new_path
)
blob_at
(
commit
.
id
,
diff
.
file_path
)
unless
file
file
=
prev_blob_for_diff
(
commit
,
diff
)
end
file
end
end
def
prev_blob_for_diff
(
commit
,
diff
)
def
prev_blob_for_diff
(
commit
,
diff
)
...
...
app/models/user.rb
View file @
d37cf642
...
@@ -183,7 +183,7 @@ class User < ActiveRecord::Base
...
@@ -183,7 +183,7 @@ class User < ActiveRecord::Base
# User's Project preference
# User's Project preference
# Note: When adding an option, it MUST go on the end of the array.
# Note: When adding an option, it MUST go on the end of the array.
enum
project_view:
[
:readme
,
:activity
]
enum
project_view:
[
:readme
,
:activity
,
:files
]
alias_attribute
:private_token
,
:authentication_token
alias_attribute
:private_token
,
:authentication_token
...
@@ -706,12 +706,15 @@ class User < ActiveRecord::Base
...
@@ -706,12 +706,15 @@ class User < ActiveRecord::Base
end
end
def
toggle_star
(
project
)
def
toggle_star
(
project
)
user_star_project
=
users_star_projects
.
UsersStarProject
.
transaction
do
where
(
project:
project
,
user:
self
).
take
user_star_project
=
users_star_projects
.
if
user_star_project
where
(
project:
project
,
user:
self
).
lock
(
true
).
first
user_star_project
.
destroy
else
if
user_star_project
UsersStarProject
.
create!
(
project:
project
,
user:
self
)
user_star_project
.
destroy
else
UsersStarProject
.
create!
(
project:
project
,
user:
self
)
end
end
end
end
end
...
...
app/services/archive_repository_service.rb
View file @
d37cf642
...
@@ -7,7 +7,7 @@ class ArchiveRepositoryService
...
@@ -7,7 +7,7 @@ class ArchiveRepositoryService
end
end
def
execute
(
options
=
{})
def
execute
(
options
=
{})
project
.
repository
.
clean_old_archives
RepositoryArchiveCacheWorker
.
perform_async
metadata
=
project
.
repository
.
archive_metadata
(
ref
,
storage_path
,
format
)
metadata
=
project
.
repository
.
archive_metadata
(
ref
,
storage_path
,
format
)
raise
"Repository or ref not found"
if
metadata
.
empty?
raise
"Repository or ref not found"
if
metadata
.
empty?
...
...
app/services/git_push_service.rb
View file @
d37cf642
...
@@ -79,7 +79,7 @@ class GitPushService
...
@@ -79,7 +79,7 @@ class GitPushService
authors
=
Hash
.
new
do
|
hash
,
commit
|
authors
=
Hash
.
new
do
|
hash
,
commit
|
email
=
commit
.
author_email
email
=
commit
.
author_email
return
hash
[
email
]
if
hash
.
has_key?
(
email
)
next
hash
[
email
]
if
hash
.
has_key?
(
email
)
hash
[
email
]
=
commit_user
(
commit
)
hash
[
email
]
=
commit_user
(
commit
)
end
end
...
...
app/services/merge_requests/post_merge_service.rb
View file @
d37cf642
...
@@ -6,6 +6,7 @@ module MergeRequests
...
@@ -6,6 +6,7 @@ module MergeRequests
#
#
class
PostMergeService
<
MergeRequests
::
BaseService
class
PostMergeService
<
MergeRequests
::
BaseService
def
execute
(
merge_request
)
def
execute
(
merge_request
)
close_issues
(
merge_request
)
merge_request
.
mark_as_merged
merge_request
.
mark_as_merged
create_merge_event
(
merge_request
,
current_user
)
create_merge_event
(
merge_request
,
current_user
)
create_note
(
merge_request
)
create_note
(
merge_request
)
...
@@ -15,6 +16,15 @@ module MergeRequests
...
@@ -15,6 +16,15 @@ module MergeRequests
private
private
def
close_issues
(
merge_request
)
return
unless
merge_request
.
target_branch
==
project
.
default_branch
closed_issues
=
merge_request
.
closes_issues
(
current_user
)
closed_issues
.
each
do
|
issue
|
Issues
::
CloseService
.
new
(
project
,
current_user
,
{}).
execute
(
issue
,
merge_request
)
end
end
def
create_merge_event
(
merge_request
,
current_user
)
def
create_merge_event
(
merge_request
,
current_user
)
EventCreateService
.
new
.
merge_mr
(
merge_request
,
current_user
)
EventCreateService
.
new
.
merge_mr
(
merge_request
,
current_user
)
end
end
...
...
app/views/abuse_report_mailer/notify.html.haml
0 → 100644
View file @
d37cf642
%p
#{
link_to
@abuse_report
.
user
.
name
,
user_url
(
@abuse_report
.
user
)
}
(@
#{
@abuse_report
.
user
.
username
}
) was reported for abuse by
#{
link_to
@abuse_report
.
reporter
.
name
,
user_url
(
@abuse_report
.
reporter
)
}
(@
#{
@abuse_report
.
reporter
.
username
}
).
%blockquote
=
@abuse_report
.
message
%p
=
link_to
"View details"
,
abuse_reports_url
app/views/abuse_report_mailer/notify.text.haml
0 → 100644
View file @
d37cf642
#{
@abuse_report
.
user
.
name
}
(@
#{
@abuse_report
.
user
.
username
}
) was reported for abuse by
#{
@abuse_report
.
reporter
.
name
}
(@
#{
@abuse_report
.
reporter
.
username
}
).
\
>
#{
@abuse_report
.
message
}
\
View details:
#{
admin_abuse_reports_url
}
app/views/admin/application_settings/_form.html.haml
View file @
d37cf642
...
@@ -47,6 +47,12 @@
...
@@ -47,6 +47,12 @@
=
f
.
label
:version_check_enabled
do
=
f
.
label
:version_check_enabled
do
=
f
.
check_box
:version_check_enabled
=
f
.
check_box
:version_check_enabled
Version check enabled
Version check enabled
.form-group
=
f
.
label
:admin_notification_email
,
class:
'control-label col-sm-2'
.col-sm-10
=
f
.
text_field
:admin_notification_email
,
class:
'form-control'
.help-block
Abuse reports will be sent to this address if it is set. Abuse reports are always available in the admin area.
%fieldset
%fieldset
%legend
Account and Limit Settings
%legend
Account and Limit Settings
...
...
app/views/users/_profile.html.haml
→
app/views/
admin/
users/_profile.html.haml
View file @
d37cf642
File moved
app/views/admin/users/show.html.haml
View file @
d37cf642
...
@@ -14,7 +14,7 @@
...
@@ -14,7 +14,7 @@
%strong
%strong
=
link_to
user_path
(
@user
)
do
=
link_to
user_path
(
@user
)
do
=
@user
.
username
=
@user
.
username
=
render
'users/profile'
,
user:
@user
=
render
'
admin/
users/profile'
,
user:
@user
.panel.panel-default
.panel.panel-default
.panel-heading
.panel-heading
...
...
app/views/ci/projects/index.html.haml
0 → 100644
View file @
d37cf642
.wiki
%h1
GitLab CI is now integrated in GitLab UI
%h2
For existing projects
%p
Check the following pages to find the CI status you're looking for:
%ul
%li
Projects page - shows CI status for each project.
%li
Project commits page - show CI status for each commit.
%h2
For new projects
%p
If you want to enable CI for a new project it is easy as adding
=
link_to
".gitlab-ci.yml"
,
"http://doc.gitlab.com/ce/ci/yaml/README.html"
file to your repository
app/views/events/_event_issue.atom.haml
View file @
d37cf642
%div
{
xmlns:
"http://www.w3.org/1999/xhtml"
}
%div
{
xmlns:
"http://www.w3.org/1999/xhtml"
}
-
if
issue
.
description
.
present?
=
markdown
(
issue
.
description
,
pipeline: :atom
,
project:
issue
.
project
)
=
markdown
(
issue
.
description
,
xhtml:
true
,
reference_only_path:
false
,
project:
issue
.
project
)
app/views/events/_event_merge_request.atom.haml
View file @
d37cf642
%div
{
xmlns:
"http://www.w3.org/1999/xhtml"
}
%div
{
xmlns:
"http://www.w3.org/1999/xhtml"
}
-
if
merge_request
.
description
.
present?
=
markdown
(
merge_request
.
description
,
pipeline: :atom
,
project:
merge_request
.
project
)
=
markdown
(
merge_request
.
description
,
xhtml:
true
,
reference_only_path:
false
,
project:
merge_request
.
project
)
app/views/events/_event_note.atom.haml
View file @
d37cf642
%div
{
xmlns:
"http://www.w3.org/1999/xhtml"
}
%div
{
xmlns:
"http://www.w3.org/1999/xhtml"
}
=
markdown
(
note
.
note
,
xhtml:
true
,
reference_only_path:
false
,
project:
note
.
project
)
=
markdown
(
note
.
note
,
pipeline: :atom
,
project:
note
.
project
)
app/views/events/_event_push.atom.haml
View file @
d37cf642
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
%i
%i
at
at
=
commit
[
:timestamp
].
to_time
.
to_s
(
:short
)
=
commit
[
:timestamp
].
to_time
.
to_s
(
:short
)
%blockquote
=
markdown
(
escape_once
(
commit
[
:message
]),
xhtml:
true
,
reference_only_path:
false
,
project:
event
.
project
)
%blockquote
=
markdown
(
escape_once
(
commit
[
:message
]),
pipeline: :atom
,
project:
event
.
project
)
-
if
event
.
commits_count
>
15
-
if
event
.
commits_count
>
15
%p
%p
%i
%i
...
...
app/views/layouts/notify.html.haml
View file @
d37cf642
...
@@ -41,4 +41,8 @@
...
@@ -41,4 +41,8 @@
#{
link_to
"view it on GitLab"
,
@target_url
}
.
#{
link_to
"view it on GitLab"
,
@target_url
}
.
-
else
-
else
#{
link_to
"View it on GitLab"
,
@target_url
}
#{
link_to
"View it on GitLab"
,
@target_url
}
%br
You're receiving this email because of your account on
#{
link_to
Gitlab
.
config
.
gitlab
.
host
,
root_url
}
.
If you'd like to receive fewer emails, you can adjust your notification settings.
=
email_action
@target_url
=
email_action
@target_url
app/views/notify/_note_message.html.haml
View file @
d37cf642
%div
%div
=
markdown
(
@note
.
note
,
reference_only_path:
false
)
=
markdown
(
@note
.
note
,
pipeline: :email
)
app/views/notify/new_issue_email.html.haml
View file @
d37cf642
-
if
@issue
.
description
-
if
@issue
.
description
=
markdown
(
@issue
.
description
,
reference_only_path:
false
)
=
markdown
(
@issue
.
description
,
pipeline: :email
)
-
if
@issue
.
assignee_id
.
present?
-
if
@issue
.
assignee_id
.
present?
%p
%p
...
...
app/views/notify/new_merge_request_email.html.haml
View file @
d37cf642
...
@@ -6,4 +6,4 @@
...
@@ -6,4 +6,4 @@
Assignee:
#{
@merge_request
.
author_name
}
→
#{
@merge_request
.
assignee_name
}
Assignee:
#{
@merge_request
.
author_name
}
→
#{
@merge_request
.
assignee_name
}
-
if
@merge_request
.
description
-
if
@merge_request
.
description
=
markdown
(
@merge_request
.
description
,
reference_only_path:
false
)
=
markdown
(
@merge_request
.
description
,
pipeline: :email
)
app/views/profiles/preferences/show.html.haml
View file @
d37cf642
...
@@ -38,7 +38,7 @@
...
@@ -38,7 +38,7 @@
.col-sm-10
.col-sm-10
=
f
.
select
:layout
,
layout_choices
,
{},
class:
'form-control'
=
f
.
select
:layout
,
layout_choices
,
{},
class:
'form-control'
.help-block
.help-block
Choose between fixed (max. 1200px) and fluid (100%) application layout
Choose between fixed (max. 1200px) and fluid (100%) application layout
.
.form-group
.form-group
=
f
.
label
:dashboard
,
class:
'control-label'
do
=
f
.
label
:dashboard
,
class:
'control-label'
do
Default Dashboard
Default Dashboard
...
@@ -52,6 +52,6 @@
...
@@ -52,6 +52,6 @@
.col-sm-10
.col-sm-10
=
f
.
select
:project_view
,
project_view_choices
,
{},
class:
'form-control'
=
f
.
select
:project_view
,
project_view_choices
,
{},
class:
'form-control'
.help-block
.help-block
Choose what content you want to see
when visit project page
Choose what content you want to see
on a project's home page.
.panel-footer
.panel-footer
=
f
.
submit
'Save'
,
class:
'btn btn-save'
=
f
.
submit
'Save'
,
class:
'btn btn-save'
app/views/projects/_activity.html.haml
View file @
d37cf642
=
render
'projects/last_push'
.gray-content-block.activity-filter-block
.gray-content-block.activity-filter-block
-
if
current_user
-
if
current_user
.pull-right
.pull-right
...
...
app/views/projects/_files.html.haml
0 → 100644
View file @
d37cf642
#tree-holder
.tree-holder.clearfix
.gray-content-block.second-block
=
render
'projects/tree/tree_header'
,
tree:
@tree
=
render
'projects/tree/tree_content'
,
tree:
@tree
app/views/projects/_readme.html.haml
View file @
d37cf642
-
if
readme
=
@repository
.
readme
-
if
readme
=
@repository
.
readme
%article
.readme-holder
#README
%article
.file-holder.readme-holder
.clearfix
.file-title
.pull-right
=
blob_icon
readme
.
mode
,
readme
.
name
=
link_to
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
tree_join
(
@repository
.
root_ref
,
readme
.
name
))
do
-
if
can?
(
current_user
,
:push_code
,
@project
)
%strong
=
link_to
namespace_project_edit_blob_path
(
@project
.
namespace
,
@project
,
tree_join
(
@repository
.
root_ref
,
readme
.
name
)),
class:
'light'
do
=
readme
.
name
%i
.fa-align.fa.fa-pencil
.file-content.wiki
.wiki
=
cache
(
readme_cache_key
)
do
=
cache
(
readme_cache_key
)
do
=
render_readme
(
readme
)
=
render_readme
(
readme
)
-
else
-
else
...
...
app/views/projects/activity.html.haml
View file @
d37cf642
-
page_title
"Activity"
-
page_title
"Activity"
-
header_title
project_title
(
@project
,
"Activity"
,
activity_project_path
(
@project
))
-
header_title
project_title
(
@project
,
"Activity"
,
activity_project_path
(
@project
))
=
render
'projects/last_push'
=
render
'projects/activity'
=
render
'projects/activity'
app/views/projects/blob/_blob.html.haml
View file @
d37cf642
%ul
.breadcrumb.repo-breadcrumb
.gray-content-block.top-block
%li
.tree-ref-holder
%i
.fa.fa-angle-right
=
render
'shared/ref_switcher'
,
destination:
'blob'
,
path:
@path
=
link_to
namespace_project_tree_path
(
@project
.
namespace
,
@project
,
@ref
)
do
=
@project
.
path
%ul
.breadcrumb.repo-breadcrumb
-
tree_breadcrumbs
(
@tree
,
6
)
do
|
title
,
path
|
%li
%li
-
if
path
=
link_to
namespace_project_tree_path
(
@project
.
namespace
,
@project
,
@ref
)
do
-
if
path
.
end_with?
(
@path
)
=
@project
.
path
=
link_to
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
path
)
do
-
tree_breadcrumbs
(
@tree
,
6
)
do
|
title
,
path
|
%strong
%li
=
truncate
(
title
,
length:
40
)
-
if
path
-
if
path
.
end_with?
(
@path
)
=
link_to
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
path
)
do
%strong
=
truncate
(
title
,
length:
40
)
-
else
=
link_to
truncate
(
title
,
length:
40
),
namespace_project_tree_path
(
@project
.
namespace
,
@project
,
path
)
-
else
-
else
=
link_to
truncate
(
title
,
length:
40
),
namespace_project_tree_path
(
@project
.
namespace
,
@project
,
path
)
=
link_to
title
,
'#'
-
else
=
link_to
title
,
'#'
%ul
.blob-commit-info.hidden-xs
%ul
.blob-commit-info.hidden-xs
-
blob_commit
=
@repository
.
last_commit_for_path
(
@commit
.
id
,
blob
.
path
)
-
blob_commit
=
@repository
.
last_commit_for_path
(
@commit
.
id
,
blob
.
path
)
...
...
app/views/projects/blob/show.html.haml
View file @
d37cf642
...
@@ -3,9 +3,6 @@
...
@@ -3,9 +3,6 @@
=
render
'projects/last_push'
=
render
'projects/last_push'
%div
.tree-ref-holder
=
render
'shared/ref_switcher'
,
destination:
'blob'
,
path:
@path
%div
#tree-holder
.tree-holder
%div
#tree-holder
.tree-holder
=
render
'blob'
,
blob:
@blob
=
render
'blob'
,
blob:
@blob
...
...
app/views/projects/buttons/_notifications.html.haml
View file @
d37cf642
-
return
unless
@membership
-
case
@membership
-
when
ProjectMember
=
form_tag
profile_notifications_path
,
method: :put
,
remote:
true
,
class:
'inline'
,
id:
'notification-form'
do
=
hidden_field_tag
:notification_type
,
'project'
=
hidden_field_tag
:notification_id
,
@membership
.
id
=
hidden_field_tag
:notification_level
%span
.dropdown
%a
.dropdown-new.btn.btn-new
#notifications-button
{
href:
'#'
,
"data-toggle"
=>
"dropdown"
}
=
icon
(
'bell'
)
=
notification_label
(
@membership
)
=
icon
(
'angle-down'
)
%ul
.dropdown-menu.dropdown-menu-right.project-home-dropdown
-
Notification
.
project_notification_levels
.
each
do
|
level
|
=
notification_list_item
(
level
,
@membership
)
=
form_tag
profile_notifications_path
,
method: :put
,
remote:
true
,
class:
'inline'
,
id:
'notification-form'
do
-
when
GroupMember
=
hidden_field_tag
:notification_type
,
'project'
.btn.btn-new.disabled.has_tooltip
{
title:
"To change the notification level, you need to be a member of the project itself, not only its group."
}
=
hidden_field_tag
:notification_id
,
@membership
.
id
=
icon
(
'bell'
)
=
hidden_field_tag
:notification_level
=
notification_label
(
@membership
)
%span
.dropdown
=
icon
(
'angle-down'
)
%a
.dropdown-new.btn.btn-new
#notifications-button
{
href:
'#'
,
"data-toggle"
=>
"dropdown"
}
=
icon
(
'bell'
)
=
notification_label
(
@membership
)
=
icon
(
'angle-down'
)
%ul
.dropdown-menu.dropdown-menu-right.project-home-dropdown
-
Notification
.
project_notification_levels
.
each
do
|
level
|
=
notification_list_item
(
level
,
@membership
)
app/views/projects/ci_services/index.html.haml
View file @
d37cf642
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
%tr
%tr
%th
%th
%th
Service
%th
Service
%th
Desription
%th
Des
c
ription
%th
Last edit
%th
Last edit
-
@services
.
sort_by
(
&
:title
).
each
do
|
service
|
-
@services
.
sort_by
(
&
:title
).
each
do
|
service
|
%tr
%tr
...
...
app/views/projects/diffs/_diffs.html.haml
View file @
d37cf642
...
@@ -15,8 +15,8 @@
...
@@ -15,8 +15,8 @@
.files
.files
-
diff_files
.
each_with_index
do
|
diff_file
,
index
|
-
diff_files
.
each_with_index
do
|
diff_file
,
index
|
-
diff_commit
=
commit_for_diff
(
diff_file
.
diff
)
-
diff_commit
=
commit_for_diff
(
diff_file
)
-
blob
=
project
.
repository
.
blob_for_diff
(
diff_commit
,
diff_file
.
diff
)
-
blob
=
project
.
repository
.
blob_for_diff
(
diff_commit
,
diff_file
)
-
next
unless
blob
-
next
unless
blob
=
render
'projects/diffs/file'
,
i:
index
,
project:
project
,
=
render
'projects/diffs/file'
,
i:
index
,
project:
project
,
...
...
app/views/projects/diffs/_file.html.haml
View file @
d37cf642
.diff-file
{
id:
"diff-#{i}"
,
data:
diff_file_html_data
(
project
,
diff_commit
,
diff_file
)}
.diff-file
{
id:
"diff-#{i}"
,
data:
diff_file_html_data
(
project
,
diff_commit
,
diff_file
)}
.diff-header
{
id:
"file-path-#{hexdigest(diff_file.
new_path || diff_file.old
_path)}"
}
.diff-header
{
id:
"file-path-#{hexdigest(diff_file.
file
_path)}"
}
-
if
diff_file
.
diff
.
submodule?
-
if
diff_file
.
diff
.
submodule?
%span
%span
-
submodule_item
=
project
.
repository
.
blob_at
(
@commit
.
id
,
diff_file
.
file_path
)
-
submodule_item
=
project
.
repository
.
blob_at
(
@commit
.
id
,
diff_file
.
file_path
)
...
@@ -38,7 +38,7 @@
...
@@ -38,7 +38,7 @@
-
else
-
else
=
render
"projects/diffs/text_file"
,
diff_file:
diff_file
,
index:
i
=
render
"projects/diffs/text_file"
,
diff_file:
diff_file
,
index:
i
-
elsif
blob
.
image?
-
elsif
blob
.
image?
-
old_file
=
project
.
repository
.
prev_blob_for_diff
(
@
commit
,
diff_file
)
-
old_file
=
project
.
repository
.
prev_blob_for_diff
(
diff_
commit
,
diff_file
)
=
render
"projects/diffs/image"
,
diff_file:
diff_file
,
old_file:
old_file
,
file:
blob
,
index:
i
=
render
"projects/diffs/image"
,
diff_file:
diff_file
,
old_file:
old_file
,
file:
blob
,
index:
i
-
else
-
else
.nothing-here-block
No preview for this file type
.nothing-here-block
No preview for this file type
...
...
app/views/projects/edit.html.haml
View file @
d37cf642
...
@@ -189,6 +189,21 @@
...
@@ -189,6 +189,21 @@
-
else
-
else
.nothing-here-block
Only the project owner can transfer a project
.nothing-here-block
Only the project owner can transfer a project
-
if
@project
.
forked?
-
if
can?
(
current_user
,
:remove_fork_project
,
@project
)
=
form_for
([
@project
.
namespace
.
becomes
(
Namespace
),
@project
],
url:
remove_fork_namespace_project_path
(
@project
.
namespace
,
@project
),
method: :delete
,
remote:
true
,
html:
{
class:
'transfer-project form-horizontal'
})
do
|
f
|
.panel.panel-default.panel.panel-danger
.panel-heading
Remove fork relationship
.panel-body
%p
This will remove the fork relationship to source project
#{
link_to
@project
.
forked_from_project
.
name_with_namespace
,
project_path
(
@project
.
forked_from_project
)
}
.
%br
%strong
Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source.
=
button_to
'Remove fork relationship'
,
'#'
,
class:
"btn btn-remove js-confirm-danger"
,
data:
{
"confirm-danger-message"
=>
remove_fork_project_message
(
@project
)
}
-
else
.nothing-here-block
Only the project owner can remove the fork relationship.
-
if
can?
(
current_user
,
:remove_project
,
@project
)
-
if
can?
(
current_user
,
:remove_project
,
@project
)
.panel.panel-default.panel.panel-danger
.panel.panel-default.panel.panel-danger
.panel-heading
Remove project
.panel-heading
Remove project
...
@@ -201,7 +216,8 @@
...
@@ -201,7 +216,8 @@
=
button_to
'Remove project'
,
'#'
,
class:
"btn btn-remove js-confirm-danger"
,
data:
{
"confirm-danger-message"
=>
remove_project_message
(
@project
)
}
=
button_to
'Remove project'
,
'#'
,
class:
"btn btn-remove js-confirm-danger"
,
data:
{
"confirm-danger-message"
=>
remove_project_message
(
@project
)
}
-
else
-
else
.nothing-here-block
Only project owner can remove a project
.nothing-here-block
Only the project owner can remove a project.
.save-project-loader.hide
.save-project-loader.hide
.center
.center
...
...
app/views/projects/issues/_closed_by_box.html.haml
0 → 100644
View file @
d37cf642
.issue-closed-by-widget
=
icon
(
'check'
)
This issue will be closed automatically when merge request
#{
gfm
(
merge_requests_sentence
(
@closed_by_merge_requests
.
sort
))
}
is accepted.
app/views/projects/issues/show.html.haml
View file @
d37cf642
...
@@ -46,6 +46,7 @@
...
@@ -46,6 +46,7 @@
=
markdown
(
@issue
.
description
)
=
markdown
(
@issue
.
description
)
%textarea
.hidden.js-task-list-field
%textarea
.hidden.js-task-list-field
=
@issue
.
description
=
@issue
.
description
-
if
@closed_by_merge_requests
.
present?
=
render
'projects/issues/closed_by_box'
.issue-discussion
.issue-discussion
=
render
'projects/issues/discussion'
=
render
'projects/issues/discussion'
app/views/projects/merge_requests/widget/_heading.html.haml
View file @
d37cf642
-
if
@merge_request
.
has_ci?
-
ci_commit
=
@merge_request
.
source_project
.
ci_commit
(
@merge_request
.
source_sha
)
-
ci_commit
=
@merge_request
.
source_project
.
ci_commit
(
@merge_request
.
source_sha
)
-
if
ci_commit
-
if
ci_commit
-
status
=
ci_commit
.
status
-
status
=
ci_commit
.
status
.mr-widget-heading
.mr-widget-heading
.ci_widget
{
class:
"ci-#{status}"
}
.ci_widget
{
class:
"ci-#{status}"
}
=
ci_status_icon
(
ci_commit
)
=
ci_status_icon
(
ci_commit
)
%span
CI build
#{
status
}
for
#{
@merge_request
.
last_commit_short_sha
}
.
%span
.ci-coverage
=
link_to
"View build details"
,
ci_status_path
(
ci_commit
)
-
elsif
@merge_request
.
has_ci?
-
# Compatibility with old CI integrations (ex jenkins) when you request status from CI server via AJAX
-
# Remove in later versions when services like Jenkins will set CI status via Commit status API
.mr-widget-heading
-
[
:success
,
:skipped
,
:canceled
,
:failed
,
:running
,
:pending
].
each
do
|
status
|
.ci_widget
{
class:
"ci-#{status}"
,
style:
"display:none"
}
-
if
status
==
:success
-
status
=
"passed"
=
icon
(
"check-circle"
)
-
else
=
icon
(
"circle"
)
%span
CI build
#{
status
}
%span
CI build
#{
status
}
for
#{
@merge_request
.
last_commit_short_sha
}
.
for
#{
@merge_request
.
last_commit_short_sha
}
.
%span
.ci-coverage
%span
.ci-coverage
=
link_to
"View build details"
,
ci_status_path
(
ci_commit
)
-
if
ci_build_details_path
(
@merge_request
)
=
link_to
"View build details"
,
ci_build_details_path
(
@merge_request
),
:"data-no-turbolink"
=>
"data-no-turbolink"
-
else
-
# Compatibility with old CI integrations (ex jenkins) when you request status from CI server via AJAX
-
# Remove in later versions when services like Jenkins will set CI status via Commit status API
.mr-widget-heading
-
[
:success
,
:skipped
,
:canceled
,
:failed
,
:running
,
:pending
].
each
do
|
status
|
.ci_widget
{
class:
"ci-#{status}"
,
style:
"display:none"
}
-
if
status
==
:success
-
status
=
"passed"
=
icon
(
"check-circle"
)
-
else
=
icon
(
"circle"
)
%span
CI build
#{
status
}
for
#{
@merge_request
.
last_commit_short_sha
}
.
%span
.ci-coverage
-
if
ci_build_details_path
(
@merge_request
)
=
link_to
"View build details"
,
ci_build_details_path
(
@merge_request
),
:"data-no-turbolink"
=>
"data-no-turbolink"
.ci_widget
.ci_widget
=
icon
(
"spinner spin"
)
=
icon
(
"spinner spin"
)
Checking CI status for
#{
@merge_request
.
last_commit_short_sha
}
…
Checking CI status for
#{
@merge_request
.
last_commit_short_sha
}
…
.ci_widget.ci-not_found
{
style:
"display:none"
}
.ci_widget.ci-not_found
{
style:
"display:none"
}
=
icon
(
"times-circle"
)
=
icon
(
"times-circle"
)
Could not find CI status for
#{
@merge_request
.
last_commit_short_sha
}
.
Could not find CI status for
#{
@merge_request
.
last_commit_short_sha
}
.
.ci_widget.ci-error
{
style:
"display:none"
}
.ci_widget.ci-error
{
style:
"display:none"
}
=
icon
(
"times-circle"
)
=
icon
(
"times-circle"
)
Could not connect to the CI server. Please check your settings and try again.
Could not connect to the CI server. Please check your settings and try again.
:coffeescript
:coffeescript
$ ->
$ ->
merge_request_widget.getCiStatus()
merge_request_widget.getCiStatus()
app/views/projects/remove_fork.js.haml
0 → 100644
View file @
d37cf642
:plain
location.href = "
#{
edit_namespace_project_path
(
@project
.
namespace
,
@project
)
}
";
app/views/projects/show.html.haml
View file @
d37cf642
...
@@ -7,8 +7,7 @@
...
@@ -7,8 +7,7 @@
=
render
'shared/no_ssh'
=
render
'shared/no_ssh'
=
render
'shared/no_password'
=
render
'shared/no_password'
-
if
prefer_readme?
=
render
'projects/last_push'
=
render
'projects/last_push'
=
render
"home_panel"
=
render
"home_panel"
...
@@ -28,7 +27,7 @@
...
@@ -28,7 +27,7 @@
=
link_to
project_files_path
(
@project
)
do
=
link_to
project_files_path
(
@project
)
do
=
repository_size
=
repository_size
-
if
!
prefer_readme?
&&
@repository
.
readme
-
if
default_project_view
!=
'readme'
&&
@repository
.
readme
%li
%li
=
link_to
'Readme'
,
readme_path
(
@project
)
=
link_to
'Readme'
,
readme_path
(
@project
)
...
@@ -68,14 +67,8 @@
...
@@ -68,14 +67,8 @@
.content-block.second-block.white
.content-block.second-block.white
=
render
'projects/last_commit'
,
commit:
@repository
.
commit
,
project:
@project
=
render
'projects/last_commit'
,
commit:
@repository
.
commit
,
project:
@project
%section
%div
{
class:
"project-show-#{default_project_view}"
}
-
if
prefer_readme?
=
render
default_project_view
.project-show-readme
=
render
'projects/readme'
-
else
.project-show-activity
=
render
'projects/activity'
-
if
current_user
-
if
current_user
-
access
=
user_max_access_in_project
(
current_user
,
@project
)
-
access
=
user_max_access_in_project
(
current_user
,
@project
)
...
...
app/views/projects/tree/_blob_item.html.haml
View file @
d37cf642
...
@@ -4,5 +4,5 @@
...
@@ -4,5 +4,5 @@
%span
.str-truncated
%span
.str-truncated
=
link_to
blob_item
.
name
,
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
tree_join
(
@id
||
@commit
.
id
,
blob_item
.
name
))
=
link_to
blob_item
.
name
,
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
tree_join
(
@id
||
@commit
.
id
,
blob_item
.
name
))
%td
.tree_time_ago.cgray
%td
.tree_time_ago.cgray
=
render
'spinner'
=
render
'
projects/tree/
spinner'
%td
.hidden-xs.tree_commit
%td
.hidden-xs.tree_commit
app/views/projects/tree/_readme.html.haml
View file @
d37cf642
%article
.file-holder.readme-holder
#README
%article
.file-holder.readme-holder
.file-title
.file-title
=
link_to
'#README'
do
=
blob_icon
readme
.
mode
,
readme
.
name
=
link_to
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
tree_join
(
@repository
.
root_ref
,
readme
.
name
))
do
%strong
%strong
%i
.fa.fa-file
=
readme
.
name
=
readme
.
name
.file-content.wiki
.file-content.wiki
=
render_readme
(
readme
)
=
render_readme
(
readme
)
app/views/projects/tree/_tree.html.haml
→
app/views/projects/tree/_tree
_content
.html.haml
View file @
d37cf642
.gray-content-block
%div
.tree-content-holder
%ul
.breadcrumb.repo-breadcrumb
%li
=
link_to
namespace_project_tree_path
(
@project
.
namespace
,
@project
,
@ref
)
do
=
@project
.
path
-
tree_breadcrumbs
(
tree
,
6
)
do
|
title
,
path
|
%li
-
if
path
=
link_to
truncate
(
title
,
length:
40
),
namespace_project_tree_path
(
@project
.
namespace
,
@project
,
path
)
-
else
=
link_to
title
,
'#'
-
if
allowed_tree_edit?
%li
%span
.dropdown
%a
.dropdown-toggle.btn.add-to-tree
{
href:
'#'
,
"data-toggle"
=>
"dropdown"
}
=
icon
(
'plus'
)
%ul
.dropdown-menu
%li
=
link_to
namespace_project_new_blob_path
(
@project
.
namespace
,
@project
,
@id
),
title:
'Create file'
,
id:
'new-file-link'
do
=
icon
(
'pencil fw'
)
Create file
%li
=
link_to
'#modal-upload-blob'
,
{
'data-target'
=>
'#modal-upload-blob'
,
'data-toggle'
=>
'modal'
}
do
=
icon
(
'file fw'
)
Upload file
%li
.divider
%li
=
link_to
'#modal-create-new-dir'
,
{
'data-target'
=>
'#modal-create-new-dir'
,
'data-toggle'
=>
'modal'
}
do
=
icon
(
'folder fw'
)
New directory
%div
#tree-content-holder
.tree-content-holder
.tree-table-holder
.tree-table-holder
%table
.table
#tree-slider
{
class:
"table_#{@hex_path} tree-table table-striped"
}
%table
.table
#tree-slider
{
class:
"table_#{@hex_path} tree-table table-striped"
}
%thead
%thead
...
@@ -60,8 +29,6 @@
...
@@ -60,8 +29,6 @@
-
if
tree
.
readme
-
if
tree
.
readme
=
render
"projects/tree/readme"
,
readme:
tree
.
readme
=
render
"projects/tree/readme"
,
readme:
tree
.
readme
%div
.tree_progress
-
if
allowed_tree_edit?
-
if
allowed_tree_edit?
=
render
'projects/blob/upload'
,
title:
'Upload'
,
placeholder:
'Upload new file'
,
button_title:
'Upload file'
,
form_path:
namespace_project_create_blob_path
(
@project
.
namespace
,
@project
,
@id
),
method: :post
=
render
'projects/blob/upload'
,
title:
'Upload'
,
placeholder:
'Upload new file'
,
button_title:
'Upload file'
,
form_path:
namespace_project_create_blob_path
(
@project
.
namespace
,
@project
,
@id
),
method: :post
=
render
'projects/blob/new_dir'
=
render
'projects/blob/new_dir'
...
...
app/views/projects/tree/_tree_header.html.haml
0 → 100644
View file @
d37cf642
.tree-ref-holder
=
render
'shared/ref_switcher'
,
destination:
'tree'
,
path:
@path
%ul
.breadcrumb.repo-breadcrumb
%li
=
link_to
namespace_project_tree_path
(
@project
.
namespace
,
@project
,
@ref
)
do
=
@project
.
path
-
tree_breadcrumbs
(
tree
,
6
)
do
|
title
,
path
|
%li
-
if
path
=
link_to
truncate
(
title
,
length:
40
),
namespace_project_tree_path
(
@project
.
namespace
,
@project
,
path
)
-
else
=
link_to
title
,
'#'
-
if
allowed_tree_edit?
%li
%span
.dropdown
%a
.dropdown-toggle.btn.add-to-tree
{
href:
'#'
,
"data-toggle"
=>
"dropdown"
}
=
icon
(
'plus'
)
%ul
.dropdown-menu
%li
=
link_to
namespace_project_new_blob_path
(
@project
.
namespace
,
@project
,
@id
),
title:
'Create file'
,
id:
'new-file-link'
do
=
icon
(
'pencil fw'
)
Create file
%li
=
link_to
'#modal-upload-blob'
,
{
'data-target'
=>
'#modal-upload-blob'
,
'data-toggle'
=>
'modal'
}
do
=
icon
(
'file fw'
)
Upload file
%li
.divider
%li
=
link_to
'#modal-create-new-dir'
,
{
'data-target'
=>
'#modal-create-new-dir'
,
'data-toggle'
=>
'modal'
}
do
=
icon
(
'folder fw'
)
New directory
app/views/projects/tree/_tree_item.html.haml
View file @
d37cf642
...
@@ -5,5 +5,5 @@
...
@@ -5,5 +5,5 @@
-
path
=
flatten_tree
(
tree_item
)
-
path
=
flatten_tree
(
tree_item
)
=
link_to
path
,
namespace_project_tree_path
(
@project
.
namespace
,
@project
,
tree_join
(
@id
||
@commit
.
id
,
path
))
=
link_to
path
,
namespace_project_tree_path
(
@project
.
namespace
,
@project
,
tree_join
(
@id
||
@commit
.
id
,
path
))
%td
.tree_time_ago.cgray
%td
.tree_time_ago.cgray
=
render
'spinner'
=
render
'
projects/tree/
spinner'
%td
.hidden-xs.tree_commit
%td
.hidden-xs.tree_commit
app/views/projects/tree/show.html.haml
View file @
d37cf642
...
@@ -6,12 +6,12 @@
...
@@ -6,12 +6,12 @@
=
render
'projects/last_push'
=
render
'projects/last_push'
.tree-ref-holder
=
render
'shared/ref_switcher'
,
destination:
'tree'
,
path:
@path
-
if
can?
current_user
,
:download_code
,
@project
-
if
can?
current_user
,
:download_code
,
@project
.tree-download-holder
.tree-download-holder
=
render
'projects/repositories/download_archive'
,
ref:
@ref
,
btn_class:
'btn-group pull-right hidden-xs hidden-sm'
,
split_button:
true
=
render
'projects/repositories/download_archive'
,
ref:
@ref
,
btn_class:
'btn-group pull-right hidden-xs hidden-sm'
,
split_button:
true
#tree-holder
.tree-holder.clearfix
#tree-holder
.tree-holder.clearfix
=
render
"tree"
,
tree:
@tree
.gray-content-block.top-block
=
render
'projects/tree/tree_header'
,
tree:
@tree
=
render
'projects/tree/tree_content'
,
tree:
@tree
app/views/shared/_clone_panel.html.haml
View file @
d37cf642
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
type:
'button'
,
|
type:
'button'
,
|
class:
"btn #{ 'active' if default_clone_protocol == 'ssh' }#{ ' has_tooltip' if current_user && current_user.require_ssh_key? }"
,
|
class:
"btn #{ 'active' if default_clone_protocol == 'ssh' }#{ ' has_tooltip' if current_user && current_user.require_ssh_key? }"
,
|
:"data-clone"
=>
project
.
ssh_url_to_repo
,
|
:"data-clone"
=>
project
.
ssh_url_to_repo
,
|
:"data-title"
=>
"Add an SSH key to your profile<br> to pull or push via SSH"
,
:"data-title"
=>
"Add an SSH key to your profile<br> to pull or push via SSH
.
"
,
:"data-html"
=>
"true"
,
:"data-html"
=>
"true"
,
:"data-container"
=>
"body"
}
:"data-container"
=>
"body"
}
SSH
SSH
...
@@ -15,7 +15,7 @@
...
@@ -15,7 +15,7 @@
type:
'button'
,
|
type:
'button'
,
|
class:
"btn #{ 'active' if default_clone_protocol == 'http' }#{ ' has_tooltip' if current_user && current_user.require_password? }"
,
|
class:
"btn #{ 'active' if default_clone_protocol == 'http' }#{ ' has_tooltip' if current_user && current_user.require_password? }"
,
|
:"data-clone"
=>
project
.
http_url_to_repo
,
|
:"data-clone"
=>
project
.
http_url_to_repo
,
|
:"data-title"
=>
"Set a password on your account<br> to pull or push via #{gitlab_config.protocol.upcase}"
,
:"data-title"
=>
"Set a password on your account<br> to pull or push via #{gitlab_config.protocol.upcase}
.
"
,
:"data-html"
=>
"true"
,
:"data-html"
=>
"true"
,
:"data-container"
=>
"body"
}
:"data-container"
=>
"body"
}
=
gitlab_config
.
protocol
.
upcase
=
gitlab_config
.
protocol
.
upcase
...
...
app/views/users/calendar.html.haml
View file @
d37cf642
%h4
Contributions calendar
.pull-right
%small
Issues, merge requests and push events
#cal-heatmap
.calendar
#cal-heatmap
.calendar
:javascript
:javascript
new
Calendar
(
new
Calendar
(
...
@@ -10,3 +6,5 @@
...
@@ -10,3 +6,5 @@
#{
@starting_month
}
,
#{
@starting_month
}
,
'
#{
user_calendar_activities_path
}
'
'
#{
user_calendar_activities_path
}
'
);
);
.calendar-hint
Summary of issues, merge requests and push events
app/views/users/show.html.haml
View file @
d37cf642
...
@@ -6,47 +6,72 @@
...
@@ -6,47 +6,72 @@
=
render
'shared/show_aside'
=
render
'shared/show_aside'
.row
.cover-block
%section
.col-md-7
.avatar-holder
.header-with-avatar
=
link_to
avatar_icon
(
@user
,
400
),
target:
'_blank'
do
=
link_to
avatar_icon
(
@user
,
400
),
target:
'_blank'
do
=
image_tag
avatar_icon
(
@user
,
90
),
class:
"avatar s90"
,
alt:
''
=
image_tag
avatar_icon
(
@user
,
90
),
class:
"avatar avatar-tile s90"
,
alt:
''
.cover-title
%h3
=
@user
.
name
=
@user
.
name
-
if
@user
==
current_user
.cover-desc
.pull-right.hidden-xs
%span
=
link_to
profile_path
,
class:
'btn btn-sm'
do
@
#{
@user
.
username
}
.
=
icon
(
'user'
)
-
if
@user
.
bio
.
present?
Profile settings
%span
-
elsif
current_user
#{
@user
.
bio
}
.
.report_abuse.pull-right
%span
-
if
@user
.
abuse_report
Member since
#{
@user
.
created_at
.
stamp
(
"Aug 21, 2011"
)
}
%span
#report_abuse_btn
.light.btn.btn-sm.btn-close
{
title:
'Already reported for abuse'
,
data:
{
toggle:
'tooltip'
,
placement:
'right'
,
container:
'body'
}}
=
icon
(
'exclamation-circle'
)
.cover-desc
-
else
-
unless
@user
.
public_email
.
blank?
%a
.light.btn.btn-sm
{
href:
new_abuse_report_path
(
user_id:
@user
.
id
),
title:
'Report abuse'
,
data:
{
toggle:
'tooltip'
,
placement:
'right'
,
container:
'body'
}}
=
link_to
@user
.
public_email
,
"mailto:
#{
@user
.
public_email
}
"
=
icon
(
'exclamation-circle'
)
-
unless
@user
.
skype
.
blank?
·
=
link_to
"Skype"
,
"skype:
#{
@user
.
skype
}
"
-
unless
@user
.
linkedin
.
blank?
·
=
link_to
"LinkedIn"
,
"http://www.linkedin.com/in/
#{
@user
.
linkedin
}
"
-
unless
@user
.
twitter
.
blank?
·
=
link_to
"Twitter"
,
"http://www.twitter.com/
#{
@user
.
twitter
}
"
-
unless
@user
.
website_url
.
blank?
·
=
link_to
@user
.
short_website_url
,
@user
.
full_website_url
-
unless
@user
.
location
.
blank?
·
=
@user
.
location
.username
@
#{
@user
.
username
}
.description
-
if
@user
.
bio
.
present?
=
@user
.
bio
.clearfix
.cover-controls
-
if
@user
==
current_user
=
link_to
profile_path
,
class:
'btn btn-gray'
do
=
icon
(
'pencil'
)
-
elsif
current_user
.report-abuse
-
if
@user
.
abuse_report
%button
.btn.btn-danger
{
title:
'Already reported for abuse'
,
data:
{
toggle:
'tooltip'
,
placement:
'left'
,
container:
'body'
}}
=
icon
(
'exclamation-circle'
)
-
else
=
link_to
new_abuse_report_path
(
user_id:
@user
.
id
),
class:
'btn btn-gray'
,
title:
'Report abuse'
,
data:
{
toggle:
'tooltip'
,
placement:
'left'
,
container:
'body'
}
do
=
icon
(
'exclamation-circle'
)
.gray-content-block.second-block
.user-calendar
%h4
.center.light
%i
.fa.fa-spinner.fa-spin
.user-calendar-activities
.row.prepend-top-20
%section
.col-md-7
-
if
@groups
.
any?
-
if
@groups
.
any?
.prepend-top-20
.prepend-top-20
%h4
Groups
%h4
Groups
=
render
'groups'
,
groups:
@groups
=
render
'groups'
,
groups:
@groups
%hr
%hr
.hidden-xs
.user-calendar
%h4
.center.light
%i
.fa.fa-spinner.fa-spin
.user-calendar-activities
%hr
%h4
%h4
User Activity
User Activity
...
@@ -59,7 +84,6 @@
...
@@ -59,7 +84,6 @@
.content_list
.content_list
=
spinner
=
spinner
%aside
.col-md-5
%aside
.col-md-5
=
render
'profile'
,
user:
@user
=
render
'projects'
,
projects:
@projects
,
contributed_projects:
@contributed_projects
=
render
'projects'
,
projects:
@projects
,
contributed_projects:
@contributed_projects
:coffeescript
:coffeescript
...
...
app/workers/repository_archive_cache_worker.rb
0 → 100644
View file @
d37cf642
class
RepositoryArchiveCacheWorker
include
Sidekiq
::
Worker
sidekiq_options
queue: :default
def
perform
Repository
.
clean_old_archives
end
end
app/workers/repository_archive_worker.rb
deleted
100644 → 0
View file @
d9944fdb
class
RepositoryArchiveWorker
include
Sidekiq
::
Worker
sidekiq_options
queue: :archive_repo
attr_accessor
:project
,
:ref
,
:format
def
perform
(
project_id
,
ref
,
format
)
@project
=
Project
.
find
(
project_id
)
@ref
,
@format
=
ref
,
format
.
downcase
repository
=
project
.
repository
repository
.
clean_old_archives
return
unless
file_path
return
if
archived?
||
archiving?
repository
.
archive_repo
(
ref
,
storage_path
,
format
)
end
private
def
storage_path
Gitlab
.
config
.
gitlab
.
repository_downloads_path
end
def
file_path
@file_path
||=
project
.
repository
.
archive_file_path
(
ref
,
storage_path
,
format
)
end
def
pid_file_path
@pid_file_path
||=
project
.
repository
.
archive_pid_file_path
(
ref
,
storage_path
,
format
)
end
def
archived?
File
.
exist?
(
file_path
)
end
def
archiving?
File
.
exist?
(
pid_file_path
)
end
end
config/routes.rb
View file @
d37cf642
...
@@ -378,6 +378,7 @@ Gitlab::Application.routes.draw do
...
@@ -378,6 +378,7 @@ Gitlab::Application.routes.draw do
[
:new
,
:create
,
:index
],
path:
"/"
)
do
[
:new
,
:create
,
:index
],
path:
"/"
)
do
member
do
member
do
put
:transfer
put
:transfer
delete
:remove_fork
post
:archive
post
:archive
post
:unarchive
post
:unarchive
post
:toggle_star
post
:toggle_star
...
...
db/fixtures/development/05_users.rb
View file @
d37cf642
Gitlab
::
Seeder
.
quiet
do
Gitlab
::
Seeder
.
quiet
do
(
2
..
20
).
each
do
|
i
|
20
.
times
do
|
i
|
begin
begin
User
.
create!
(
User
.
create!
(
username:
FFaker
::
Internet
.
user_name
,
username:
FFaker
::
Internet
.
user_name
,
...
@@ -15,7 +15,7 @@ Gitlab::Seeder.quiet do
...
@@ -15,7 +15,7 @@ Gitlab::Seeder.quiet do
end
end
end
end
(
1
..
5
).
each
do
|
i
|
5
.
times
do
|
i
|
begin
begin
User
.
create!
(
User
.
create!
(
username:
"user
#{
i
}
"
,
username:
"user
#{
i
}
"
,
...
...
db/fixtures/development/07_milestones.rb
View file @
d37cf642
Gitlab
::
Seeder
.
quiet
do
Gitlab
::
Seeder
.
quiet
do
Project
.
all
.
each
do
|
project
|
Project
.
all
.
each
do
|
project
|
(
1
..
5
).
each
do
|
i
|
5
.
times
do
|
i
|
milestone_params
=
{
milestone_params
=
{
title:
"v
#{
i
}
.0"
,
title:
"v
#{
i
}
.0"
,
description:
FFaker
::
Lorem
.
sentence
,
description:
FFaker
::
Lorem
.
sentence
,
...
...
db/fixtures/development/09_issues.rb
View file @
d37cf642
Gitlab
::
Seeder
.
quiet
do
Gitlab
::
Seeder
.
quiet
do
Project
.
all
.
each
do
|
project
|
Project
.
all
.
each
do
|
project
|
(
1
..
10
).
each
do
|
i
|
10
.
times
do
issue_params
=
{
issue_params
=
{
title:
FFaker
::
Lorem
.
sentence
(
6
),
title:
FFaker
::
Lorem
.
sentence
(
6
),
description:
FFaker
::
Lorem
.
sentence
,
description:
FFaker
::
Lorem
.
sentence
,
...
...
db/fixtures/development/12_snippets.rb
View file @
d37cf642
...
@@ -22,7 +22,7 @@ class Member < ActiveRecord::Base
...
@@ -22,7 +22,7 @@ class Member < ActiveRecord::Base
end
end
eos
eos
(
1
..
50
).
each
do
|
i
|
50
.
times
do
|
i
|
user
=
User
.
all
.
sample
user
=
User
.
all
.
sample
PersonalSnippet
.
seed
(
:id
,
[{
PersonalSnippet
.
seed
(
:id
,
[{
...
...
db/migrate/20151008143519_add_admin_notification_email_setting.rb
0 → 100644
View file @
d37cf642
class
AddAdminNotificationEmailSetting
<
ActiveRecord
::
Migration
def
change
add_column
:application_settings
,
:admin_notification_email
,
:string
end
end
db/migrate/20151019111551_fix_build_tags.rb
0 → 100644
View file @
d37cf642
class
FixBuildTags
<
ActiveRecord
::
Migration
def
change
execute
(
"UPDATE taggings SET taggable_type='CommitStatus' WHERE taggable_type='Ci::Build'"
)
end
end
db/migrate/20151019111703_fail_build_without_names.rb
0 → 100644
View file @
d37cf642
class
FailBuildWithoutNames
<
ActiveRecord
::
Migration
def
change
execute
(
"UPDATE ci_builds SET status='failed' WHERE name IS NULL AND status='pending'"
)
end
end
db/migrate/20151020173516_ci_limits_to_mysql.rb
0 → 100644
View file @
d37cf642
class
CiLimitsToMysql
<
ActiveRecord
::
Migration
def
change
return
unless
ActiveRecord
::
Base
.
configurations
[
Rails
.
env
][
'adapter'
]
=~
/^mysql/
# CI
change_column
:ci_builds
,
:trace
,
:text
,
limit:
1073741823
change_column
:ci_commits
,
:push_data
,
:text
,
limit:
16777215
end
end
db/migrate/20151020173906_add_ci_builds_index_for_status.rb
0 → 100644
View file @
d37cf642
class
AddCiBuildsIndexForStatus
<
ActiveRecord
::
Migration
def
change
add_index
:ci_builds
,
[
:commit_id
,
:status
,
:type
]
end
end
db/migrate/limits_to_mysql.rb
View file @
d37cf642
...
@@ -6,9 +6,5 @@ class LimitsToMysql < ActiveRecord::Migration
...
@@ -6,9 +6,5 @@ class LimitsToMysql < ActiveRecord::Migration
change_column
:merge_request_diffs
,
:st_diffs
,
:text
,
limit:
2147483647
change_column
:merge_request_diffs
,
:st_diffs
,
:text
,
limit:
2147483647
change_column
:snippets
,
:content
,
:text
,
limit:
2147483647
change_column
:snippets
,
:content
,
:text
,
limit:
2147483647
change_column
:notes
,
:st_diff
,
:text
,
limit:
2147483647
change_column
:notes
,
:st_diff
,
:text
,
limit:
2147483647
# CI
change_column
:ci_builds
,
:trace
,
:text
,
limit:
1073741823
change_column
:ci_commits
,
:push_data
,
:text
,
limit:
16777215
end
end
end
end
db/schema.rb
View file @
d37cf642
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
#
#
# It's strongly recommended that you check this file into your version control system.
# It's strongly recommended that you check this file into your version control system.
ActiveRecord
::
Schema
.
define
(
version:
201510
161957
06
)
do
ActiveRecord
::
Schema
.
define
(
version:
201510
201739
06
)
do
# These are extensions that must be enabled in order to support this database
# These are extensions that must be enabled in order to support this database
enable_extension
"plpgsql"
enable_extension
"plpgsql"
...
@@ -46,6 +46,7 @@ ActiveRecord::Schema.define(version: 20151016195706) do
...
@@ -46,6 +46,7 @@ ActiveRecord::Schema.define(version: 20151016195706) do
t
.
integer
"session_expire_delay"
,
default:
10080
,
null:
false
t
.
integer
"session_expire_delay"
,
default:
10080
,
null:
false
t
.
text
"import_sources"
t
.
text
"import_sources"
t
.
text
"help_page_text"
t
.
text
"help_page_text"
t
.
string
"admin_notification_email"
end
end
create_table
"audit_events"
,
force:
true
do
|
t
|
create_table
"audit_events"
,
force:
true
do
|
t
|
...
@@ -109,6 +110,7 @@ ActiveRecord::Schema.define(version: 20151016195706) do
...
@@ -109,6 +110,7 @@ ActiveRecord::Schema.define(version: 20151016195706) do
end
end
add_index
"ci_builds"
,
[
"commit_id"
,
"stage_idx"
,
"created_at"
],
name:
"index_ci_builds_on_commit_id_and_stage_idx_and_created_at"
,
using: :btree
add_index
"ci_builds"
,
[
"commit_id"
,
"stage_idx"
,
"created_at"
],
name:
"index_ci_builds_on_commit_id_and_stage_idx_and_created_at"
,
using: :btree
add_index
"ci_builds"
,
[
"commit_id"
,
"status"
,
"type"
],
name:
"index_ci_builds_on_commit_id_and_status_and_type"
,
using: :btree
add_index
"ci_builds"
,
[
"commit_id"
,
"type"
,
"name"
,
"ref"
],
name:
"index_ci_builds_on_commit_id_and_type_and_name_and_ref"
,
using: :btree
add_index
"ci_builds"
,
[
"commit_id"
,
"type"
,
"name"
,
"ref"
],
name:
"index_ci_builds_on_commit_id_and_type_and_name_and_ref"
,
using: :btree
add_index
"ci_builds"
,
[
"commit_id"
,
"type"
,
"ref"
],
name:
"index_ci_builds_on_commit_id_and_type_and_ref"
,
using: :btree
add_index
"ci_builds"
,
[
"commit_id"
,
"type"
,
"ref"
],
name:
"index_ci_builds_on_commit_id_and_type_and_ref"
,
using: :btree
add_index
"ci_builds"
,
[
"commit_id"
],
name:
"index_ci_builds_on_commit_id"
,
using: :btree
add_index
"ci_builds"
,
[
"commit_id"
],
name:
"index_ci_builds_on_commit_id"
,
using: :btree
...
...
doc/update/8.0-to-8.1.md
View file @
d37cf642
...
@@ -70,7 +70,16 @@ sudo -u git -H git fetch
...
@@ -70,7 +70,16 @@ sudo -u git -H git fetch
sudo
-u
git
-H
git checkout v2.6.5
sudo
-u
git
-H
git checkout v2.6.5
```
```
### 5. Install libs, migrations, etc.
### 5. Update gitlab-git-http-server
```
bash
cd
/home/git/gitlab-git-http-server
sudo
-u
git
-H
git fetch origin
sudo
-u
git
-H
git checkout 0.3.0
sudo
-u
git
-H
make
```
### 6. Install libs, migrations, etc.
```
bash
```
bash
cd
/home/git/gitlab
cd
/home/git/gitlab
...
@@ -91,7 +100,7 @@ sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS
...
@@ -91,7 +100,7 @@ sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS
sudo cp
lib/support/init.d/gitlab /etc/init.d/gitlab
sudo cp
lib/support/init.d/gitlab /etc/init.d/gitlab
```
```
###
6
. Update configuration files
###
7
. Update configuration files
#### New configuration options for `gitlab.yml`
#### New configuration options for `gitlab.yml`
...
@@ -101,12 +110,33 @@ There are new configuration options available for [`gitlab.yml`](config/gitlab.y
...
@@ -101,12 +110,33 @@ There are new configuration options available for [`gitlab.yml`](config/gitlab.y
git diff origin/8-0-stable:config/gitlab.yml.example origin/8-1-stable:config/gitlab.yml.example
git diff origin/8-0-stable:config/gitlab.yml.example origin/8-1-stable:config/gitlab.yml.example
```
```
### 7. Start application
#### Nginx configuration
View changes between the previous recommended Nginx configuration and the
current one:
```
sh
# For HTTPS configurations
git diff origin/8-0-stable:lib/support/nginx/gitlab-ssl origin/8-1-stable:lib/support/nginx/gitlab-ssl
# For HTTP configurations
git diff origin/8-0-stable:lib/support/nginx/gitlab origin/8-1-stable:lib/support/nginx/gitlab
```
If you are using Apache instead of NGINX please see the updated [Apache templates].
Also note that because Apache does not support upstreams behind Unix sockets you
will need to let gitlab-git-http-server listen on a TCP port. You can do this
via [/etc/default/gitlab].
[
Apache templates
]:
https://gitlab.com/gitlab-org/gitlab-recipes/tree/master/web-server/apache
[
/etc/default/gitlab
]:
https://gitlab.com/gitlab-org/gitlab-ce/blob/8-1-stable/lib/support/init.d/gitlab.default.example#L34
### 8. Start application
sudo service gitlab start
sudo service gitlab start
sudo service nginx restart
sudo service nginx restart
###
8
. Check application status
###
9
. Check application status
Check if GitLab and its environment are configured correctly:
Check if GitLab and its environment are configured correctly:
...
...
doc/update/patch_versions.md
View file @
d37cf642
...
@@ -49,9 +49,7 @@ sudo -u git -H bundle install --without development test mysql --deployment
...
@@ -49,9 +49,7 @@ sudo -u git -H bundle install --without development test mysql --deployment
sudo
-u
git
-H
bundle
install
--without
development
test
postgres
--deployment
sudo
-u
git
-H
bundle
install
--without
development
test
postgres
--deployment
sudo
-u
git
-H
bundle
exec
rake db:migrate
RAILS_ENV
=
production
sudo
-u
git
-H
bundle
exec
rake db:migrate
RAILS_ENV
=
production
sudo
-u
git
-H
bundle
exec
rake assets:clean
RAILS_ENV
=
production
sudo
-u
git
-H
bundle
exec
rake assets:clean assets:precompile cache:clear
RAILS_ENV
=
production
sudo
-u
git
-H
bundle
exec
rake assets:precompile
RAILS_ENV
=
production
sudo
-u
git
-H
bundle
exec
rake cache:clear
RAILS_ENV
=
production
```
```
### 5. Start application
### 5. Start application
...
...
features/steps/abuse_reports.rb
View file @
d37cf642
...
@@ -23,7 +23,7 @@ class Spinach::Features::AbuseReports < Spinach::FeatureSteps
...
@@ -23,7 +23,7 @@ class Spinach::Features::AbuseReports < Spinach::FeatureSteps
end
end
step
'I should see a red "Report abuse" button'
do
step
'I should see a red "Report abuse" button'
do
expect
(
find
(
:css
,
'.report_abuse'
)).
to
have_selector
(
:css
,
'span.btn-close'
)
expect
(
page
).
to
have_button
(
"Already reported for abuse"
)
end
end
def
user_mike
def
user_mike
...
...
features/steps/project/project.rb
View file @
d37cf642
...
@@ -86,13 +86,13 @@ class Spinach::Features::Project < Spinach::FeatureSteps
...
@@ -86,13 +86,13 @@ class Spinach::Features::Project < Spinach::FeatureSteps
end
end
step
'I should see project "Forum" README'
do
step
'I should see project "Forum" README'
do
page
.
within
(
'
#README
'
)
do
page
.
within
(
'
.readme-holder
'
)
do
expect
(
page
).
to
have_content
'Sample repo for testing gitlab features'
expect
(
page
).
to
have_content
'Sample repo for testing gitlab features'
end
end
end
end
step
'I should see project "Shop" README'
do
step
'I should see project "Shop" README'
do
page
.
within
(
'
#README
'
)
do
page
.
within
(
'
.readme-holder
'
)
do
expect
(
page
).
to
have_content
'testme'
expect
(
page
).
to
have_content
'testme'
end
end
end
end
...
...
lib/api/projects.rb
View file @
d37cf642
...
@@ -246,8 +246,8 @@ module API
...
@@ -246,8 +246,8 @@ module API
# Example Request:
# Example Request:
# DELETE /projects/:id/fork
# DELETE /projects/:id/fork
delete
":id/fork"
do
delete
":id/fork"
do
auth
enticated_as_admin!
auth
orize!
:remove_fork_project
,
user_project
unless
user_project
.
forked_project_link
.
nil
?
if
user_project
.
forked
?
user_project
.
forked_project_link
.
destroy
user_project
.
forked_project_link
.
destroy
end
end
end
end
...
...
lib/gitlab/markdown.rb
View file @
d37cf642
...
@@ -7,6 +7,14 @@ module Gitlab
...
@@ -7,6 +7,14 @@ module Gitlab
module
Markdown
module
Markdown
# Convert a Markdown String into an HTML-safe String of HTML
# Convert a Markdown String into an HTML-safe String of HTML
#
#
# Note that while the returned HTML will have been sanitized of dangerous
# HTML, it may post a risk of information leakage if it's not also passed
# through `post_process`.
#
# Also note that the returned String is always HTML, not XHTML. Views
# requiring XHTML, such as Atom feeds, need to call `post_process` on the
# result, providing the appropriate `pipeline` option.
#
# markdown - Markdown String
# markdown - Markdown String
# context - Hash of context options passed to our HTML Pipeline
# context - Hash of context options passed to our HTML Pipeline
#
#
...
@@ -31,6 +39,33 @@ module Gitlab
...
@@ -31,6 +39,33 @@ module Gitlab
renderer
.
render
(
markdown
)
renderer
.
render
(
markdown
)
end
end
# Perform post-processing on an HTML String
#
# This method is used to perform state-dependent changes to a String of
# HTML, such as removing references that the current user doesn't have
# permission to make (`RedactorFilter`).
#
# html - String to process
# options - Hash of options to customize output
# :pipeline - Symbol pipeline type
# :project - Project
# :user - User object
#
# Returns an HTML-safe String
def
self
.
post_process
(
html
,
options
)
context
=
{
project:
options
[
:project
],
current_user:
options
[
:user
]
}
doc
=
post_processor
.
to_document
(
html
,
context
)
if
options
[
:pipeline
]
==
:atom
doc
.
to_html
(
save_with:
Nokogiri
::
XML
::
Node
::
SaveOptions
::
AS_XHTML
)
else
doc
.
to_html
end
.
html_safe
end
# Provide autoload paths for filters to prevent a circular dependency error
# Provide autoload paths for filters to prevent a circular dependency error
autoload
:AutolinkFilter
,
'gitlab/markdown/autolink_filter'
autoload
:AutolinkFilter
,
'gitlab/markdown/autolink_filter'
autoload
:CommitRangeReferenceFilter
,
'gitlab/markdown/commit_range_reference_filter'
autoload
:CommitRangeReferenceFilter
,
'gitlab/markdown/commit_range_reference_filter'
...
@@ -41,6 +76,7 @@ module Gitlab
...
@@ -41,6 +76,7 @@ module Gitlab
autoload
:IssueReferenceFilter
,
'gitlab/markdown/issue_reference_filter'
autoload
:IssueReferenceFilter
,
'gitlab/markdown/issue_reference_filter'
autoload
:LabelReferenceFilter
,
'gitlab/markdown/label_reference_filter'
autoload
:LabelReferenceFilter
,
'gitlab/markdown/label_reference_filter'
autoload
:MergeRequestReferenceFilter
,
'gitlab/markdown/merge_request_reference_filter'
autoload
:MergeRequestReferenceFilter
,
'gitlab/markdown/merge_request_reference_filter'
autoload
:RedactorFilter
,
'gitlab/markdown/redactor_filter'
autoload
:RelativeLinkFilter
,
'gitlab/markdown/relative_link_filter'
autoload
:RelativeLinkFilter
,
'gitlab/markdown/relative_link_filter'
autoload
:SanitizationFilter
,
'gitlab/markdown/sanitization_filter'
autoload
:SanitizationFilter
,
'gitlab/markdown/sanitization_filter'
autoload
:SnippetReferenceFilter
,
'gitlab/markdown/snippet_reference_filter'
autoload
:SnippetReferenceFilter
,
'gitlab/markdown/snippet_reference_filter'
...
@@ -50,26 +86,20 @@ module Gitlab
...
@@ -50,26 +86,20 @@ module Gitlab
autoload
:UserReferenceFilter
,
'gitlab/markdown/user_reference_filter'
autoload
:UserReferenceFilter
,
'gitlab/markdown/user_reference_filter'
autoload
:UploadLinkFilter
,
'gitlab/markdown/upload_link_filter'
autoload
:UploadLinkFilter
,
'gitlab/markdown/upload_link_filter'
# Public: Parse the provided text with GitLab-Flavored Markdown
# Public: Parse the provided HTML with GitLab-Flavored Markdown
#
# html - HTML String
# options - A Hash of options used to customize output (default: {})
# :no_header_anchors - Disable header anchors in TableOfContentsFilter
# :path - Current path String
# :pipeline - Symbol pipeline type
# :project - Current Project object
# :project_wiki - Current ProjectWiki object
# :ref - Current ref String
#
#
# text - the source text
# Returns an HTML-safe String
# options - A Hash of options used to customize output (default: {}):
def
self
.
gfm
(
html
,
options
=
{})
# :xhtml - output XHTML instead of HTML
return
''
unless
html
.
present?
# :reference_only_path - Use relative path for reference links
def
self
.
gfm
(
text
,
options
=
{})
return
text
if
text
.
nil?
# Duplicate the string so we don't alter the original, then call to_str
# to cast it back to a String instead of a SafeBuffer. This is required
# for gsub calls to work as we need them to.
text
=
text
.
dup
.
to_str
options
.
reverse_merge!
(
xhtml:
false
,
reference_only_path:
true
,
project:
options
[
:project
],
current_user:
options
[
:current_user
]
)
@pipeline
||=
HTML
::
Pipeline
.
new
(
filters
)
@pipeline
||=
HTML
::
Pipeline
.
new
(
filters
)
...
@@ -78,41 +108,36 @@ module Gitlab
...
@@ -78,41 +108,36 @@ module Gitlab
pipeline:
options
[
:pipeline
],
pipeline:
options
[
:pipeline
],
# EmojiFilter
# EmojiFilter
asset_root:
Gitlab
.
config
.
gitlab
.
base_url
,
asset_host:
Gitlab
::
Application
.
config
.
asset_host
,
asset_host:
Gitlab
::
Application
.
config
.
asset_host
,
asset_root:
Gitlab
.
config
.
gitlab
.
base_url
,
# TableOfContentsFilter
no_header_anchors:
options
[
:no_header_anchors
],
# ReferenceFilter
# ReferenceFilter
current_user:
options
[
:current_user
],
only_path:
only_path_pipeline?
(
options
[
:pipeline
]),
only_path:
options
[
:reference_only_path
],
project:
options
[
:project
],
project:
options
[
:project
],
# RelativeLinkFilter
# RelativeLinkFilter
project_wiki:
options
[
:project_wiki
],
ref:
options
[
:ref
],
ref:
options
[
:ref
],
requested_path:
options
[
:path
],
requested_path:
options
[
:path
],
project_wiki:
options
[
:project_wiki
]
}
result
=
@pipeline
.
call
(
text
,
context
)
save_options
=
0
# TableOfContentsFilter
if
options
[
:xhtml
]
no_header_anchors:
options
[
:no_header_anchors
]
save_options
|=
Nokogiri
::
XML
::
Node
::
SaveOptions
::
AS_XHTML
}
end
text
=
result
[
:output
].
to_html
(
save_with:
save_options
)
text
.
html_safe
@pipeline
.
to_html
(
html
,
context
)
.
html_safe
end
end
private
private
def
self
.
renderer
# Check if a pipeline enables the `only_path` context option
@markdown
||=
begin
#
renderer
=
Redcarpet
::
Render
::
HTML
.
new
# Returns Boolean
Redcarpet
::
Markdown
.
new
(
renderer
,
redcarpet_options
)
def
self
.
only_path_pipeline?
(
pipeline
)
case
pipeline
when
:atom
,
:email
false
else
true
end
end
end
end
...
@@ -130,6 +155,17 @@ module Gitlab
...
@@ -130,6 +155,17 @@ module Gitlab
}.
freeze
}.
freeze
end
end
def
self
.
renderer
@markdown
||=
begin
renderer
=
Redcarpet
::
Render
::
HTML
.
new
Redcarpet
::
Markdown
.
new
(
renderer
,
redcarpet_options
)
end
end
def
self
.
post_processor
@post_processor
||=
HTML
::
Pipeline
.
new
([
Gitlab
::
Markdown
::
RedactorFilter
])
end
# Filters used in our pipeline
# Filters used in our pipeline
#
#
# SanitizationFilter should come first so that all generated reference HTML
# SanitizationFilter should come first so that all generated reference HTML
...
...
lib/gitlab/markdown/commit_range_reference_filter.rb
View file @
d37cf642
...
@@ -26,6 +26,18 @@ module Gitlab
...
@@ -26,6 +26,18 @@ module Gitlab
end
end
end
end
def
self
.
referenced_by
(
node
)
project
=
Project
.
find
(
node
.
attr
(
"data-project"
))
rescue
nil
return
unless
project
id
=
node
.
attr
(
"data-commit-range"
)
range
=
CommitRange
.
new
(
id
,
project
)
return
unless
range
.
valid_commits?
{
commit_range:
range
}
end
def
initialize
(
*
args
)
def
initialize
(
*
args
)
super
super
...
@@ -53,13 +65,11 @@ module Gitlab
...
@@ -53,13 +65,11 @@ module Gitlab
range
=
CommitRange
.
new
(
id
,
project
)
range
=
CommitRange
.
new
(
id
,
project
)
if
range
.
valid_commits?
if
range
.
valid_commits?
push_result
(
:commit_range
,
range
)
url
=
url_for_commit_range
(
project
,
range
)
url
=
url_for_commit_range
(
project
,
range
)
title
=
range
.
reference_title
title
=
range
.
reference_title
klass
=
reference_class
(
:commit_range
)
klass
=
reference_class
(
:commit_range
)
data
=
data_attribute
(
project
.
id
)
data
=
data_attribute
(
project
:
project
.
id
,
commit_range:
id
)
project_ref
+=
'@'
if
project_ref
project_ref
+=
'@'
if
project_ref
...
...
lib/gitlab/markdown/commit_reference_filter.rb
View file @
d37cf642
...
@@ -26,6 +26,18 @@ module Gitlab
...
@@ -26,6 +26,18 @@ module Gitlab
end
end
end
end
def
self
.
referenced_by
(
node
)
project
=
Project
.
find
(
node
.
attr
(
"data-project"
))
rescue
nil
return
unless
project
id
=
node
.
attr
(
"data-commit"
)
commit
=
commit_from_ref
(
project
,
id
)
return
unless
commit
{
commit:
commit
}
end
def
call
def
call
replace_text_nodes_matching
(
Commit
.
reference_pattern
)
do
|
content
|
replace_text_nodes_matching
(
Commit
.
reference_pattern
)
do
|
content
|
commit_link_filter
(
content
)
commit_link_filter
(
content
)
...
@@ -39,17 +51,15 @@ module Gitlab
...
@@ -39,17 +51,15 @@ module Gitlab
# Returns a String with commit references replaced with links. All links
# Returns a String with commit references replaced with links. All links
# have `gfm` and `gfm-commit` class names attached for styling.
# have `gfm` and `gfm-commit` class names attached for styling.
def
commit_link_filter
(
text
)
def
commit_link_filter
(
text
)
self
.
class
.
references_in
(
text
)
do
|
match
,
commit_ref
,
project_ref
|
self
.
class
.
references_in
(
text
)
do
|
match
,
id
,
project_ref
|
project
=
self
.
project_from_ref
(
project_ref
)
project
=
self
.
project_from_ref
(
project_ref
)
if
commit
=
commit_from_ref
(
project
,
commit_ref
)
if
commit
=
self
.
class
.
commit_from_ref
(
project
,
id
)
push_result
(
:commit
,
commit
)
url
=
url_for_commit
(
project
,
commit
)
url
=
url_for_commit
(
project
,
commit
)
title
=
escape_once
(
commit
.
link_title
)
title
=
escape_once
(
commit
.
link_title
)
klass
=
reference_class
(
:commit
)
klass
=
reference_class
(
:commit
)
data
=
data_attribute
(
project
.
id
)
data
=
data_attribute
(
project
:
project
.
id
,
commit:
id
)
project_ref
+=
'@'
if
project_ref
project_ref
+=
'@'
if
project_ref
...
@@ -62,9 +72,9 @@ module Gitlab
...
@@ -62,9 +72,9 @@ module Gitlab
end
end
end
end
def
commit_from_ref
(
project
,
commit_ref
)
def
self
.
commit_from_ref
(
project
,
id
)
if
project
&&
project
.
valid_repo?
if
project
&&
project
.
valid_repo?
project
.
commit
(
commit_ref
)
project
.
commit
(
id
)
end
end
end
end
...
...
lib/gitlab/markdown/cross_project_reference.rb
View file @
d37cf642
...
@@ -13,18 +13,11 @@ module Gitlab
...
@@ -13,18 +13,11 @@ module Gitlab
#
#
# ref - String reference.
# ref - String reference.
#
#
# Returns a Project, or nil if the reference can't be
accesse
d
# Returns a Project, or nil if the reference can't be
foun
d
def
project_from_ref
(
ref
)
def
project_from_ref
(
ref
)
return
context
[
:project
]
unless
ref
return
context
[
:project
]
unless
ref
other
=
Project
.
find_with_namespace
(
ref
)
Project
.
find_with_namespace
(
ref
)
return
nil
unless
other
&&
user_can_reference_project?
(
other
)
other
end
def
user_can_reference_project?
(
project
,
user
=
context
[
:current_user
])
Ability
.
abilities
.
allowed?
(
user
,
:read_project
,
project
)
end
end
end
end
end
end
...
...
lib/gitlab/markdown/external_issue_reference_filter.rb
View file @
d37cf642
...
@@ -47,8 +47,9 @@ module Gitlab
...
@@ -47,8 +47,9 @@ module Gitlab
title
=
escape_once
(
"Issue in
#{
project
.
external_issue_tracker
.
title
}
"
)
title
=
escape_once
(
"Issue in
#{
project
.
external_issue_tracker
.
title
}
"
)
klass
=
reference_class
(
:issue
)
klass
=
reference_class
(
:issue
)
data
=
data_attribute
(
project:
project
.
id
)
%(<a href="#{url}"
%(<a href="#{url}"
#{data}
title="#{title}"
title="#{title}"
class="#{klass}">#{match}</a>)
class="#{klass}">#{match}</a>)
end
end
...
...
lib/gitlab/markdown/issue_reference_filter.rb
View file @
d37cf642
...
@@ -27,6 +27,10 @@ module Gitlab
...
@@ -27,6 +27,10 @@ module Gitlab
end
end
end
end
def
self
.
referenced_by
(
node
)
{
issue:
LazyReference
.
new
(
Issue
,
node
.
attr
(
"data-issue"
))
}
end
def
call
def
call
replace_text_nodes_matching
(
Issue
.
reference_pattern
)
do
|
content
|
replace_text_nodes_matching
(
Issue
.
reference_pattern
)
do
|
content
|
issue_link_filter
(
content
)
issue_link_filter
(
content
)
...
@@ -45,13 +49,11 @@ module Gitlab
...
@@ -45,13 +49,11 @@ module Gitlab
project
=
self
.
project_from_ref
(
project_ref
)
project
=
self
.
project_from_ref
(
project_ref
)
if
project
&&
issue
=
project
.
get_issue
(
id
)
if
project
&&
issue
=
project
.
get_issue
(
id
)
push_result
(
:issue
,
issue
)
url
=
url_for_issue
(
id
,
project
,
only_path:
context
[
:only_path
])
url
=
url_for_issue
(
id
,
project
,
only_path:
context
[
:only_path
])
title
=
escape_once
(
"Issue:
#{
issue
.
title
}
"
)
title
=
escape_once
(
"Issue:
#{
issue
.
title
}
"
)
klass
=
reference_class
(
:issue
)
klass
=
reference_class
(
:issue
)
data
=
data_attribute
(
project
.
id
)
data
=
data_attribute
(
project
:
project
.
id
,
issue:
issue
.
id
)
%(<a href="#{url}" #{data}
%(<a href="#{url}" #{data}
title="#{title}"
title="#{title}"
...
...
lib/gitlab/markdown/label_reference_filter.rb
View file @
d37cf642
...
@@ -22,6 +22,10 @@ module Gitlab
...
@@ -22,6 +22,10 @@ module Gitlab
end
end
end
end
def
self
.
referenced_by
(
node
)
{
label:
LazyReference
.
new
(
Label
,
node
.
attr
(
"data-label"
))
}
end
def
call
def
call
replace_text_nodes_matching
(
Label
.
reference_pattern
)
do
|
content
|
replace_text_nodes_matching
(
Label
.
reference_pattern
)
do
|
content
|
label_link_filter
(
content
)
label_link_filter
(
content
)
...
@@ -41,11 +45,9 @@ module Gitlab
...
@@ -41,11 +45,9 @@ module Gitlab
params
=
label_params
(
id
,
name
)
params
=
label_params
(
id
,
name
)
if
label
=
project
.
labels
.
find_by
(
params
)
if
label
=
project
.
labels
.
find_by
(
params
)
push_result
(
:label
,
label
)
url
=
url_for_label
(
project
,
label
)
url
=
url_for_label
(
project
,
label
)
klass
=
reference_class
(
:label
)
klass
=
reference_class
(
:label
)
data
=
data_attribute
(
project
.
id
)
data
=
data_attribute
(
project
:
project
.
id
,
label:
label
.
id
)
%(<a href="#{url}" #{data}
%(<a href="#{url}" #{data}
class="#{klass}">#{render_colored_label(label)}</a>)
class="#{klass}">#{render_colored_label(label)}</a>)
...
...
lib/gitlab/markdown/merge_request_reference_filter.rb
View file @
d37cf642
...
@@ -27,6 +27,10 @@ module Gitlab
...
@@ -27,6 +27,10 @@ module Gitlab
end
end
end
end
def
self
.
referenced_by
(
node
)
{
merge_request:
LazyReference
.
new
(
MergeRequest
,
node
.
attr
(
"data-merge-request"
))
}
end
def
call
def
call
replace_text_nodes_matching
(
MergeRequest
.
reference_pattern
)
do
|
content
|
replace_text_nodes_matching
(
MergeRequest
.
reference_pattern
)
do
|
content
|
merge_request_link_filter
(
content
)
merge_request_link_filter
(
content
)
...
@@ -45,11 +49,9 @@ module Gitlab
...
@@ -45,11 +49,9 @@ module Gitlab
project
=
self
.
project_from_ref
(
project_ref
)
project
=
self
.
project_from_ref
(
project_ref
)
if
project
&&
merge_request
=
project
.
merge_requests
.
find_by
(
iid:
id
)
if
project
&&
merge_request
=
project
.
merge_requests
.
find_by
(
iid:
id
)
push_result
(
:merge_request
,
merge_request
)
title
=
escape_once
(
"Merge Request:
#{
merge_request
.
title
}
"
)
title
=
escape_once
(
"Merge Request:
#{
merge_request
.
title
}
"
)
klass
=
reference_class
(
:merge_request
)
klass
=
reference_class
(
:merge_request
)
data
=
data_attribute
(
project
.
id
)
data
=
data_attribute
(
project
:
project
.
id
,
merge_request:
merge_request
.
id
)
url
=
url_for_merge_request
(
merge_request
,
project
)
url
=
url_for_merge_request
(
merge_request
,
project
)
...
...
lib/gitlab/markdown/redactor_filter.rb
0 → 100644
View file @
d37cf642
require
'gitlab/markdown'
require
'html/pipeline/filter'
module
Gitlab
module
Markdown
# HTML filter that removes references to records that the current user does
# not have permission to view.
#
# Expected to be run in its own post-processing pipeline.
#
class
RedactorFilter
<
HTML
::
Pipeline
::
Filter
def
call
doc
.
css
(
'a.gfm'
).
each
do
|
node
|
unless
user_can_reference?
(
node
)
node
.
replace
(
node
.
text
)
end
end
doc
end
private
def
user_can_reference?
(
node
)
if
node
.
has_attribute?
(
'data-reference-filter'
)
reference_type
=
node
.
attr
(
'data-reference-filter'
)
reference_filter
=
reference_type
.
constantize
reference_filter
.
user_can_reference?
(
current_user
,
node
,
context
)
else
true
end
end
def
current_user
context
[
:current_user
]
end
end
end
end
lib/gitlab/markdown/reference_filter.rb
View file @
d37cf642
...
@@ -11,30 +11,57 @@ module Gitlab
...
@@ -11,30 +11,57 @@ module Gitlab
# Context options:
# Context options:
# :project (required) - Current project, ignored if reference is cross-project.
# :project (required) - Current project, ignored if reference is cross-project.
# :only_path - Generate path-only links.
# :only_path - Generate path-only links.
#
# Results:
# :references - A Hash of references that were found and replaced.
class
ReferenceFilter
<
HTML
::
Pipeline
::
Filter
class
ReferenceFilter
<
HTML
::
Pipeline
::
Filter
def
initialize
(
*
args
)
LazyReference
=
Struct
.
new
(
:klass
,
:ids
)
do
super
def
self
.
load
(
refs
)
lazy_references
,
values
=
refs
.
partition
{
|
ref
|
ref
.
is_a?
(
self
)
}
lazy_values
=
lazy_references
.
group_by
(
&
:klass
).
flat_map
do
|
klass
,
refs
|
ids
=
refs
.
flat_map
(
&
:ids
)
klass
.
where
(
id:
ids
)
end
values
+
lazy_values
end
def
load
self
.
klass
.
where
(
id:
self
.
ids
)
end
end
def
self
.
user_can_reference?
(
user
,
node
,
context
)
if
node
.
has_attribute?
(
'data-project'
)
project_id
=
node
.
attr
(
'data-project'
).
to_i
return
true
if
project_id
==
context
[
:project
].
try
(
:id
)
project
=
Project
.
find
(
project_id
)
rescue
nil
Ability
.
abilities
.
allowed?
(
user
,
:read_project
,
project
)
else
true
end
end
result
[
:references
]
=
Hash
.
new
{
|
hash
,
type
|
hash
[
type
]
=
[]
}
def
self
.
referenced_by
(
node
)
raise
NotImplementedError
,
"
#{
self
}
does not implement
#{
__method__
}
"
end
end
# Returns a data attribute String to attach to a reference link
# Returns a data attribute String to attach to a reference link
#
#
#
id - Object ID
#
attributes - Hash, where the key becomes the data attribute name and the
#
type - Object type (default: :project)
#
value is the data attribute value
#
#
# Examples:
# Examples:
#
#
# data_attribute(1) # => "data-project-id=\"1\""
# data_attribute(project: 1, issue: 2)
# data_attribute(2, :user) # => "data-user-id=\"2\""
# # => "data-reference-filter=\"Gitlab::Markdown::SomeReferenceFilter\" data-project=\"1\" data-issue=\"2\""
# data_attribute(3, :group) # => "data-group-id=\"3\""
#
# data_attribute(project: 3, merge_request: 4)
# # => "data-reference-filter=\"Gitlab::Markdown::SomeReferenceFilter\" data-project=\"3\" data-merge-request=\"4\""
#
#
# Returns a String
# Returns a String
def
data_attribute
(
id
,
type
=
:project
)
def
data_attribute
(
attributes
=
{})
%Q(data-
#{
type
}
-id="
#{
id
}
")
attributes
[
:reference_filter
]
=
self
.
class
.
name
attributes
.
map
{
|
key
,
value
|
%Q(data-
#{
key
.
to_s
.
dasherize
}
="
#{
value
}
")
}.
join
(
" "
)
end
end
def
escape_once
(
html
)
def
escape_once
(
html
)
...
@@ -59,16 +86,6 @@ module Gitlab
...
@@ -59,16 +86,6 @@ module Gitlab
context
[
:project
]
context
[
:project
]
end
end
# Add a reference to the pipeline's result Hash
#
# type - Singular Symbol reference type (e.g., :issue, :user, etc.)
# values - One or more Objects to add
def
push_result
(
type
,
*
values
)
return
if
values
.
empty?
result
[
:references
][
type
].
push
(
*
values
)
end
def
reference_class
(
type
)
def
reference_class
(
type
)
"gfm gfm-
#{
type
}
"
"gfm gfm-
#{
type
}
"
end
end
...
@@ -85,15 +102,15 @@ module Gitlab
...
@@ -85,15 +102,15 @@ module Gitlab
# Yields the current node's String contents. The result of the block will
# Yields the current node's String contents. The result of the block will
# replace the node's existing content and update the current document.
# replace the node's existing content and update the current document.
#
#
# Returns the updated Nokogiri::
XML::Docu
ment object.
# Returns the updated Nokogiri::
HTML::DocumentFrag
ment object.
def
replace_text_nodes_matching
(
pattern
)
def
replace_text_nodes_matching
(
pattern
)
return
doc
if
project
.
nil?
return
doc
if
project
.
nil?
search_text_nodes
(
doc
).
each
do
|
node
|
search_text_nodes
(
doc
).
each
do
|
node
|
content
=
node
.
to_html
next
unless
content
.
match
(
pattern
)
next
if
ignored_ancestry?
(
node
)
next
if
ignored_ancestry?
(
node
)
next
unless
node
.
text
=~
pattern
content
=
node
.
to_html
html
=
yield
content
html
=
yield
content
...
...
lib/gitlab/markdown/reference_gatherer_filter.rb
0 → 100644
View file @
d37cf642
require
'gitlab/markdown'
require
'html/pipeline/filter'
module
Gitlab
module
Markdown
# HTML filter that gathers all referenced records that the current user has
# permission to view.
#
# Expected to be run in its own post-processing pipeline.
#
class
ReferenceGathererFilter
<
HTML
::
Pipeline
::
Filter
def
initialize
(
*
)
super
result
[
:references
]
||=
Hash
.
new
{
|
hash
,
type
|
hash
[
type
]
=
[]
}
end
def
call
doc
.
css
(
'a.gfm'
).
each
do
|
node
|
gather_references
(
node
)
end
load_lazy_references
unless
context
[
:load_lazy_references
]
==
false
doc
end
private
def
gather_references
(
node
)
return
unless
node
.
has_attribute?
(
'data-reference-filter'
)
reference_type
=
node
.
attr
(
'data-reference-filter'
)
reference_filter
=
reference_type
.
constantize
return
if
context
[
:reference_filter
]
&&
reference_filter
!=
context
[
:reference_filter
]
return
unless
reference_filter
.
user_can_reference?
(
current_user
,
node
,
context
)
references
=
reference_filter
.
referenced_by
(
node
)
return
unless
references
references
.
each
do
|
type
,
values
|
Array
.
wrap
(
values
).
each
do
|
value
|
result
[
:references
][
type
]
<<
value
end
end
end
# Will load all references of one type using one query.
def
load_lazy_references
refs
=
result
[
:references
]
refs
.
each
do
|
type
,
values
|
refs
[
type
]
=
ReferenceFilter
::
LazyReference
.
load
(
values
)
end
end
def
current_user
context
[
:current_user
]
end
end
end
end
lib/gitlab/markdown/snippet_reference_filter.rb
View file @
d37cf642
...
@@ -27,6 +27,10 @@ module Gitlab
...
@@ -27,6 +27,10 @@ module Gitlab
end
end
end
end
def
self
.
referenced_by
(
node
)
{
snippet:
LazyReference
.
new
(
Snippet
,
node
.
attr
(
"data-snippet"
))
}
end
def
call
def
call
replace_text_nodes_matching
(
Snippet
.
reference_pattern
)
do
|
content
|
replace_text_nodes_matching
(
Snippet
.
reference_pattern
)
do
|
content
|
snippet_link_filter
(
content
)
snippet_link_filter
(
content
)
...
@@ -45,11 +49,9 @@ module Gitlab
...
@@ -45,11 +49,9 @@ module Gitlab
project
=
self
.
project_from_ref
(
project_ref
)
project
=
self
.
project_from_ref
(
project_ref
)
if
project
&&
snippet
=
project
.
snippets
.
find_by
(
id:
id
)
if
project
&&
snippet
=
project
.
snippets
.
find_by
(
id:
id
)
push_result
(
:snippet
,
snippet
)
title
=
escape_once
(
"Snippet:
#{
snippet
.
title
}
"
)
title
=
escape_once
(
"Snippet:
#{
snippet
.
title
}
"
)
klass
=
reference_class
(
:snippet
)
klass
=
reference_class
(
:snippet
)
data
=
data_attribute
(
project
.
id
)
data
=
data_attribute
(
project
:
project
.
id
,
snippet:
snippet
.
id
)
url
=
url_for_snippet
(
snippet
,
project
)
url
=
url_for_snippet
(
snippet
,
project
)
...
...
lib/gitlab/markdown/user_reference_filter.rb
View file @
d37cf642
...
@@ -23,6 +23,31 @@ module Gitlab
...
@@ -23,6 +23,31 @@ module Gitlab
end
end
end
end
def
self
.
referenced_by
(
node
)
if
node
.
has_attribute?
(
'data-group'
)
group
=
Group
.
find
(
node
.
attr
(
'data-group'
))
rescue
nil
return
unless
group
{
user:
group
.
users
}
elsif
node
.
has_attribute?
(
'data-user'
)
{
user:
LazyReference
.
new
(
User
,
node
.
attr
(
'data-user'
))
}
elsif
node
.
has_attribute?
(
'data-project'
)
project
=
Project
.
find
(
node
.
attr
(
'data-project'
))
rescue
nil
return
unless
project
{
user:
project
.
team
.
members
.
flatten
}
end
end
def
self
.
user_can_reference?
(
user
,
node
,
context
)
if
node
.
has_attribute?
(
'data-group'
)
group
=
Group
.
find
(
node
.
attr
(
'data-group'
))
rescue
nil
Ability
.
abilities
.
allowed?
(
user
,
:read_group
,
group
)
else
super
end
end
def
call
def
call
replace_text_nodes_matching
(
User
.
reference_pattern
)
do
|
content
|
replace_text_nodes_matching
(
User
.
reference_pattern
)
do
|
content
|
user_link_filter
(
content
)
user_link_filter
(
content
)
...
@@ -61,14 +86,12 @@ module Gitlab
...
@@ -61,14 +86,12 @@ module Gitlab
def
link_to_all
def
link_to_all
project
=
context
[
:project
]
project
=
context
[
:project
]
# FIXME (rspeicher): Law of Demeter
push_result
(
:user
,
*
project
.
team
.
members
.
flatten
)
url
=
urls
.
namespace_project_url
(
project
.
namespace
,
project
,
url
=
urls
.
namespace_project_url
(
project
.
namespace
,
project
,
only_path:
context
[
:only_path
])
only_path:
context
[
:only_path
])
data
=
data_attribute
(
project:
project
.
id
)
text
=
User
.
reference_prefix
+
'all'
text
=
User
.
reference_prefix
+
'all'
%(<a href="#{url}" class="#{link_class}">#{text}</a>)
%(<a href="#{url}"
#{data}
class="#{link_class}">#{text}</a>)
end
end
def
link_to_namespace
(
namespace
)
def
link_to_namespace
(
namespace
)
...
@@ -80,30 +103,20 @@ module Gitlab
...
@@ -80,30 +103,20 @@ module Gitlab
end
end
def
link_to_group
(
group
,
namespace
)
def
link_to_group
(
group
,
namespace
)
return
unless
user_can_reference_group?
(
namespace
)
push_result
(
:user
,
*
namespace
.
users
)
url
=
urls
.
group_url
(
group
,
only_path:
context
[
:only_path
])
url
=
urls
.
group_url
(
group
,
only_path:
context
[
:only_path
])
data
=
data_attribute
(
namespace
.
id
,
:group
)
data
=
data_attribute
(
group:
namespace
.
id
)
text
=
Group
.
reference_prefix
+
group
text
=
Group
.
reference_prefix
+
group
%(<a href="#{url}" #{data} class="#{link_class}">#{text}</a>)
%(<a href="#{url}" #{data} class="#{link_class}">#{text}</a>)
end
end
def
link_to_user
(
user
,
namespace
)
def
link_to_user
(
user
,
namespace
)
push_result
(
:user
,
namespace
.
owner
)
url
=
urls
.
user_url
(
user
,
only_path:
context
[
:only_path
])
url
=
urls
.
user_url
(
user
,
only_path:
context
[
:only_path
])
data
=
data_attribute
(
namespace
.
owner_id
,
:user
)
data
=
data_attribute
(
user:
namespace
.
owner_id
)
text
=
User
.
reference_prefix
+
user
text
=
User
.
reference_prefix
+
user
%(<a href="#{url}" #{data} class="#{link_class}">#{text}</a>)
%(<a href="#{url}" #{data} class="#{link_class}">#{text}</a>)
end
end
def
user_can_reference_group?
(
group
)
Ability
.
abilities
.
allowed?
(
context
[
:current_user
],
:read_group
,
group
)
end
end
end
end
end
end
end
lib/gitlab/reference_extractor.rb
View file @
d37cf642
...
@@ -3,11 +3,12 @@ require 'gitlab/markdown'
...
@@ -3,11 +3,12 @@ require 'gitlab/markdown'
module
Gitlab
module
Gitlab
# Extract possible GFM references from an arbitrary String for further processing.
# Extract possible GFM references from an arbitrary String for further processing.
class
ReferenceExtractor
class
ReferenceExtractor
attr_accessor
:project
,
:current_user
attr_accessor
:project
,
:current_user
,
:load_lazy_references
def
initialize
(
project
,
current_user
=
nil
)
def
initialize
(
project
,
current_user
=
nil
,
load_lazy_references:
true
)
@project
=
project
@project
=
project
@current_user
=
current_user
@current_user
=
current_user
@load_lazy_references
=
load_lazy_references
end
end
def
analyze
(
text
)
def
analyze
(
text
)
...
@@ -26,9 +27,9 @@ module Gitlab
...
@@ -26,9 +27,9 @@ module Gitlab
def
references
def
references
@references
||=
Hash
.
new
do
|
references
,
type
|
@references
||=
Hash
.
new
do
|
references
,
type
|
type
=
type
.
to_sym
type
=
type
.
to_sym
return
references
[
type
]
if
references
.
has_key?
(
type
)
next
references
[
type
]
if
references
.
has_key?
(
type
)
references
[
type
]
=
pipeline_result
(
type
)
.
uniq
references
[
type
]
=
pipeline_result
(
type
)
end
end
end
end
...
@@ -41,21 +42,32 @@ module Gitlab
...
@@ -41,21 +42,32 @@ module Gitlab
def
pipeline_result
(
filter_type
)
def
pipeline_result
(
filter_type
)
return
[]
if
@text
.
blank?
return
[]
if
@text
.
blank?
klass
=
filter_type
.
to_s
.
camelize
+
'ReferenceFilter'
klass
=
"
#{
filter_type
.
to_s
.
camelize
}
ReferenceFilter"
filter
=
Gitlab
::
Markdown
.
const_get
(
klass
)
filter
=
Gitlab
::
Markdown
.
const_get
(
klass
)
context
=
{
context
=
{
project:
project
,
project:
project
,
current_user:
current_user
,
current_user:
current_user
,
# We don't actually care about the links generated
# We don't actually care about the links generated
only_path:
true
,
only_path:
true
,
ignore_blockquotes:
true
ignore_blockquotes:
true
,
# ReferenceGathererFilter
load_lazy_references:
false
,
reference_filter:
filter
}
}
pipeline
=
HTML
::
Pipeline
.
new
([
filter
],
context
)
pipeline
=
HTML
::
Pipeline
.
new
([
filter
,
Gitlab
::
Markdown
::
ReferenceGathererFilter
],
context
)
result
=
pipeline
.
call
(
@text
)
result
=
pipeline
.
call
(
@text
)
result
[
:references
][
filter_type
]
values
=
result
[
:references
][
filter_type
].
uniq
if
@load_lazy_references
values
=
Gitlab
::
Markdown
::
ReferenceFilter
::
LazyReference
.
load
(
values
).
uniq
end
values
end
end
end
end
end
end
lib/tasks/gitlab/check.rake
View file @
d37cf642
...
@@ -335,7 +335,7 @@ namespace :gitlab do
...
@@ -335,7 +335,7 @@ namespace :gitlab do
print
"Redis version >=
#{
min_redis_version
}
? ... "
print
"Redis version >=
#{
min_redis_version
}
? ... "
redis_version
=
run
(
%W(redis-cli --version)
)
redis_version
=
run
(
%W(redis-cli --version)
)
redis_version
=
redis_version
.
try
(
:match
,
/redis-cli (
.*
)/
)
redis_version
=
redis_version
.
try
(
:match
,
/redis-cli (
\d+\.\d+\.\d+
)/
)
if
redis_version
&&
if
redis_version
&&
(
Gem
::
Version
.
new
(
redis_version
[
1
])
>
Gem
::
Version
.
new
(
min_redis_version
))
(
Gem
::
Version
.
new
(
redis_version
[
1
])
>
Gem
::
Version
.
new
(
min_redis_version
))
puts
"yes"
.
green
puts
"yes"
.
green
...
...
spec/benchmarks/lib/gitlab/markdown/reference_filter_spec.rb
0 → 100644
View file @
d37cf642
require
'spec_helper'
describe
Gitlab
::
Markdown
::
ReferenceFilter
,
benchmark:
true
do
let
(
:input
)
do
html
=
<<-
EOF
<p>Hello @alice and @bob, how are you doing today?</p>
<p>This is simple @dummy text to see how the @ReferenceFilter class performs
when @processing HTML.</p>
EOF
Nokogiri
::
HTML
.
fragment
(
html
)
end
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:filter
)
{
described_class
.
new
(
input
,
project:
project
)
}
describe
'#replace_text_nodes_matching'
do
let
(
:iterations
)
{
6000
}
describe
'with identical input and output HTML'
do
benchmark_subject
do
filter
.
replace_text_nodes_matching
(
User
.
reference_pattern
)
do
|
content
|
content
end
end
it
{
is_expected
.
to
iterate_per_second
(
iterations
)
}
end
describe
'with different input and output HTML'
do
benchmark_subject
do
filter
.
replace_text_nodes_matching
(
User
.
reference_pattern
)
do
|
content
|
'@eve'
end
end
it
{
is_expected
.
to
iterate_per_second
(
iterations
)
}
end
end
end
spec/benchmarks/models/milestone_spec.rb
0 → 100644
View file @
d37cf642
require
'spec_helper'
describe
Milestone
,
benchmark:
true
do
describe
'#sort_issues'
do
let
(
:milestone
)
{
create
(
:milestone
)
}
let
(
:issue1
)
{
create
(
:issue
,
milestone:
milestone
)
}
let
(
:issue2
)
{
create
(
:issue
,
milestone:
milestone
)
}
let
(
:issue3
)
{
create
(
:issue
,
milestone:
milestone
)
}
let
(
:issue_ids
)
{
[
issue3
.
id
,
issue2
.
id
,
issue1
.
id
]
}
benchmark_subject
{
milestone
.
sort_issues
(
issue_ids
)
}
it
{
is_expected
.
to
iterate_per_second
(
500
)
}
end
end
spec/controllers/abuse_reports_controller_spec.rb
0 → 100644
View file @
d37cf642
require
'spec_helper'
describe
AbuseReportsController
do
let
(
:reporter
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:message
)
{
"This user is a spammer"
}
before
do
sign_in
(
reporter
)
end
describe
"POST create"
do
context
"with admin notification email set"
do
let
(
:admin_email
)
{
"admin@example.com"
}
before
(
:each
)
do
stub_application_setting
(
admin_notification_email:
admin_email
)
end
it
"sends a notification email"
do
post
:create
,
abuse_report:
{
user_id:
user
.
id
,
message:
message
}
email
=
ActionMailer
::
Base
.
deliveries
.
last
expect
(
email
.
to
).
to
eq
([
admin_email
])
expect
(
email
.
subject
).
to
include
(
user
.
username
)
expect
(
email
.
text_part
.
body
).
to
include
(
message
)
end
it
"saves the abuse report"
do
expect
do
post
:create
,
abuse_report:
{
user_id:
user
.
id
,
message:
message
}
end
.
to
change
{
AbuseReport
.
count
}.
by
(
1
)
end
end
context
"without admin notification email set"
do
before
(
:each
)
do
stub_application_setting
(
admin_notification_email:
nil
)
end
it
"does not send a notification email"
do
expect
do
post
:create
,
abuse_report:
{
user_id:
user
.
id
,
message:
message
}
end
.
not_to
change
{
ActionMailer
::
Base
.
deliveries
.
count
}
end
it
"saves the abuse report"
do
expect
do
post
:create
,
abuse_report:
{
user_id:
user
.
id
,
message:
message
}
end
.
to
change
{
AbuseReport
.
count
}.
by
(
1
)
end
end
end
end
spec/controllers/admin/users_controller_spec.rb
View file @
d37cf642
...
@@ -37,6 +37,32 @@ describe Admin::UsersController do
...
@@ -37,6 +37,32 @@ describe Admin::UsersController do
end
end
end
end
describe
'PUT block/:id'
do
let
(
:user
)
{
create
(
:user
)
}
it
'blocks user'
do
put
:block
,
id:
user
.
username
user
.
reload
expect
(
user
.
blocked?
).
to
be_truthy
expect
(
flash
[
:notice
]).
to
eq
'Successfully blocked'
end
end
describe
'PUT unblock/:id'
do
let
(
:user
)
{
create
(
:user
)
}
before
do
user
.
block
end
it
'unblocks user'
do
put
:unblock
,
id:
user
.
username
user
.
reload
expect
(
user
.
blocked?
).
to
be_falsey
expect
(
flash
[
:notice
]).
to
eq
'Successfully unblocked'
end
end
describe
'PUT unlock/:id'
do
describe
'PUT unlock/:id'
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
...
...
spec/controllers/import/github_controller_spec.rb
View file @
d37cf642
...
@@ -41,7 +41,7 @@ describe Import::GithubController do
...
@@ -41,7 +41,7 @@ describe Import::GithubController do
it
"assigns variables"
do
it
"assigns variables"
do
@project
=
create
(
:project
,
import_type:
'github'
,
creator_id:
user
.
id
)
@project
=
create
(
:project
,
import_type:
'github'
,
creator_id:
user
.
id
)
stub_client
(
repos:
[
@repo
],
orgs:
[
@org
],
org_repos:
[
@org_repo
])
stub_client
(
repos:
[
@repo
,
@org_repo
],
orgs:
[
@org
],
org_repos:
[
@org_repo
])
get
:status
get
:status
...
...
spec/controllers/invites_controller_spec.rb
0 → 100644
View file @
d37cf642
require
'spec_helper'
describe
InvitesController
do
let
(
:token
)
{
'123456'
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:member
)
{
create
(
:project_member
,
invite_token:
token
,
invite_email:
'test@abc.com'
,
user:
user
)
}
before
do
controller
.
instance_variable_set
(
:@member
,
member
)
sign_in
(
user
)
end
describe
'GET #accept'
do
it
'accepts user'
do
get
:accept
,
id:
token
member
.
reload
expect
(
response
.
status
).
to
eq
(
302
)
expect
(
member
.
user
).
to
eq
(
user
)
expect
(
flash
[
:notice
]).
to
include
'You have been granted'
end
end
describe
'GET #decline'
do
it
'declines user'
do
get
:decline
,
id:
token
expect
{
member
.
reload
}.
to
raise_error
ActiveRecord
::
RecordNotFound
expect
(
response
.
status
).
to
eq
(
302
)
expect
(
flash
[
:notice
]).
to
include
'You have declined the invitation to join'
end
end
end
spec/controllers/projects/services_controller_spec.rb
View file @
d37cf642
...
@@ -10,26 +10,43 @@ describe Projects::ServicesController do
...
@@ -10,26 +10,43 @@ describe Projects::ServicesController do
project
.
team
<<
[
user
,
:master
]
project
.
team
<<
[
user
,
:master
]
controller
.
instance_variable_set
(
:@project
,
project
)
controller
.
instance_variable_set
(
:@project
,
project
)
controller
.
instance_variable_set
(
:@service
,
service
)
controller
.
instance_variable_set
(
:@service
,
service
)
request
.
env
[
"HTTP_REFERER"
]
=
"/"
end
end
describe
"#test"
do
shared_examples_for
'services controller'
do
|
referrer
|
context
'success'
do
before
do
it
"should redirect and show success message"
do
request
.
env
[
"HTTP_REFERER"
]
=
referrer
expect
(
service
).
to
receive
(
:test
).
and_return
({
success:
true
,
result:
'done'
})
get
:test
,
namespace_id:
project
.
namespace
.
id
,
project_id:
project
.
id
,
id:
service
.
id
,
format: :html
expect
(
response
.
status
).
to
redirect_to
(
'/'
)
expect
(
flash
[
:notice
]).
to
eq
(
'We sent a request to the provided URL'
)
end
end
end
context
'failure'
do
describe
"#test"
do
it
"should redirect and show failure message"
do
context
'success'
do
expect
(
service
).
to
receive
(
:test
).
and_return
({
success:
false
,
result:
'Bad test'
})
it
"should redirect and show success message"
do
get
:test
,
namespace_id:
project
.
namespace
.
id
,
project_id:
project
.
id
,
id:
service
.
id
,
format: :html
expect
(
service
).
to
receive
(
:test
).
and_return
({
success:
true
,
result:
'done'
})
expect
(
response
.
status
).
to
redirect_to
(
'/'
)
get
:test
,
namespace_id:
project
.
namespace
.
id
,
project_id:
project
.
id
,
id:
service
.
id
,
format: :html
expect
(
flash
[
:alert
]).
to
eq
(
'We tried to send a request to the provided URL but an error occurred: Bad test'
)
expect
(
response
.
status
).
to
redirect_to
(
'/'
)
expect
(
flash
[
:notice
]).
to
eq
(
'We sent a request to the provided URL'
)
end
end
context
'failure'
do
it
"should redirect and show failure message"
do
expect
(
service
).
to
receive
(
:test
).
and_return
({
success:
false
,
result:
'Bad test'
})
get
:test
,
namespace_id:
project
.
namespace
.
id
,
project_id:
project
.
id
,
id:
service
.
id
,
format: :html
expect
(
response
.
status
).
to
redirect_to
(
'/'
)
expect
(
flash
[
:alert
]).
to
eq
(
'We tried to send a request to the provided URL but an error occurred: Bad test'
)
end
end
end
end
end
end
end
describe
'referrer defined'
do
it_should_behave_like
'services controller'
do
let!
(
:referrer
)
{
"/"
}
end
end
describe
'referrer undefined'
do
it_should_behave_like
'services controller'
do
let!
(
:referrer
)
{
nil
}
end
end
end
end
spec/controllers/projects_controller_spec.rb
View file @
d37cf642
...
@@ -22,6 +22,34 @@ describe ProjectsController do
...
@@ -22,6 +22,34 @@ describe ProjectsController do
end
end
end
end
context
"rendering default project view"
do
render_views
it
"renders the activity view"
do
allow
(
controller
).
to
receive
(
:current_user
).
and_return
(
user
)
allow
(
user
).
to
receive
(
:project_view
).
and_return
(
'activity'
)
get
:show
,
namespace_id:
public_project
.
namespace
.
path
,
id:
public_project
.
path
expect
(
response
).
to
render_template
(
'_activity'
)
end
it
"renders the readme view"
do
allow
(
controller
).
to
receive
(
:current_user
).
and_return
(
user
)
allow
(
user
).
to
receive
(
:project_view
).
and_return
(
'readme'
)
get
:show
,
namespace_id:
public_project
.
namespace
.
path
,
id:
public_project
.
path
expect
(
response
).
to
render_template
(
'_readme'
)
end
it
"renders the files view"
do
allow
(
controller
).
to
receive
(
:current_user
).
and_return
(
user
)
allow
(
user
).
to
receive
(
:project_view
).
and_return
(
'files'
)
get
:show
,
namespace_id:
public_project
.
namespace
.
path
,
id:
public_project
.
path
expect
(
response
).
to
render_template
(
'_files'
)
end
end
context
"when requested with case sensitive namespace and project path"
do
context
"when requested with case sensitive namespace and project path"
do
it
"redirects to the normalized path for case mismatch"
do
it
"redirects to the normalized path for case mismatch"
do
get
:show
,
namespace_id:
public_project
.
namespace
.
path
,
id:
public_project
.
path
.
upcase
get
:show
,
namespace_id:
public_project
.
namespace
.
path
,
id:
public_project
.
path
.
upcase
...
@@ -62,4 +90,50 @@ describe ProjectsController do
...
@@ -62,4 +90,50 @@ describe ProjectsController do
expect
(
user
.
starred?
(
public_project
)).
to
be_falsey
expect
(
user
.
starred?
(
public_project
)).
to
be_falsey
end
end
end
end
describe
"DELETE remove_fork"
do
context
'when signed in'
do
before
do
sign_in
(
user
)
end
context
'with forked project'
do
let
(
:project_fork
)
{
create
(
:project
,
namespace:
user
.
namespace
)
}
before
do
create
(
:forked_project_link
,
forked_to_project:
project_fork
)
end
it
'should remove fork from project'
do
delete
(
:remove_fork
,
namespace_id:
project_fork
.
namespace
.
to_param
,
id:
project_fork
.
to_param
,
format: :js
)
expect
(
project_fork
.
forked?
).
to
be_falsey
expect
(
flash
[
:notice
]).
to
eq
(
'The fork relationship has been removed.'
)
expect
(
response
).
to
render_template
(
:remove_fork
)
end
end
context
'when project not forked'
do
let
(
:unforked_project
)
{
create
(
:project
,
namespace:
user
.
namespace
)
}
it
'should do nothing if project was not forked'
do
delete
(
:remove_fork
,
namespace_id:
unforked_project
.
namespace
.
to_param
,
id:
unforked_project
.
to_param
,
format: :js
)
expect
(
flash
[
:notice
]).
to
be_nil
expect
(
response
).
to
render_template
(
:remove_fork
)
end
end
end
it
"does nothing if user is not signed in"
do
delete
(
:remove_fork
,
namespace_id:
project
.
namespace
.
to_param
,
id:
project
.
to_param
,
format: :js
)
expect
(
response
.
status
).
to
eq
(
401
)
end
end
end
end
spec/features/markdown_spec.rb
View file @
d37cf642
...
@@ -220,7 +220,7 @@ describe 'GitLab Markdown', feature: true do
...
@@ -220,7 +220,7 @@ describe 'GitLab Markdown', feature: true do
end
end
end
end
#
`markdown` calls these two methods
#
Fake a `current_user` helper
def
current_user
def
current_user
@feat
.
user
@feat
.
user
end
end
...
...
spec/features/projects_spec.rb
View file @
d37cf642
...
@@ -34,6 +34,27 @@ feature 'Project', feature: true do
...
@@ -34,6 +34,27 @@ feature 'Project', feature: true do
end
end
end
end
describe
'remove forked relationship'
,
js:
true
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:project
)
{
create
(
:project
,
namespace:
user
.
namespace
)
}
before
do
login_with
user
create
(
:forked_project_link
,
forked_to_project:
project
)
visit
edit_namespace_project_path
(
project
.
namespace
,
project
)
end
it
'should remove fork'
do
expect
(
page
).
to
have_content
'Remove fork relationship'
remove_with_confirm
(
'Remove fork relationship'
,
project
.
path
)
expect
(
page
).
to
have_content
'The fork relationship has been removed.'
expect
(
project
.
forked?
).
to
be_falsey
expect
(
page
).
not_to
have_content
'Remove fork relationship'
end
end
describe
'removal'
,
js:
true
do
describe
'removal'
,
js:
true
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:project
)
{
create
(
:project
,
namespace:
user
.
namespace
)
}
let
(
:project
)
{
create
(
:project
,
namespace:
user
.
namespace
)
}
...
@@ -45,13 +66,13 @@ feature 'Project', feature: true do
...
@@ -45,13 +66,13 @@ feature 'Project', feature: true do
end
end
it
'should remove project'
do
it
'should remove project'
do
expect
{
remove_
project
}.
to
change
{
Project
.
count
}.
by
(
-
1
)
expect
{
remove_
with_confirm
(
'Remove project'
,
project
.
path
)
}.
to
change
{
Project
.
count
}.
by
(
-
1
)
end
end
end
end
def
remove_
project
def
remove_
with_confirm
(
button_text
,
confirm_with
)
click_button
"Remove project"
click_button
button_text
fill_in
'confirm_name_input'
,
with:
project
.
pa
th
fill_in
'confirm_name_input'
,
with:
confirm_wi
th
click_button
'Confirm'
click_button
'Confirm'
end
end
end
end
spec/helpers/gitlab_markdown_helper_spec.rb
View file @
d37cf642
...
@@ -11,12 +11,15 @@ describe GitlabMarkdownHelper do
...
@@ -11,12 +11,15 @@ describe GitlabMarkdownHelper do
let
(
:merge_request
)
{
create
(
:merge_request
,
source_project:
project
,
target_project:
project
)
}
let
(
:merge_request
)
{
create
(
:merge_request
,
source_project:
project
,
target_project:
project
)
}
let
(
:snippet
)
{
create
(
:project_snippet
,
project:
project
)
}
let
(
:snippet
)
{
create
(
:project_snippet
,
project:
project
)
}
# Helper expects a current_user method.
let
(
:current_user
)
{
user
}
before
do
before
do
# Ensure the generated reference links aren't redacted
project
.
team
<<
[
user
,
:master
]
# Helper expects a @project instance variable
# Helper expects a @project instance variable
@project
=
project
helper
.
instance_variable_set
(
:@project
,
project
)
# Stub the `current_user` helper
allow
(
helper
).
to
receive
(
:current_user
).
and_return
(
user
)
end
end
describe
"#markdown"
do
describe
"#markdown"
do
...
@@ -25,23 +28,23 @@ describe GitlabMarkdownHelper do
...
@@ -25,23 +28,23 @@ describe GitlabMarkdownHelper do
it
"should link to the merge request"
do
it
"should link to the merge request"
do
expected
=
namespace_project_merge_request_path
(
project
.
namespace
,
project
,
merge_request
)
expected
=
namespace_project_merge_request_path
(
project
.
namespace
,
project
,
merge_request
)
expect
(
markdown
(
actual
)).
to
match
(
expected
)
expect
(
helper
.
markdown
(
actual
)).
to
match
(
expected
)
end
end
it
"should link to the commit"
do
it
"should link to the commit"
do
expected
=
namespace_project_commit_path
(
project
.
namespace
,
project
,
commit
)
expected
=
namespace_project_commit_path
(
project
.
namespace
,
project
,
commit
)
expect
(
markdown
(
actual
)).
to
match
(
expected
)
expect
(
helper
.
markdown
(
actual
)).
to
match
(
expected
)
end
end
it
"should link to the issue"
do
it
"should link to the issue"
do
expected
=
namespace_project_issue_path
(
project
.
namespace
,
project
,
issue
)
expected
=
namespace_project_issue_path
(
project
.
namespace
,
project
,
issue
)
expect
(
markdown
(
actual
)).
to
match
(
expected
)
expect
(
helper
.
markdown
(
actual
)).
to
match
(
expected
)
end
end
end
end
describe
"override default project"
do
describe
"override default project"
do
let
(
:actual
)
{
issue
.
to_reference
}
let
(
:actual
)
{
issue
.
to_reference
}
let
(
:second_project
)
{
create
(
:project
)
}
let
(
:second_project
)
{
create
(
:project
,
:public
)
}
let
(
:second_issue
)
{
create
(
:issue
,
project:
second_project
)
}
let
(
:second_issue
)
{
create
(
:issue
,
project:
second_project
)
}
it
'should link to the issue'
do
it
'should link to the issue'
do
...
@@ -56,7 +59,7 @@ describe GitlabMarkdownHelper do
...
@@ -56,7 +59,7 @@ describe GitlabMarkdownHelper do
let
(
:issues
)
{
create_list
(
:issue
,
2
,
project:
project
)
}
let
(
:issues
)
{
create_list
(
:issue
,
2
,
project:
project
)
}
it
'should handle references nested in links with all the text'
do
it
'should handle references nested in links with all the text'
do
actual
=
link_to_gfm
(
"This should finally fix
#{
issues
[
0
].
to_reference
}
and
#{
issues
[
1
].
to_reference
}
for real"
,
commit_path
)
actual
=
helper
.
link_to_gfm
(
"This should finally fix
#{
issues
[
0
].
to_reference
}
and
#{
issues
[
1
].
to_reference
}
for real"
,
commit_path
)
doc
=
Nokogiri
::
HTML
.
parse
(
actual
)
doc
=
Nokogiri
::
HTML
.
parse
(
actual
)
# Make sure we didn't create invalid markup
# Make sure we didn't create invalid markup
...
@@ -86,7 +89,7 @@ describe GitlabMarkdownHelper do
...
@@ -86,7 +89,7 @@ describe GitlabMarkdownHelper do
end
end
it
'should forward HTML options'
do
it
'should forward HTML options'
do
actual
=
link_to_gfm
(
"Fixed in
#{
commit
.
id
}
"
,
commit_path
,
class:
'foo'
)
actual
=
helper
.
link_to_gfm
(
"Fixed in
#{
commit
.
id
}
"
,
commit_path
,
class:
'foo'
)
doc
=
Nokogiri
::
HTML
.
parse
(
actual
)
doc
=
Nokogiri
::
HTML
.
parse
(
actual
)
expect
(
doc
.
css
(
'a'
)).
to
satisfy
do
|
v
|
expect
(
doc
.
css
(
'a'
)).
to
satisfy
do
|
v
|
...
@@ -97,13 +100,13 @@ describe GitlabMarkdownHelper do
...
@@ -97,13 +100,13 @@ describe GitlabMarkdownHelper do
it
"escapes HTML passed in as the body"
do
it
"escapes HTML passed in as the body"
do
actual
=
"This is a <h1>test</h1> - see
#{
issues
[
0
].
to_reference
}
"
actual
=
"This is a <h1>test</h1> - see
#{
issues
[
0
].
to_reference
}
"
expect
(
link_to_gfm
(
actual
,
commit_path
)).
expect
(
helper
.
link_to_gfm
(
actual
,
commit_path
)).
to
match
(
'<h1>test</h1>'
)
to
match
(
'<h1>test</h1>'
)
end
end
it
'ignores reference links when they are the entire body'
do
it
'ignores reference links when they are the entire body'
do
text
=
issues
[
0
].
to_reference
text
=
issues
[
0
].
to_reference
act
=
link_to_gfm
(
text
,
'/foo'
)
act
=
helper
.
link_to_gfm
(
text
,
'/foo'
)
expect
(
act
).
to
eq
%Q(<a href="/foo">
#{
issues
[
0
].
to_reference
}
</a>)
expect
(
act
).
to
eq
%Q(<a href="/foo">
#{
issues
[
0
].
to_reference
}
</a>)
end
end
...
...
spec/helpers/issues_helper_spec.rb
View file @
d37cf642
...
@@ -117,4 +117,14 @@ describe IssuesHelper do
...
@@ -117,4 +117,14 @@ describe IssuesHelper do
end
end
end
end
describe
"#merge_requests_sentence"
do
subject
{
merge_requests_sentence
(
merge_requests
)}
let
(
:merge_requests
)
do
[
build
(
:merge_request
,
iid:
1
),
build
(
:merge_request
,
iid:
2
),
build
(
:merge_request
,
iid:
3
)]
end
it
{
is_expected
.
to
eq
(
"!1, !2, or !3"
)
}
end
end
end
spec/lib/gitlab/closing_issue_extractor_spec.rb
View file @
d37cf642
...
@@ -140,28 +140,28 @@ describe Gitlab::ClosingIssueExtractor do
...
@@ -140,28 +140,28 @@ describe Gitlab::ClosingIssueExtractor do
message
=
"Closes
#{
reference
}
and fix
#{
reference2
}
"
message
=
"Closes
#{
reference
}
and fix
#{
reference2
}
"
expect
(
subject
.
closed_by_message
(
message
)).
expect
(
subject
.
closed_by_message
(
message
)).
to
eq
([
issue
,
other_issue
])
to
match_array
([
issue
,
other_issue
])
end
end
it
'fetches comma-separated issues references in single line message'
do
it
'fetches comma-separated issues references in single line message'
do
message
=
"Closes
#{
reference
}
, closes
#{
reference2
}
"
message
=
"Closes
#{
reference
}
, closes
#{
reference2
}
"
expect
(
subject
.
closed_by_message
(
message
)).
expect
(
subject
.
closed_by_message
(
message
)).
to
eq
([
issue
,
other_issue
])
to
match_array
([
issue
,
other_issue
])
end
end
it
'fetches comma-separated issues numbers in single line message'
do
it
'fetches comma-separated issues numbers in single line message'
do
message
=
"Closes
#{
reference
}
,
#{
reference2
}
and
#{
reference3
}
"
message
=
"Closes
#{
reference
}
,
#{
reference2
}
and
#{
reference3
}
"
expect
(
subject
.
closed_by_message
(
message
)).
expect
(
subject
.
closed_by_message
(
message
)).
to
eq
([
issue
,
other_issue
,
third_issue
])
to
match_array
([
issue
,
other_issue
,
third_issue
])
end
end
it
'fetches issues in multi-line message'
do
it
'fetches issues in multi-line message'
do
message
=
"Awesome commit (closes
#{
reference
}
)
\n
Also fixes
#{
reference2
}
"
message
=
"Awesome commit (closes
#{
reference
}
)
\n
Also fixes
#{
reference2
}
"
expect
(
subject
.
closed_by_message
(
message
)).
expect
(
subject
.
closed_by_message
(
message
)).
to
eq
([
issue
,
other_issue
])
to
match_array
([
issue
,
other_issue
])
end
end
it
'fetches issues in hybrid message'
do
it
'fetches issues in hybrid message'
do
...
@@ -169,7 +169,7 @@ describe Gitlab::ClosingIssueExtractor do
...
@@ -169,7 +169,7 @@ describe Gitlab::ClosingIssueExtractor do
"Also fixing issues
#{
reference2
}
,
#{
reference3
}
and #4"
"Also fixing issues
#{
reference2
}
,
#{
reference3
}
and #4"
expect
(
subject
.
closed_by_message
(
message
)).
expect
(
subject
.
closed_by_message
(
message
)).
to
eq
([
issue
,
other_issue
,
third_issue
])
to
match_array
([
issue
,
other_issue
,
third_issue
])
end
end
end
end
end
end
...
...
spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb
View file @
d37cf642
...
@@ -4,7 +4,7 @@ module Gitlab::Markdown
...
@@ -4,7 +4,7 @@ module Gitlab::Markdown
describe
CommitRangeReferenceFilter
do
describe
CommitRangeReferenceFilter
do
include
FilterSpecHelper
include
FilterSpecHelper
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
,
:public
)
}
let
(
:commit1
)
{
project
.
commit
}
let
(
:commit1
)
{
project
.
commit
}
let
(
:commit2
)
{
project
.
commit
(
"HEAD~2"
)
}
let
(
:commit2
)
{
project
.
commit
(
"HEAD~2"
)
}
...
@@ -75,12 +75,20 @@ module Gitlab::Markdown
...
@@ -75,12 +75,20 @@ module Gitlab::Markdown
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-commit_range'
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-commit_range'
end
end
it
'includes a data-project
-id
attribute'
do
it
'includes a data-project attribute'
do
doc
=
filter
(
"See
#{
reference
}
"
)
doc
=
filter
(
"See
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-project-id'
)
expect
(
link
).
to
have_attribute
(
'data-project'
)
expect
(
link
.
attr
(
'data-project-id'
)).
to
eq
project
.
id
.
to_s
expect
(
link
.
attr
(
'data-project'
)).
to
eq
project
.
id
.
to_s
end
it
'includes a data-commit-range attribute'
do
doc
=
filter
(
"See
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-commit-range'
)
expect
(
link
.
attr
(
'data-commit-range'
)).
to
eq
range
.
to_reference
end
end
it
'supports an :only_path option'
do
it
'supports an :only_path option'
do
...
@@ -92,59 +100,45 @@ module Gitlab::Markdown
...
@@ -92,59 +100,45 @@ module Gitlab::Markdown
end
end
it
'adds to the results hash'
do
it
'adds to the results hash'
do
result
=
pipeline_result
(
"See
#{
reference
}
"
)
result
=
reference_
pipeline_result
(
"See
#{
reference
}
"
)
expect
(
result
[
:references
][
:commit_range
]).
not_to
be_empty
expect
(
result
[
:references
][
:commit_range
]).
not_to
be_empty
end
end
end
end
context
'cross-project reference'
do
context
'cross-project reference'
do
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
let
(
:project2
)
{
create
(
:project
,
namespace:
namespace
)
}
let
(
:project2
)
{
create
(
:project
,
:public
,
namespace:
namespace
)
}
let
(
:reference
)
{
range
.
to_reference
(
project
)
}
let
(
:reference
)
{
range
.
to_reference
(
project
)
}
before
do
before
do
range
.
project
=
project2
range
.
project
=
project2
end
end
context
'when user can access reference'
do
it
'links to a valid reference'
do
before
{
allow_cross_reference!
}
doc
=
filter
(
"See
#{
reference
}
"
)
it
'links to a valid reference'
do
doc
=
filter
(
"See
#{
reference
}
"
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
namespace_project_compare_url
(
project2
.
namespace
,
project2
,
range
.
to_param
)
end
it
'links with adjacent text'
do
doc
=
filter
(
"Fixed (
#{
reference
}
.)"
)
exp
=
Regexp
.
escape
(
"
#{
project2
.
to_reference
}
@
#{
range
.
to_s
}
"
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
exp
}
<\/a>\.\)/
)
end
it
'ignores invalid commit IDs on the referenced project'
do
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
exp
=
act
=
"Fixed
#{
project2
.
to_reference
}
@
#{
commit1
.
id
.
reverse
}
...
#{
commit2
.
id
}
"
to
eq
urls
.
namespace_project_compare_url
(
project2
.
namespace
,
project2
,
range
.
to_param
)
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
exp
=
act
=
"Fixed
#{
project2
.
to_reference
}
@
#{
commit1
.
id
}
...
#{
commit2
.
id
.
reverse
}
"
it
'links with adjacent text'
do
expect
(
filter
(
act
).
to_html
).
to
eq
exp
doc
=
filter
(
"Fixed (
#{
reference
}
.)"
)
end
it
'adds to the results hash'
do
exp
=
Regexp
.
escape
(
"
#{
project2
.
to_reference
}
@
#{
range
.
to_s
}
"
)
result
=
pipeline_result
(
"See
#{
reference
}
"
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
exp
}
<\/a>\.\)/
)
expect
(
result
[
:references
][
:commit_range
]).
not_to
be_empty
end
end
end
context
'when user cannot access reference'
do
it
'ignores invalid commit IDs on the referenced project'
do
before
{
disallow_cross_reference!
}
exp
=
act
=
"Fixed
#{
project2
.
to_reference
}
@
#{
commit1
.
id
.
reverse
}
...
#{
commit2
.
id
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
it
'ignores valid references'
do
exp
=
act
=
"Fixed
#{
project2
.
to_reference
}
@
#{
commit1
.
id
}
...
#{
commit2
.
id
.
reverse
}
"
exp
=
act
=
"See
#{
reference
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
expect
(
filter
(
act
).
to_html
).
to
eq
exp
it
'adds to the results hash'
do
end
result
=
reference_pipeline_result
(
"See
#{
reference
}
"
)
expect
(
result
[
:references
][
:commit_range
]).
not_to
be_empty
end
end
end
end
end
end
...
...
spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
View file @
d37cf642
...
@@ -4,7 +4,7 @@ module Gitlab::Markdown
...
@@ -4,7 +4,7 @@ module Gitlab::Markdown
describe
CommitReferenceFilter
do
describe
CommitReferenceFilter
do
include
FilterSpecHelper
include
FilterSpecHelper
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
,
:public
)
}
let
(
:commit
)
{
project
.
commit
}
let
(
:commit
)
{
project
.
commit
}
it
'requires project context'
do
it
'requires project context'
do
...
@@ -71,12 +71,20 @@ module Gitlab::Markdown
...
@@ -71,12 +71,20 @@ module Gitlab::Markdown
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-commit'
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-commit'
end
end
it
'includes a data-project
-id
attribute'
do
it
'includes a data-project attribute'
do
doc
=
filter
(
"See
#{
reference
}
"
)
doc
=
filter
(
"See
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-project-id'
)
expect
(
link
).
to
have_attribute
(
'data-project'
)
expect
(
link
.
attr
(
'data-project-id'
)).
to
eq
project
.
id
.
to_s
expect
(
link
.
attr
(
'data-project'
)).
to
eq
project
.
id
.
to_s
end
it
'includes a data-commit attribute'
do
doc
=
filter
(
"See
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-commit'
)
expect
(
link
.
attr
(
'data-commit'
)).
to
eq
commit
.
id
end
end
it
'supports an :only_path context'
do
it
'supports an :only_path context'
do
...
@@ -88,53 +96,39 @@ module Gitlab::Markdown
...
@@ -88,53 +96,39 @@ module Gitlab::Markdown
end
end
it
'adds to the results hash'
do
it
'adds to the results hash'
do
result
=
pipeline_result
(
"See
#{
reference
}
"
)
result
=
reference_
pipeline_result
(
"See
#{
reference
}
"
)
expect
(
result
[
:references
][
:commit
]).
not_to
be_empty
expect
(
result
[
:references
][
:commit
]).
not_to
be_empty
end
end
end
end
context
'cross-project reference'
do
context
'cross-project reference'
do
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
let
(
:project2
)
{
create
(
:project
,
namespace:
namespace
)
}
let
(
:project2
)
{
create
(
:project
,
:public
,
namespace:
namespace
)
}
let
(
:commit
)
{
project2
.
commit
}
let
(
:commit
)
{
project2
.
commit
}
let
(
:reference
)
{
commit
.
to_reference
(
project
)
}
let
(
:reference
)
{
commit
.
to_reference
(
project
)
}
context
'when user can access reference'
do
it
'links to a valid reference'
do
before
{
allow_cross_reference!
}
doc
=
filter
(
"See
#{
reference
}
"
)
it
'links to a valid reference'
do
doc
=
filter
(
"See
#{
reference
}
"
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
namespace_project_commit_url
(
project2
.
namespace
,
project2
,
commit
.
id
)
end
it
'links with adjacent text'
do
doc
=
filter
(
"Fixed (
#{
reference
}
.)"
)
exp
=
Regexp
.
escape
(
project2
.
to_reference
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
exp
}
@
#{
commit
.
short_id
}
<\/a>\.\)/
)
to
eq
urls
.
namespace_project_commit_url
(
project2
.
namespace
,
project2
,
commit
.
id
)
end
end
it
'ignores invalid commit IDs on the referenced project'
do
it
'links with adjacent text'
do
exp
=
act
=
"Committed
#{
invalidate_reference
(
reference
)
}
"
doc
=
filter
(
"Fixed (
#{
reference
}
.)"
)
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
it
'adds to the results hash'
do
exp
=
Regexp
.
escape
(
project2
.
to_reference
)
result
=
pipeline_result
(
"See
#{
reference
}
"
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
exp
}
@
#{
commit
.
short_id
}
<\/a>\.\)/
)
expect
(
result
[
:references
][
:commit
]).
not_to
be_empty
end
end
end
context
'when user cannot access reference'
do
it
'ignores invalid commit IDs on the referenced project'
do
before
{
disallow_cross_reference!
}
exp
=
act
=
"Committed
#{
invalidate_reference
(
reference
)
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
it
'ignores valid references'
do
end
exp
=
act
=
"See
#{
reference
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
it
'adds to the results hash'
do
end
result
=
reference_pipeline_result
(
"See
#{
reference
}
"
)
expect
(
result
[
:references
][
:commit
]).
not_to
be_empty
end
end
end
end
end
end
...
...
spec/lib/gitlab/markdown/cross_project_reference_spec.rb
View file @
d37cf642
...
@@ -2,20 +2,16 @@ require 'spec_helper'
...
@@ -2,20 +2,16 @@ require 'spec_helper'
module
Gitlab::Markdown
module
Gitlab::Markdown
describe
CrossProjectReference
do
describe
CrossProjectReference
do
# context in the html-pipeline sense, not in the rspec sense
let
(
:context
)
do
{
current_user:
double
(
'user'
),
project:
double
(
'project'
)
}
end
include
described_class
include
described_class
describe
'#project_from_ref'
do
describe
'#project_from_ref'
do
context
'when no project was referenced'
do
context
'when no project was referenced'
do
it
'returns the project from context'
do
it
'returns the project from context'
do
expect
(
project_from_ref
(
nil
)).
to
eq
context
[
:project
]
project
=
double
allow
(
self
).
to
receive
(
:context
).
and_return
({
project:
project
})
expect
(
project_from_ref
(
nil
)).
to
eq
project
end
end
end
end
...
@@ -26,29 +22,13 @@ module Gitlab::Markdown
...
@@ -26,29 +22,13 @@ module Gitlab::Markdown
end
end
context
'when referenced project exists'
do
context
'when referenced project exists'
do
let
(
:project2
)
{
double
(
'referenced project'
)
}
it
'returns the referenced project'
do
project2
=
double
(
'referenced project'
)
before
do
expect
(
Project
).
to
receive
(
:find_with_namespace
).
expect
(
Project
).
to
receive
(
:find_with_namespace
).
with
(
'cross/reference'
).
and_return
(
project2
)
with
(
'cross/reference'
).
and_return
(
project2
)
end
context
'and the user has permission to read it'
do
it
'returns the referenced project'
do
expect
(
self
).
to
receive
(
:user_can_reference_project?
).
with
(
project2
).
and_return
(
true
)
expect
(
project_from_ref
(
'cross/reference'
)).
to
eq
project2
end
end
context
'and the user does not have permission to read it'
do
it
'returns nil'
do
expect
(
self
).
to
receive
(
:user_can_reference_project?
).
with
(
project2
).
and_return
(
false
)
expect
(
project_from_ref
(
'cross/reference'
)).
to
be_nil
expect
(
project_from_ref
(
'cross/reference'
)).
to
eq
project2
end
end
end
end
end
end
end
...
...
spec/lib/gitlab/markdown/issue_reference_filter_spec.rb
View file @
d37cf642
...
@@ -8,7 +8,7 @@ module Gitlab::Markdown
...
@@ -8,7 +8,7 @@ module Gitlab::Markdown
IssuesHelper
IssuesHelper
end
end
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:project
)
{
create
(
:empty_project
,
:public
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
it
'requires project context'
do
it
'requires project context'
do
...
@@ -68,12 +68,20 @@ module Gitlab::Markdown
...
@@ -68,12 +68,20 @@ module Gitlab::Markdown
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-issue'
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-issue'
end
end
it
'includes a data-project
-id
attribute'
do
it
'includes a data-project attribute'
do
doc
=
filter
(
"Issue
#{
reference
}
"
)
doc
=
filter
(
"Issue
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-project-id'
)
expect
(
link
).
to
have_attribute
(
'data-project'
)
expect
(
link
.
attr
(
'data-project-id'
)).
to
eq
project
.
id
.
to_s
expect
(
link
.
attr
(
'data-project'
)).
to
eq
project
.
id
.
to_s
end
it
'includes a data-issue attribute'
do
doc
=
filter
(
"See
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-issue'
)
expect
(
link
.
attr
(
'data-issue'
)).
to
eq
issue
.
id
.
to_s
end
end
it
'supports an :only_path context'
do
it
'supports an :only_path context'
do
...
@@ -85,60 +93,46 @@ module Gitlab::Markdown
...
@@ -85,60 +93,46 @@ module Gitlab::Markdown
end
end
it
'adds to the results hash'
do
it
'adds to the results hash'
do
result
=
pipeline_result
(
"Fixed
#{
reference
}
"
)
result
=
reference_
pipeline_result
(
"Fixed
#{
reference
}
"
)
expect
(
result
[
:references
][
:issue
]).
to
eq
[
issue
]
expect
(
result
[
:references
][
:issue
]).
to
eq
[
issue
]
end
end
end
end
context
'cross-project reference'
do
context
'cross-project reference'
do
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
let
(
:project2
)
{
create
(
:empty_project
,
namespace:
namespace
)
}
let
(
:project2
)
{
create
(
:empty_project
,
:public
,
namespace:
namespace
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project2
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project2
)
}
let
(
:reference
)
{
issue
.
to_reference
(
project
)
}
let
(
:reference
)
{
issue
.
to_reference
(
project
)
}
context
'when user can access reference'
do
it
'ignores valid references when cross-reference project uses external tracker'
do
before
{
allow_cross_reference!
}
expect_any_instance_of
(
Project
).
to
receive
(
:get_issue
).
with
(
issue
.
iid
).
and_return
(
nil
)
it
'ignores valid references when cross-reference project uses external tracker'
do
expect_any_instance_of
(
Project
).
to
receive
(
:get_issue
).
with
(
issue
.
iid
).
and_return
(
nil
)
exp
=
act
=
"Issue
#{
reference
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
it
'links to a valid reference'
do
exp
=
act
=
"Issue
#{
reference
}
"
doc
=
filter
(
"See
#{
reference
}
"
)
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
helper
.
url_for_issue
(
issue
.
iid
,
project2
)
end
it
'links with adjacent text'
do
doc
=
filter
(
"Fixed (
#{
reference
}
.)"
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
it
'ignores invalid issue IDs on the referenced project
'
do
it
'links to a valid reference
'
do
exp
=
act
=
"Fixed
#{
invalidate_reference
(
reference
)
}
"
doc
=
filter
(
"See
#{
reference
}
"
)
expect
(
filter
(
act
).
to_html
).
to
eq
exp
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
end
to
eq
helper
.
url_for_issue
(
issue
.
iid
,
project2
)
end
it
'adds to the results hash'
do
it
'links with adjacent text'
do
result
=
pipeline_result
(
"Fixed
#{
reference
}
"
)
doc
=
filter
(
"Fixed (
#{
reference
}
.)"
)
expect
(
result
[
:references
][
:issue
]).
to
eq
[
issue
]
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
end
end
context
'when user cannot access reference
'
do
it
'ignores invalid issue IDs on the referenced project
'
do
before
{
disallow_cross_reference!
}
exp
=
act
=
"Fixed
#{
invalidate_reference
(
reference
)
}
"
it
'ignores valid references'
do
expect
(
filter
(
act
).
to_html
).
to
eq
exp
exp
=
act
=
"See
#{
reference
}
"
end
expect
(
filter
(
act
).
to_html
).
to
eq
exp
it
'adds to the results hash'
do
end
result
=
reference_pipeline_result
(
"Fixed
#{
reference
}
"
)
expect
(
result
[
:references
][
:issue
]).
to
eq
[
issue
]
end
end
end
end
end
end
...
...
spec/lib/gitlab/markdown/label_reference_filter_spec.rb
View file @
d37cf642
...
@@ -5,7 +5,7 @@ module Gitlab::Markdown
...
@@ -5,7 +5,7 @@ module Gitlab::Markdown
describe
LabelReferenceFilter
do
describe
LabelReferenceFilter
do
include
FilterSpecHelper
include
FilterSpecHelper
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:project
)
{
create
(
:empty_project
,
:public
)
}
let
(
:label
)
{
create
(
:label
,
project:
project
)
}
let
(
:label
)
{
create
(
:label
,
project:
project
)
}
let
(
:reference
)
{
label
.
to_reference
}
let
(
:reference
)
{
label
.
to_reference
}
...
@@ -25,12 +25,20 @@ module Gitlab::Markdown
...
@@ -25,12 +25,20 @@ module Gitlab::Markdown
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-label'
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-label'
end
end
it
'includes a data-project
-id
attribute'
do
it
'includes a data-project attribute'
do
doc
=
filter
(
"Label
#{
reference
}
"
)
doc
=
filter
(
"Label
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-project-id'
)
expect
(
link
).
to
have_attribute
(
'data-project'
)
expect
(
link
.
attr
(
'data-project-id'
)).
to
eq
project
.
id
.
to_s
expect
(
link
.
attr
(
'data-project'
)).
to
eq
project
.
id
.
to_s
end
it
'includes a data-label attribute'
do
doc
=
filter
(
"See
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-label'
)
expect
(
link
.
attr
(
'data-label'
)).
to
eq
label
.
id
.
to_s
end
end
it
'supports an :only_path context'
do
it
'supports an :only_path context'
do
...
@@ -42,7 +50,7 @@ module Gitlab::Markdown
...
@@ -42,7 +50,7 @@ module Gitlab::Markdown
end
end
it
'adds to the results hash'
do
it
'adds to the results hash'
do
result
=
pipeline_result
(
"Label
#{
reference
}
"
)
result
=
reference_
pipeline_result
(
"Label
#{
reference
}
"
)
expect
(
result
[
:references
][
:label
]).
to
eq
[
label
]
expect
(
result
[
:references
][
:label
]).
to
eq
[
label
]
end
end
...
...
spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb
View file @
d37cf642
...
@@ -4,7 +4,7 @@ module Gitlab::Markdown
...
@@ -4,7 +4,7 @@ module Gitlab::Markdown
describe
MergeRequestReferenceFilter
do
describe
MergeRequestReferenceFilter
do
include
FilterSpecHelper
include
FilterSpecHelper
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
,
:public
)
}
let
(
:merge
)
{
create
(
:merge_request
,
source_project:
project
)
}
let
(
:merge
)
{
create
(
:merge_request
,
source_project:
project
)
}
it
'requires project context'
do
it
'requires project context'
do
...
@@ -56,12 +56,20 @@ module Gitlab::Markdown
...
@@ -56,12 +56,20 @@ module Gitlab::Markdown
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-merge_request'
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-merge_request'
end
end
it
'includes a data-project
-id
attribute'
do
it
'includes a data-project attribute'
do
doc
=
filter
(
"Merge
#{
reference
}
"
)
doc
=
filter
(
"Merge
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-project-id'
)
expect
(
link
).
to
have_attribute
(
'data-project'
)
expect
(
link
.
attr
(
'data-project-id'
)).
to
eq
project
.
id
.
to_s
expect
(
link
.
attr
(
'data-project'
)).
to
eq
project
.
id
.
to_s
end
it
'includes a data-merge-request attribute'
do
doc
=
filter
(
"See
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-merge-request'
)
expect
(
link
.
attr
(
'data-merge-request'
)).
to
eq
merge
.
id
.
to_s
end
end
it
'supports an :only_path context'
do
it
'supports an :only_path context'
do
...
@@ -73,53 +81,39 @@ module Gitlab::Markdown
...
@@ -73,53 +81,39 @@ module Gitlab::Markdown
end
end
it
'adds to the results hash'
do
it
'adds to the results hash'
do
result
=
pipeline_result
(
"Merge
#{
reference
}
"
)
result
=
reference_
pipeline_result
(
"Merge
#{
reference
}
"
)
expect
(
result
[
:references
][
:merge_request
]).
to
eq
[
merge
]
expect
(
result
[
:references
][
:merge_request
]).
to
eq
[
merge
]
end
end
end
end
context
'cross-project reference'
do
context
'cross-project reference'
do
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
let
(
:project2
)
{
create
(
:project
,
namespace:
namespace
)
}
let
(
:project2
)
{
create
(
:project
,
:public
,
namespace:
namespace
)
}
let
(
:merge
)
{
create
(
:merge_request
,
source_project:
project2
)
}
let
(
:merge
)
{
create
(
:merge_request
,
source_project:
project2
)
}
let
(
:reference
)
{
merge
.
to_reference
(
project
)
}
let
(
:reference
)
{
merge
.
to_reference
(
project
)
}
context
'when user can access reference'
do
it
'links to a valid reference'
do
before
{
allow_cross_reference!
}
doc
=
filter
(
"See
#{
reference
}
"
)
it
'links to a valid reference'
do
doc
=
filter
(
"See
#{
reference
}
"
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
namespace_project_merge_request_url
(
project2
.
namespace
,
project
,
merge
)
end
it
'links with adjacent text'
do
doc
=
filter
(
"Merge (
#{
reference
}
.)"
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
it
'ignores invalid merge IDs on the referenced project'
do
exp
=
act
=
"Merge
#{
invalidate_reference
(
reference
)
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
end
to
eq
urls
.
namespace_project_merge_request_url
(
project2
.
namespace
,
project
,
merge
)
end
it
'adds to the results hash'
do
it
'links with adjacent text'
do
result
=
pipeline_result
(
"Merge
#{
reference
}
"
)
doc
=
filter
(
"Merge (
#{
reference
}
.)"
)
expect
(
result
[
:references
][
:merge_request
]).
to
eq
[
merge
]
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
end
end
context
'when user cannot access reference
'
do
it
'ignores invalid merge IDs on the referenced project
'
do
before
{
disallow_cross_reference!
}
exp
=
act
=
"Merge
#{
invalidate_reference
(
reference
)
}
"
it
'ignores valid references'
do
expect
(
filter
(
act
).
to_html
).
to
eq
exp
exp
=
act
=
"See
#{
reference
}
"
end
expect
(
filter
(
act
).
to_html
).
to
eq
exp
it
'adds to the results hash'
do
end
result
=
reference_pipeline_result
(
"Merge
#{
reference
}
"
)
expect
(
result
[
:references
][
:merge_request
]).
to
eq
[
merge
]
end
end
end
end
end
end
...
...
spec/lib/gitlab/markdown/redactor_filter_spec.rb
0 → 100644
View file @
d37cf642
require
'spec_helper'
module
Gitlab::Markdown
describe
RedactorFilter
do
include
ActionView
::
Helpers
::
UrlHelper
include
FilterSpecHelper
it
'ignores non-GFM links'
do
html
=
%(See <a href="https://google.com/">Google</a>)
doc
=
filter
(
html
,
current_user:
double
)
expect
(
doc
.
css
(
'a'
).
length
).
to
eq
1
end
def
reference_link
(
data
)
link_to
(
'text'
,
''
,
class:
'gfm'
,
data:
data
)
end
context
'with data-project'
do
it
'removes unpermitted Project references'
do
user
=
create
(
:user
)
project
=
create
(
:empty_project
)
link
=
reference_link
(
project:
project
.
id
,
reference_filter:
Gitlab
::
Markdown
::
ReferenceFilter
.
name
)
doc
=
filter
(
link
,
current_user:
user
)
expect
(
doc
.
css
(
'a'
).
length
).
to
eq
0
end
it
'allows permitted Project references'
do
user
=
create
(
:user
)
project
=
create
(
:empty_project
)
project
.
team
<<
[
user
,
:master
]
link
=
reference_link
(
project:
project
.
id
,
reference_filter:
Gitlab
::
Markdown
::
ReferenceFilter
.
name
)
doc
=
filter
(
link
,
current_user:
user
)
expect
(
doc
.
css
(
'a'
).
length
).
to
eq
1
end
it
'handles invalid Project references'
do
link
=
reference_link
(
project:
12345
,
reference_filter:
Gitlab
::
Markdown
::
ReferenceFilter
.
name
)
expect
{
filter
(
link
)
}.
not_to
raise_error
end
end
context
"for user references"
do
context
'with data-group'
do
it
'removes unpermitted Group references'
do
user
=
create
(
:user
)
group
=
create
(
:group
)
link
=
reference_link
(
group:
group
.
id
,
reference_filter:
Gitlab
::
Markdown
::
UserReferenceFilter
.
name
)
doc
=
filter
(
link
,
current_user:
user
)
expect
(
doc
.
css
(
'a'
).
length
).
to
eq
0
end
it
'allows permitted Group references'
do
user
=
create
(
:user
)
group
=
create
(
:group
)
group
.
add_developer
(
user
)
link
=
reference_link
(
group:
group
.
id
,
reference_filter:
Gitlab
::
Markdown
::
UserReferenceFilter
.
name
)
doc
=
filter
(
link
,
current_user:
user
)
expect
(
doc
.
css
(
'a'
).
length
).
to
eq
1
end
it
'handles invalid Group references'
do
link
=
reference_link
(
group:
12345
,
reference_filter:
Gitlab
::
Markdown
::
UserReferenceFilter
.
name
)
expect
{
filter
(
link
)
}.
not_to
raise_error
end
end
context
'with data-user'
do
it
'allows any User reference'
do
user
=
create
(
:user
)
link
=
reference_link
(
user:
user
.
id
,
reference_filter:
Gitlab
::
Markdown
::
UserReferenceFilter
.
name
)
doc
=
filter
(
link
)
expect
(
doc
.
css
(
'a'
).
length
).
to
eq
1
end
end
end
end
end
spec/lib/gitlab/markdown/reference_gatherer_filter_spec.rb
0 → 100644
View file @
d37cf642
require
'spec_helper'
module
Gitlab::Markdown
describe
ReferenceGathererFilter
do
include
ActionView
::
Helpers
::
UrlHelper
include
FilterSpecHelper
def
reference_link
(
data
)
link_to
(
'text'
,
''
,
class:
'gfm'
,
data:
data
)
end
context
"for issue references"
do
context
'with data-project'
do
it
'removes unpermitted Project references'
do
user
=
create
(
:user
)
project
=
create
(
:empty_project
)
issue
=
create
(
:issue
,
project:
project
)
link
=
reference_link
(
project:
project
.
id
,
issue:
issue
.
id
,
reference_filter:
Gitlab
::
Markdown
::
IssueReferenceFilter
.
name
)
result
=
pipeline_result
(
link
,
current_user:
user
)
expect
(
result
[
:references
][
:issue
]).
to
be_empty
end
it
'allows permitted Project references'
do
user
=
create
(
:user
)
project
=
create
(
:empty_project
)
issue
=
create
(
:issue
,
project:
project
)
project
.
team
<<
[
user
,
:master
]
link
=
reference_link
(
project:
project
.
id
,
issue:
issue
.
id
,
reference_filter:
Gitlab
::
Markdown
::
IssueReferenceFilter
.
name
)
result
=
pipeline_result
(
link
,
current_user:
user
)
expect
(
result
[
:references
][
:issue
]).
to
eq
([
issue
])
end
it
'handles invalid Project references'
do
link
=
reference_link
(
project:
12345
,
issue:
12345
,
reference_filter:
Gitlab
::
Markdown
::
IssueReferenceFilter
.
name
)
expect
{
pipeline_result
(
link
)
}.
not_to
raise_error
end
end
end
context
"for user references"
do
context
'with data-group'
do
it
'removes unpermitted Group references'
do
user
=
create
(
:user
)
group
=
create
(
:group
)
link
=
reference_link
(
group:
group
.
id
,
reference_filter:
Gitlab
::
Markdown
::
UserReferenceFilter
.
name
)
result
=
pipeline_result
(
link
,
current_user:
user
)
expect
(
result
[
:references
][
:user
]).
to
be_empty
end
it
'allows permitted Group references'
do
user
=
create
(
:user
)
group
=
create
(
:group
)
group
.
add_developer
(
user
)
link
=
reference_link
(
group:
group
.
id
,
reference_filter:
Gitlab
::
Markdown
::
UserReferenceFilter
.
name
)
result
=
pipeline_result
(
link
,
current_user:
user
)
expect
(
result
[
:references
][
:user
]).
to
eq
([
user
])
end
it
'handles invalid Group references'
do
link
=
reference_link
(
group:
12345
,
reference_filter:
Gitlab
::
Markdown
::
UserReferenceFilter
.
name
)
expect
{
pipeline_result
(
link
)
}.
not_to
raise_error
end
end
context
'with data-user'
do
it
'allows any User reference'
do
user
=
create
(
:user
)
link
=
reference_link
(
user:
user
.
id
,
reference_filter:
Gitlab
::
Markdown
::
UserReferenceFilter
.
name
)
result
=
pipeline_result
(
link
)
expect
(
result
[
:references
][
:user
]).
to
eq
([
user
])
end
end
end
end
end
spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
View file @
d37cf642
...
@@ -4,7 +4,7 @@ module Gitlab::Markdown
...
@@ -4,7 +4,7 @@ module Gitlab::Markdown
describe
SnippetReferenceFilter
do
describe
SnippetReferenceFilter
do
include
FilterSpecHelper
include
FilterSpecHelper
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:project
)
{
create
(
:empty_project
,
:public
)
}
let
(
:snippet
)
{
create
(
:project_snippet
,
project:
project
)
}
let
(
:snippet
)
{
create
(
:project_snippet
,
project:
project
)
}
let
(
:reference
)
{
snippet
.
to_reference
}
let
(
:reference
)
{
snippet
.
to_reference
}
...
@@ -55,12 +55,20 @@ module Gitlab::Markdown
...
@@ -55,12 +55,20 @@ module Gitlab::Markdown
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-snippet'
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-snippet'
end
end
it
'includes a data-project
-id
attribute'
do
it
'includes a data-project attribute'
do
doc
=
filter
(
"Snippet
#{
reference
}
"
)
doc
=
filter
(
"Snippet
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-project-id'
)
expect
(
link
).
to
have_attribute
(
'data-project'
)
expect
(
link
.
attr
(
'data-project-id'
)).
to
eq
project
.
id
.
to_s
expect
(
link
.
attr
(
'data-project'
)).
to
eq
project
.
id
.
to_s
end
it
'includes a data-snippet attribute'
do
doc
=
filter
(
"See
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-snippet'
)
expect
(
link
.
attr
(
'data-snippet'
)).
to
eq
snippet
.
id
.
to_s
end
end
it
'supports an :only_path context'
do
it
'supports an :only_path context'
do
...
@@ -72,52 +80,38 @@ module Gitlab::Markdown
...
@@ -72,52 +80,38 @@ module Gitlab::Markdown
end
end
it
'adds to the results hash'
do
it
'adds to the results hash'
do
result
=
pipeline_result
(
"Snippet
#{
reference
}
"
)
result
=
reference_
pipeline_result
(
"Snippet
#{
reference
}
"
)
expect
(
result
[
:references
][
:snippet
]).
to
eq
[
snippet
]
expect
(
result
[
:references
][
:snippet
]).
to
eq
[
snippet
]
end
end
end
end
context
'cross-project reference'
do
context
'cross-project reference'
do
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
let
(
:project2
)
{
create
(
:empty_project
,
namespace:
namespace
)
}
let
(
:project2
)
{
create
(
:empty_project
,
:public
,
namespace:
namespace
)
}
let
(
:snippet
)
{
create
(
:project_snippet
,
project:
project2
)
}
let
(
:snippet
)
{
create
(
:project_snippet
,
project:
project2
)
}
let
(
:reference
)
{
snippet
.
to_reference
(
project
)
}
let
(
:reference
)
{
snippet
.
to_reference
(
project
)
}
context
'when user can access reference'
do
it
'links to a valid reference'
do
before
{
allow_cross_reference!
}
doc
=
filter
(
"See
#{
reference
}
"
)
it
'links to a valid reference'
do
doc
=
filter
(
"See
#{
reference
}
"
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
namespace_project_snippet_url
(
project2
.
namespace
,
project2
,
snippet
)
end
it
'links with adjacent text'
do
doc
=
filter
(
"See (
#{
reference
}
.)"
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
it
'ignores invalid snippet IDs on the referenced project'
do
exp
=
act
=
"See
#{
invalidate_reference
(
reference
)
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
end
to
eq
urls
.
namespace_project_snippet_url
(
project2
.
namespace
,
project2
,
snippet
)
end
it
'adds to the results hash'
do
it
'links with adjacent text'
do
result
=
pipeline_result
(
"Snippet
#{
reference
}
"
)
doc
=
filter
(
"See (
#{
reference
}
.)"
)
expect
(
result
[
:references
][
:snippet
]).
to
eq
[
snippet
]
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
end
end
context
'when user cannot access reference
'
do
it
'ignores invalid snippet IDs on the referenced project
'
do
before
{
disallow_cross_reference!
}
exp
=
act
=
"See
#{
invalidate_reference
(
reference
)
}
"
it
'ignores valid references'
do
expect
(
filter
(
act
).
to_html
).
to
eq
exp
exp
=
act
=
"See
#{
reference
}
"
end
expect
(
filter
(
act
).
to_html
).
to
eq
exp
it
'adds to the results hash'
do
end
result
=
reference_pipeline_result
(
"Snippet
#{
reference
}
"
)
expect
(
result
[
:references
][
:snippet
]).
to
eq
[
snippet
]
end
end
end
end
end
end
...
...
spec/lib/gitlab/markdown/user_reference_filter_spec.rb
View file @
d37cf642
...
@@ -4,7 +4,7 @@ module Gitlab::Markdown
...
@@ -4,7 +4,7 @@ module Gitlab::Markdown
describe
UserReferenceFilter
do
describe
UserReferenceFilter
do
include
FilterSpecHelper
include
FilterSpecHelper
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:project
)
{
create
(
:empty_project
,
:public
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:reference
)
{
user
.
to_reference
}
let
(
:reference
)
{
user
.
to_reference
}
...
@@ -39,7 +39,7 @@ module Gitlab::Markdown
...
@@ -39,7 +39,7 @@ module Gitlab::Markdown
end
end
it
'adds to the results hash'
do
it
'adds to the results hash'
do
result
=
pipeline_result
(
"Hey
#{
reference
}
"
)
result
=
reference_
pipeline_result
(
"Hey
#{
reference
}
"
)
expect
(
result
[
:references
][
:user
]).
to
eq
[
project
.
creator
]
expect
(
result
[
:references
][
:user
]).
to
eq
[
project
.
creator
]
end
end
end
end
...
@@ -64,59 +64,40 @@ module Gitlab::Markdown
...
@@ -64,59 +64,40 @@ module Gitlab::Markdown
expect
(
doc
.
css
(
'a'
).
length
).
to
eq
1
expect
(
doc
.
css
(
'a'
).
length
).
to
eq
1
end
end
it
'includes a data-user
-id
attribute'
do
it
'includes a data-user attribute'
do
doc
=
filter
(
"Hey
#{
reference
}
"
)
doc
=
filter
(
"Hey
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-user
-id
'
)
expect
(
link
).
to
have_attribute
(
'data-user'
)
expect
(
link
.
attr
(
'data-user
-id
'
)).
to
eq
user
.
namespace
.
owner_id
.
to_s
expect
(
link
.
attr
(
'data-user'
)).
to
eq
user
.
namespace
.
owner_id
.
to_s
end
end
it
'adds to the results hash'
do
it
'adds to the results hash'
do
result
=
pipeline_result
(
"Hey
#{
reference
}
"
)
result
=
reference_
pipeline_result
(
"Hey
#{
reference
}
"
)
expect
(
result
[
:references
][
:user
]).
to
eq
[
user
]
expect
(
result
[
:references
][
:user
]).
to
eq
[
user
]
end
end
end
end
context
'mentioning a group'
do
context
'mentioning a group'
do
let
(
:group
)
{
create
(
:group
)
}
let
(
:group
)
{
create
(
:group
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:reference
)
{
group
.
to_reference
}
let
(
:reference
)
{
group
.
to_reference
}
context
'that the current user can read'
do
it
'links to the Group'
do
before
do
doc
=
filter
(
"Hey
#{
reference
}
"
)
group
.
add_developer
(
user
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
group_url
(
group
)
end
end
it
'links to the Group'
do
doc
=
filter
(
"Hey
#{
reference
}
"
,
current_user:
user
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
group_url
(
group
)
end
it
'includes a data-group-id attribute'
do
doc
=
filter
(
"Hey
#{
reference
}
"
,
current_user:
user
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-group-id'
)
it
'includes a data-group attribute'
do
expect
(
link
.
attr
(
'data-group-id'
)).
to
eq
group
.
id
.
to_s
doc
=
filter
(
"Hey
#{
reference
}
"
)
end
link
=
doc
.
css
(
'a'
).
first
it
'adds to the results hash'
do
expect
(
link
).
to
have_attribute
(
'data-group'
)
result
=
pipeline_result
(
"Hey
#{
reference
}
"
,
current_user:
user
)
expect
(
link
.
attr
(
'data-group'
)).
to
eq
group
.
id
.
to_s
expect
(
result
[
:references
][
:user
]).
to
eq
group
.
users
end
end
end
context
'that the current user cannot read'
do
it
'adds to the results hash'
do
it
'ignores references to the Group'
do
result
=
reference_pipeline_result
(
"Hey
#{
reference
}
"
)
doc
=
filter
(
"Hey
#{
reference
}
"
,
current_user:
user
)
expect
(
result
[
:references
][
:user
]).
to
eq
group
.
users
expect
(
doc
.
to_html
).
to
eq
"Hey
#{
reference
}
"
end
it
'does not add to the results hash'
do
result
=
pipeline_result
(
"Hey
#{
reference
}
"
,
current_user:
user
)
expect
(
result
[
:references
][
:user
]).
to
eq
[]
end
end
end
end
end
...
...
spec/lib/gitlab/reference_extractor_spec.rb
View file @
d37cf642
...
@@ -13,7 +13,7 @@ describe Gitlab::ReferenceExtractor do
...
@@ -13,7 +13,7 @@ describe Gitlab::ReferenceExtractor do
project
.
team
<<
[
@u_bar
,
:guest
]
project
.
team
<<
[
@u_bar
,
:guest
]
subject
.
analyze
(
'@foo, @baduser, @bar, and @offteam'
)
subject
.
analyze
(
'@foo, @baduser, @bar, and @offteam'
)
expect
(
subject
.
users
).
to
eq
([
@u_foo
,
@u_bar
,
@u_offteam
])
expect
(
subject
.
users
).
to
match_array
([
@u_foo
,
@u_bar
,
@u_offteam
])
end
end
it
'ignores user mentions inside specific elements'
do
it
'ignores user mentions inside specific elements'
do
...
@@ -37,7 +37,7 @@ describe Gitlab::ReferenceExtractor do
...
@@ -37,7 +37,7 @@ describe Gitlab::ReferenceExtractor do
> @offteam
> @offteam
}
)
}
)
expect
(
subject
.
users
).
to
eq
([])
expect
(
subject
.
users
).
to
match_array
([])
end
end
it
'accesses valid issue objects'
do
it
'accesses valid issue objects'
do
...
@@ -45,7 +45,7 @@ describe Gitlab::ReferenceExtractor do
...
@@ -45,7 +45,7 @@ describe Gitlab::ReferenceExtractor do
@i1
=
create
(
:issue
,
project:
project
)
@i1
=
create
(
:issue
,
project:
project
)
subject
.
analyze
(
"
#{
@i0
.
to_reference
}
,
#{
@i1
.
to_reference
}
, and
#{
Issue
.
reference_prefix
}
999."
)
subject
.
analyze
(
"
#{
@i0
.
to_reference
}
,
#{
@i1
.
to_reference
}
, and
#{
Issue
.
reference_prefix
}
999."
)
expect
(
subject
.
issues
).
to
eq
([
@i0
,
@i1
])
expect
(
subject
.
issues
).
to
match_array
([
@i0
,
@i1
])
end
end
it
'accesses valid merge requests'
do
it
'accesses valid merge requests'
do
...
@@ -53,7 +53,7 @@ describe Gitlab::ReferenceExtractor do
...
@@ -53,7 +53,7 @@ describe Gitlab::ReferenceExtractor do
@m1
=
create
(
:merge_request
,
source_project:
project
,
target_project:
project
,
source_branch:
'feature_conflict'
)
@m1
=
create
(
:merge_request
,
source_project:
project
,
target_project:
project
,
source_branch:
'feature_conflict'
)
subject
.
analyze
(
"!999, !
#{
@m1
.
iid
}
, and !
#{
@m0
.
iid
}
."
)
subject
.
analyze
(
"!999, !
#{
@m1
.
iid
}
, and !
#{
@m0
.
iid
}
."
)
expect
(
subject
.
merge_requests
).
to
eq
([
@m1
,
@m0
])
expect
(
subject
.
merge_requests
).
to
match_array
([
@m1
,
@m0
])
end
end
it
'accesses valid labels'
do
it
'accesses valid labels'
do
...
@@ -62,7 +62,7 @@ describe Gitlab::ReferenceExtractor do
...
@@ -62,7 +62,7 @@ describe Gitlab::ReferenceExtractor do
@l2
=
create
(
:label
)
@l2
=
create
(
:label
)
subject
.
analyze
(
"~
#{
@l0
.
id
}
, ~999, ~
#{
@l2
.
id
}
, ~
#{
@l1
.
id
}
"
)
subject
.
analyze
(
"~
#{
@l0
.
id
}
, ~999, ~
#{
@l2
.
id
}
, ~
#{
@l1
.
id
}
"
)
expect
(
subject
.
labels
).
to
eq
([
@l0
,
@l1
])
expect
(
subject
.
labels
).
to
match_array
([
@l0
,
@l1
])
end
end
it
'accesses valid snippets'
do
it
'accesses valid snippets'
do
...
@@ -71,7 +71,7 @@ describe Gitlab::ReferenceExtractor do
...
@@ -71,7 +71,7 @@ describe Gitlab::ReferenceExtractor do
@s2
=
create
(
:project_snippet
)
@s2
=
create
(
:project_snippet
)
subject
.
analyze
(
"$
#{
@s0
.
id
}
, $999, $
#{
@s2
.
id
}
, $
#{
@s1
.
id
}
"
)
subject
.
analyze
(
"$
#{
@s0
.
id
}
, $999, $
#{
@s2
.
id
}
, $
#{
@s1
.
id
}
"
)
expect
(
subject
.
snippets
).
to
eq
([
@s0
,
@s1
])
expect
(
subject
.
snippets
).
to
match_array
([
@s0
,
@s1
])
end
end
it
'accesses valid commits'
do
it
'accesses valid commits'
do
...
@@ -109,7 +109,7 @@ describe Gitlab::ReferenceExtractor do
...
@@ -109,7 +109,7 @@ describe Gitlab::ReferenceExtractor do
subject
.
analyze
(
"this refers issue
#{
issue
.
to_reference
(
project
)
}
"
)
subject
.
analyze
(
"this refers issue
#{
issue
.
to_reference
(
project
)
}
"
)
extracted
=
subject
.
issues
extracted
=
subject
.
issues
expect
(
extracted
.
size
).
to
eq
(
1
)
expect
(
extracted
.
size
).
to
eq
(
1
)
expect
(
extracted
).
to
eq
([
issue
])
expect
(
extracted
).
to
match_array
([
issue
])
end
end
end
end
end
end
spec/models/concerns/issuable_spec.rb
View file @
d37cf642
...
@@ -68,7 +68,6 @@ describe Issue, "Issuable" do
...
@@ -68,7 +68,6 @@ describe Issue, "Issuable" do
end
end
end
end
describe
"#to_hook_data"
do
describe
"#to_hook_data"
do
let
(
:hook_data
)
{
issue
.
to_hook_data
(
user
)
}
let
(
:hook_data
)
{
issue
.
to_hook_data
(
user
)
}
...
...
spec/models/issue_spec.rb
View file @
d37cf642
...
@@ -68,6 +68,43 @@ describe Issue do
...
@@ -68,6 +68,43 @@ describe Issue do
end
end
end
end
describe
'#closed_by_merge_requests'
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
,
state:
"opened"
)}
let
(
:closed_issue
)
{
build
(
:issue
,
project:
project
,
state:
"closed"
)}
let
(
:mr
)
do
opts
=
{
title:
'Awesome merge_request'
,
description:
"Fixes
#{
issue
.
to_reference
}
"
,
source_branch:
'feature'
,
target_branch:
'master'
}
MergeRequests
::
CreateService
.
new
(
project
,
project
.
owner
,
opts
).
execute
end
let
(
:closed_mr
)
do
opts
=
{
title:
'Awesome merge_request 2'
,
description:
"Fixes
#{
issue
.
to_reference
}
"
,
source_branch:
'feature'
,
target_branch:
'master'
,
state:
'closed'
}
MergeRequests
::
CreateService
.
new
(
project
,
project
.
owner
,
opts
).
execute
end
it
'returns the merge request to close this issue'
do
allow
(
mr
).
to
receive
(
:closes_issue?
).
with
(
issue
).
and_return
(
true
)
expect
(
issue
.
closed_by_merge_requests
).
to
eq
([
mr
])
end
it
"returns an empty array when the current issue is closed already"
do
expect
(
closed_issue
.
closed_by_merge_requests
).
to
eq
([])
end
end
it_behaves_like
'an editable mentionable'
do
it_behaves_like
'an editable mentionable'
do
subject
{
create
(
:issue
)
}
subject
{
create
(
:issue
)
}
...
...
spec/models/milestone_spec.rb
View file @
d37cf642
...
@@ -140,4 +140,32 @@ describe Milestone do
...
@@ -140,4 +140,32 @@ describe Milestone do
end
end
end
end
describe
'#sort_issues'
do
let
(
:milestone
)
{
create
(
:milestone
)
}
let
(
:issue1
)
{
create
(
:issue
,
milestone:
milestone
,
position:
1
)
}
let
(
:issue2
)
{
create
(
:issue
,
milestone:
milestone
,
position:
2
)
}
let
(
:issue3
)
{
create
(
:issue
,
milestone:
milestone
,
position:
3
)
}
let
(
:issue4
)
{
create
(
:issue
,
position:
42
)
}
it
'sorts the given issues'
do
milestone
.
sort_issues
([
issue3
.
id
,
issue2
.
id
,
issue1
.
id
])
issue1
.
reload
issue2
.
reload
issue3
.
reload
expect
(
issue1
.
position
).
to
eq
(
3
)
expect
(
issue2
.
position
).
to
eq
(
2
)
expect
(
issue3
.
position
).
to
eq
(
1
)
end
it
'ignores issues not part of the milestone'
do
milestone
.
sort_issues
([
issue3
.
id
,
issue2
.
id
,
issue1
.
id
,
issue4
.
id
])
issue4
.
reload
expect
(
issue4
.
position
).
to
eq
(
42
)
end
end
end
end
spec/requests/api/projects_spec.rb
View file @
d37cf642
...
@@ -606,28 +606,42 @@ describe API::API, api: true do
...
@@ -606,28 +606,42 @@ describe API::API, api: true do
describe
'DELETE /projects/:id/fork'
do
describe
'DELETE /projects/:id/fork'
do
it
"shouldn't
available for non admin users
"
do
it
"shouldn't
be visible to users outside group
"
do
delete
api
(
"/projects/
#{
project_fork_target
.
id
}
/fork"
,
user
)
delete
api
(
"/projects/
#{
project_fork_target
.
id
}
/fork"
,
user
)
expect
(
response
.
status
).
to
eq
(
40
3
)
expect
(
response
.
status
).
to
eq
(
40
4
)
end
end
it
'should make forked project unforked'
do
context
'when users belong to project group'
do
post
api
(
"/projects/
#{
project_fork_target
.
id
}
/fork/
#{
project_fork_source
.
id
}
"
,
admin
)
let
(
:project_fork_target
)
{
create
(
:project
,
group:
create
(
:group
))
}
project_fork_target
.
reload
expect
(
project_fork_target
.
forked_from_project
).
not_to
be_nil
expect
(
project_fork_target
.
forked?
).
to
be_truthy
delete
api
(
"/projects/
#{
project_fork_target
.
id
}
/fork"
,
admin
)
expect
(
response
.
status
).
to
eq
(
200
)
project_fork_target
.
reload
expect
(
project_fork_target
.
forked_from_project
).
to
be_nil
expect
(
project_fork_target
.
forked?
).
not_to
be_truthy
end
it
'should be idempotent if not forked'
do
before
do
expect
(
project_fork_target
.
forked_from_project
).
to
be_nil
project_fork_target
.
group
.
add_owner
user
delete
api
(
"/projects/
#{
project_fork_target
.
id
}
/fork"
,
admin
)
project_fork_target
.
group
.
add_developer
user2
expect
(
response
.
status
).
to
eq
(
200
)
end
expect
(
project_fork_target
.
reload
.
forked_from_project
).
to
be_nil
it
'should be forbidden to non-owner users'
do
delete
api
(
"/projects/
#{
project_fork_target
.
id
}
/fork"
,
user2
)
expect
(
response
.
status
).
to
eq
(
403
)
end
it
'should make forked project unforked'
do
post
api
(
"/projects/
#{
project_fork_target
.
id
}
/fork/
#{
project_fork_source
.
id
}
"
,
admin
)
project_fork_target
.
reload
expect
(
project_fork_target
.
forked_from_project
).
not_to
be_nil
expect
(
project_fork_target
.
forked?
).
to
be_truthy
delete
api
(
"/projects/
#{
project_fork_target
.
id
}
/fork"
,
admin
)
expect
(
response
.
status
).
to
eq
(
200
)
project_fork_target
.
reload
expect
(
project_fork_target
.
forked_from_project
).
to
be_nil
expect
(
project_fork_target
.
forked?
).
not_to
be_truthy
end
it
'should be idempotent if not forked'
do
expect
(
project_fork_target
.
forked_from_project
).
to
be_nil
delete
api
(
"/projects/
#{
project_fork_target
.
id
}
/fork"
,
admin
)
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
project_fork_target
.
reload
.
forked_from_project
).
to
be_nil
end
end
end
end
end
end
end
...
...
spec/services/archive_repository_service_spec.rb
View file @
d37cf642
...
@@ -6,7 +6,7 @@ describe ArchiveRepositoryService do
...
@@ -6,7 +6,7 @@ describe ArchiveRepositoryService do
describe
"#execute"
do
describe
"#execute"
do
it
"cleans old archives"
do
it
"cleans old archives"
do
expect
(
project
.
repository
).
to
receive
(
:clean_old_archives
)
expect
(
RepositoryArchiveCacheWorker
).
to
receive
(
:perform_async
)
subject
.
execute
(
timeout:
0.0
)
subject
.
execute
(
timeout:
0.0
)
end
end
...
...
spec/support/filter_spec_helper.rb
View file @
d37cf642
...
@@ -29,12 +29,19 @@ module FilterSpecHelper
...
@@ -29,12 +29,19 @@ module FilterSpecHelper
#
#
# Returns the Hash
# Returns the Hash
def
pipeline_result
(
body
,
contexts
=
{})
def
pipeline_result
(
body
,
contexts
=
{})
contexts
.
reverse_merge!
(
project:
project
)
contexts
.
reverse_merge!
(
project:
project
)
if
defined?
(
project
)
pipeline
=
HTML
::
Pipeline
.
new
([
described_class
],
contexts
)
pipeline
=
HTML
::
Pipeline
.
new
([
described_class
],
contexts
)
pipeline
.
call
(
body
)
pipeline
.
call
(
body
)
end
end
def
reference_pipeline_result
(
body
,
contexts
=
{})
contexts
.
reverse_merge!
(
project:
project
)
if
defined?
(
project
)
pipeline
=
HTML
::
Pipeline
.
new
([
described_class
,
Gitlab
::
Markdown
::
ReferenceGathererFilter
],
contexts
)
pipeline
.
call
(
body
)
end
# Modify a String reference to make it invalid
# Modify a String reference to make it invalid
#
#
# Commit SHAs get reversed, IDs get incremented by 1, all other Strings get
# Commit SHAs get reversed, IDs get incremented by 1, all other Strings get
...
@@ -55,20 +62,6 @@ module FilterSpecHelper
...
@@ -55,20 +62,6 @@ module FilterSpecHelper
end
end
end
end
# Stub CrossProjectReference#user_can_reference_project? to return true for
# the current test
def
allow_cross_reference!
allow_any_instance_of
(
described_class
).
to
receive
(
:user_can_reference_project?
).
and_return
(
true
)
end
# Stub CrossProjectReference#user_can_reference_project? to return false for
# the current test
def
disallow_cross_reference!
allow_any_instance_of
(
described_class
).
to
receive
(
:user_can_reference_project?
).
and_return
(
false
)
end
# Shortcut to Rails' auto-generated routes helpers, to avoid including the
# Shortcut to Rails' auto-generated routes helpers, to avoid including the
# module
# module
def
urls
def
urls
...
...
spec/support/markdown_feature.rb
View file @
d37cf642
...
@@ -15,18 +15,17 @@ class MarkdownFeature
...
@@ -15,18 +15,17 @@ class MarkdownFeature
end
end
def
group
def
group
unless
@group
@group
||=
create
(
:group
).
tap
do
|
group
|
@group
=
create
(
:group
)
group
.
add_developer
(
user
)
@group
.
add_developer
(
user
)
end
end
@group
end
end
# Direct references ----------------------------------------------------------
# Direct references ----------------------------------------------------------
def
project
def
project
@project
||=
create
(
:project
)
@project
||=
create
(
:project
).
tap
do
|
project
|
project
.
team
<<
[
user
,
:master
]
end
end
end
def
issue
def
issue
...
@@ -46,12 +45,10 @@ class MarkdownFeature
...
@@ -46,12 +45,10 @@ class MarkdownFeature
end
end
def
commit_range
def
commit_range
unless
@commit_range
@commit_range
||=
begin
commit2
=
project
.
commit
(
'HEAD~3'
)
commit2
=
project
.
commit
(
'HEAD~3'
)
@commit_range
=
CommitRange
.
new
(
"
#{
commit
.
id
}
...
#{
commit2
.
id
}
"
,
project
)
CommitRange
.
new
(
"
#{
commit
.
id
}
...
#{
commit2
.
id
}
"
,
project
)
end
end
@commit_range
end
end
def
simple_label
def
simple_label
...
@@ -65,13 +62,12 @@ class MarkdownFeature
...
@@ -65,13 +62,12 @@ class MarkdownFeature
# Cross-references -----------------------------------------------------------
# Cross-references -----------------------------------------------------------
def
xproject
def
xproject
unless
@xproject
@xproject
||=
begin
namespace
=
create
(
:namespace
,
name:
'cross-reference'
)
namespace
=
create
(
:namespace
,
name:
'cross-reference'
)
@xproject
=
create
(
:project
,
namespace:
namespace
)
create
(
:project
,
namespace:
namespace
)
do
|
project
|
@xproject
.
team
<<
[
user
,
:developer
]
project
.
team
<<
[
user
,
:developer
]
end
end
end
@xproject
end
end
def
xissue
def
xissue
...
@@ -91,12 +87,10 @@ class MarkdownFeature
...
@@ -91,12 +87,10 @@ class MarkdownFeature
end
end
def
xcommit_range
def
xcommit_range
unless
@xcommit_range
@xcommit_range
||=
begin
xcommit2
=
xproject
.
commit
(
'HEAD~2'
)
xcommit2
=
xproject
.
commit
(
'HEAD~2'
)
@xcommit_range
=
CommitRange
.
new
(
"
#{
xcommit
.
id
}
...
#{
xcommit2
.
id
}
"
,
xproject
)
CommitRange
.
new
(
"
#{
xcommit
.
id
}
...
#{
xcommit2
.
id
}
"
,
xproject
)
end
end
@xcommit_range
end
end
def
raw_markdown
def
raw_markdown
...
...
spec/support/mentionable_shared_examples.rb
View file @
d37cf642
...
@@ -50,6 +50,8 @@ def common_mentionable_setup
...
@@ -50,6 +50,8 @@ def common_mentionable_setup
}
}
extra_commits
.
each
{
|
c
|
commitmap
[
c
.
short_id
]
=
c
}
extra_commits
.
each
{
|
c
|
commitmap
[
c
.
short_id
]
=
c
}
allow
(
Project
).
to
receive
(
:find
).
and_call_original
allow
(
Project
).
to
receive
(
:find
).
with
(
project
.
id
.
to_s
).
and_return
(
project
)
allow
(
project
.
repository
).
to
receive
(
:commit
)
{
|
sha
|
commitmap
[
sha
]
}
allow
(
project
.
repository
).
to
receive
(
:commit
)
{
|
sha
|
commitmap
[
sha
]
}
set_mentionable_text
.
call
(
ref_string
)
set_mentionable_text
.
call
(
ref_string
)
...
...
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