Commit 08f4e0a2 authored by Stan Hu's avatar Stan Hu

Merge branch 'master' into sh-support-bitbucket-server-import

parents d5ac4ea3 255db3d5
......@@ -327,7 +327,7 @@ cloud-native-image:
cache: {}
script:
- gem install gitlab --no-ri --no-rdoc
- ./trigger-build cng
- ./scripts/trigger-build cng
only:
- tags@gitlab-org/gitlab-ce
- tags@gitlab-org/gitlab-ee
......
......@@ -199,12 +199,6 @@ Naming/HeredocDelimiterCase:
Naming/HeredocDelimiterNaming:
Enabled: false
# Offense count: 27
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect.
Performance/HashEachMethods:
Enabled: false
# Offense count: 1
Performance/UnfreezeString:
Exclude:
......
......@@ -104,7 +104,7 @@ gem 'hashie-forbidden_attributes'
gem 'kaminari', '~> 1.0'
# HAML
gem 'hamlit', '~> 2.6.1'
gem 'hamlit', '~> 2.8.8'
# Files attachments
gem 'carrierwave', '~> 1.2'
......@@ -351,9 +351,9 @@ group :development, :test do
gem 'spring', '~> 2.0.0'
gem 'spring-commands-rspec', '~> 1.0.4'
gem 'gitlab-styles', '~> 2.3', require: false
gem 'gitlab-styles', '~> 2.4', require: false
# Pin these dependencies, otherwise a new rule could break the CI pipelines
gem 'rubocop', '~> 0.52.1'
gem 'rubocop', '~> 0.54.0'
gem 'rubocop-rspec', '~> 1.22.1'
gem 'scss_lint', '~> 0.56.0', require: false
......
......@@ -312,8 +312,8 @@ GEM
mime-types (>= 1.16)
posix-spawn (~> 0.3)
gitlab-markup (1.6.4)
gitlab-styles (2.3.2)
rubocop (~> 0.51)
gitlab-styles (2.4.1)
rubocop (~> 0.54.0)
rubocop-gitlab-security (~> 0.1.0)
rubocop-rspec (~> 1.19)
gitlab_omniauth-ldap (2.0.4)
......@@ -381,8 +381,8 @@ GEM
rake (>= 10, < 13)
rubocop (>= 0.49.0)
sysexits (~> 1.1)
hamlit (2.6.1)
temple (~> 0.7.6)
hamlit (2.8.8)
temple (>= 0.8.0)
thor
tilt
hashdiff (0.3.4)
......@@ -776,16 +776,16 @@ GEM
pg
rails
sqlite3
rubocop (0.52.1)
rubocop (0.54.0)
parallel (~> 1.10)
parser (>= 2.4.0.2, < 3.0)
parser (>= 2.5)
powerpack (~> 0.1)
rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
rubocop-gitlab-security (0.1.1)
rubocop (>= 0.51)
rubocop-rspec (1.22.1)
rubocop-rspec (1.22.2)
rubocop (>= 0.52.1)
ruby-enum (0.7.2)
i18n
......@@ -889,7 +889,7 @@ GEM
sys-filesystem (1.1.6)
ffi
sysexits (1.2.0)
temple (0.7.7)
temple (0.8.0)
test-prof (0.2.5)
test_after_commit (1.1.0)
activerecord (>= 3.2)
......@@ -900,7 +900,7 @@ GEM
rack (>= 1, < 3)
thor (0.19.4)
thread_safe (0.3.6)
tilt (2.0.6)
tilt (2.0.8)
timecop (0.8.1)
timfel-krb5-auth (0.8.3)
toml (0.1.2)
......@@ -1043,7 +1043,7 @@ DEPENDENCIES
gitlab-gollum-lib (~> 4.2)
gitlab-gollum-rugged_adapter (~> 0.4.4)
gitlab-markup (~> 1.6.4)
gitlab-styles (~> 2.3)
gitlab-styles (~> 2.4)
gitlab_omniauth-ldap (~> 2.0.4)
gon (~> 6.2)
google-api-client (~> 0.19.8)
......@@ -1057,7 +1057,7 @@ DEPENDENCIES
graphql (~> 1.8.0)
grpc (~> 1.11.0)
haml_lint (~> 0.26.0)
hamlit (~> 2.6.1)
hamlit (~> 2.8.8)
hashie-forbidden_attributes
health_check (~> 2.6.0)
hipchat (~> 1.5.0)
......@@ -1143,7 +1143,7 @@ DEPENDENCIES
rspec-retry (~> 0.4.5)
rspec-set (~> 0.1.3)
rspec_profiling (~> 0.0.5)
rubocop (~> 0.52.1)
rubocop (~> 0.54.0)
rubocop-rspec (~> 1.22.1)
ruby-fogbugz (~> 0.2.1)
ruby-prof (~> 0.17.0)
......
......@@ -79,7 +79,7 @@ GEM
babosa (1.0.2)
base32 (0.3.2)
batch-loader (1.2.1)
bcrypt (3.1.11)
bcrypt (3.1.12)
bcrypt_pbkdf (1.0.0)
benchmark-ips (2.3.0)
better_errors (2.1.1)
......@@ -111,7 +111,7 @@ GEM
capybara-screenshot (1.0.14)
capybara (>= 1.0, < 3)
launchy
carrierwave (1.2.1)
carrierwave (1.2.3)
activemodel (>= 4.0.0)
activesupport (>= 4.0.0)
mime-types (>= 1.16)
......@@ -315,8 +315,8 @@ GEM
mime-types (>= 1.16)
posix-spawn (~> 0.3)
gitlab-markup (1.6.4)
gitlab-styles (2.3.2)
rubocop (~> 0.51)
gitlab-styles (2.4.1)
rubocop (~> 0.54.0)
rubocop-gitlab-security (~> 0.1.0)
rubocop-rspec (~> 1.19)
gitlab_omniauth-ldap (2.0.4)
......@@ -384,8 +384,8 @@ GEM
rake (>= 10, < 13)
rubocop (>= 0.49.0)
sysexits (~> 1.1)
hamlit (2.6.1)
temple (~> 0.7.6)
hamlit (2.8.8)
temple (>= 0.8.0)
thor
tilt
hashdiff (0.3.4)
......@@ -514,7 +514,7 @@ GEM
net-ssh (5.0.1)
netrc (0.11.0)
nio4r (2.3.1)
nokogiri (1.8.2)
nokogiri (1.8.3)
mini_portile2 (~> 2.3.0)
nokogumbo (1.5.0)
nokogiri
......@@ -785,16 +785,16 @@ GEM
pg
rails
sqlite3
rubocop (0.52.1)
rubocop (0.54.0)
parallel (~> 1.10)
parser (>= 2.4.0.2, < 3.0)
parser (>= 2.5)
powerpack (~> 0.1)
rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
rubocop-gitlab-security (0.1.1)
rubocop (>= 0.51)
rubocop-rspec (1.22.1)
rubocop-rspec (1.22.2)
rubocop (>= 0.52.1)
ruby-enum (0.7.2)
i18n
......@@ -811,7 +811,7 @@ GEM
rubyzip (1.2.1)
rufus-scheduler (3.4.0)
et-orbi (~> 1.0)
rugged (0.27.1)
rugged (0.27.2)
safe_yaml (1.0.4)
sanitize (4.6.5)
crass (~> 1.0.2)
......@@ -877,7 +877,7 @@ GEM
activesupport (>= 4.2)
spring-commands-rspec (1.0.4)
spring (>= 0.9.1)
sprockets (3.7.1)
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.2.1)
......@@ -898,7 +898,7 @@ GEM
sys-filesystem (1.1.6)
ffi
sysexits (1.2.0)
temple (0.7.7)
temple (0.8.0)
test-prof (0.2.5)
text (1.3.1)
thin (1.7.0)
......@@ -1053,7 +1053,7 @@ DEPENDENCIES
gitlab-gollum-lib (~> 4.2)
gitlab-gollum-rugged_adapter (~> 0.4.4)
gitlab-markup (~> 1.6.4)
gitlab-styles (~> 2.3)
gitlab-styles (~> 2.4)
gitlab_omniauth-ldap (~> 2.0.4)
gon (~> 6.2)
google-api-client (~> 0.19.8)
......@@ -1067,7 +1067,7 @@ DEPENDENCIES
graphql (~> 1.8.0)
grpc (~> 1.11.0)
haml_lint (~> 0.26.0)
hamlit (~> 2.6.1)
hamlit (~> 2.8.8)
hashie-forbidden_attributes
health_check (~> 2.6.0)
hipchat (~> 1.5.0)
......@@ -1154,7 +1154,7 @@ DEPENDENCIES
rspec-retry (~> 0.4.5)
rspec-set (~> 0.1.3)
rspec_profiling (~> 0.0.5)
rubocop (~> 0.52.1)
rubocop (~> 0.54.0)
rubocop-rspec (~> 1.22.1)
ruby-fogbugz (~> 0.2.1)
ruby-prof (~> 0.17.0)
......
# GitLab
[![Build status](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/build.svg)](https://gitlab.com/gitlab-org/gitlab-ce/commits/master)
[![Overall test coverage](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/coverage.svg)](https://gitlab.com/gitlab-org/gitlab-ce/pipelines)
[![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.svg)](https://codeclimate.com/github/gitlabhq/gitlabhq)
[![Core Infrastructure Initiative Best Practices](https://bestpractices.coreinfrastructure.org/projects/42/badge)](https://bestpractices.coreinfrastructure.org/projects/42)
[![Gitter](https://badges.gitter.im/gitlabhq/gitlabhq.svg)](https://gitter.im/gitlabhq/gitlabhq?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
## Test coverage
- [![Ruby coverage](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/coverage.svg?job=coverage)](https://gitlab-org.gitlab.io/gitlab-ce/coverage-ruby) Ruby
......
......@@ -2,9 +2,9 @@
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require File.expand_path('../config/application', __FILE__)
require File.expand_path('config/application', __dir__)
relative_url_conf = File.expand_path('../config/initializers/relative_url', __FILE__)
relative_url_conf = File.expand_path('config/initializers/relative_url', __dir__)
require relative_url_conf if File.exist?("#{relative_url_conf}.rb")
Gitlab::Application.load_tasks
......
......@@ -63,7 +63,8 @@ export default {
plainDiffPath: state => state.diffs.plainDiffPath,
emailPatchPath: state => state.diffs.emailPatchPath,
}),
...mapGetters(['isParallelView', 'isNotesFetched']),
...mapGetters('diffs', ['isParallelView']),
...mapGetters(['isNotesFetched']),
targetBranch() {
return {
branchName: this.targetBranchName,
......@@ -115,7 +116,7 @@ export default {
this.adjustView();
},
methods: {
...mapActions(['setBaseConfig', 'fetchDiffFiles']),
...mapActions('diffs', ['setBaseConfig', 'fetchDiffFiles']),
fetchData() {
this.fetchDiffFiles().catch(() => {
createFlash(__('Something went wrong on our end. Please try again!'));
......
......@@ -31,7 +31,7 @@ export default {
};
},
computed: {
...mapGetters(['isInlineView', 'isParallelView', 'areAllFilesCollapsed']),
...mapGetters('diffs', ['isInlineView', 'isParallelView', 'areAllFilesCollapsed']),
sumAddedLines() {
return this.sumValues('addedLines');
},
......@@ -66,7 +66,7 @@ export default {
document.removeEventListener('scroll', this.handleScroll);
},
methods: {
...mapActions(['setInlineDiffViewType', 'setParallelDiffViewType', 'expandAllFiles']),
...mapActions('diffs', ['setInlineDiffViewType', 'setParallelDiffViewType', 'expandAllFiles']),
pluralize,
handleScroll() {
if (!this.updating) {
......
......@@ -22,7 +22,7 @@ export default {
projectPath: state => state.diffs.projectPath,
endpoint: state => state.diffs.endpoint,
}),
...mapGetters(['isInlineView', 'isParallelView']),
...mapGetters('diffs', ['isInlineView', 'isParallelView']),
diffMode() {
const diffModeKey = Object.keys(diffModes).find(key => this.diffFile[`${key}File`]);
return diffModes[diffModeKey] || diffModes.replaced;
......@@ -39,12 +39,12 @@ export default {
<div class="diff-viewer">
<template v-if="isTextFile">
<inline-diff-view
v-show="isInlineView"
v-if="isInlineView"
:diff-file="diffFile"
:diff-lines="diffFile.highlightedDiffLines || []"
/>
<parallel-diff-view
v-show="isParallelView"
v-if="isParallelView"
:diff-file="diffFile"
:diff-lines="diffFile.parallelDiffLines || []"
/>
......
......@@ -15,9 +15,7 @@ export default {
</script>
<template>
<div
v-if="discussions.length"
>
<div>
<div
v-for="discussion in discussions"
:key="discussion.id"
......
......@@ -47,6 +47,9 @@ export default {
false,
);
},
showExpandMessage() {
return this.isCollapsed && !this.isLoadingCollapsedDiff && !this.file.tooLarge;
},
},
mounted() {
document.addEventListener('scroll', this.handleScroll);
......@@ -55,7 +58,7 @@ export default {
document.removeEventListener('scroll', this.handleScroll);
},
methods: {
...mapActions(['loadCollapsedDiff']),
...mapActions('diffs', ['loadCollapsedDiff']),
handleToggle() {
const { collapsed, highlightedDiffLines, parallelDiffLines } = this.file;
......@@ -159,7 +162,7 @@ export default {
</div>
<diff-content
v-show="!isCollapsed"
v-if="!isCollapsed"
:class="{ hidden: isCollapsed || file.tooLarge }"
:diff-file="file"
/>
......@@ -168,7 +171,7 @@ export default {
class="diff-content loading"
/>
<div
v-show="isCollapsed && !isLoadingCollapsedDiff && !file.tooLarge"
v-if="showExpandMessage"
class="nothing-here-block diff-collapsed"
>
{{ __('This diff is collapsed.') }}
......
......@@ -145,6 +145,7 @@ export default {
@click.stop="handleToggle"
/>
<a
v-once
ref="titleWrapper"
:href="titleLink"
class="append-right-4"
......
......@@ -108,7 +108,7 @@ export default {
},
},
methods: {
...mapActions(['loadMoreLines', 'showCommentForm']),
...mapActions('diffs', ['loadMoreLines', 'showCommentForm']),
handleCommentButton() {
this.showCommentForm({ lineCode: this.lineCode });
},
......@@ -189,6 +189,7 @@ export default {
</button>
<a
v-if="lineNumber"
v-once
:data-linenumber="lineNumber"
:href="lineHref"
>
......
......@@ -59,7 +59,8 @@ export default {
}
},
methods: {
...mapActions(['cancelCommentForm', 'saveNote', 'fetchDiscussions']),
...mapActions('diffs', ['cancelCommentForm']),
...mapActions(['saveNote', 'refetchDiscussionById']),
handleCancelCommentForm() {
this.autosave.reset();
this.cancelCommentForm({
......@@ -78,10 +79,10 @@ export default {
});
this.saveNote(postData)
.then(() => {
.then(result => {
const endpoint = this.getNotesDataByProp('discussionsPath');
this.fetchDiscussions(endpoint)
this.refetchDiscussionById({ path: endpoint, discussionId: result.discussion_id })
.then(() => {
this.handleCancelCommentForm();
})
......
......@@ -117,14 +117,6 @@ export default {
<template>
<td
v-if="isContentLine"
:class="lineType"
class="line_content"
v-html="normalizedLine.richText"
>
</td>
<td
v-else
:class="classNameMap"
>
<diff-line-gutter-content
......
......@@ -31,22 +31,9 @@ export default {
diffLineCommentForms: state => state.diffs.diffLineCommentForms,
}),
...mapGetters(['discussionsByLineCode']),
isDiscussionExpanded() {
if (!this.discussions.length) {
return false;
}
return this.discussions.every(discussion => discussion.expanded);
},
hasCommentForm() {
return this.diffLineCommentForms[this.line.lineCode];
},
discussions() {
return this.discussionsByLineCode[this.line.lineCode] || [];
},
shouldRender() {
return this.isDiscussionExpanded || this.hasCommentForm;
},
className() {
return this.discussions.length ? '' : 'js-temp-notes-holder';
},
......@@ -56,7 +43,6 @@ export default {
<template>
<tr
v-if="shouldRender"
:class="className"
class="notes_holder"
>
......@@ -67,6 +53,7 @@ export default {
<td class="notes_content">
<div class="content">
<diff-discussions
v-if="discussions.length"
:discussions="discussions"
/>
<diff-line-note-form
......
......@@ -36,7 +36,7 @@ export default {
};
},
computed: {
...mapGetters(['isInlineView']),
...mapGetters('diffs', ['isInlineView']),
isContextLine() {
return this.line.type === CONTEXT_LINE_TYPE;
},
......@@ -94,11 +94,12 @@ export default {
:is-hover="isHover"
class="diff-line-num new_line"
/>
<diff-table-cell
<td
v-once
:class="line.type"
:diff-file="diffFile"
:line="line"
:is-content-line="true"
/>
class="line_content"
v-html="line.richText"
>
</td>
</tr>
</template>
<script>
import { mapGetters } from 'vuex';
import { mapGetters, mapState } from 'vuex';
import inlineDiffTableRow from './inline_diff_table_row.vue';
import inlineDiffCommentRow from './inline_diff_comment_row.vue';
import { trimFirstCharOfLineContent } from '../store/utils';
......@@ -20,7 +20,11 @@ export default {
},
},
computed: {
...mapGetters(['commitId']),
...mapGetters('diffs', ['commitId']),
...mapGetters(['discussionsByLineCode']),
...mapState({
diffLineCommentForms: state => state.diffs.diffLineCommentForms,
}),
normalizedDiffLines() {
return this.diffLines.map(line => (line.richText ? trimFirstCharOfLineContent(line) : line));
},
......@@ -31,6 +35,18 @@ export default {
return window.gon.user_color_scheme;
},
},
methods: {
shouldRenderCommentRow(line) {
if (this.diffLineCommentForms[line.lineCode]) return true;
const lineDiscussions = this.discussionsByLineCode[line.lineCode];
if (lineDiscussions === undefined) {
return false;
}
return lineDiscussions.every(discussion => discussion.expanded);
},
},
};
</script>
......@@ -50,6 +66,7 @@ export default {
:key="line.lineCode"
/>
<inline-diff-comment-row
v-if="shouldRenderCommentRow(line)"
:diff-file="diffFile"
:diff-lines="normalizedDiffLines"
:line="line"
......
......@@ -55,13 +55,6 @@ export default {
hasAnyExpandedDiscussion() {
return this.hasExpandedDiscussionOnLeft || this.hasExpandedDiscussionOnRight;
},
shouldRenderDiscussionsRow() {
const hasDiscussion = this.hasDiscussion && this.hasAnyExpandedDiscussion;
const hasCommentFormOnLeft = this.diffLineCommentForms[this.leftLineCode];
const hasCommentFormOnRight = this.diffLineCommentForms[this.rightLineCode];
return hasDiscussion || hasCommentFormOnLeft || hasCommentFormOnRight;
},
shouldRenderDiscussionsOnLeft() {
return this.discussionsByLineCode[this.leftLineCode] && this.hasExpandedDiscussionOnLeft;
},
......@@ -81,7 +74,6 @@ export default {
<template>
<tr
v-if="shouldRenderDiscussionsRow"
:class="className"
class="notes_holder"
>
......@@ -92,6 +84,7 @@ export default {
class="content"
>
<diff-discussions
v-if="discussionsByLineCode[leftLineCode].length"
:discussions="discussionsByLineCode[leftLineCode]"
/>
</div>
......@@ -112,6 +105,7 @@ export default {
class="content"
>
<diff-discussions
v-if="discussionsByLineCode[rightLineCode].length"
:discussions="discussionsByLineCode[rightLineCode]"
/>
</div>
......
......@@ -40,7 +40,7 @@ export default {
};
},
computed: {
...mapGetters(['isParallelView']),
...mapGetters('diffs', ['isParallelView']),
isContextLine() {
return this.line.left.type === CONTEXT_LINE_TYPE;
},
......@@ -113,17 +113,15 @@ export default {
:diff-view-type="parallelDiffViewType"
class="diff-line-num old_line"
/>
<diff-table-cell
<td
v-once
:id="line.left.lineCode"
:diff-file="diffFile"
:line="line"
:is-content-line="true"
:line-position="linePositionLeft"
:line-type="parallelViewLeftLineType"
:diff-view-type="parallelDiffViewType"
:class="parallelViewLeftLineType"
class="line_content parallel left-side"
@mousedown.native="handleParallelLineMouseDown"
/>
v-html="line.left.richText"
>
</td>
<diff-table-cell
:diff-file="diffFile"
:line="line"
......@@ -135,16 +133,14 @@ export default {
:diff-view-type="parallelDiffViewType"
class="diff-line-num new_line"
/>
<diff-table-cell
<td
v-once
:id="line.right.lineCode"
:diff-file="diffFile"
:line="line"
:is-content-line="true"
:line-position="linePositionRight"
:line-type="line.right.type"
:diff-view-type="parallelDiffViewType"
:class="line.right.type"
class="line_content parallel right-side"
@mousedown.native="handleParallelLineMouseDown"
/>
v-html="line.right.richText"
>
</td>
</tr>
</template>
<script>
import { mapGetters } from 'vuex';
import { mapState, mapGetters } from 'vuex';
import parallelDiffTableRow from './parallel_diff_table_row.vue';
import parallelDiffCommentRow from './parallel_diff_comment_row.vue';
import { EMPTY_CELL_TYPE } from '../constants';
......@@ -21,7 +21,11 @@ export default {
},
},
computed: {
...mapGetters(['commitId']),
...mapGetters('diffs', ['commitId']),
...mapGetters(['discussionsByLineCode']),
...mapState({
diffLineCommentForms: state => state.diffs.diffLineCommentForms,
}),
parallelDiffLines() {
return this.diffLines.map(line => {
const parallelLine = Object.assign({}, line);
......@@ -48,6 +52,32 @@ export default {
return window.gon.user_color_scheme;
},
},
methods: {
shouldRenderCommentRow(line) {
const leftLineCode = line.left.lineCode;
const rightLineCode = line.right.lineCode;
const discussions = this.discussionsByLineCode;
const leftDiscussions = discussions[leftLineCode];
const rightDiscussions = discussions[rightLineCode];
const hasDiscussion = leftDiscussions || rightDiscussions;
const hasExpandedDiscussionOnLeft = leftDiscussions
? leftDiscussions.every(discussion => discussion.expanded)
: false;
const hasExpandedDiscussionOnRight = rightDiscussions
? rightDiscussions.every(discussion => discussion.expanded)
: false;
if (hasDiscussion && (hasExpandedDiscussionOnLeft || hasExpandedDiscussionOnRight)) {
return true;
}
const hasCommentFormOnLeft = this.diffLineCommentForms[leftLineCode];
const hasCommentFormOnRight = this.diffLineCommentForms[rightLineCode];
return hasCommentFormOnLeft || hasCommentFormOnRight;
},
},
};
</script>
......@@ -69,6 +99,7 @@ export default {
:key="index"
/>
<parallel-diff-comment-row
v-if="shouldRenderCommentRow(line)"
:key="line.left.lineCode || line.right.lineCode"
:line="line"
:diff-file="diffFile"
......
......@@ -4,6 +4,7 @@ import mutations from '../mutations';
import createState from './diff_state';
export default {
namespaced: true,
state: createState(),
getters,
actions,
......
......@@ -171,6 +171,8 @@ export default class DueDateSelectors {
initMilestoneDatePicker() {
$('.datepicker').each(function initPikadayMilestone() {
const $datePicker = $(this);
const datePickerVal = $datePicker.val();
const calendar = new Pikaday({
field: $datePicker.get(0),
theme: 'gitlab-theme animate-picker',
......@@ -183,7 +185,7 @@ export default class DueDateSelectors {
},
});
calendar.setDate(parsePikadayDate($datePicker.val()));
calendar.setDate(parsePikadayDate(datePickerVal));
$datePicker.data('pikaday', calendar);
});
......
......@@ -9,6 +9,7 @@ export default {
'diffEditor.insertedTextBackground': '#ddfbe6',
'diffEditor.removedTextBackground': '#f9d7dc',
'editor.selectionBackground': '#aad6f8',
'editorIndentGuide.activeBackground': '#cccccc',
},
},
};
......@@ -41,6 +41,15 @@ export const fetchDiscussions = ({ commit }, path) =>
commit(types.SET_INITIAL_DISCUSSIONS, discussions);
});
export const refetchDiscussionById = ({ commit }, { path, discussionId }) =>
service
.fetchDiscussions(path)
.then(res => res.json())
.then(discussions => {
const selectedDiscussion = discussions.find(discussion => discussion.id === discussionId);
if (selectedDiscussion) commit(types.UPDATE_DISCUSSION, selectedDiscussion);
});
export const deleteNote = ({ commit }, note) =>
service.deleteNote(note.path).then(() => {
commit(types.DELETE_NOTE, note);
......
......@@ -114,7 +114,6 @@ export default {
Object.assign(state, { discussions });
},
[types.SET_LAST_FETCHED_AT](state, fetchedAt) {
Object.assign(state, { lastFetchedAt: fetchedAt });
},
......
......@@ -79,66 +79,62 @@ export default {
</script>
<template>
<div class="mr-widget-heading deploy-heading">
<div class="mr-widget-heading deploy-heading append-bottom-default">
<div class="ci-widget media">
<div class="ci-status-icon ci-status-icon-success">
<span class="js-icon-link icon-link">
<status-icon status="success" />
</span>
</div>
<div class="media-body">
<div class="deploy-body">
<template v-if="hasDeploymentMeta">
<span>
Deployed to
</span>
<a
:href="deployment.url"
target="_blank"
rel="noopener noreferrer nofollow"
class="deploy-link js-deploy-meta"
<div class="deployment-info">
<template v-if="hasDeploymentMeta">
<span>
Deployed to
</span>
<a
:href="deployment.url"
target="_blank"
rel="noopener noreferrer nofollow"
class="deploy-link js-deploy-meta"
>
{{ deployment.name }}
</a>
</template>
<span
v-tooltip
v-if="hasDeploymentTime"
:title="deployment.deployed_at_formatted"
class="js-deploy-time"
>
{{ deployment.name }}
</a>
</template>
<template v-if="hasExternalUrls">
<span>
on
{{ deployTimeago }}
</span>
<memory-usage
v-if="hasMetrics"
:metrics-url="deployment.metrics_url"
:metrics-monitoring-url="deployment.metrics_monitoring_url"
/>
</div>
<div>
<a
v-if="hasExternalUrls"
:href="deployment.external_url"
target="_blank"
rel="noopener noreferrer nofollow"
class="deploy-link js-deploy-url"
class="deploy-link js-deploy-url btn btn-default btn-sm inline"
>
{{ deployment.external_url_formatted }}
<icon
:size="16"
name="external-link"
/>
<span>
View app
<icon name="external-link" />
</span>
</a>
</template>
<span
v-tooltip
v-if="hasDeploymentTime"
:title="deployment.deployed_at_formatted"
class="js-deploy-time"
>
{{ deployTimeago }}
</span>
<loading-button
v-if="deployment.stop_url"
:loading="isStopping"
container-class="btn btn-default btn-sm prepend-left-default"
label="Stop environment"
@click="stopEnvironment"
/>
<loading-button
v-if="deployment.stop_url"
:loading="isStopping"
container-class="btn btn-default btn-sm inline prepend-left-4"
title="Stop environment"
@click="stopEnvironment"
>
<icon name="stop" />
</loading-button>
</div>
</div>
<memory-usage
v-if="hasMetrics"
:metrics-url="deployment.metrics_url"
:metrics-monitoring-url="deployment.metrics_monitoring_url"
/>
</div>
</div>
</div>
......
......@@ -2,7 +2,7 @@
import tooltip from '~/vue_shared/directives/tooltip';
import { n__ } from '~/locale';
import { webIDEUrl } from '~/lib/utils/url_utility';
import icon from '~/vue_shared/components/icon.vue';
import Icon from '~/vue_shared/components/icon.vue';
import clipboardButton from '~/vue_shared/components/clipboard_button.vue';
export default {
......@@ -11,7 +11,7 @@ export default {
tooltip,
},
components: {
icon,
Icon,
clipboardButton,
},
props: {
......@@ -54,104 +54,114 @@ export default {
};
</script>
<template>
<div class="mr-source-target">
<div class="normal">
<strong>
{{ s__("mrWidget|Request to merge") }}
<span
:class="{ 'label-truncated': isSourceBranchLong }"
:title="isSourceBranchLong ? mr.sourceBranch : ''"
:v-tooltip="isSourceBranchLong"
class="label-branch js-source-branch"
data-placement="bottom"
v-html="mr.sourceBranchLink"
>
</span>
<div class="mr-source-target append-bottom-default">
<div class="git-merge-icon-container append-right-default">
<icon name="git-merge" />
</div>
<div class="git-merge-container d-flex">
<div class="normal">
<strong>
{{ s__("mrWidget|Request to merge") }}
<span
:class="{ 'label-truncated': isSourceBranchLong }"
:title="isSourceBranchLong ? mr.sourceBranch : ''"
:v-tooltip="isSourceBranchLong"
class="label-branch js-source-branch"
data-placement="bottom"
v-html="mr.sourceBranchLink"
>
</span>
<clipboard-button
:text="branchNameClipboardData"
:title="__('Copy branch name to clipboard')"
css-class="btn-default btn-transparent btn-clipboard"
/>
<clipboard-button
:text="branchNameClipboardData"
:title="__('Copy branch name to clipboard')"
css-class="btn-default btn-transparent btn-clipboard"
/>
{{ s__("mrWidget|into") }}
{{ s__("mrWidget|into") }}
<span
:v-tooltip="isTargetBranchLong"
:class="{ 'label-truncatedtooltip': isTargetBranchLong }"
:title="isTargetBranchLong ? mr.targetBranch : ''"
class="label-branch"
data-placement="bottom"
>
<a
:href="mr.targetBranchTreePath"
class="js-target-branch"
<span
:v-tooltip="isTargetBranchLong"
:class="{ 'label-truncatedtooltip': isTargetBranchLong }"
:title="isTargetBranchLong ? mr.targetBranch : ''"
class="label-branch"
data-placement="bottom"
>
{{ mr.targetBranch }}
</a>
</span>
</strong>
<span
v-if="shouldShowCommitsBehindText"
class="diverged-commits-count"
>
(<a :href="mr.targetBranchPath">{{ commitsText }}</a>)
</span>
</div>
<a
:href="mr.targetBranchTreePath"
class="js-target-branch"
>
{{ mr.targetBranch }}
</a>
</span>
</strong>
<div
v-if="shouldShowCommitsBehindText"
class="diverged-commits-count"
>
<span class="monospace">{{ mr.sourceBranch }}</span>
is {{ commitsText }}
<span class="monospace">{{ mr.targetBranch }}</span>
</div>
</div>
<div v-if="mr.isOpen">
<a
v-if="!mr.sourceBranchRemoved"
:href="webIdePath"
class="btn btn-sm btn-default inline js-web-ide"
>
{{ s__("mrWidget|Web IDE") }}
</a>
<button
:disabled="mr.sourceBranchRemoved"
data-target="#modal_merge_info"
data-toggle="modal"
class="btn btn-sm btn-default inline js-check-out-branch"
type="button"
<div
v-if="mr.isOpen"
class="branch-actions"
>
{{ s__("mrWidget|Check out branch") }}
</button>
<span class="dropdown prepend-left-10">
<a
v-if="!mr.sourceBranchRemoved"
:href="webIdePath"
class="btn btn-default inline js-web-ide d-none d-md-inline-block"
>
{{ s__("mrWidget|Open in Web IDE") }}
</a>
<button
:disabled="mr.sourceBranchRemoved"
data-target="#modal_merge_info"
data-toggle="modal"
class="btn btn-default inline js-check-out-branch"
type="button"
class="btn btn-sm inline dropdown-toggle"
data-toggle="dropdown"
aria-label="Download as"
aria-haspopup="true"
aria-expanded="false"
>
<icon name="download" />
<i
class="fa fa-caret-down"
aria-hidden="true">
</i>
{{ s__("mrWidget|Check out branch") }}
</button>
<ul class="dropdown-menu dropdown-menu-right">
<li>
<a
:href="mr.emailPatchesPath"
class="js-download-email-patches"
download
>
{{ s__("mrWidget|Email patches") }}
</a>
</li>
<li>
<a
:href="mr.plainDiffPath"
class="js-download-plain-diff"
download
>
{{ s__("mrWidget|Plain diff") }}
</a>
</li>
</ul>
</span>
<span class="dropdown prepend-left-10">
<button
type="button"
class="btn inline dropdown-toggle"
data-toggle="dropdown"
aria-label="Download as"
aria-haspopup="true"
aria-expanded="false"
>
<icon name="download" />
<i
class="fa fa-caret-down"
aria-hidden="true">
</i>
</button>
<ul class="dropdown-menu dropdown-menu-right">
<li>
<a
:href="mr.emailPatchesPath"
class="js-download-email-patches"
download
>
{{ s__("mrWidget|Email patches") }}
</a>
</li>
<li>
<a
:href="mr.plainDiffPath"
class="js-download-plain-diff"
download
>
{{ s__("mrWidget|Plain diff") }}
</a>
</li>
</ul>
</span>
</div>
</div>
</div>
</template>
......@@ -26,6 +26,10 @@ export default {
type: String,
required: false,
},
sourceBranchLink: {
type: String,
required: false,
},
},
computed: {
hasPipeline() {
......@@ -54,12 +58,18 @@ export default {
<template>
<div
v-if="hasPipeline || hasCIError"
class="mr-widget-heading"
class="mr-widget-heading append-bottom-default"
>
<div class="ci-widget media">
<template v-if="hasCIError">
<div class="ci-status-icon ci-status-icon-failed ci-error js-ci-error append-right-10">
<icon name="status_failed" />
<div
class="add-border ci-status-icon ci-status-icon-failed ci-error
js-ci-error append-right-default"
>
<icon
:size="32"
name="status_failed_borderless"
/>
</div>
<div class="media-body">
Could not connect to the CI server. Please check your settings and try again
......@@ -68,50 +78,66 @@ export default {
<template v-else-if="hasPipeline">
<a
:href="status.details_path"
class="append-right-10"
class="align-self-start append-right-default"
>
<ci-icon :status="status" />
<ci-icon
:status="status"
:size="32"
:borderless="true"
class="add-border"
/>
</a>
<div class="ci-widget-container d-flex">
<div class="ci-widget-content">
<div class="media-body">
<div class="font-weight-bold">
Pipeline
<a
:href="pipeline.path"
class="pipeline-id font-weight-normal pipeline-number"
>#{{ pipeline.id }}</a>
<div class="media-body">
Pipeline
<a
:href="pipeline.path"
class="pipeline-id"
>
#{{ pipeline.id }}
</a>
{{ pipeline.details.status.label }}
{{ pipeline.details.status.label }}
<template v-if="hasCommitInfo">
for
<a
:href="pipeline.commit.commit_path"
class="commit-sha js-commit-link"
>
{{ pipeline.commit.short_id }}</a>.
</template>
<span class="mr-widget-pipeline-graph">
<span
v-if="hasStages"
class="stage-cell"
>
<template v-if="hasCommitInfo">
for
<a
:href="pipeline.commit.commit_path"
class="commit-sha js-commit-link font-weight-normal"
>
{{ pipeline.commit.short_id }}</a>
on
<span
class="label-branch"
v-html="sourceBranchLink"
>
</span>
</template>
</div>
<div
v-for="(stage, i) in pipeline.details.stages"
:key="i"
class="stage-container dropdown js-mini-pipeline-graph"
v-if="pipeline.coverage"
class="coverage"
>
<pipeline-stage :stage="stage" />
Coverage {{ pipeline.coverage }}%
</div>
</div>
</div>
<div>
<span class="mr-widget-pipeline-graph">
<span
v-if="hasStages"
class="stage-cell"
>
<div
v-for="(stage, i) in pipeline.details.stages"
:key="i"
class="stage-container dropdown js-mini-pipeline-graph mr-widget-pipeline-stages"
>
<pipeline-stage :stage="stage" />
</div>
</span>
</span>
</span>
<template v-if="pipeline.coverage">
Coverage {{ pipeline.coverage }}%
</template>
</div>
</div>
</template>
</div>
......
......@@ -43,6 +43,7 @@
<ci-icon
v-else
:status="statusObj"
:size="24"
/>
<button
......
......@@ -252,41 +252,44 @@ export default {
:pipeline="mr.pipeline"
:ci-status="mr.ciStatus"
:has-ci="mr.hasCI"
:source-branch-link="mr.sourceBranchLink"
/>
<deployment
v-for="deployment in mr.deployments"
:key="deployment.id"
:deployment="deployment"
/>
<div class="mr-widget-section">
<component
:is="componentName"
:mr="mr"
:service="service"
/>
<div class="mr-section-container">
<div class="mr-widget-section">
<component
:is="componentName"
:mr="mr"
:service="service"
/>
<section
v-if="mr.allowCollaboration"
class="mr-info-list mr-links"
>
{{ s__("mrWidget|Allows commits from members who can merge to the target branch") }}
</section>
<section
v-if="mr.allowCollaboration"
class="mr-info-list mr-links"
>
{{ s__("mrWidget|Allows commits from members who can merge to the target branch") }}
</section>
<mr-widget-related-links
v-if="shouldRenderRelatedLinks"
:state="mr.state"
:related-links="mr.relatedLinks"
/>
<mr-widget-related-links
v-if="shouldRenderRelatedLinks"
:state="mr.state"
:related-links="mr.relatedLinks"
/>
<source-branch-removal-status
v-if="shouldRenderSourceBranchRemovalStatus"
/>
</div>
<div
v-if="shouldRenderMergeHelp"
class="mr-widget-footer"
>
<mr-widget-merge-help />
<source-branch-removal-status
v-if="shouldRenderSourceBranchRemovalStatus"
/>
</div>
<div
v-if="shouldRenderMergeHelp"
class="mr-widget-footer"
>
<mr-widget-merge-help />
</div>
</div>
</div>
</template>
......@@ -224,7 +224,10 @@
.form-control {
position: relative;
min-width: 200px;
padding: 5px 25px 6px 0;
padding-right: 25px;
padding-left: 0;
height: $input-height;
line-height: inherit;
border-color: transparent;
&:focus,
......
......@@ -3,12 +3,20 @@
svg {
fill: $green-500;
}
&.add-border {
@include borderless-status-icon($green-500);
}
}
.ci-status-icon-failed {
svg {
fill: $gl-danger;
}
&.add-border {
@include borderless-status-icon($red-500);
}
}
.ci-status-icon-pending,
......@@ -17,12 +25,20 @@
svg {
fill: $orange-500;
}
&.add-border {
@include borderless-status-icon($orange-500);
}
}
.ci-status-icon-running {
svg {
fill: $blue-400;
}
&.add-border {
@include borderless-status-icon($blue-400);
}
}
.ci-status-icon-canceled,
......@@ -30,6 +46,10 @@
svg {
fill: $gl-text-color;
}
&.add-border {
@include borderless-status-icon($gl-text-color);
}
}
.ci-status-icon-created,
......@@ -38,6 +58,10 @@
svg {
fill: $gray-darkest;
}
&.add-border {
@include borderless-status-icon($gray-darkest);
}
}
.ci-status-icon-manual {
......
......@@ -232,3 +232,10 @@
word-break: break-word;
max-width: 100%;
}
@mixin borderless-status-icon($color) {
svg {
border: 1px solid $color;
border-radius: 50%;
}
}
......@@ -350,7 +350,8 @@ code {
}
.commit-sha,
.ref-name {
.ref-name,
.pipeline-number {
@extend .monospace;
font-size: 95%;
}
......
......@@ -743,6 +743,7 @@ Pipeline Graph
*/
$stage-hover-bg: $gray-darker;
$ci-action-icon-size: 22px;
$ci-action-icon-size-lg: 24px;
$pipeline-dropdown-line-height: 20px;
$pipeline-dropdown-status-icon-size: 18px;
$ci-action-dropdown-button-size: 24px;
......
......@@ -15,16 +15,38 @@
}
}
.mr-widget-heading {
position: relative;
border: 1px solid $border-color;
border-radius: 4px;
&:not(.deploy-heading)::before {
content: '';
border-left: 1px solid $theme-gray-200;
position: absolute;
left: 32px;
top: -17px;
height: 16px;
}
}
.mr-section-container {
border: 1px solid $border-color;
border-radius: $border-radius-default;
border-top: 0;
}
.mr-widget-heading,
.mr-widget-section,
.mr-widget-footer {
padding: $gl-padding;
}
.mr-state-widget {
color: $gl-text-color;
border: 1px solid $border-color;
border-radius: 2px;
line-height: 28px;
.mr-widget-heading,
.mr-widget-section,
.mr-widget-footer {
padding: $gl-padding;
border-top: solid 1px $border-color;
}
......@@ -124,10 +146,17 @@
.ci-widget {
color: $gl-text-color;
display: flex;
align-items: center;
justify-content: space-between;
@include media-breakpoint-down(xs) {
flex-wrap: wrap;
}
.ci-widget-content {
display: flex;
align-items: center;
}
}
.mr-widget-icon {
......@@ -136,8 +165,6 @@
}
.ci-status-icon svg {
width: $status-icon-size;
height: $status-icon-size;
margin: 3px 0;
position: relative;
overflow: visible;
......@@ -145,8 +172,6 @@
}
.mr-widget-pipeline-graph {
padding: 0 4px;
.dropdown-menu {
z-index: 300;
}
......@@ -157,7 +182,7 @@
}
.normal {
line-height: 28px;
flex: 1;
}
.capitalize {
......@@ -168,7 +193,7 @@
@extend .ref-name;
color: $gl-text-color;
font-weight: $gl-font-weight-bold;
font-weight: normal;
overflow: hidden;
word-break: break-all;
......@@ -192,6 +217,8 @@
}
.mr-widget-body {
line-height: 28px;
@include clearfix;
&.media > *:first-child {
......@@ -474,18 +501,66 @@
}
}
.merge-request-details .content-block {
border-bottom: 0;
}
.mr-source-target {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
background-color: $gray-light;
border-radius: $border-radius-default $border-radius-default 0 0;
padding: $gl-padding / 2 $gl-padding;
border-radius: $border-radius-default;
padding: $gl-padding;
border: 1px solid $border-color;
min-height: 69px;
@include media-breakpoint-up(md) {
align-items: center;
}
.dropdown-toggle .fa {
color: $gl-text-color;
}
.git-merge-icon-container {
border: 1px solid $theme-gray-400;
border-radius: 50%;
height: 32px;
width: 32px;
color: $theme-gray-700;
line-height: 28px;
.ic-git-merge {
vertical-align: middle;
width: 31px;
}
}
.git-merge-container {
justify-content: space-between;
flex: 1;
flex-direction: row;
align-items: center;
@include media-breakpoint-down(md) {
flex-direction: column;
align-items: flex-start;
.branch-actions {
margin-top: 16px;
}
}
@include media-breakpoint-up(lg) {
.branch-actions {
align-self: center;
}
}
}
.diverged-commits-count {
color: $gl-text-color-secondary;
font-size: 12px;
}
}
.card-new-merge-request {
......@@ -720,13 +795,25 @@
}
.deploy-heading {
margin-top: -19px;
border-top-left-radius: 0;
border-top-right-radius: 0;
background-color: $gray-light;
@include media-breakpoint-up(md) {
padding: $gl-padding-8 $gl-padding;
}
.media-body {
min-width: 0;
font-size: 12px;
margin-left: 48px;
}
}
.deploy-body {
display: flex;
align-items: center;
flex-wrap: wrap;
@include media-breakpoint-up(xs) {
......@@ -734,6 +821,15 @@
white-space: nowrap;
}
@include media-breakpoint-down(md) {
flex-direction: column;
align-items: flex-start;
.deployment-info {
margin-bottom: $gl-padding;
}
}
> *:not(:last-child) {
margin-right: .3em;
}
......@@ -741,18 +837,22 @@
svg {
vertical-align: text-top;
}
}
.deploy-link {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-width: 100px;
max-width: 150px;
.deployment-info {
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-width: 100px;
@include media-breakpoint-up(xs) {
min-width: 0;
max-width: 100%;
@include media-breakpoint-up(xs) {
min-width: 0;
max-width: 100%;
}
}
.btn svg {
fill: $theme-gray-700;
}
}
......@@ -772,3 +872,33 @@
}
}
}
.ci-widget-container {
justify-content: space-between;
flex: 1;
flex-direction: row;
@include media-breakpoint-down(md) {
flex-direction: column;
.stage-cell .stage-container {
margin-top: 16px;
}
.dropdown .mini-pipeline-graph-dropdown-menu.dropdown-menu {
transform: initial;
}
}
.coverage {
font-size: 12px;
color: $theme-gray-700;
line-height: initial;
}
.mini-pipeline-graph-dropdown-toggle,
.stage-cell .mini-pipeline-graph-dropdown-toggle svg {
height: $ci-action-icon-size-lg;
width: $ci-action-icon-size-lg;
}
}
......@@ -301,6 +301,21 @@
border-bottom: 2px solid $border-color;
}
}
//delete when all pipelines are updated to new size
&.mr-widget-pipeline-stages {
+ .stage-container {
margin-left: 4px;
}
&:not(:last-child) {
&::after {
width: 4px;
right: -4px;
top: 11px;
}
}
}
}
}
......
......@@ -22,7 +22,7 @@ class Admin::DeployKeysController < Admin::ApplicationController
end
def update
if deploy_key.update_attributes(update_params)
if deploy_key.update(update_params)
flash[:notice] = 'Deploy key was successfully updated.'
redirect_to admin_deploy_keys_path
else
......@@ -34,7 +34,7 @@ class Admin::DeployKeysController < Admin::ApplicationController
deploy_key.destroy
respond_to do |format|
format.html { redirect_to admin_deploy_keys_path, status: 302 }
format.html { redirect_to admin_deploy_keys_path, status: :found }
format.json { head :ok }
end
end
......
......@@ -39,7 +39,7 @@ class Admin::GroupsController < Admin::ApplicationController
end
def update
if @group.update_attributes(group_params)
if @group.update(group_params)
redirect_to [:admin, @group], notice: 'Group was successfully updated.'
else
render "edit"
......
......@@ -23,7 +23,7 @@ class Admin::HooksController < Admin::ApplicationController
end
def update
if hook.update_attributes(hook_params)
if hook.update(hook_params)
flash[:notice] = 'System hook was successfully updated.'
redirect_to admin_hooks_path
else
......@@ -34,7 +34,7 @@ class Admin::HooksController < Admin::ApplicationController
def destroy
hook.destroy
redirect_to admin_hooks_path, status: 302
redirect_to admin_hooks_path, status: :found
end
def test
......
......@@ -25,7 +25,7 @@ class Admin::IdentitiesController < Admin::ApplicationController
end
def update
if @identity.update_attributes(identity_params)
if @identity.update(identity_params)
RepairLdapBlockedUserService.new(@user).execute
redirect_to admin_user_identities_path(@user), notice: 'User identity was successfully updated.'
else
......
......@@ -11,7 +11,7 @@ class Admin::ImpersonationsController < Admin::ApplicationController
session[:impersonator_id] = nil
redirect_to admin_user_path(original_user), status: 302
redirect_to admin_user_path(original_user), status: :found
end
private
......
......@@ -20,6 +20,6 @@ class Admin::JobsController < Admin::ApplicationController
def cancel_all
Ci::Build.running_or_pending.each(&:cancel)
redirect_to admin_jobs_path, status: 303
redirect_to admin_jobs_path, status: :see_other
end
end
......@@ -16,7 +16,7 @@ class Admin::RunnerProjectsController < Admin::ApplicationController
runner = rp.runner
rp.destroy
redirect_to admin_runner_path(runner), status: 302
redirect_to admin_runner_path(runner), status: :found
end
private
......
......@@ -28,7 +28,7 @@ class Admin::RunnersController < Admin::ApplicationController
def destroy
@runner.destroy
redirect_to admin_runners_path, status: 302
redirect_to admin_runners_path, status: :found
end
def resume
......
......@@ -16,7 +16,7 @@ class Admin::ServicesController < Admin::ApplicationController
end
def update
if service.update_attributes(service_params[:service])
if service.update(service_params[:service])
PropagateServiceTemplateWorker.perform_async(service.id) if service.active?
redirect_to admin_application_settings_services_path,
......
......@@ -163,7 +163,7 @@ class Admin::UsersController < Admin::ApplicationController
format.json { head :ok }
else
format.html { redirect_back_or_admin_user(alert: 'There was an error removing the e-mail.') }
format.json { render json: 'There was an error removing the e-mail.', status: 400 }
format.json { render json: 'There was an error removing the e-mail.', status: :bad_request }
end
end
end
......
......@@ -127,7 +127,7 @@ module IssuableActions
errors: [
"Someone edited this #{issuable.human_class_name} at the same time you did. Please refresh your browser and make sure your changes will not unintentionally remove theirs."
]
}, status: 409
}, status: :conflict
end
end
end
......
......@@ -27,7 +27,7 @@ module LfsRequest
message: 'Git LFS is not enabled on this GitLab server, contact your admin.',
documentation_url: help_url
},
status: 501
status: :not_implemented
)
end
......
......@@ -7,6 +7,6 @@ class Groups::AvatarsController < Groups::ApplicationController
@group.remove_avatar!
@group.save
redirect_to edit_group_path(@group), status: 302
redirect_to edit_group_path(@group), status: :found
end
end
......@@ -23,7 +23,7 @@ class Groups::RunnersController < Groups::ApplicationController
def destroy
@runner.destroy
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), status: 302
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), status: :found
end
def resume
......
......@@ -41,7 +41,7 @@ class JwtController < ApplicationController
"You must use a personal access token with 'api' scope for Git over HTTP.\n" \
"You can generate one at #{profile_personal_access_tokens_url}" }
]
}, status: 401
}, status: :unauthorized
end
def render_unauthorized
......@@ -50,7 +50,7 @@ class JwtController < ApplicationController
{ code: 'UNAUTHORIZED',
message: 'HTTP Basic: Access denied' }
]
}, status: 401
}, status: :unauthorized
end
def auth_params
......
......@@ -5,14 +5,14 @@ class NotificationSettingsController < ApplicationController
return render_404 unless can_read?(resource)
@notification_setting = current_user.notification_settings_for(resource)
@saved = @notification_setting.update_attributes(notification_setting_params)
@saved = @notification_setting.update(notification_setting_params)
render_response
end
def update
@notification_setting = current_user.notification_settings.find(params[:id])
@saved = @notification_setting.update_attributes(notification_setting_params)
@saved = @notification_setting.update(notification_setting_params)
render_response
end
......
......@@ -7,7 +7,7 @@ class Profiles::ActiveSessionsController < Profiles::ApplicationController
ActiveSession.destroy(current_user, params[:id])
respond_to do |format|
format.html { redirect_to profile_active_sessions_url, status: 302 }
format.html { redirect_to profile_active_sessions_url, status: :found }
format.js { head :ok }
end
end
......
......@@ -4,6 +4,6 @@ class Profiles::AvatarsController < Profiles::ApplicationController
Users::UpdateService.new(current_user, user: @user).execute { |user| user.remove_avatar! }
redirect_to profile_path, status: 302
redirect_to profile_path, status: :found
end
end
......@@ -39,7 +39,7 @@ class Profiles::ChatNamesController < Profiles::ApplicationController
flash[:alert] = "Could not delete chat nickname #{@chat_name.chat_name}."
end
redirect_to profile_chat_names_path, status: 302
redirect_to profile_chat_names_path, status: :found
end
private
......
......@@ -19,7 +19,7 @@ class Profiles::EmailsController < Profiles::ApplicationController
Emails::DestroyService.new(current_user, user: current_user).execute(@email)
respond_to do |format|
format.html { redirect_to profile_emails_url, status: 302 }
format.html { redirect_to profile_emails_url, status: :found }
format.js { head :ok }
end
end
......
......@@ -21,7 +21,7 @@ class Profiles::GpgKeysController < Profiles::ApplicationController
@gpg_key.destroy
respond_to do |format|
format.html { redirect_to profile_gpg_keys_url, status: 302 }
format.html { redirect_to profile_gpg_keys_url, status: :found }
format.js { head :ok }
end
end
......@@ -30,7 +30,7 @@ class Profiles::GpgKeysController < Profiles::ApplicationController
@gpg_key.revoke
respond_to do |format|
format.html { redirect_to profile_gpg_keys_url, status: 302 }
format.html { redirect_to profile_gpg_keys_url, status: :found }
format.js { head :ok }
end
end
......
......@@ -26,7 +26,7 @@ class Profiles::KeysController < Profiles::ApplicationController
Keys::DestroyService.new(current_user).execute(@key)
respond_to do |format|
format.html { redirect_to profile_keys_url, status: 302 }
format.html { redirect_to profile_keys_url, status: :found }
format.js { head :ok }
end
end
......
......@@ -78,7 +78,7 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
def destroy
current_user.disable_two_factor!
redirect_to profile_account_path, status: 302
redirect_to profile_account_path, status: :found
end
def skip
......
......@@ -61,7 +61,7 @@ class Projects::ApplicationController < ApplicationController
def require_non_empty_project
# Be sure to return status code 303 to avoid a double DELETE:
# http://api.rubyonrails.org/classes/ActionController/Redirecting.html
redirect_to project_path(@project), status: 303 if @project.empty_repo?
redirect_to project_path(@project), status: :see_other if @project.empty_repo?
end
def require_branch_head
......
......@@ -21,6 +21,6 @@ class Projects::AvatarsController < Projects::ApplicationController
@project.save
redirect_to edit_project_path(@project), status: 302
redirect_to edit_project_path(@project), status: :found
end
end
......@@ -98,7 +98,7 @@ class Projects::BranchesController < Projects::ApplicationController
flash_type = result[:status] == :error ? :alert : :notice
flash[flash_type] = result[:message]
redirect_to project_branches_path(@project), status: 303
redirect_to project_branches_path(@project), status: :see_other
end
format.js { render nothing: true, status: result[:return_code] }
......
......@@ -62,7 +62,7 @@ class Projects::ClustersController < Projects::ApplicationController
def destroy
if cluster.destroy
flash[:notice] = _('Kubernetes cluster integration was successfully removed.')
redirect_to project_clusters_path(project), status: 302
redirect_to project_clusters_path(project), status: :found
else
flash[:notice] = _('Kubernetes cluster integration was not removed.')
render :show
......
......@@ -35,7 +35,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
end
def update
if deploy_key.update_attributes(update_params)
if deploy_key.update(update_params)
flash[:notice] = 'Deploy key was successfully updated.'
redirect_to_repository_settings(@project)
else
......
......@@ -116,7 +116,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController
set_workhorse_internal_api_content_type
render json: Gitlab::Workhorse.terminal_websocket(terminal)
else
render text: 'Not found', status: 404
render text: 'Not found', status: :not_found
end
end
......
......@@ -53,7 +53,7 @@ class Projects::GitHttpClientController < Projects::ApplicationController
end
send_challenges
render plain: "HTTP Basic: Access denied\n", status: 401
render plain: "HTTP Basic: Access denied\n", status: :unauthorized
rescue Gitlab::Auth::MissingPersonalAccessTokenError
render_missing_personal_access_token
end
......@@ -83,7 +83,7 @@ class Projects::GitHttpClientController < Projects::ApplicationController
render plain: "HTTP Basic: Access denied\n" \
"You must use a personal access token with 'api' scope for Git over HTTP.\n" \
"You can generate one at #{profile_personal_access_tokens_url}",
status: 401
status: :unauthorized
end
def repository
......
......@@ -24,7 +24,7 @@ class Projects::GroupLinksController < Projects::ApplicationController
def update
@group_link = @project.project_group_links.find(params[:id])
@group_link.update_attributes(group_link_params)
@group_link.update(group_link_params)
end
def destroy
......@@ -34,7 +34,7 @@ class Projects::GroupLinksController < Projects::ApplicationController
respond_to do |format|
format.html do
redirect_to project_project_members_path(project), status: 302
redirect_to project_project_members_path(project), status: :found
end
format.js { head :ok }
end
......
......@@ -29,7 +29,7 @@ class Projects::HooksController < Projects::ApplicationController
end
def update
if hook.update_attributes(hook_params)
if hook.update(hook_params)
flash[:notice] = 'Hook was successfully updated.'
redirect_to project_settings_integrations_path(@project)
else
......@@ -48,7 +48,7 @@ class Projects::HooksController < Projects::ApplicationController
def destroy
hook.destroy
redirect_to project_settings_integrations_path(@project), status: 302
redirect_to project_settings_integrations_path(@project), status: :found
end
private
......
......@@ -39,7 +39,7 @@ class Projects::LabelsController < Projects::ApplicationController
else
respond_to do |format|
format.html { render :new }
format.json { render json: { message: @label.errors.messages }, status: 400 }
format.json { render json: { message: @label.errors.messages }, status: :bad_request }
end
end
end
......@@ -115,7 +115,7 @@ class Projects::LabelsController < Projects::ApplicationController
flash[:notice] = "#{@label.title} promoted to <a href=\"#{group_labels_path(@project.group)}\">group label</a>.".html_safe
respond_to do |format|
format.html do
redirect_to(project_labels_path(@project), status: 303)
redirect_to(project_labels_path(@project), status: :see_other)
end
format.json do
render json: { url: project_labels_path(@project) }
......
......@@ -25,7 +25,7 @@ class Projects::LfsApiController < Projects::GitHttpClientController
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"
},
status: 501
status: :not_implemented
)
end
......
......@@ -28,7 +28,7 @@ class Projects::LfsStorageController < Projects::GitHttpClientController
if store_file!(oid, size)
head 200
else
render plain: 'Unprocessable entity', status: 422
render plain: 'Unprocessable entity', status: :unprocessable_entity
end
rescue ActiveRecord::RecordInvalid
render_lfs_forbidden
......
......@@ -227,7 +227,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
def rebase
RebaseWorker.perform_async(@merge_request.id, current_user.id)
render nothing: true, status: 200
render nothing: true, status: :ok
end
protected
......
......@@ -96,7 +96,7 @@ class Projects::MilestonesController < Projects::ApplicationController
Milestones::DestroyService.new(project, current_user).execute(milestone)
respond_to do |format|
format.html { redirect_to namespace_project_milestones_path, status: 303 }
format.html { redirect_to namespace_project_milestones_path, status: :see_other }
format.js { head :ok }
end
end
......
......@@ -13,7 +13,7 @@ class Projects::MirrorsController < Projects::ApplicationController
end
def update
if project.update_attributes(mirror_params)
if project.update(mirror_params)
flash[:notice] = 'Mirroring settings were successfully updated.'
else
flash[:alert] = project.errors.full_messages.join(', ').html_safe
......
......@@ -64,7 +64,7 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController
def destroy
if schedule.destroy
redirect_to pipeline_schedules_path(@project), status: 302
redirect_to pipeline_schedules_path(@project), status: :found
else
redirect_to pipeline_schedules_path(@project),
status: :forbidden,
......
......@@ -14,7 +14,7 @@ class Projects::ReleasesController < Projects::ApplicationController
# it exists only to save a description to each Tag.
# If description is empty we should destroy the existing record.
if release_params[:description].present?
release.update_attributes(release_params)
release.update(release_params)
else
release.destroy
end
......
......@@ -24,7 +24,7 @@ class Projects::RepositoriesController < Projects::ApplicationController
send_git_archive @repository, ref: @ref, format: params[:format], append_sha: append_sha
rescue => ex
logger.error("#{self.class.name}: #{ex}")
return git_not_found!
git_not_found!
end
def assign_archive_vars
......
......@@ -21,6 +21,6 @@ class Projects::RunnerProjectsController < Projects::ApplicationController
runner_project = project.runner_projects.find(params[:id])
runner_project.destroy
redirect_to project_runners_path(project), status: 302
redirect_to project_runners_path(project), status: :found
end
end
......@@ -24,7 +24,7 @@ class Projects::RunnersController < Projects::ApplicationController
@runner.destroy
end
redirect_to project_runners_path(@project), status: 302
redirect_to project_runners_path(@project), status: :found
end
def resume
......
......@@ -34,7 +34,7 @@ class Projects::ServicesController < Projects::ApplicationController
private
def service_test_response
if @service.update_attributes(service_params[:service])
if @service.update(service_params[:service])
data = @service.test_data(project, current_user)
outcome = @service.test(data)
......
......@@ -82,7 +82,7 @@ class Projects::SnippetsController < Projects::ApplicationController
@snippet.destroy
redirect_to project_snippets_path(@project), status: 302
redirect_to project_snippets_path(@project), status: :found
end
protected
......
......@@ -50,7 +50,7 @@ class Projects::TagsController < Projects::ApplicationController
respond_to do |format|
if result[:status] == :success
format.html do
redirect_to project_tags_path(@project), status: 303
redirect_to project_tags_path(@project), status: :see_other
end
format.js
......
......@@ -14,6 +14,6 @@ class Projects::TemplatesController < Projects::ApplicationController
def get_template_class
template_types = { issue: Gitlab::Template::IssueTemplate, merge_request: Gitlab::Template::MergeRequestTemplate }.with_indifferent_access
@template_type = template_types[params[:template_type]]
render json: [], status: 404 unless @template_type
render json: [], status: :not_found unless @template_type
end
end
......@@ -50,7 +50,7 @@ class Projects::TriggersController < Projects::ApplicationController
flash[:alert] = "Could not remove the trigger."
end
redirect_to project_settings_ci_cd_path(@project), status: 302
redirect_to project_settings_ci_cd_path(@project), status: :found
end
private
......
......@@ -120,7 +120,7 @@ class Projects::WikisController < Projects::ApplicationController
rescue ProjectWiki::CouldNotCreateWikiError
flash[:notice] = "Could not create Wiki Repository at this time. Please try again later."
redirect_to project_path(@project)
return false
false
end
def wiki_params
......@@ -129,7 +129,7 @@ class Projects::WikisController < Projects::ApplicationController
def build_page(args)
WikiPage.new(@project_wiki).tap do |page|
page.update_attributes(args)
page.update_attributes(args) # rubocop:disable Rails/ActiveRecordAliases
end
end
end
......@@ -133,7 +133,7 @@ class ProjectsController < Projects::ApplicationController
::Projects::DestroyService.new(@project, current_user, {}).async_execute
flash[:notice] = _("Project '%{project_name}' is in the process of being deleted.") % { project_name: @project.full_name }
redirect_to dashboard_projects_path, status: 302
redirect_to dashboard_projects_path, status: :found
rescue Projects::DestroyService::DestroyError => ex
redirect_to edit_project_path(@project), status: 302, alert: ex.message
end
......
......@@ -32,8 +32,8 @@ class SessionsController < Devise::SessionsController
super do |resource|
# User has successfully signed in, so clear any unused reset token
if resource.reset_password_token.present?
resource.update_attributes(reset_password_token: nil,
reset_password_sent_at: nil)
resource.update(reset_password_token: nil,
reset_password_sent_at: nil)
end
# hide the signed-in notification
......
......@@ -13,7 +13,7 @@ module Sherlock
def destroy_all
Gitlab::Sherlock.collection.clear
redirect_to :back, status: 302
redirect_to :back, status: :found
end
end
end
......@@ -89,7 +89,7 @@ class SnippetsController < ApplicationController
@snippet.destroy
redirect_to snippets_path, status: 302
redirect_to snippets_path, status: :found
end
protected
......
......@@ -371,7 +371,7 @@ module Ci
def update_coverage
coverage = trace.extract_coverage(coverage_regex)
update_attributes(coverage: coverage) if coverage.present?
update(coverage: coverage) if coverage.present?
end
def parse_trace_sections!
......
......@@ -7,7 +7,7 @@ module CacheableAttributes
class_methods do
def cache_key
"#{name}:#{Gitlab::VERSION}:#{Gitlab.migrations_hash}:#{Rails.version}".freeze
"#{name}:#{Gitlab::VERSION}:#{Rails.version}".freeze
end
# Can be overriden
......@@ -69,6 +69,6 @@ module CacheableAttributes
end
def cache!
Rails.cache.write(self.class.cache_key, self)
Rails.cache.write(self.class.cache_key, self, expires_in: 1.minute)
end
end
......@@ -23,7 +23,7 @@ module ProtectedRef
# If we don't `protected_branch` or `protected_tag` would be empty and
# `project` cannot be delegated to it, which in turn would cause validations
# to fail.
has_many :"#{type}_access_levels", inverse_of: self.model_name.singular # rubocop:disable Cop/ActiveRecordDependent
has_many :"#{type}_access_levels", inverse_of: self.model_name.singular
validates :"#{type}_access_levels", length: { is: 1, message: "are restricted to a single instance per #{self.model_name.human}." }
......
......@@ -11,8 +11,8 @@ module Network
@parent_spaces = []
end
def method_missing(m, *args, &block)
@commit.__send__(m, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
def method_missing(msg, *args, &block)
@commit.__send__(msg, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
end
def space
......
......@@ -107,7 +107,7 @@ class ProjectWiki
update_project_activity
rescue Gitlab::Git::Wiki::DuplicatePageError => e
@error_message = "Duplicate page: #{e.message}"
return false
false
end
def update_page(page, content:, title: nil, format: :markdown, message: nil)
......
......@@ -57,7 +57,7 @@ class RemoteMirror < ActiveRecord::Base
Gitlab::Metrics.add_event(:remote_mirrors_finished, path: remote_mirror.project.full_path)
timestamp = Time.now
remote_mirror.update_attributes!(
remote_mirror.update!(
last_update_at: timestamp, last_successful_update_at: timestamp, last_error: nil
)
end
......
......@@ -462,12 +462,12 @@ class Repository
expire_branches_cache
end
def method_missing(m, *args, &block)
if m == :lookup && !block_given?
lookup_cache[m] ||= {}
lookup_cache[m][args.join(":")] ||= raw_repository.__send__(m, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
def method_missing(msg, *args, &block)
if msg == :lookup && !block_given?
lookup_cache[msg] ||= {}
lookup_cache[msg][args.join(":")] ||= raw_repository.__send__(msg, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
else
raw_repository.__send__(m, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
raw_repository.__send__(msg, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
end
end
......
......@@ -496,7 +496,7 @@ class User < ActiveRecord::Base
def disable_two_factor!
transaction do
update_attributes(
update(
otp_required_for_login: false,
encrypted_otp_secret: nil,
encrypted_otp_secret_iv: nil,
......@@ -1053,7 +1053,7 @@ class User < ActiveRecord::Base
return @global_notification_setting if defined?(@global_notification_setting)
@global_notification_setting = notification_settings.find_or_initialize_by(source: nil)
@global_notification_setting.update_attributes(level: NotificationSetting.levels[DEFAULT_NOTIFICATION_LEVEL]) unless @global_notification_setting.persisted?
@global_notification_setting.update(level: NotificationSetting.levels[DEFAULT_NOTIFICATION_LEVEL]) unless @global_notification_setting.persisted?
@global_notification_setting
end
......@@ -1333,8 +1333,8 @@ class User < ActiveRecord::Base
end
end
def self.unique_internal(scope, username, email_pattern, &b)
scope.first || create_unique_internal(scope, username, email_pattern, &b)
def self.unique_internal(scope, username, email_pattern, &block)
scope.first || create_unique_internal(scope, username, email_pattern, &block)
end
def self.create_unique_internal(scope, username, email_pattern, &creation_block)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment