summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2017-05-11 09:32:41 +0100
committerPhil Hughes <me@iamphill.com>2017-05-11 09:32:41 +0100
commit1ed0673c254003fc9e3f861fce8671712d71a2de (patch)
tree20b9d1c4baec3c593fe2c9b06c0d809c224562c0 /app
parent584ea586ff04bd57852748f4e6b046200eac7f68 (diff)
parent4067dd4f84681dd109fb8e1957b6327b4db20193 (diff)
downloadgitlab-ce-1ed0673c254003fc9e3f861fce8671712d71a2de.tar.gz
Merge branch 'master' into refactor-realtime-issue
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/blob/viewer/index.js5
-rw-r--r--app/assets/javascripts/boards/components/board_sidebar.js3
-rw-r--r--app/assets/javascripts/dispatcher.js2
-rw-r--r--app/assets/javascripts/lib/utils/ajax_cache.js70
-rw-r--r--app/assets/javascripts/milestone_select.js37
-rw-r--r--app/assets/stylesheets/framework/blocks.scss21
-rw-r--r--app/assets/stylesheets/pages/issues.scss10
-rw-r--r--app/assets/stylesheets/pages/pipelines.scss4
-rw-r--r--app/controllers/autocomplete_controller.rb2
-rw-r--r--app/controllers/concerns/lfs_request.rb6
-rw-r--r--app/controllers/dashboard/snippets_controller.rb7
-rw-r--r--app/controllers/explore/groups_controller.rb2
-rw-r--r--app/controllers/explore/snippets_controller.rb2
-rw-r--r--app/controllers/groups_controller.rb2
-rw-r--r--app/controllers/health_controller.rb2
-rw-r--r--app/controllers/jwt_controller.rb2
-rw-r--r--app/controllers/profiles/preferences_controller.rb2
-rw-r--r--app/controllers/projects/deployments_controller.rb2
-rw-r--r--app/controllers/projects/issues_controller.rb4
-rw-r--r--app/controllers/projects/lfs_api_controller.rb4
-rw-r--r--app/controllers/projects/pipelines_controller.rb2
-rw-r--r--app/controllers/projects/snippets_controller.rb5
-rw-r--r--app/controllers/projects/tags_controller.rb2
-rw-r--r--app/controllers/projects/tree_controller.rb2
-rw-r--r--app/controllers/projects_controller.rb2
-rw-r--r--app/controllers/snippets_controller.rb26
-rw-r--r--app/controllers/users_controller.rb7
-rw-r--r--app/finders/groups_finder.rb20
-rw-r--r--app/finders/notes_finder.rb2
-rw-r--r--app/finders/snippets_finder.rb102
-rw-r--r--app/helpers/diff_helper.rb2
-rw-r--r--app/helpers/emails_helper.rb2
-rw-r--r--app/helpers/events_helper.rb2
-rw-r--r--app/helpers/explore_helper.rb2
-rw-r--r--app/helpers/markup_helper.rb14
-rw-r--r--app/helpers/merge_requests_helper.rb2
-rw-r--r--app/helpers/notes_helper.rb4
-rw-r--r--app/helpers/search_helper.rb6
-rw-r--r--app/helpers/selects_helper.rb2
-rw-r--r--app/helpers/sorting_helper.rb2
-rw-r--r--app/helpers/submodule_helper.rb46
-rw-r--r--app/helpers/todos_helper.rb2
-rw-r--r--app/models/blob.rb2
-rw-r--r--app/models/ci/build.rb4
-rw-r--r--app/models/commit.rb2
-rw-r--r--app/models/commit_status.rb11
-rw-r--r--app/models/diff_discussion.rb2
-rw-r--r--app/models/environment.rb2
-rw-r--r--app/models/hooks/web_hook.rb2
-rw-r--r--app/models/key.rb2
-rw-r--r--app/models/namespace.rb2
-rw-r--r--app/models/project.rb2
-rw-r--r--app/models/project_services/bamboo_service.rb2
-rw-r--r--app/models/project_services/chat_notification_service.rb2
-rw-r--r--app/models/project_services/emails_on_push_service.rb2
-rw-r--r--app/models/project_services/external_wiki_service.rb2
-rw-r--r--app/models/project_services/flowdock_service.rb2
-rw-r--r--app/models/project_services/hipchat_service.rb2
-rw-r--r--app/models/project_services/irker_service.rb2
-rw-r--r--app/models/project_services/jira_service.rb2
-rw-r--r--app/models/project_services/kubernetes_service.rb2
-rw-r--r--app/models/project_services/microsoft_teams_service.rb2
-rw-r--r--app/models/project_services/mock_ci_service.rb2
-rw-r--r--app/models/project_services/pipelines_email_service.rb2
-rw-r--r--app/models/project_services/pushover_service.rb2
-rw-r--r--app/models/project_services/teamcity_service.rb4
-rw-r--r--app/models/readme_blob.rb13
-rw-r--r--app/models/repository.rb4
-rw-r--r--app/models/sent_notification.rb2
-rw-r--r--app/models/snippet.rb13
-rw-r--r--app/models/tree.rb5
-rw-r--r--app/policies/project_snippet_policy.rb2
-rw-r--r--app/services/akismet_service.rb2
-rw-r--r--app/services/audit_event_service.rb2
-rw-r--r--app/services/boards/issues/move_service.rb2
-rw-r--r--app/services/ci/process_pipeline_service.rb20
-rw-r--r--app/services/ci/retry_build_service.rb13
-rw-r--r--app/services/ci/retry_pipeline_service.rb2
-rw-r--r--app/services/notification_service.rb2
-rw-r--r--app/services/projects/update_pages_configuration_service.rb2
-rw-r--r--app/services/search/snippet_service.rb2
-rw-r--r--app/services/system_hooks_service.rb4
-rw-r--r--app/views/discussions/_diff_with_notes.html.haml2
-rw-r--r--app/views/import/base/create.js.haml2
-rw-r--r--app/views/projects/_readme.html.haml6
-rw-r--r--app/views/projects/_zen.html.haml3
-rw-r--r--app/views/projects/blob/_viewer.html.haml4
-rw-r--r--app/views/projects/boards/components/sidebar/_milestone.html.haml3
-rw-r--r--app/views/projects/cycle_analytics/show.html.haml2
-rw-r--r--app/views/projects/diffs/_file_header.html.haml6
-rw-r--r--app/views/projects/imports/new.html.haml2
-rw-r--r--app/views/projects/tags/new.html.haml4
-rw-r--r--app/views/projects/tree/_readme.html.haml6
-rw-r--r--app/views/projects/wikis/git_access.html.haml2
-rw-r--r--app/views/shared/empty_states/_issues.html.haml4
-rw-r--r--app/views/shared/empty_states/_labels.html.haml4
-rw-r--r--app/views/shared/empty_states/_merge_requests.html.haml4
-rw-r--r--app/views/shared/issuable/_milestone_dropdown.html.haml2
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml2
-rw-r--r--app/views/shared/notes/_note.html.haml2
-rw-r--r--app/views/shared/notifications/_custom_notifications.html.haml6
-rw-r--r--app/workers/namespaceless_project_destroy_worker.rb43
-rw-r--r--app/workers/repository_check/clear_worker.rb2
-rw-r--r--app/workers/repository_check/single_repository_worker.rb2
104 files changed, 422 insertions, 287 deletions
diff --git a/app/assets/javascripts/blob/viewer/index.js b/app/assets/javascripts/blob/viewer/index.js
index 07d67d49aa5..69ff2f95799 100644
--- a/app/assets/javascripts/blob/viewer/index.js
+++ b/app/assets/javascripts/blob/viewer/index.js
@@ -8,7 +8,10 @@ export default class BlobViewer {
this.richViewer = document.querySelector('.blob-viewer[data-type="rich"]');
this.$fileHolder = $('.file-holder');
- let initialViewerName = document.querySelector('.blob-viewer:not(.hidden)').getAttribute('data-type');
+ const initialViewer = document.querySelector('.blob-viewer:not(.hidden)');
+ if (!initialViewer) return;
+
+ let initialViewerName = initialViewer.getAttribute('data-type');
this.initBindings();
diff --git a/app/assets/javascripts/boards/components/board_sidebar.js b/app/assets/javascripts/boards/components/board_sidebar.js
index 317cef9f227..9bcea302da2 100644
--- a/app/assets/javascripts/boards/components/board_sidebar.js
+++ b/app/assets/javascripts/boards/components/board_sidebar.js
@@ -36,6 +36,9 @@ gl.issueBoards.BoardSidebar = Vue.extend({
},
assigneeId() {
return this.issue.assignee ? this.issue.assignee.id : 0;
+ },
+ milestoneTitle() {
+ return this.issue.milestone ? this.issue.milestone.title : 'No Milestone';
}
},
watch: {
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index abb871c3af0..43ad127a4db 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -246,6 +246,7 @@ const ShortcutsBlob = require('./shortcuts_blob');
new NotificationsForm();
if ($('#tree-slider').length) {
new TreeView();
+ new BlobViewer();
}
break;
case 'projects:pipelines:builds':
@@ -300,6 +301,7 @@ const ShortcutsBlob = require('./shortcuts_blob');
case 'projects:tree:show':
shortcut_handler = new ShortcutsNavigation();
new TreeView();
+ new BlobViewer();
gl.TargetBranchDropDown.bootstrap();
break;
case 'projects:find_file:show':
diff --git a/app/assets/javascripts/lib/utils/ajax_cache.js b/app/assets/javascripts/lib/utils/ajax_cache.js
index d99eefb5089..cf030d613df 100644
--- a/app/assets/javascripts/lib/utils/ajax_cache.js
+++ b/app/assets/javascripts/lib/utils/ajax_cache.js
@@ -1,32 +1,54 @@
-const AjaxCache = {
- internalStorage: { },
+class AjaxCache {
+ constructor() {
+ this.internalStorage = { };
+ this.pendingRequests = { };
+ }
+
get(endpoint) {
return this.internalStorage[endpoint];
- },
+ }
+
hasData(endpoint) {
return Object.prototype.hasOwnProperty.call(this.internalStorage, endpoint);
- },
- purge(endpoint) {
+ }
+
+ remove(endpoint) {
delete this.internalStorage[endpoint];
- },
+ }
+
retrieve(endpoint) {
- if (AjaxCache.hasData(endpoint)) {
- return Promise.resolve(AjaxCache.get(endpoint));
+ if (this.hasData(endpoint)) {
+ return Promise.resolve(this.get(endpoint));
}
- return new Promise((resolve, reject) => {
- $.ajax(endpoint) // eslint-disable-line promise/catch-or-return
- .then(data => resolve(data),
- (jqXHR, textStatus, errorThrown) => {
- const error = new Error(`${endpoint}: ${errorThrown}`);
- error.textStatus = textStatus;
- reject(error);
- },
- );
- })
- .then((data) => { this.internalStorage[endpoint] = data; })
- .then(() => AjaxCache.get(endpoint));
- },
-};
-
-export default AjaxCache;
+ let pendingRequest = this.pendingRequests[endpoint];
+
+ if (!pendingRequest) {
+ pendingRequest = new Promise((resolve, reject) => {
+ // jQuery 2 is not Promises/A+ compatible (missing catch)
+ $.ajax(endpoint) // eslint-disable-line promise/catch-or-return
+ .then(data => resolve(data),
+ (jqXHR, textStatus, errorThrown) => {
+ const error = new Error(`${endpoint}: ${errorThrown}`);
+ error.textStatus = textStatus;
+ reject(error);
+ },
+ );
+ })
+ .then((data) => {
+ this.internalStorage[endpoint] = data;
+ delete this.pendingRequests[endpoint];
+ })
+ .catch((error) => {
+ delete this.pendingRequests[endpoint];
+ throw error;
+ });
+
+ this.pendingRequests[endpoint] = pendingRequest;
+ }
+
+ return pendingRequest.then(() => this.get(endpoint));
+ }
+}
+
+export default new AjaxCache();
diff --git a/app/assets/javascripts/milestone_select.js b/app/assets/javascripts/milestone_select.js
index 11e68c0a3be..9d481d7c003 100644
--- a/app/assets/javascripts/milestone_select.js
+++ b/app/assets/javascripts/milestone_select.js
@@ -18,12 +18,11 @@
}
$els.each(function(i, dropdown) {
- var $block, $dropdown, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, collapsedSidebarLabelTemplate, defaultLabel, issuableId, issueUpdateURL, milestoneLinkNoneTemplate, milestoneLinkTemplate, milestonesUrl, projectId, selectedMilestone, showAny, showNo, showUpcoming, showStarted, useId, showMenuAbove;
+ var $block, $dropdown, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, collapsedSidebarLabelTemplate, defaultLabel, defaultNo, issuableId, issueUpdateURL, milestoneLinkNoneTemplate, milestoneLinkTemplate, milestonesUrl, projectId, selectedMilestone, selectedMilestoneDefault, showAny, showNo, showUpcoming, showStarted, useId, showMenuAbove;
$dropdown = $(dropdown);
projectId = $dropdown.data('project-id');
milestonesUrl = $dropdown.data('milestones');
issueUpdateURL = $dropdown.data('issueUpdate');
- selectedMilestone = $dropdown.data('selected');
showNo = $dropdown.data('show-no');
showAny = $dropdown.data('show-any');
showMenuAbove = $dropdown.data('showMenuAbove');
@@ -31,6 +30,7 @@
showStarted = $dropdown.data('show-started');
useId = $dropdown.data('use-id');
defaultLabel = $dropdown.data('default-label');
+ defaultNo = $dropdown.data('default-no');
issuableId = $dropdown.data('issuable-id');
abilityName = $dropdown.data('ability-name');
$selectbox = $dropdown.closest('.selectbox');
@@ -38,6 +38,9 @@
$sidebarCollapsedValue = $block.find('.sidebar-collapsed-icon');
$value = $block.find('.value');
$loading = $block.find('.block-loading').fadeOut();
+ selectedMilestoneDefault = (showAny ? '' : null);
+ selectedMilestoneDefault = (showNo && defaultNo ? 'No Milestone' : selectedMilestoneDefault);
+ selectedMilestone = $dropdown.data('selected') || selectedMilestoneDefault;
if (issueUpdateURL) {
milestoneLinkTemplate = _.template('<a href="/<%- full_path %>/milestones/<%- iid %>" class="bold has-tooltip" data-container="body" title="<%- remaining %>"><%- title %></a>');
milestoneLinkNoneTemplate = '<span class="no-value">None</span>';
@@ -86,8 +89,18 @@
if (showMenuAbove) {
$dropdown.data('glDropdown').positionMenuAbove();
}
+ $(`[data-milestone-id="${selectedMilestone}"] > a`).addClass('is-active');
});
},
+ renderRow: function(milestone) {
+ return `
+ <li data-milestone-id="${milestone.name}">
+ <a href='#' class='dropdown-menu-milestone-link'>
+ ${_.escape(milestone.title)}
+ </a>
+ </li>
+ `;
+ },
filterable: true,
search: {
fields: ['title']
@@ -120,15 +133,24 @@
// display:block overrides the hide-collapse rule
return $value.css('display', '');
},
+ opened: function(e) {
+ const $el = $(e.currentTarget);
+ if ($dropdown.hasClass('js-issue-board-sidebar')) {
+ selectedMilestone = $dropdown[0].dataset.selected || selectedMilestoneDefault;
+ }
+ $('a.is-active', $el).removeClass('is-active');
+ $(`[data-milestone-id="${selectedMilestone}"] > a`, $el).addClass('is-active');
+ },
vue: $dropdown.hasClass('js-issue-board-sidebar'),
clicked: function(options) {
const { $el, e } = options;
let selected = options.selectedObj;
-
- var data, isIssueIndex, isMRIndex, page, boardsStore;
+ var data, isIssueIndex, isMRIndex, isSelecting, page, boardsStore;
page = $('body').data('page');
isIssueIndex = page === 'projects:issues:index';
isMRIndex = (page === page && page === 'projects:merge_requests:index');
+ isSelecting = (selected.name !== selectedMilestone);
+ selectedMilestone = isSelecting ? selected.name : selectedMilestoneDefault;
if ($dropdown.hasClass('js-filter-bulk-update') || $dropdown.hasClass('js-issuable-form-dropdown')) {
e.preventDefault();
return;
@@ -142,16 +164,11 @@
boardsStore[$dropdown.data('field-name')] = selected.name;
e.preventDefault();
} else if ($dropdown.hasClass('js-filter-submit') && (isIssueIndex || isMRIndex)) {
- if (selected.name != null) {
- selectedMilestone = selected.name;
- } else {
- selectedMilestone = '';
- }
return Issuable.filterResults($dropdown.closest('form'));
} else if ($dropdown.hasClass('js-filter-submit')) {
return $dropdown.closest('form').submit();
} else if ($dropdown.hasClass('js-issue-board-sidebar')) {
- if (selected.id !== -1) {
+ if (selected.id !== -1 && isSelecting) {
gl.issueBoards.boardStoreIssueSet('milestone', new ListMilestone({
id: selected.id,
title: selected.name
diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss
index ac1fc0eb8ae..3dec911d289 100644
--- a/app/assets/stylesheets/framework/blocks.scss
+++ b/app/assets/stylesheets/framework/blocks.scss
@@ -312,7 +312,7 @@
}
.empty-state {
- margin: 100px 0 0;
+ margin: 5% auto 0;
.text-content {
max-width: 460px;
@@ -335,27 +335,12 @@
}
.btn {
- margin: $btn-side-margin $btn-side-margin 0 0;
- }
-
- @media(max-width: $screen-xs-max) {
- margin-top: 50px;
- text-align: center;
+ margin: $btn-side-margin 5px;
- .btn {
+ @media(max-width: $screen-xs-max) {
width: 100%;
}
}
-
- @media(min-width: $screen-xs-max) {
- &.merge-requests .text-content {
- margin-top: 40px;
- }
-
- &.labels .text-content {
- margin-top: 70px;
- }
- }
}
.flex-container-block {
diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss
index ad3b6e0344b..bee9b13b375 100644
--- a/app/assets/stylesheets/pages/issues.scss
+++ b/app/assets/stylesheets/pages/issues.scss
@@ -51,6 +51,7 @@ ul.related-merge-requests > li {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
+ align-items: center;
.merge-request-id {
flex-shrink: 0;
@@ -59,6 +60,14 @@ ul.related-merge-requests > li {
.merge-request-info {
margin-left: 5px;
}
+
+ .row_title {
+ vertical-align: bottom;
+ }
+
+ gl-emoji {
+ font-size: 1em;
+ }
}
.merge-requests-title,
@@ -114,7 +123,6 @@ ul.related-merge-requests > li {
.related-merge-requests {
.ci-status-link {
display: block;
- margin-top: 3px;
margin-right: 5px;
}
diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss
index e7553c7a4bf..685b9775fe1 100644
--- a/app/assets/stylesheets/pages/pipelines.scss
+++ b/app/assets/stylesheets/pages/pipelines.scss
@@ -8,10 +8,6 @@
white-space: nowrap;
}
- .empty-state {
- margin: 5% auto 0;
- }
-
.table-holder {
width: 100%;
diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb
index b79ca034c5b..e2f5aa8508e 100644
--- a/app/controllers/autocomplete_controller.rb
+++ b/app/controllers/autocomplete_controller.rb
@@ -41,7 +41,7 @@ class AutocompleteController < ApplicationController
no_project = {
id: 0,
- name_with_namespace: 'No project',
+ name_with_namespace: 'No project'
}
projects.unshift(no_project) unless params[:offset_id].present?
diff --git a/app/controllers/concerns/lfs_request.rb b/app/controllers/concerns/lfs_request.rb
index ed22b1e5470..ae91e02488a 100644
--- a/app/controllers/concerns/lfs_request.rb
+++ b/app/controllers/concerns/lfs_request.rb
@@ -23,7 +23,7 @@ module LfsRequest
render(
json: {
message: 'Git LFS is not enabled on this GitLab server, contact your admin.',
- documentation_url: help_url,
+ documentation_url: help_url
},
status: 501
)
@@ -48,7 +48,7 @@ module LfsRequest
render(
json: {
message: 'Access forbidden. Check your access level.',
- documentation_url: help_url,
+ documentation_url: help_url
},
content_type: "application/vnd.git-lfs+json",
status: 403
@@ -59,7 +59,7 @@ module LfsRequest
render(
json: {
message: 'Not found.',
- documentation_url: help_url,
+ documentation_url: help_url
},
content_type: "application/vnd.git-lfs+json",
status: 404
diff --git a/app/controllers/dashboard/snippets_controller.rb b/app/controllers/dashboard/snippets_controller.rb
index bcfdbe14be9..8dd91264451 100644
--- a/app/controllers/dashboard/snippets_controller.rb
+++ b/app/controllers/dashboard/snippets_controller.rb
@@ -1,11 +1,10 @@
class Dashboard::SnippetsController < Dashboard::ApplicationController
def index
- @snippets = SnippetsFinder.new.execute(
+ @snippets = SnippetsFinder.new(
current_user,
- filter: :by_user,
- user: current_user,
+ author: current_user,
scope: params[:scope]
- )
+ ).execute
@snippets = @snippets.page(params[:page])
end
end
diff --git a/app/controllers/explore/groups_controller.rb b/app/controllers/explore/groups_controller.rb
index 68228c095da..81883c543ba 100644
--- a/app/controllers/explore/groups_controller.rb
+++ b/app/controllers/explore/groups_controller.rb
@@ -1,6 +1,6 @@
class Explore::GroupsController < Explore::ApplicationController
def index
- @groups = GroupsFinder.new.execute(current_user)
+ @groups = GroupsFinder.new(current_user).execute
@groups = @groups.search(params[:filter_groups]) if params[:filter_groups].present?
@groups = @groups.sort(@sort = params[:sort])
@groups = @groups.page(params[:page])
diff --git a/app/controllers/explore/snippets_controller.rb b/app/controllers/explore/snippets_controller.rb
index 28760c3f84b..d3f0e033068 100644
--- a/app/controllers/explore/snippets_controller.rb
+++ b/app/controllers/explore/snippets_controller.rb
@@ -1,6 +1,6 @@
class Explore::SnippetsController < Explore::ApplicationController
def index
- @snippets = SnippetsFinder.new.execute(current_user, filter: :all)
+ @snippets = SnippetsFinder.new(current_user).execute
@snippets = @snippets.page(params[:page])
end
end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 46c3ff10694..1515173d0ac 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -64,7 +64,7 @@ class GroupsController < Groups::ApplicationController
end
def subgroups
- @nested_groups = group.children
+ @nested_groups = GroupsFinder.new(current_user, parent: group).execute
@nested_groups = @nested_groups.search(params[:filter_groups]) if params[:filter_groups].present?
end
diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb
index df0fc3132ed..125746d0426 100644
--- a/app/controllers/health_controller.rb
+++ b/app/controllers/health_controller.rb
@@ -5,7 +5,7 @@ class HealthController < ActionController::Base
CHECKS = [
Gitlab::HealthChecks::DbCheck,
Gitlab::HealthChecks::RedisCheck,
- Gitlab::HealthChecks::FsShardsCheck,
+ Gitlab::HealthChecks::FsShardsCheck
].freeze
def readiness
diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb
index 3109439b2ff..1c01be06451 100644
--- a/app/controllers/jwt_controller.rb
+++ b/app/controllers/jwt_controller.rb
@@ -4,7 +4,7 @@ class JwtController < ApplicationController
before_action :authenticate_project_or_user
SERVICES = {
- Auth::ContainerRegistryAuthenticationService::AUDIENCE => Auth::ContainerRegistryAuthenticationService,
+ Auth::ContainerRegistryAuthenticationService::AUDIENCE => Auth::ContainerRegistryAuthenticationService
}.freeze
def auth
diff --git a/app/controllers/profiles/preferences_controller.rb b/app/controllers/profiles/preferences_controller.rb
index 0d891ef4004..5414142e2df 100644
--- a/app/controllers/profiles/preferences_controller.rb
+++ b/app/controllers/profiles/preferences_controller.rb
@@ -33,7 +33,7 @@ class Profiles::PreferencesController < Profiles::ApplicationController
:color_scheme_id,
:layout,
:dashboard,
- :project_view,
+ :project_view
)
end
end
diff --git a/app/controllers/projects/deployments_controller.rb b/app/controllers/projects/deployments_controller.rb
index b33c0b00ad9..f06a4d943f3 100644
--- a/app/controllers/projects/deployments_controller.rb
+++ b/app/controllers/projects/deployments_controller.rb
@@ -6,7 +6,7 @@ class Projects::DeploymentsController < Projects::ApplicationController
deployments = environment.deployments.reorder(created_at: :desc)
deployments = deployments.where('created_at > ?', params[:after].to_time) if params[:after]&.to_time
- render json: { deployments: DeploymentSerializer.new(user: @current_user, project: project)
+ render json: { deployments: DeploymentSerializer.new(project: project)
.represent_concise(deployments) }
end
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index c9cd42cf99d..760ba246e3e 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -208,7 +208,7 @@ class Projects::IssuesController < Projects::ApplicationController
description: view_context.markdown_field(@issue, :description),
description_text: @issue.description,
task_status: @issue.task_status,
- updated_at: @issue.updated_at,
+ updated_at: @issue.updated_at
}
end
@@ -268,7 +268,7 @@ class Projects::IssuesController < Projects::ApplicationController
def issue_params
params.require(:issue).permit(
:title, :assignee_id, :position, :description, :confidential,
- :milestone_id, :due_date, :state_event, :task_num, :lock_version, label_ids: [], assignee_ids: [],
+ :milestone_id, :due_date, :state_event, :task_num, :lock_version, label_ids: [], assignee_ids: []
)
end
diff --git a/app/controllers/projects/lfs_api_controller.rb b/app/controllers/projects/lfs_api_controller.rb
index 8a5a645ed0e..1b0d3aab3fa 100644
--- a/app/controllers/projects/lfs_api_controller.rb
+++ b/app/controllers/projects/lfs_api_controller.rb
@@ -22,7 +22,7 @@ class Projects::LfsApiController < Projects::GitHttpClientController
render(
json: {
message: 'Server supports batch API only, please update your Git LFS client to version 1.0.1 and up.',
- documentation_url: "#{Gitlab.config.gitlab.url}/help",
+ documentation_url: "#{Gitlab.config.gitlab.url}/help"
},
status: 501
)
@@ -55,7 +55,7 @@ class Projects::LfsApiController < Projects::GitHttpClientController
else
object[:error] = {
code: 404,
- message: "Object does not exist on the server or you don't have permissions to access it",
+ message: "Object does not exist on the server or you don't have permissions to access it"
}
end
end
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index 7fe3c3c116c..602d3dd8c1c 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -44,7 +44,7 @@ class Projects::PipelinesController < Projects::ApplicationController
all: @pipelines_count,
running: @running_count,
pending: @pending_count,
- finished: @finished_count,
+ finished: @finished_count
}
}
end
diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb
index 66f913f8f9d..3b2b0d9e502 100644
--- a/app/controllers/projects/snippets_controller.rb
+++ b/app/controllers/projects/snippets_controller.rb
@@ -23,12 +23,11 @@ class Projects::SnippetsController < Projects::ApplicationController
respond_to :html
def index
- @snippets = SnippetsFinder.new.execute(
+ @snippets = SnippetsFinder.new(
current_user,
- filter: :by_project,
project: @project,
scope: params[:scope]
- )
+ ).execute
@snippets = @snippets.page(params[:page])
if @snippets.out_of_range? && @snippets.total_pages != 0
redirect_to namespace_project_snippets_path(page: @snippets.total_pages)
diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb
index 750c3ec486a..afbea3e2b40 100644
--- a/app/controllers/projects/tags_controller.rb
+++ b/app/controllers/projects/tags_controller.rb
@@ -38,6 +38,8 @@ class Projects::TagsController < Projects::ApplicationController
redirect_to namespace_project_tag_path(@project.namespace, @project, @tag.name)
else
@error = result[:message]
+ @message = params[:message]
+ @release_description = params[:release_description]
render action: 'new'
end
end
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index 5e2182c883e..3ce65b29b3c 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -48,7 +48,7 @@ class Projects::TreeController < Projects::ApplicationController
@dir_name = File.join(@path, params[:dir_name])
@commit_params = {
file_path: @dir_name,
- commit_message: params[:commit_message],
+ commit_message: params[:commit_message]
}
end
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 69310b26e76..63d018c8cbf 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -220,7 +220,7 @@ class ProjectsController < Projects::ApplicationController
branches = BranchesFinder.new(@repository, params).execute.map(&:name)
options = {
- 'Branches' => branches.take(100),
+ 'Branches' => branches.take(100)
}
unless @repository.tag_count.zero?
diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb
index 19e07e3ab86..7445f61195d 100644
--- a/app/controllers/snippets_controller.rb
+++ b/app/controllers/snippets_controller.rb
@@ -27,12 +27,8 @@ class SnippetsController < ApplicationController
return render_404 unless @user
- @snippets = SnippetsFinder.new.execute(current_user, {
- filter: :by_user,
- user: @user,
- scope: params[:scope]
- })
- .page(params[:page])
+ @snippets = SnippetsFinder.new(current_user, author: @user, scope: params[:scope])
+ .execute.page(params[:page])
render 'index'
else
@@ -103,20 +99,20 @@ class SnippetsController < ApplicationController
protected
def snippet
- @snippet ||= if current_user
- PersonalSnippet.where("author_id = ? OR visibility_level IN (?)",
- current_user.id,
- [Snippet::PUBLIC, Snippet::INTERNAL]).
- find(params[:id])
- else
- PersonalSnippet.find(params[:id])
- end
+ @snippet ||= PersonalSnippet.find_by(id: params[:id])
end
+
alias_method :awardable, :snippet
alias_method :spammable, :snippet
def authorize_read_snippet!
- authenticate_user! unless can?(current_user, :read_personal_snippet, @snippet)
+ return if can?(current_user, :read_personal_snippet, @snippet)
+
+ if current_user
+ render_404
+ else
+ authenticate_user!
+ end
end
def authorize_update_snippet!
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index ca89ed221c6..ba22b2f9d29 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -128,12 +128,11 @@ class UsersController < ApplicationController
end
def load_snippets
- @snippets = SnippetsFinder.new.execute(
+ @snippets = SnippetsFinder.new(
current_user,
- filter: :by_user,
- user: user,
+ author: user,
scope: params[:scope]
- ).page(params[:page])
+ ).execute.page(params[:page])
end
def projects_for_current_user
diff --git a/app/finders/groups_finder.rb b/app/finders/groups_finder.rb
index d932a17883f..f68610e197c 100644
--- a/app/finders/groups_finder.rb
+++ b/app/finders/groups_finder.rb
@@ -1,13 +1,19 @@
class GroupsFinder < UnionFinder
- def execute(current_user = nil)
- segments = all_groups(current_user)
+ def initialize(current_user = nil, params = {})
+ @current_user = current_user
+ @params = params
+ end
- find_union(segments, Group).with_route.order_id_desc
+ def execute
+ groups = find_union(all_groups, Group).with_route.order_id_desc
+ by_parent(groups)
end
private
- def all_groups(current_user)
+ attr_reader :current_user, :params
+
+ def all_groups
groups = []
groups << current_user.authorized_groups if current_user
@@ -15,4 +21,10 @@ class GroupsFinder < UnionFinder
groups
end
+
+ def by_parent(groups)
+ return groups unless params[:parent]
+
+ groups.where(parent: params[:parent])
+ end
end
diff --git a/app/finders/notes_finder.rb b/app/finders/notes_finder.rb
index dc6a8ad1f66..02eb983bf55 100644
--- a/app/finders/notes_finder.rb
+++ b/app/finders/notes_finder.rb
@@ -67,7 +67,7 @@ class NotesFinder
when "merge_request"
MergeRequestsFinder.new(@current_user, project_id: @project.id).execute
when "snippet", "project_snippet"
- SnippetsFinder.new.execute(@current_user, filter: :by_project, project: @project)
+ SnippetsFinder.new(@current_user, project: @project).execute
when "personal_snippet"
PersonalSnippet.all
else
diff --git a/app/finders/snippets_finder.rb b/app/finders/snippets_finder.rb
index da6e6e87a6f..c04f61de79c 100644
--- a/app/finders/snippets_finder.rb
+++ b/app/finders/snippets_finder.rb
@@ -1,66 +1,74 @@
-class SnippetsFinder
- def execute(current_user, params = {})
- filter = params[:filter]
- user = params.fetch(:user, current_user)
-
- case filter
- when :all then
- snippets(current_user).fresh
- when :public then
- Snippet.are_public.fresh
- when :by_user then
- by_user(current_user, user, params[:scope])
- when :by_project
- by_project(current_user, params[:project], params[:scope])
- end
+class SnippetsFinder < UnionFinder
+ attr_accessor :current_user, :params
+
+ def initialize(current_user, params = {})
+ @current_user = current_user
+ @params = params
+ end
+
+ def execute
+ items = init_collection
+ items = by_project(items)
+ items = by_author(items)
+ items = by_visibility(items)
+
+ items.fresh
end
private
- def snippets(current_user)
- if current_user
- Snippet.public_and_internal
- else
- # Not authenticated
- #
- # Return only:
- # public snippets
- Snippet.are_public
- end
+ def init_collection
+ items = Snippet.all
+
+ accessible(items)
end
- def by_user(current_user, user, scope)
- snippets = user.snippets.fresh
+ def accessible(items)
+ segments = []
+ segments << items.public_to_user(current_user)
+ segments << authorized_to_user(items) if current_user
- if current_user
- include_private = user == current_user
- by_scope(snippets, scope, include_private)
- else
- snippets.are_public
- end
+ find_union(segments, Snippet)
end
- def by_project(current_user, project, scope)
- snippets = project.snippets.fresh
+ def authorized_to_user(items)
+ items.where(
+ 'author_id = :author_id
+ OR project_id IN (:project_ids)',
+ author_id: current_user.id,
+ project_ids: current_user.authorized_projects.select(:id))
+ end
- if current_user
- include_private = project.team.member?(current_user) || current_user.admin?
- by_scope(snippets, scope, include_private)
- else
- snippets.are_public
- end
+ def by_visibility(items)
+ visibility = params[:visibility] || visibility_from_scope
+
+ return items unless visibility
+
+ items.where(visibility_level: visibility)
+ end
+
+ def by_author(items)
+ return items unless params[:author]
+
+ items.where(author_id: params[:author].id)
+ end
+
+ def by_project(items)
+ return items unless params[:project]
+
+ items.where(project_id: params[:project].id)
end
- def by_scope(snippets, scope = nil, include_private = false)
- case scope.to_s
+ def visibility_from_scope
+ case params[:scope].to_s
when 'are_private'
- include_private ? snippets.are_private : Snippet.none
+ Snippet::PRIVATE
when 'are_internal'
- snippets.are_internal
+ Snippet::INTERNAL
when 'are_public'
- snippets.are_public
+ Snippet::PUBLIC
else
- include_private ? snippets : snippets.public_and_internal
+ nil
end
end
end
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index dc144906548..63bc3b11b56 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -98,7 +98,7 @@ module DiffHelper
[
content_tag(:span, link_to(truncate(blob.name, length: 40), tree)),
'@',
- content_tag(:span, commit_id, class: 'monospace'),
+ content_tag(:span, commit_id, class: 'monospace')
].join(' ').html_safe
end
diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb
index f927cfc998f..3b24f183785 100644
--- a/app/helpers/emails_helper.rb
+++ b/app/helpers/emails_helper.rb
@@ -12,7 +12,7 @@ module EmailsHelper
"action" => {
"@type" => "ViewAction",
"name" => name,
- "url" => url,
+ "url" => url
}
}
diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb
index 960111ca045..c14438da281 100644
--- a/app/helpers/events_helper.rb
+++ b/app/helpers/events_helper.rb
@@ -41,7 +41,7 @@ module EventsHelper
link_opts = {
class: "event-filter-link",
id: "#{key}_event_filter",
- title: "Filter by #{tooltip.downcase}",
+ title: "Filter by #{tooltip.downcase}"
}
content_tag :li, class: active do
diff --git a/app/helpers/explore_helper.rb b/app/helpers/explore_helper.rb
index 7bd212a3ef9..b981a1e8242 100644
--- a/app/helpers/explore_helper.rb
+++ b/app/helpers/explore_helper.rb
@@ -10,7 +10,7 @@ module ExploreHelper
personal: params[:personal],
archived: params[:archived],
shared: params[:shared],
- namespace_id: params[:namespace_id],
+ namespace_id: params[:namespace_id]
}
options = exist_opts.merge(options).delete_if { |key, value| value.blank? }
diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb
index b241a14740b..0009cad86c4 100644
--- a/app/helpers/markup_helper.rb
+++ b/app/helpers/markup_helper.rb
@@ -32,7 +32,7 @@ module MarkupHelper
context = {
project: @project,
current_user: (current_user if defined?(current_user)),
- pipeline: :single_line,
+ pipeline: :single_line
}
gfm_body = Banzai.render(body, context)
@@ -116,13 +116,13 @@ module MarkupHelper
if gitlab_markdown?(file_name)
markdown_unsafe(text, context)
elsif asciidoc?(file_name)
- asciidoc_unsafe(text)
+ asciidoc_unsafe(text, context)
elsif plain?(file_name)
content_tag :pre, class: 'plain-readme' do
text
end
else
- other_markup_unsafe(file_name, text)
+ other_markup_unsafe(file_name, text, context)
end
rescue RuntimeError
simple_format(text)
@@ -217,12 +217,12 @@ module MarkupHelper
Banzai.render(text, context)
end
- def asciidoc_unsafe(text)
- Gitlab::Asciidoc.render(text)
+ def asciidoc_unsafe(text, context = {})
+ Gitlab::Asciidoc.render(text, context)
end
- def other_markup_unsafe(file_name, text)
- Gitlab::OtherMarkup.render(file_name, text)
+ def other_markup_unsafe(file_name, text, context = {})
+ Gitlab::OtherMarkup.render(file_name, text, context)
end
def prepare_for_rendering(html, context = {})
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 23e55539f0a..39d30631646 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -54,7 +54,7 @@ module MergeRequestsHelper
source_project_id: merge_request.source_project_id,
target_project_id: merge_request.target_project_id,
source_branch: merge_request.source_branch,
- target_branch: merge_request.target_branch,
+ target_branch: merge_request.target_branch
},
change_branches: true
)
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index 52403640c05..375110b77e2 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -19,7 +19,7 @@ module NotesHelper
id: noteable.id,
class: noteable.class.name,
resources: noteable.class.table_name,
- project_id: noteable.project.id,
+ project_id: noteable.project.id
}.to_json
end
@@ -34,7 +34,7 @@ module NotesHelper
data = {
line_code: line_code,
- line_type: line_type,
+ line_type: line_type
}
if @use_legacy_diff_notes
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index 8ff8db16514..9c46035057f 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -42,7 +42,7 @@ module SearchHelper
{ category: "Settings", label: "User settings", url: profile_path },
{ category: "Settings", label: "SSH Keys", url: profile_keys_path },
{ category: "Settings", label: "Dashboard", url: root_path },
- { category: "Settings", label: "Admin Section", url: admin_root_path },
+ { category: "Settings", label: "Admin Section", url: admin_root_path }
]
end
@@ -57,7 +57,7 @@ module SearchHelper
{ category: "Help", label: "SSH Keys Help", url: help_page_path("ssh/README") },
{ category: "Help", label: "System Hooks Help", url: help_page_path("system_hooks/system_hooks") },
{ category: "Help", label: "Webhooks Help", url: help_page_path("user/project/integrations/webhooks") },
- { category: "Help", label: "Workflow Help", url: help_page_path("workflow/README") },
+ { category: "Help", label: "Workflow Help", url: help_page_path("workflow/README") }
]
end
@@ -76,7 +76,7 @@ module SearchHelper
{ category: "Current Project", label: "Milestones", url: namespace_project_milestones_path(@project.namespace, @project) },
{ category: "Current Project", label: "Snippets", url: namespace_project_snippets_path(@project.namespace, @project) },
{ category: "Current Project", label: "Members", url: namespace_project_settings_members_path(@project.namespace, @project) },
- { category: "Current Project", label: "Wiki", url: namespace_project_wikis_path(@project.namespace, @project) },
+ { category: "Current Project", label: "Wiki", url: namespace_project_wikis_path(@project.namespace, @project) }
]
else
[]
diff --git a/app/helpers/selects_helper.rb b/app/helpers/selects_helper.rb
index 8706876ae4a..a7d1fe4aa47 100644
--- a/app/helpers/selects_helper.rb
+++ b/app/helpers/selects_helper.rb
@@ -67,7 +67,7 @@ module SelectsHelper
current_user: opts[:current_user] || false,
"push-code-to-protected-branches" => opts[:push_code_to_protected_branches],
author_id: opts[:author_id] || '',
- skip_users: opts[:skip_users] ? opts[:skip_users].map(&:id) : nil,
+ skip_users: opts[:skip_users] ? opts[:skip_users].map(&:id) : nil
}
end
end
diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb
index 4882d9b71d2..b408ec0c6a4 100644
--- a/app/helpers/sorting_helper.rb
+++ b/app/helpers/sorting_helper.rb
@@ -58,7 +58,7 @@ module SortingHelper
sort_value_due_date_soon => sort_title_due_date_soon,
sort_value_due_date_later => sort_title_due_date_later,
sort_value_start_date_soon => sort_title_start_date_soon,
- sort_value_start_date_later => sort_title_start_date_later,
+ sort_value_start_date_later => sort_title_start_date_later
}
end
diff --git a/app/helpers/submodule_helper.rb b/app/helpers/submodule_helper.rb
index a762b320d56..b739554a7a4 100644
--- a/app/helpers/submodule_helper.rb
+++ b/app/helpers/submodule_helper.rb
@@ -1,28 +1,30 @@
module SubmoduleHelper
include Gitlab::ShellAdapter
+ VALID_SUBMODULE_PROTOCOLS = %w[http https git ssh].freeze
+
# links to files listing for submodule if submodule is a project on this server
def submodule_links(submodule_item, ref = nil, repository = @repository)
url = repository.submodule_url_for(ref, submodule_item.path)
- return url, nil unless url =~ /([^\/:]+)\/([^\/]+(?:\.git)?)\Z/
-
- namespace = $1
- project = $2
- project.chomp!('.git')
+ if url =~ /([^\/:]+)\/([^\/]+(?:\.git)?)\Z/
+ namespace, project = $1, $2
+ project.sub!(/\.git\z/, '')
- if self_url?(url, namespace, project)
- return namespace_project_path(namespace, project),
- namespace_project_tree_path(namespace, project,
- submodule_item.id)
- elsif relative_self_url?(url)
- relative_self_links(url, submodule_item.id)
- elsif github_dot_com_url?(url)
- standard_links('github.com', namespace, project, submodule_item.id)
- elsif gitlab_dot_com_url?(url)
- standard_links('gitlab.com', namespace, project, submodule_item.id)
+ if self_url?(url, namespace, project)
+ [namespace_project_path(namespace, project),
+ namespace_project_tree_path(namespace, project, submodule_item.id)]
+ elsif relative_self_url?(url)
+ relative_self_links(url, submodule_item.id)
+ elsif github_dot_com_url?(url)
+ standard_links('github.com', namespace, project, submodule_item.id)
+ elsif gitlab_dot_com_url?(url)
+ standard_links('gitlab.com', namespace, project, submodule_item.id)
+ else
+ [sanitize_submodule_url(url), nil]
+ end
else
- return url, nil
+ [sanitize_submodule_url(url), nil]
end
end
@@ -73,4 +75,16 @@ module SubmoduleHelper
namespace_project_tree_path(namespace, base, commit)
]
end
+
+ def sanitize_submodule_url(url)
+ uri = URI.parse(url)
+
+ if uri.scheme.in?(VALID_SUBMODULE_PROTOCOLS)
+ uri.to_s
+ else
+ nil
+ end
+ rescue URI::InvalidURIError
+ nil
+ end
end
diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb
index f19e2f9db9c..0ff2d5ce4cd 100644
--- a/app/helpers/todos_helper.rb
+++ b/app/helpers/todos_helper.rb
@@ -63,7 +63,7 @@ module TodosHelper
project_id: params[:project_id],
author_id: params[:author_id],
type: params[:type],
- action_id: params[:action_id],
+ action_id: params[:action_id]
}
end
diff --git a/app/models/blob.rb b/app/models/blob.rb
index eaf0b713122..8452a96e909 100644
--- a/app/models/blob.rb
+++ b/app/models/blob.rb
@@ -33,7 +33,7 @@ class Blob < SimpleDelegator
BlobViewer::PDF,
BlobViewer::BinarySTL,
- BlobViewer::TextSTL,
+ BlobViewer::TextSTL
].freeze
BINARY_VIEWERS = RICH_VIEWERS.select(&:binary?).freeze
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 971ab7cb0ee..3c4a4d93349 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -124,8 +124,8 @@ module Ci
success? || failed? || canceled?
end
- def retried?
- !self.pipeline.statuses.latest.include?(self)
+ def latest?
+ !retried?
end
def expanded_environment_name
diff --git a/app/models/commit.rb b/app/models/commit.rb
index dea18bfedef..3a143a5a1f6 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -49,7 +49,7 @@ class Commit
def max_diff_options
{
max_files: DIFF_HARD_LIMIT_FILES,
- max_lines: DIFF_HARD_LIMIT_LINES,
+ max_lines: DIFF_HARD_LIMIT_LINES
}
end
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index 75d04fd2b08..ffafc678968 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -18,13 +18,7 @@ class CommitStatus < ActiveRecord::Base
validates :name, presence: true
alias_attribute :author, :user
-
- scope :latest, -> do
- max_id = unscope(:select).select("max(#{quoted_table_name}.id)")
-
- where(id: max_id.group(:name, :commit_id))
- end
-
+
scope :failed_but_allowed, -> do
where(allow_failure: true, status: [:failed, :canceled])
end
@@ -37,7 +31,8 @@ class CommitStatus < ActiveRecord::Base
false, all_state_names - [:failed, :canceled, :manual])
end
- scope :retried, -> { where.not(id: latest) }
+ scope :latest, -> { where(retried: [false, nil]) }
+ scope :retried, -> { where(retried: true) }
scope :ordered, -> { order(:name) }
scope :latest_ordered, -> { latest.ordered.includes(project: :namespace) }
scope :retried_ordered, -> { retried.ordered.includes(project: :namespace) }
diff --git a/app/models/diff_discussion.rb b/app/models/diff_discussion.rb
index d627fbe327f..14ddd2fcc88 100644
--- a/app/models/diff_discussion.rb
+++ b/app/models/diff_discussion.rb
@@ -39,7 +39,7 @@ class DiffDiscussion < Discussion
def reply_attributes
super.merge(
original_position: original_position.to_json,
- position: position.to_json,
+ position: position.to_json
)
end
end
diff --git a/app/models/environment.rb b/app/models/environment.rb
index bf33010fd21..61efc1b2d17 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -62,7 +62,7 @@ class Environment < ActiveRecord::Base
def predefined_variables
[
{ key: 'CI_ENVIRONMENT_NAME', value: name, public: true },
- { key: 'CI_ENVIRONMENT_SLUG', value: slug, public: true },
+ { key: 'CI_ENVIRONMENT_SLUG', value: slug, public: true }
]
end
diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb
index 595602e80fe..22a177ed367 100644
--- a/app/models/hooks/web_hook.rb
+++ b/app/models/hooks/web_hook.rb
@@ -31,7 +31,7 @@ class WebHook < ActiveRecord::Base
post_url = url.gsub("#{parsed_url.userinfo}@", '')
auth = {
username: CGI.unescape(parsed_url.user),
- password: CGI.unescape(parsed_url.password),
+ password: CGI.unescape(parsed_url.password)
}
response = WebHook.post(post_url,
body: data.to_json,
diff --git a/app/models/key.rb b/app/models/key.rb
index 9c74ca84753..b7956052c3f 100644
--- a/app/models/key.rb
+++ b/app/models/key.rb
@@ -74,7 +74,7 @@ class Key < ActiveRecord::Base
GitlabShellWorker.perform_async(
:remove_key,
shell_id,
- key,
+ key
)
end
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 397dc7a25ab..a7ede5e3b9e 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -56,7 +56,7 @@ class Namespace < ActiveRecord::Base
'COALESCE(SUM(ps.storage_size), 0) AS storage_size',
'COALESCE(SUM(ps.repository_size), 0) AS repository_size',
'COALESCE(SUM(ps.lfs_objects_size), 0) AS lfs_objects_size',
- 'COALESCE(SUM(ps.build_artifacts_size), 0) AS build_artifacts_size',
+ 'COALESCE(SUM(ps.build_artifacts_size), 0) AS build_artifacts_size'
)
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 1f550cc02e2..be4960aef8a 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -967,7 +967,7 @@ class Project < ActiveRecord::Base
namespace: namespace.name,
visibility_level: visibility_level,
path_with_namespace: path_with_namespace,
- default_branch: default_branch,
+ default_branch: default_branch
}
# Backward compatibility
diff --git a/app/models/project_services/bamboo_service.rb b/app/models/project_services/bamboo_service.rb
index 400020ee04a..3f5b3eb159b 100644
--- a/app/models/project_services/bamboo_service.rb
+++ b/app/models/project_services/bamboo_service.rb
@@ -52,7 +52,7 @@ class BambooService < CiService
placeholder: 'Bamboo build plan key like KEY' },
{ type: 'text', name: 'username',
placeholder: 'A user with API access, if applicable' },
- { type: 'password', name: 'password' },
+ { type: 'password', name: 'password' }
]
end
diff --git a/app/models/project_services/chat_notification_service.rb b/app/models/project_services/chat_notification_service.rb
index 6464bf3f4a4..779ef54cfcb 100644
--- a/app/models/project_services/chat_notification_service.rb
+++ b/app/models/project_services/chat_notification_service.rb
@@ -39,7 +39,7 @@ class ChatNotificationService < Service
{ type: 'text', name: 'webhook', placeholder: "e.g. #{webhook_placeholder}" },
{ type: 'text', name: 'username', placeholder: 'e.g. GitLab' },
{ type: 'checkbox', name: 'notify_only_broken_pipelines' },
- { type: 'checkbox', name: 'notify_only_default_branch' },
+ { type: 'checkbox', name: 'notify_only_default_branch' }
]
end
diff --git a/app/models/project_services/emails_on_push_service.rb b/app/models/project_services/emails_on_push_service.rb
index f4f913ee0b6..1a236e232f9 100644
--- a/app/models/project_services/emails_on_push_service.rb
+++ b/app/models/project_services/emails_on_push_service.rb
@@ -47,7 +47,7 @@ class EmailsOnPushService < Service
help: "Send notifications from the committer's email address if the domain is part of the domain GitLab is running on (e.g. #{domains})." },
{ type: 'checkbox', name: 'disable_diffs', title: "Disable code diffs",
help: "Don't include possibly sensitive code diffs in notification body." },
- { type: 'textarea', name: 'recipients', placeholder: 'Emails separated by whitespace' },
+ { type: 'textarea', name: 'recipients', placeholder: 'Emails separated by whitespace' }
]
end
end
diff --git a/app/models/project_services/external_wiki_service.rb b/app/models/project_services/external_wiki_service.rb
index bdf6fa6a586..b4d7c977ce4 100644
--- a/app/models/project_services/external_wiki_service.rb
+++ b/app/models/project_services/external_wiki_service.rb
@@ -19,7 +19,7 @@ class ExternalWikiService < Service
def fields
[
- { type: 'text', name: 'external_wiki_url', placeholder: 'The URL of the external Wiki' },
+ { type: 'text', name: 'external_wiki_url', placeholder: 'The URL of the external Wiki' }
]
end
diff --git a/app/models/project_services/flowdock_service.rb b/app/models/project_services/flowdock_service.rb
index 10a13c3fbdc..2a05d757eb4 100644
--- a/app/models/project_services/flowdock_service.rb
+++ b/app/models/project_services/flowdock_service.rb
@@ -37,7 +37,7 @@ class FlowdockService < Service
repo: project.repository.path_to_repo,
repo_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}",
commit_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/commit/%s",
- diff_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/compare/%s...%s",
+ diff_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/compare/%s...%s"
)
end
end
diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb
index 8b181221bb0..c19fed339ba 100644
--- a/app/models/project_services/hipchat_service.rb
+++ b/app/models/project_services/hipchat_service.rb
@@ -41,7 +41,7 @@ class HipchatService < Service
placeholder: 'Leave blank for default (v2)' },
{ type: 'text', name: 'server',
placeholder: 'Leave blank for default. https://hipchat.example.com' },
- { type: 'checkbox', name: 'notify_only_broken_pipelines' },
+ { type: 'checkbox', name: 'notify_only_broken_pipelines' }
]
end
diff --git a/app/models/project_services/irker_service.rb b/app/models/project_services/irker_service.rb
index c62bb4fa120..a51d43adcb9 100644
--- a/app/models/project_services/irker_service.rb
+++ b/app/models/project_services/irker_service.rb
@@ -58,7 +58,7 @@ class IrkerService < Service
' want to use a password, you have to omit the "#" on the channel). If you ' \
' specify a default IRC URI to prepend before each recipient, you can just ' \
' give a channel name.' },
- { type: 'checkbox', name: 'colorize_messages' },
+ { type: 'checkbox', name: 'colorize_messages' }
]
end
diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb
index 97e997d3899..f388773efee 100644
--- a/app/models/project_services/jira_service.rb
+++ b/app/models/project_services/jira_service.rb
@@ -149,7 +149,7 @@ class JiraService < IssueTrackerService
data = {
user: {
name: author.name,
- url: resource_url(user_path(author)),
+ url: resource_url(user_path(author))
},
project: {
name: self.project.path_with_namespace,
diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb
index 9c56518c991..b2494a0be6e 100644
--- a/app/models/project_services/kubernetes_service.rb
+++ b/app/models/project_services/kubernetes_service.rb
@@ -73,7 +73,7 @@ class KubernetesService < DeploymentService
{ type: 'textarea',
name: 'ca_pem',
title: 'Custom CA bundle',
- placeholder: 'Certificate Authority bundle (PEM format)' },
+ placeholder: 'Certificate Authority bundle (PEM format)' }
]
end
diff --git a/app/models/project_services/microsoft_teams_service.rb b/app/models/project_services/microsoft_teams_service.rb
index 9b218fd81b4..2facff53e26 100644
--- a/app/models/project_services/microsoft_teams_service.rb
+++ b/app/models/project_services/microsoft_teams_service.rb
@@ -35,7 +35,7 @@ class MicrosoftTeamsService < ChatNotificationService
[
{ type: 'text', name: 'webhook', placeholder: "e.g. #{webhook_placeholder}" },
{ type: 'checkbox', name: 'notify_only_broken_pipelines' },
- { type: 'checkbox', name: 'notify_only_default_branch' },
+ { type: 'checkbox', name: 'notify_only_default_branch' }
]
end
diff --git a/app/models/project_services/mock_ci_service.rb b/app/models/project_services/mock_ci_service.rb
index a8d581a1f67..546b6e0a498 100644
--- a/app/models/project_services/mock_ci_service.rb
+++ b/app/models/project_services/mock_ci_service.rb
@@ -21,7 +21,7 @@ class MockCiService < CiService
[
{ type: 'text',
name: 'mock_service_url',
- placeholder: 'http://localhost:4004' },
+ placeholder: 'http://localhost:4004' }
]
end
diff --git a/app/models/project_services/pipelines_email_service.rb b/app/models/project_services/pipelines_email_service.rb
index ac617f409d9..f824171ad09 100644
--- a/app/models/project_services/pipelines_email_service.rb
+++ b/app/models/project_services/pipelines_email_service.rb
@@ -55,7 +55,7 @@ class PipelinesEmailService < Service
name: 'recipients',
placeholder: 'Emails separated by comma' },
{ type: 'checkbox',
- name: 'notify_only_broken_pipelines' },
+ name: 'notify_only_broken_pipelines' }
]
end
diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb
index 3e618a8dbf1..fc29a5277bb 100644
--- a/app/models/project_services/pushover_service.rb
+++ b/app/models/project_services/pushover_service.rb
@@ -55,7 +55,7 @@ class PushoverService < Service
['Pushover Echo (long)', 'echo'],
['Up Down (long)', 'updown'],
['None (silent)', 'none']
- ] },
+ ] }
]
end
diff --git a/app/models/project_services/teamcity_service.rb b/app/models/project_services/teamcity_service.rb
index cbaffb8ce48..b16beb406b9 100644
--- a/app/models/project_services/teamcity_service.rb
+++ b/app/models/project_services/teamcity_service.rb
@@ -55,7 +55,7 @@ class TeamcityService < CiService
placeholder: 'Build configuration ID' },
{ type: 'text', name: 'username',
placeholder: 'A user with permissions to trigger a manual build' },
- { type: 'password', name: 'password' },
+ { type: 'password', name: 'password' }
]
end
@@ -78,7 +78,7 @@ class TeamcityService < CiService
auth = {
username: username,
- password: password,
+ password: password
}
branch = Gitlab::Git.ref_name(data[:ref])
diff --git a/app/models/readme_blob.rb b/app/models/readme_blob.rb
new file mode 100644
index 00000000000..1863a08f1de
--- /dev/null
+++ b/app/models/readme_blob.rb
@@ -0,0 +1,13 @@
+class ReadmeBlob < SimpleDelegator
+ attr_reader :repository
+
+ def initialize(blob, repository)
+ @repository = repository
+
+ super(blob)
+ end
+
+ def rendered_markup
+ repository.rendered_readme
+ end
+end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 0c797dd5814..9d9d94c4486 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -518,7 +518,7 @@ class Repository
def readme
if head = tree(:head)
- head.readme
+ ReadmeBlob.new(head.readme, self)
end
end
@@ -833,7 +833,7 @@ class Repository
actual_options = options.merge(
parents: [our_commit, their_commit],
- tree: merge_index.write_tree(rugged),
+ tree: merge_index.write_tree(rugged)
)
commit_id = create_commit(actual_options)
diff --git a/app/models/sent_notification.rb b/app/models/sent_notification.rb
index bfaf0eb2fae..0ae5864615a 100644
--- a/app/models/sent_notification.rb
+++ b/app/models/sent_notification.rb
@@ -39,7 +39,7 @@ class SentNotification < ActiveRecord::Base
noteable_type: noteable.class.name,
noteable_id: noteable_id,
- commit_id: commit_id,
+ commit_id: commit_id
)
create(attrs)
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index abfbefdf9a0..882e2fa0594 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -152,18 +152,5 @@ class Snippet < ActiveRecord::Base
where(table[:content].matches(pattern))
end
-
- def accessible_to(user)
- return are_public unless user.present?
- return all if user.admin?
-
- where(
- 'visibility_level IN (:visibility_levels)
- OR author_id = :author_id
- OR project_id IN (:project_ids)',
- visibility_levels: [Snippet::PUBLIC, Snippet::INTERNAL],
- author_id: user.id,
- project_ids: user.authorized_projects.select(:id))
- end
end
end
diff --git a/app/models/tree.rb b/app/models/tree.rb
index fe148b0ec65..c89b8eca9be 100644
--- a/app/models/tree.rb
+++ b/app/models/tree.rb
@@ -40,10 +40,7 @@ class Tree
readme_path = path == '/' ? readme_tree.name : File.join(path, readme_tree.name)
- git_repo = repository.raw_repository
- @readme = Gitlab::Git::Blob.find(git_repo, sha, readme_path)
- @readme.load_all_data!(git_repo)
- @readme
+ @readme = repository.blob_at(sha, readme_path)
end
def trees
diff --git a/app/policies/project_snippet_policy.rb b/app/policies/project_snippet_policy.rb
index 3a96836917e..cf8ff92617f 100644
--- a/app/policies/project_snippet_policy.rb
+++ b/app/policies/project_snippet_policy.rb
@@ -13,7 +13,7 @@ class ProjectSnippetPolicy < BasePolicy
can! :read_project_snippet
end
- if @subject.private? && @subject.project.team.member?(@user)
+ if @subject.project.team.member?(@user)
can! :read_project_snippet
end
end
diff --git a/app/services/akismet_service.rb b/app/services/akismet_service.rb
index 76b9f1feda7..8e11a2a36a7 100644
--- a/app/services/akismet_service.rb
+++ b/app/services/akismet_service.rb
@@ -16,7 +16,7 @@ class AkismetService
created_at: DateTime.now,
author: owner.name,
author_email: owner.email,
- referrer: options[:referrer],
+ referrer: options[:referrer]
}
begin
diff --git a/app/services/audit_event_service.rb b/app/services/audit_event_service.rb
index 8a000585e89..5ad9a50687c 100644
--- a/app/services/audit_event_service.rb
+++ b/app/services/audit_event_service.rb
@@ -8,7 +8,7 @@ class AuditEventService
with: @details[:with],
target_id: @author.id,
target_type: 'User',
- target_details: @author.name,
+ target_details: @author.name
}
self
diff --git a/app/services/boards/issues/move_service.rb b/app/services/boards/issues/move_service.rb
index e73b1a4361a..ecabb2a48e4 100644
--- a/app/services/boards/issues/move_service.rb
+++ b/app/services/boards/issues/move_service.rb
@@ -38,7 +38,7 @@ module Boards
attrs.merge!(
add_label_ids: add_label_ids,
remove_label_ids: remove_label_ids,
- state_event: issue_state,
+ state_event: issue_state
)
end
diff --git a/app/services/ci/process_pipeline_service.rb b/app/services/ci/process_pipeline_service.rb
index 25ba54ffa0d..55af193d717 100644
--- a/app/services/ci/process_pipeline_service.rb
+++ b/app/services/ci/process_pipeline_service.rb
@@ -5,6 +5,8 @@ module Ci
def execute(pipeline)
@pipeline = pipeline
+ update_retried
+
new_builds =
stage_indexes_of_created_builds.map do |index|
process_stage(index)
@@ -71,5 +73,23 @@ module Ci
def created_builds
pipeline.builds.created
end
+
+ # This method is for compatibility and data consistency and should be removed with 9.3 version of GitLab
+ # This replicates what is db/post_migrate/20170416103934_upate_retried_for_ci_build.rb
+ # and ensures that functionality will not be broken before migration is run
+ # this updates only when there are data that needs to be updated, there are two groups with no retried flag
+ def update_retried
+ # find the latest builds for each name
+ latest_statuses = pipeline.statuses.latest
+ .group(:name)
+ .having('count(*) > 1')
+ .pluck('max(id)', 'name')
+
+ # mark builds that are retried
+ pipeline.statuses.latest
+ .where(name: latest_statuses.map(&:second))
+ .where.not(id: latest_statuses.map(&:first))
+ .update_all(retried: true) if latest_statuses.any?
+ end
end
end
diff --git a/app/services/ci/retry_build_service.rb b/app/services/ci/retry_build_service.rb
index 89da05b72bb..f51e9fd1d54 100644
--- a/app/services/ci/retry_build_service.rb
+++ b/app/services/ci/retry_build_service.rb
@@ -6,7 +6,7 @@ module Ci
description tag_list].freeze
def execute(build)
- reprocess(build).tap do |new_build|
+ reprocess!(build).tap do |new_build|
build.pipeline.mark_as_processable_after_stage(build.stage_idx)
new_build.enqueue!
@@ -17,7 +17,7 @@ module Ci
end
end
- def reprocess(build)
+ def reprocess!(build)
unless can?(current_user, :update_build, build)
raise Gitlab::Access::AccessDeniedError
end
@@ -28,7 +28,14 @@ module Ci
attributes.push([:user, current_user])
- project.builds.create(Hash[attributes])
+ Ci::Build.transaction do
+ # mark all other builds of that name as retried
+ build.pipeline.builds.latest
+ .where(name: build.name)
+ .update_all(retried: true)
+
+ project.builds.create!(Hash[attributes])
+ end
end
end
end
diff --git a/app/services/ci/retry_pipeline_service.rb b/app/services/ci/retry_pipeline_service.rb
index 5b207157345..c5a43869990 100644
--- a/app/services/ci/retry_pipeline_service.rb
+++ b/app/services/ci/retry_pipeline_service.rb
@@ -11,7 +11,7 @@ module Ci
next unless can?(current_user, :update_build, build)
Ci::RetryBuildService.new(project, current_user)
- .reprocess(build)
+ .reprocess!(build)
end
pipeline.builds.latest.skipped.find_each do |skipped|
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index c65c66d7150..646ccbdb2bf 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -298,7 +298,7 @@ class NotificationService
recipients ||= NotificationRecipientService.new(pipeline.project).build_pipeline_recipients(
pipeline,
pipeline.user,
- action: pipeline.status,
+ action: pipeline.status
).map(&:notification_email)
if recipients.any?
diff --git a/app/services/projects/update_pages_configuration_service.rb b/app/services/projects/update_pages_configuration_service.rb
index eb4809afa85..cacb74b1205 100644
--- a/app/services/projects/update_pages_configuration_service.rb
+++ b/app/services/projects/update_pages_configuration_service.rb
@@ -27,7 +27,7 @@ module Projects
{
domain: domain.domain,
certificate: domain.certificate,
- key: domain.key,
+ key: domain.key
}
end
end
diff --git a/app/services/search/snippet_service.rb b/app/services/search/snippet_service.rb
index 4f161beea4d..85da0be6fff 100644
--- a/app/services/search/snippet_service.rb
+++ b/app/services/search/snippet_service.rb
@@ -7,7 +7,7 @@ module Search
end
def execute
- snippets = Snippet.accessible_to(current_user)
+ snippets = SnippetsFinder.new(current_user).execute
Gitlab::SnippetSearchResults.new(snippets, params[:search])
end
diff --git a/app/services/system_hooks_service.rb b/app/services/system_hooks_service.rb
index af0ddbe5934..ed476fc9d0c 100644
--- a/app/services/system_hooks_service.rb
+++ b/app/services/system_hooks_service.rb
@@ -51,7 +51,7 @@ class SystemHooksService
path: model.path,
group_id: model.id,
owner_name: owner.respond_to?(:name) ? owner.name : nil,
- owner_email: owner.respond_to?(:email) ? owner.email : nil,
+ owner_email: owner.respond_to?(:email) ? owner.email : nil
)
when GroupMember
data.merge!(group_member_data(model))
@@ -113,7 +113,7 @@ class SystemHooksService
user_name: model.user.name,
user_email: model.user.email,
user_id: model.user.id,
- group_access: model.human_access,
+ group_access: model.human_access
}
end
end
diff --git a/app/views/discussions/_diff_with_notes.html.haml b/app/views/discussions/_diff_with_notes.html.haml
index 78c5b0c1dda..c3f55ff821f 100644
--- a/app/views/discussions/_diff_with_notes.html.haml
+++ b/app/views/discussions/_diff_with_notes.html.haml
@@ -3,7 +3,7 @@
.diff-file.file-holder
.js-file-title.file-title
- = render "projects/diffs/file_header", diff_file: diff_file, blob: blob, diff_commit: diff_file.content_commit, project: discussion.project, url: discussion_path(discussion)
+ = render "projects/diffs/file_header", diff_file: diff_file, blob: blob, diff_commit: diff_file.content_commit, project: discussion.project, url: discussion_path(discussion), show_toggle: false
.diff-content.code.js-syntax-highlight
%table
diff --git a/app/views/import/base/create.js.haml b/app/views/import/base/create.js.haml
index 8e929538351..57e8c3ca1e1 100644
--- a/app/views/import/base/create.js.haml
+++ b/app/views/import/base/create.js.haml
@@ -10,4 +10,4 @@
- else
:plain
job = $("tr#repo_#{@repo_id}")
- job.find(".import-actions").html("<i class='fa fa-exclamation-circle'></i> Error saving project: #{escape_javascript(@project.errors.full_messages.join(','))}")
+ job.find(".import-actions").html("<i class='fa fa-exclamation-circle'></i> Error saving project: #{escape_javascript(h(@project.errors.full_messages.join(',')))}")
diff --git a/app/views/projects/_readme.html.haml b/app/views/projects/_readme.html.haml
index c0d12cbc66e..cf09d9db6b7 100644
--- a/app/views/projects/_readme.html.haml
+++ b/app/views/projects/_readme.html.haml
@@ -2,9 +2,9 @@
%article.readme-holder
.pull-right
- if can?(current_user, :push_code, @project)
- = link_to icon('pencil'), namespace_project_edit_blob_path(@project.namespace, @project, tree_join(@repository.root_ref, readme.name)), class: 'light edit-project-readme'
- .file-content.wiki
- = markup(readme.name, readme.data, rendered: @repository.rendered_readme)
+ = link_to icon('pencil'), namespace_project_edit_blob_path(@project.namespace, @project, tree_join(@repository.root_ref, readme.path)), class: 'light edit-project-readme'
+
+ = render 'projects/blob/viewer', viewer: readme.rich_viewer, viewer_url: namespace_project_blob_path(@project.namespace, @project, tree_join(@repository.root_ref, readme.path), viewer: :rich, format: :json)
- else
.row-content-block.second-block.center
%h3.page-title
diff --git a/app/views/projects/_zen.html.haml b/app/views/projects/_zen.html.haml
index 0c8241053e7..3b3d08ddd3c 100644
--- a/app/views/projects/_zen.html.haml
+++ b/app/views/projects/_zen.html.haml
@@ -1,10 +1,11 @@
- @gfm_form = true
+- current_text ||= nil
- supports_slash_commands = local_assigns.fetch(:supports_slash_commands, false)
.zen-backdrop
- classes << ' js-gfm-input js-autosize markdown-area'
- if defined?(f) && f
= f.text_area attr, class: classes, placeholder: placeholder, data: { supports_slash_commands: supports_slash_commands }
- else
- = text_area_tag attr, nil, class: classes, placeholder: placeholder
+ = text_area_tag attr, current_text, class: classes, placeholder: placeholder
%a.zen-control.zen-control-leave.js-zen-leave{ href: "#" }
= icon('compress')
diff --git a/app/views/projects/blob/_viewer.html.haml b/app/views/projects/blob/_viewer.html.haml
index 5326bb3e0cf..41187d5ce66 100644
--- a/app/views/projects/blob/_viewer.html.haml
+++ b/app/views/projects/blob/_viewer.html.haml
@@ -2,8 +2,8 @@
- render_error = viewer.render_error
- load_asynchronously = local_assigns.fetch(:load_asynchronously, viewer.server_side?) && render_error.nil?
-- url = url_for(params.merge(viewer: viewer.type, format: :json)) if load_asynchronously
-.blob-viewer{ data: { type: viewer.type, url: url }, class: ('hidden' if hidden) }
+- viewer_url = local_assigns.fetch(:viewer_url) { url_for(params.merge(viewer: viewer.type, format: :json)) } if load_asynchronously
+.blob-viewer{ data: { type: viewer.type, url: viewer_url }, class: ('hidden' if hidden) }
- if load_asynchronously
.text-center.prepend-top-default.append-bottom-default
= icon('spinner spin 2x', 'aria-hidden' => 'true', 'aria-label' => 'Loading content')
diff --git a/app/views/projects/boards/components/sidebar/_milestone.html.haml b/app/views/projects/boards/components/sidebar/_milestone.html.haml
index 190e7290303..4e46351bf8a 100644
--- a/app/views/projects/boards/components/sidebar/_milestone.html.haml
+++ b/app/views/projects/boards/components/sidebar/_milestone.html.haml
@@ -16,7 +16,8 @@
name: "issue[milestone_id]",
"v-if" => "issue.milestone" }
.dropdown
- %button.dropdown-menu-toggle.js-milestone-select.js-issue-board-sidebar{ type: "button", data: { toggle: "dropdown", show_no: "true", field_name: "issue[milestone_id]", project_id: @project.id, milestones: namespace_project_milestones_path(@project.namespace, @project, :json), ability_name: "issue", use_id: "true" },
+ %button.dropdown-menu-toggle.js-milestone-select.js-issue-board-sidebar{ type: "button", data: { toggle: "dropdown", show_no: "true", field_name: "issue[milestone_id]", project_id: @project.id, milestones: namespace_project_milestones_path(@project.namespace, @project, :json), ability_name: "issue", use_id: "true", default_no: "true" },
+ ":data-selected" => "milestoneTitle",
":data-issuable-id" => "issue.id",
":data-issue-update" => "'#{namespace_project_issues_path(@project.namespace, @project)}/' + issue.id + '.json'" }
Milestone
diff --git a/app/views/projects/cycle_analytics/show.html.haml b/app/views/projects/cycle_analytics/show.html.haml
index b158a81471c..74255167352 100644
--- a/app/views/projects/cycle_analytics/show.html.haml
+++ b/app/views/projects/cycle_analytics/show.html.haml
@@ -51,7 +51,7 @@
%ul
%li.stage-header
%span.stage-name
- {{ __('ProjectLifecycle|Stage') }}
+ {{ s__('ProjectLifecycle|Stage') }}
%i.has-tooltip.fa.fa-question-circle{ "data-placement" => "top", title: _("The phase of the development lifecycle."), "aria-hidden" => "true" }
%li.median-header
%span.stage-name
diff --git a/app/views/projects/diffs/_file_header.html.haml b/app/views/projects/diffs/_file_header.html.haml
index 7d6b3701f95..4e4fdb73ae3 100644
--- a/app/views/projects/diffs/_file_header.html.haml
+++ b/app/views/projects/diffs/_file_header.html.haml
@@ -1,4 +1,8 @@
-%i.fa.diff-toggle-caret.fa-fw
+- show_toggle = local_assigns.fetch(:show_toggle, true)
+
+- if show_toggle
+ %i.fa.diff-toggle-caret.fa-fw
+
- if defined?(blob) && blob && diff_file.submodule?
%span
= icon('archive fw')
diff --git a/app/views/projects/imports/new.html.haml b/app/views/projects/imports/new.html.haml
index 2cd8d03e30e..25a87411cac 100644
--- a/app/views/projects/imports/new.html.haml
+++ b/app/views/projects/imports/new.html.haml
@@ -10,7 +10,7 @@
.panel-body
%pre
:preserve
- #{sanitize_repo_path(@project, @project.import_error)}
+ #{h(sanitize_repo_path(@project, @project.import_error))}
= form_for @project, url: namespace_project_import_path(@project.namespace, @project), method: :post, html: { class: 'form-horizontal' } do |f|
= render "shared/import_form", f: f
diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml
index 7c607d2956b..cbf841762b7 100644
--- a/app/views/projects/tags/new.html.haml
+++ b/app/views/projects/tags/new.html.haml
@@ -22,14 +22,14 @@
.form-group
= label_tag :message, nil, class: 'control-label'
.col-sm-10
- = text_area_tag :message, nil, required: false, tabindex: 3, class: 'form-control', rows: 5
+ = text_area_tag :message, @message, required: false, tabindex: 3, class: 'form-control', rows: 5
.help-block Optionally, add a message to the tag.
%hr
.form-group
= label_tag :release_description, 'Release notes', class: 'control-label'
.col-sm-10
= render layout: 'projects/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do
- = render 'projects/zen', attr: :release_description, classes: 'note-textarea', placeholder: "Write your release notes or drag files here..."
+ = render 'projects/zen', attr: :release_description, classes: 'note-textarea', placeholder: "Write your release notes or drag files here...", current_text: @release_description
= render 'shared/notes/hints'
.help-block Optionally, add release notes to the tag. They will be stored in the GitLab database and displayed on the tags page.
.form-actions
diff --git a/app/views/projects/tree/_readme.html.haml b/app/views/projects/tree/_readme.html.haml
index 01599060844..2c2f64283f5 100644
--- a/app/views/projects/tree/_readme.html.haml
+++ b/app/views/projects/tree/_readme.html.haml
@@ -1,8 +1,8 @@
%article.file-holder.readme-holder
.js-file-title.file-title
= blob_icon readme.mode, readme.name
- = link_to namespace_project_blob_path(@project.namespace, @project, tree_join(@ref, @path, readme.name)) do
+ = link_to namespace_project_blob_path(@project.namespace, @project, tree_join(@ref, readme.path)) do
%strong
= readme.name
- .file-content.wiki
- = markup(readme.name, readme.data)
+
+ = render 'projects/blob/viewer', viewer: readme.rich_viewer, viewer_url: namespace_project_blob_path(@project.namespace, @project, tree_join(@ref, readme.path), viewer: :rich, format: :json)
diff --git a/app/views/projects/wikis/git_access.html.haml b/app/views/projects/wikis/git_access.html.haml
index fb0efd85dcd..68862206248 100644
--- a/app/views/projects/wikis/git_access.html.haml
+++ b/app/views/projects/wikis/git_access.html.haml
@@ -28,7 +28,7 @@
%h3 Clone your wiki
%pre.dark
:preserve
- git clone #{ content_tag(:span, default_url_to_repo(@project_wiki), class: 'clone')}
+ git clone #{ content_tag(:span, h(default_url_to_repo(@project_wiki)), class: 'clone')}
cd #{h @project_wiki.path}
%h3 Start Gollum and edit locally
diff --git a/app/views/shared/empty_states/_issues.html.haml b/app/views/shared/empty_states/_issues.html.haml
index c229d18903f..12d99c3ab4b 100644
--- a/app/views/shared/empty_states/_issues.html.haml
+++ b/app/views/shared/empty_states/_issues.html.haml
@@ -3,10 +3,10 @@
- has_button = button_path || project_select_button
.row.empty-state
- .pull-right.col-xs-12{ class: "#{'col-sm-6' if has_button}" }
+ .col-xs-12
.svg-content
= render 'shared/empty_states/icons/issues.svg'
- .col-xs-12{ class: "#{'col-sm-6' if has_button}" }
+ .col-xs-12.text-center
.text-content
- if has_button && current_user
%h4
diff --git a/app/views/shared/empty_states/_labels.html.haml b/app/views/shared/empty_states/_labels.html.haml
index 00fb77bdb3b..5e2f4cf109d 100644
--- a/app/views/shared/empty_states/_labels.html.haml
+++ b/app/views/shared/empty_states/_labels.html.haml
@@ -1,8 +1,8 @@
.row.empty-state.labels
- .pull-right.col-xs-12.col-sm-6
+ .col-xs-12
.svg-content
= render 'shared/empty_states/icons/labels.svg'
- .col-xs-12.col-sm-6
+ .col-xs-12.text-center
.text-content
%h4 Labels can be applied to issues and merge requests to categorize them.
%p You can also star a label to make it a priority label.
diff --git a/app/views/shared/empty_states/_merge_requests.html.haml b/app/views/shared/empty_states/_merge_requests.html.haml
index 7f2f99f3406..3e64f403b8b 100644
--- a/app/views/shared/empty_states/_merge_requests.html.haml
+++ b/app/views/shared/empty_states/_merge_requests.html.haml
@@ -3,10 +3,10 @@
- has_button = button_path || project_select_button
.row.empty-state.merge-requests
- .col-xs-12{ class: "#{'col-sm-6 pull-right' if has_button}" }
+ .col-xs-12
.svg-content
= render 'shared/empty_states/icons/merge_requests.svg'
- .col-xs-12{ class: "#{'col-sm-6' if has_button}" }
+ .col-xs-12.text-center
.text-content
- if has_button
%h4
diff --git a/app/views/shared/issuable/_milestone_dropdown.html.haml b/app/views/shared/issuable/_milestone_dropdown.html.haml
index f0d50828e2a..6750921338a 100644
--- a/app/views/shared/issuable/_milestone_dropdown.html.haml
+++ b/app/views/shared/issuable/_milestone_dropdown.html.haml
@@ -6,7 +6,7 @@
- if selected.present? || params[:milestone_title].present?
= hidden_field_tag(name, name == :milestone_title ? selected_text : selected.id)
= dropdown_tag(milestone_dropdown_label(selected_text), options: { title: dropdown_title, toggle_class: "js-milestone-select js-filter-submit #{extra_class}", filter: true, dropdown_class: "dropdown-menu-selectable dropdown-menu-milestone",
- placeholder: "Search milestones", footer_content: project.present?, data: { show_no: true, show_menu_above: show_menu_above, show_any: show_any, show_upcoming: show_upcoming, show_started: show_started, field_name: name, selected: selected.try(:title), project_id: project.try(:id), milestones: milestones_filter_dropdown_path, default_label: "Milestone" } }) do
+ placeholder: "Search milestones", footer_content: project.present?, data: { show_no: true, show_menu_above: show_menu_above, show_any: show_any, show_upcoming: show_upcoming, show_started: show_started, field_name: name, selected: selected_text, project_id: project.try(:id), milestones: milestones_filter_dropdown_path, default_label: "Milestone" } }) do
- if project
%ul.dropdown-footer-list
- if can? current_user, :admin_milestone, project
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index 3a66880e177..305d1c36a73 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -43,7 +43,7 @@
.selectbox.hide-collapsed
= f.hidden_field 'milestone_id', value: issuable.milestone_id, id: nil
- = dropdown_tag('Milestone', options: { title: 'Assign milestone', toggle_class: 'js-milestone-select js-extra-options', filter: true, dropdown_class: 'dropdown-menu-selectable', placeholder: 'Search milestones', data: { show_no: true, field_name: "#{issuable.to_ability_name}[milestone_id]", project_id: @project.id, issuable_id: issuable.id, milestones: namespace_project_milestones_path(@project.namespace, @project, :json), ability_name: issuable.to_ability_name, issue_update: issuable_json_path(issuable), use_id: true }})
+ = dropdown_tag('Milestone', options: { title: 'Assign milestone', toggle_class: 'js-milestone-select js-extra-options', filter: true, dropdown_class: 'dropdown-menu-selectable', placeholder: 'Search milestones', data: { show_no: true, field_name: "#{issuable.to_ability_name}[milestone_id]", project_id: @project.id, issuable_id: issuable.id, milestones: namespace_project_milestones_path(@project.namespace, @project, :json), ability_name: issuable.to_ability_name, issue_update: issuable_json_path(issuable), use_id: true, default_no: true, selected: (issuable.milestone.name if issuable.milestone), null_default: true }})
- if issuable.has_attribute?(:time_estimate)
#issuable-time-tracker.block
// Fallback while content is loading
diff --git a/app/views/shared/notes/_note.html.haml b/app/views/shared/notes/_note.html.haml
index 5c1156b06fb..87aae793966 100644
--- a/app/views/shared/notes/_note.html.haml
+++ b/app/views/shared/notes/_note.html.haml
@@ -29,6 +29,8 @@
- if note.system
%span.system-note-message
= note.redacted_note_html
+ .original-note-content.hidden
+ = note.note
%a{ href: "##{dom_id(note)}" }
= time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago')
- unless note.system?
diff --git a/app/views/shared/notifications/_custom_notifications.html.haml b/app/views/shared/notifications/_custom_notifications.html.haml
index 708adbc38f1..183ed34fba1 100644
--- a/app/views/shared/notifications/_custom_notifications.html.haml
+++ b/app/views/shared/notifications/_custom_notifications.html.haml
@@ -1,9 +1,9 @@
-.modal.fade{ tabindex: "-1", role: "dialog", id: notifications_menu_identifier("modal", notification_setting), aria: { labelledby: "custom-notifications-title" } }
+.modal.fade{ tabindex: "-1", role: "dialog", id: notifications_menu_identifier("modal", notification_setting), "aria-labelledby": "custom-notifications-title" }
.modal-dialog
.modal-content
.modal-header
- %button.close{ type: "button", data: { dismiss: "modal" }, aria: { label: "close" } }
- %span{ aria: { hidden: "true" } } ×
+ %button.close{ type: "button", "aria-label": "close", data: { dismiss: "modal" } }
+ %span{ "aria-hidden": "true" } } ×
%h4#custom-notifications-title.modal-title
Custom notification events
diff --git a/app/workers/namespaceless_project_destroy_worker.rb b/app/workers/namespaceless_project_destroy_worker.rb
new file mode 100644
index 00000000000..bfae0c77700
--- /dev/null
+++ b/app/workers/namespaceless_project_destroy_worker.rb
@@ -0,0 +1,43 @@
+# Worker to destroy projects that do not have a namespace
+#
+# It destroys everything it can without having the info about the namespace it
+# used to belong to. Projects in this state should be rare.
+# The worker will reject doing anything for projects that *do* have a
+# namespace. For those use ProjectDestroyWorker instead.
+class NamespacelessProjectDestroyWorker
+ include Sidekiq::Worker
+ include DedicatedSidekiqQueue
+
+ def self.bulk_perform_async(args_list)
+ Sidekiq::Client.push_bulk('class' => self, 'queue' => sidekiq_options['queue'], 'args' => args_list)
+ end
+
+ def perform(project_id)
+ begin
+ project = Project.unscoped.find(project_id)
+ rescue ActiveRecord::RecordNotFound
+ return
+ end
+ return unless project.namespace_id.nil? # Reject doing anything for projects that *do* have a namespace
+
+ project.team.truncate
+
+ unlink_fork(project) if project.forked?
+
+ # Override Project#remove_pages for this instance so it doesn't do anything
+ def project.remove_pages
+ end
+
+ project.destroy!
+ end
+
+ private
+
+ def unlink_fork(project)
+ merge_requests = project.forked_from_project.merge_requests.opened.from_project(project)
+
+ merge_requests.update_all(state: 'closed')
+
+ project.forked_project_link.destroy
+ end
+end
diff --git a/app/workers/repository_check/clear_worker.rb b/app/workers/repository_check/clear_worker.rb
index 1f1b38540ee..85bc9103538 100644
--- a/app/workers/repository_check/clear_worker.rb
+++ b/app/workers/repository_check/clear_worker.rb
@@ -8,7 +8,7 @@ module RepositoryCheck
Project.select(:id).find_in_batches(batch_size: 100) do |batch|
Project.where(id: batch.map(&:id)).update_all(
last_repository_check_failed: nil,
- last_repository_check_at: nil,
+ last_repository_check_at: nil
)
end
end
diff --git a/app/workers/repository_check/single_repository_worker.rb b/app/workers/repository_check/single_repository_worker.rb
index 3d8bfc6fc6c..164586cf0b7 100644
--- a/app/workers/repository_check/single_repository_worker.rb
+++ b/app/workers/repository_check/single_repository_worker.rb
@@ -7,7 +7,7 @@ module RepositoryCheck
project = Project.find(project_id)
project.update_columns(
last_repository_check_failed: !check(project),
- last_repository_check_at: Time.now,
+ last_repository_check_at: Time.now
)
end