Commit fcd2c832 authored by Steve Azzopardi's avatar Steve Azzopardi

Merge branch 'ce-to-ee-2018-11-09' into 'master'

CE upstream - 2018-11-09 05:08 UTC

Closes gitlab-org/quality/nightly#30 and gitlab-org/quality/nightly#34

See merge request gitlab-org/gitlab-ee!8375
parents 562eba72 38e41d8b
...@@ -55,6 +55,11 @@ export default { ...@@ -55,6 +55,11 @@ export default {
required: false, required: false,
default: false, default: false,
}, },
isContextLine: {
type: Boolean,
required: false,
default: false,
},
isHover: { isHover: {
type: Boolean, type: Boolean,
required: false, required: false,
...@@ -76,6 +81,7 @@ export default { ...@@ -76,6 +81,7 @@ export default {
this.showCommentButton && this.showCommentButton &&
this.isHover && this.isHover &&
!this.isMatchLine && !this.isMatchLine &&
!this.isContextLine &&
!this.isMetaLine && !this.isMetaLine &&
!this.hasDiscussions !this.hasDiscussions
); );
......
...@@ -3,6 +3,7 @@ import { mapGetters } from 'vuex'; ...@@ -3,6 +3,7 @@ import { mapGetters } from 'vuex';
import DiffLineGutterContent from './diff_line_gutter_content.vue'; import DiffLineGutterContent from './diff_line_gutter_content.vue';
import { import {
MATCH_LINE_TYPE, MATCH_LINE_TYPE,
CONTEXT_LINE_TYPE,
EMPTY_CELL_TYPE, EMPTY_CELL_TYPE,
OLD_LINE_TYPE, OLD_LINE_TYPE,
OLD_NO_NEW_LINE_TYPE, OLD_NO_NEW_LINE_TYPE,
...@@ -70,6 +71,9 @@ export default { ...@@ -70,6 +71,9 @@ export default {
isMatchLine() { isMatchLine() {
return this.line.type === MATCH_LINE_TYPE; return this.line.type === MATCH_LINE_TYPE;
}, },
isContextLine() {
return this.line.type === CONTEXT_LINE_TYPE;
},
isMetaLine() { isMetaLine() {
const { type } = this.line; const { type } = this.line;
...@@ -84,7 +88,11 @@ export default { ...@@ -84,7 +88,11 @@ export default {
[type]: type, [type]: type,
[LINE_UNFOLD_CLASS_NAME]: this.isMatchLine, [LINE_UNFOLD_CLASS_NAME]: this.isMatchLine,
[LINE_HOVER_CLASS_NAME]: [LINE_HOVER_CLASS_NAME]:
this.isLoggedIn && this.isHover && !this.isMatchLine && !this.isMetaLine, this.isLoggedIn &&
this.isHover &&
!this.isMatchLine &&
!this.isContextLine &&
!this.isMetaLine,
}; };
}, },
lineNumber() { lineNumber() {
......
...@@ -4,6 +4,8 @@ import DiffTableCell from './diff_table_cell.vue'; ...@@ -4,6 +4,8 @@ import DiffTableCell from './diff_table_cell.vue';
import { import {
NEW_LINE_TYPE, NEW_LINE_TYPE,
OLD_LINE_TYPE, OLD_LINE_TYPE,
CONTEXT_LINE_TYPE,
CONTEXT_LINE_CLASS_NAME,
PARALLEL_DIFF_VIEW_TYPE, PARALLEL_DIFF_VIEW_TYPE,
LINE_POSITION_LEFT, LINE_POSITION_LEFT,
LINE_POSITION_RIGHT, LINE_POSITION_RIGHT,
...@@ -39,9 +41,13 @@ export default { ...@@ -39,9 +41,13 @@ export default {
}, },
computed: { computed: {
...mapGetters('diffs', ['isInlineView']), ...mapGetters('diffs', ['isInlineView']),
isContextLine() {
return this.line.type === CONTEXT_LINE_TYPE;
},
classNameMap() { classNameMap() {
return { return {
[this.line.type]: this.line.type, [this.line.type]: this.line.type,
[CONTEXT_LINE_CLASS_NAME]: this.isContextLine,
[PARALLEL_DIFF_VIEW_TYPE]: this.isParallelView, [PARALLEL_DIFF_VIEW_TYPE]: this.isParallelView,
}; };
}, },
......
...@@ -5,6 +5,8 @@ import DiffTableCell from './diff_table_cell.vue'; ...@@ -5,6 +5,8 @@ import DiffTableCell from './diff_table_cell.vue';
import { import {
NEW_LINE_TYPE, NEW_LINE_TYPE,
OLD_LINE_TYPE, OLD_LINE_TYPE,
CONTEXT_LINE_TYPE,
CONTEXT_LINE_CLASS_NAME,
OLD_NO_NEW_LINE_TYPE, OLD_NO_NEW_LINE_TYPE,
PARALLEL_DIFF_VIEW_TYPE, PARALLEL_DIFF_VIEW_TYPE,
NEW_NO_NEW_LINE_TYPE, NEW_NO_NEW_LINE_TYPE,
...@@ -41,8 +43,12 @@ export default { ...@@ -41,8 +43,12 @@ export default {
}; };
}, },
computed: { computed: {
isContextLine() {
return this.line.left && this.line.left.type === CONTEXT_LINE_TYPE;
},
classNameMap() { classNameMap() {
return { return {
[CONTEXT_LINE_CLASS_NAME]: this.isContextLine,
[PARALLEL_DIFF_VIEW_TYPE]: true, [PARALLEL_DIFF_VIEW_TYPE]: true,
}; };
}, },
......
...@@ -3,6 +3,7 @@ export const PARALLEL_DIFF_VIEW_TYPE = 'parallel'; ...@@ -3,6 +3,7 @@ export const PARALLEL_DIFF_VIEW_TYPE = 'parallel';
export const MATCH_LINE_TYPE = 'match'; export const MATCH_LINE_TYPE = 'match';
export const OLD_NO_NEW_LINE_TYPE = 'old-nonewline'; export const OLD_NO_NEW_LINE_TYPE = 'old-nonewline';
export const NEW_NO_NEW_LINE_TYPE = 'new-nonewline'; export const NEW_NO_NEW_LINE_TYPE = 'new-nonewline';
export const CONTEXT_LINE_TYPE = 'context';
export const EMPTY_CELL_TYPE = 'empty-cell'; export const EMPTY_CELL_TYPE = 'empty-cell';
export const COMMENT_FORM_TYPE = 'commentForm'; export const COMMENT_FORM_TYPE = 'commentForm';
export const DIFF_NOTE_TYPE = 'DiffNote'; export const DIFF_NOTE_TYPE = 'DiffNote';
...@@ -21,6 +22,7 @@ export const LINE_SIDE_RIGHT = 'right-side'; ...@@ -21,6 +22,7 @@ export const LINE_SIDE_RIGHT = 'right-side';
export const DIFF_VIEW_COOKIE_NAME = 'diff_view'; export const DIFF_VIEW_COOKIE_NAME = 'diff_view';
export const LINE_HOVER_CLASS_NAME = 'is-over'; export const LINE_HOVER_CLASS_NAME = 'is-over';
export const LINE_UNFOLD_CLASS_NAME = 'unfold js-unfold'; export const LINE_UNFOLD_CLASS_NAME = 'unfold js-unfold';
export const CONTEXT_LINE_CLASS_NAME = 'diff-expanded';
export const UNFOLD_COUNT = 20; export const UNFOLD_COUNT = 20;
export const COUNT_OF_AVATARS_IN_GUTTER = 3; export const COUNT_OF_AVATARS_IN_GUTTER = 3;
......
...@@ -65,13 +65,7 @@ export default { ...@@ -65,13 +65,7 @@ export default {
const { highlightedDiffLines, parallelDiffLines } = diffFile; const { highlightedDiffLines, parallelDiffLines } = diffFile;
removeMatchLine(diffFile, lineNumbers, bottom); removeMatchLine(diffFile, lineNumbers, bottom);
const lines = addLineReferences(contextLines, lineNumbers, bottom);
const lines = addLineReferences(contextLines, lineNumbers, bottom).map(line => ({
...line,
lineCode: line.lineCode || `${fileHash}_${line.oldLine}_${line.newLine}`,
discussions: line.discussions || [],
}));
addContextLines({ addContextLines({
inlineLines: highlightedDiffLines, inlineLines: highlightedDiffLines,
parallelLines: parallelDiffLines, parallelLines: parallelDiffLines,
......
<script> <script>
import { GlTooltipDirective } from '@gitlab-org/gitlab-ui';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import tooltip from '../../vue_shared/directives/tooltip'; import { s__ } from '~/locale';
import { s__ } from '../../locale';
/** /**
* Renders the external url link in environments table. * Renders the external url link in environments table.
...@@ -11,7 +11,7 @@ export default { ...@@ -11,7 +11,7 @@ export default {
Icon, Icon,
}, },
directives: { directives: {
tooltip, GlTooltip: GlTooltipDirective,
}, },
props: { props: {
externalUrl: { externalUrl: {
...@@ -28,12 +28,11 @@ export default { ...@@ -28,12 +28,11 @@ export default {
</script> </script>
<template> <template>
<a <a
v-tooltip v-gl-tooltip
:title="title" :title="title"
:aria-label="title" :aria-label="title"
:href="externalUrl" :href="externalUrl"
class="btn external-url" class="btn external-url"
data-container="body"
target="_blank" target="_blank"
rel="noopener noreferrer nofollow" rel="noopener noreferrer nofollow"
> >
......
<script> <script>
import Timeago from 'timeago.js'; import Timeago from 'timeago.js';
import _ from 'underscore'; import _ from 'underscore';
import tooltip from '~/vue_shared/directives/tooltip'; import { GlTooltipDirective } from '@gitlab-org/gitlab-ui';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue'; import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import { humanize } from '~/lib/utils/text_utility'; import { humanize } from '~/lib/utils/text_utility';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
...@@ -36,7 +36,7 @@ export default { ...@@ -36,7 +36,7 @@ export default {
}, },
directives: { directives: {
tooltip, GlTooltip: GlTooltipDirective,
}, },
props: { props: {
...@@ -462,7 +462,7 @@ export default { ...@@ -462,7 +462,7 @@ export default {
class="gl-responsive-table-row" class="gl-responsive-table-row"
role="row"> role="row">
<div <div
v-tooltip v-gl-tooltip
:title="model.name" :title="model.name"
class="table-section section-wrap section-15 text-truncate" class="table-section section-wrap section-15 text-truncate"
role="gridcell" role="gridcell"
......
...@@ -2,9 +2,8 @@ ...@@ -2,9 +2,8 @@
/** /**
* Renders the Monitoring (Metrics) link in environments table. * Renders the Monitoring (Metrics) link in environments table.
*/ */
import { GlButton } from '@gitlab-org/gitlab-ui'; import { GlButton, GlTooltipDirective } from '@gitlab-org/gitlab-ui';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import tooltip from '../../vue_shared/directives/tooltip';
export default { export default {
components: { components: {
...@@ -12,7 +11,7 @@ export default { ...@@ -12,7 +11,7 @@ export default {
GlButton, GlButton,
}, },
directives: { directives: {
tooltip, GlTooltip: GlTooltipDirective,
}, },
props: { props: {
monitoringUrl: { monitoringUrl: {
...@@ -29,12 +28,11 @@ export default { ...@@ -29,12 +28,11 @@ export default {
</script> </script>
<template> <template>
<gl-button <gl-button
v-tooltip v-gl-tooltip
:href="monitoringUrl" :href="monitoringUrl"
:title="title" :title="title"
:aria-label="title" :aria-label="title"
class="monitoring-url d-none d-sm-none d-md-block" class="monitoring-url d-none d-sm-none d-md-block"
data-container="body"
rel="noopener noreferrer nofollow" rel="noopener noreferrer nofollow"
variant="default" variant="default"
> >
......
...@@ -6,21 +6,18 @@ ...@@ -6,21 +6,18 @@
* Makes a post request when the button is clicked. * Makes a post request when the button is clicked.
*/ */
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { GlTooltipDirective, GlLoadingIcon } from '@gitlab-org/gitlab-ui';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import tooltip from '~/vue_shared/directives/tooltip';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
import { GlLoadingIcon } from '@gitlab-org/gitlab-ui';
export default { export default {
components: { components: {
Icon, Icon,
GlLoadingIcon, GlLoadingIcon,
}, },
directives: { directives: {
tooltip, GlTooltip: GlTooltipDirective,
}, },
props: { props: {
retryUrl: { retryUrl: {
type: String, type: String,
...@@ -57,21 +54,21 @@ export default { ...@@ -57,21 +54,21 @@ export default {
</script> </script>
<template> <template>
<button <button
v-tooltip v-gl-tooltip
:disabled="isLoading" :disabled="isLoading"
:title="title" :title="title"
type="button" type="button"
class="btn d-none d-sm-none d-md-block" class="btn d-none d-sm-none d-md-block"
@click="onClick" @click="onClick"
> >
<icon <icon
v-if="isLastDeployment" v-if="isLastDeployment"
name="repeat" /> name="repeat"
/>
<icon <icon
v-else v-else
name="redo"/> name="redo"
/>
<gl-loading-icon v-if="isLoading" /> <gl-loading-icon v-if="isLoading" />
</button> </button>
</template> </template>
...@@ -5,49 +5,42 @@ ...@@ -5,49 +5,42 @@
*/ */
import $ from 'jquery'; import $ from 'jquery';
import { GlTooltipDirective } from '@gitlab-org/gitlab-ui';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
import LoadingButton from '../../vue_shared/components/loading_button.vue'; import LoadingButton from '../../vue_shared/components/loading_button.vue';
import tooltip from '../../vue_shared/directives/tooltip';
export default { export default {
components: { components: {
Icon, Icon,
LoadingButton, LoadingButton,
}, },
directives: { directives: {
tooltip, GlTooltip: GlTooltipDirective,
}, },
props: { props: {
environment: { environment: {
type: Object, type: Object,
required: true, required: true,
}, },
}, },
data() { data() {
return { return {
isLoading: false, isLoading: false,
}; };
}, },
computed: { computed: {
title() { title() {
return s__('Environments|Stop environment'); return s__('Environments|Stop environment');
}, },
}, },
mounted() { mounted() {
eventHub.$on('stopEnvironment', this.onStopEnvironment); eventHub.$on('stopEnvironment', this.onStopEnvironment);
}, },
beforeDestroy() { beforeDestroy() {
eventHub.$off('stopEnvironment', this.onStopEnvironment); eventHub.$off('stopEnvironment', this.onStopEnvironment);
}, },
methods: { methods: {
onClick() { onClick() {
$(this.$el).tooltip('dispose'); $(this.$el).tooltip('dispose');
...@@ -63,12 +56,11 @@ export default { ...@@ -63,12 +56,11 @@ export default {
</script> </script>
<template> <template>
<loading-button <loading-button
v-tooltip v-gl-tooltip
:loading="isLoading" :loading="isLoading"
:title="title" :title="title"
:aria-label="title" :aria-label="title"
container-class="btn btn-danger d-none d-sm-none d-md-block" container-class="btn btn-danger d-none d-sm-none d-md-block"
data-container="body"
data-toggle="modal" data-toggle="modal"
data-target="#stop-environment-modal" data-target="#stop-environment-modal"
@click="onClick" @click="onClick"
......
...@@ -3,15 +3,15 @@ ...@@ -3,15 +3,15 @@
* Renders a terminal button to open a web terminal. * Renders a terminal button to open a web terminal.
* Used in environments table. * Used in environments table.
*/ */
import { GlTooltipDirective } from '@gitlab-org/gitlab-ui';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import tooltip from '../../vue_shared/directives/tooltip';
export default { export default {
components: { components: {
Icon, Icon,
}, },
directives: { directives: {
tooltip, GlTooltip: GlTooltipDirective,
}, },
props: { props: {
terminalPath: { terminalPath: {
...@@ -29,12 +29,11 @@ export default { ...@@ -29,12 +29,11 @@ export default {
</script> </script>
<template> <template>
<a <a
v-tooltip v-gl-tooltip
:title="title" :title="title"
:aria-label="title" :aria-label="title"
:href="terminalPath" :href="terminalPath"
class="btn terminal-button d-none d-sm-none d-md-block" class="btn terminal-button d-none d-sm-none d-md-block"
data-container="body"
> >
<icon name="terminal" /> <icon name="terminal" />
</a> </a>
......
<script> <script>
import { GlTooltipDirective } from '@gitlab-org/gitlab-ui';
import GlModal from '~/vue_shared/components/gl_modal.vue'; import GlModal from '~/vue_shared/components/gl_modal.vue';
import { s__, sprintf } from '~/locale'; import { s__, sprintf } from '~/locale';
import tooltip from '~/vue_shared/directives/tooltip';
import LoadingButton from '~/vue_shared/components/loading_button.vue'; import LoadingButton from '~/vue_shared/components/loading_button.vue';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
...@@ -15,7 +15,7 @@ export default { ...@@ -15,7 +15,7 @@ export default {
}, },
directives: { directives: {
tooltip, GlTooltip: GlTooltipDirective,
}, },
props: { props: {
...@@ -67,7 +67,7 @@ export default { ...@@ -67,7 +67,7 @@ export default {
> >
Stopping Stopping
<span <span
v-tooltip v-gl-tooltip
:title="environment.name" :title="environment.name"
class="text-truncate ml-1 mr-1 flex-fill" class="text-truncate ml-1 mr-1 flex-fill"
>{{ environment.name }}</span> >{{ environment.name }}</span>
......
...@@ -50,6 +50,7 @@ export default { ...@@ -50,6 +50,7 @@ export default {
}, },
data() { data() {
return { return {
isFetching: false,
currentFilter: null, currentFilter: null,
}; };
}, },
...@@ -141,6 +142,10 @@ export default { ...@@ -141,6 +142,10 @@ export default {
return discussion.individual_note ? { note: discussion.notes[0] } : { discussion }; return discussion.individual_note ? { note: discussion.notes[0] } : { discussion };
}, },
fetchNotes() { fetchNotes() {
if (this.isFetching) return null;
this.isFetching = true;
return this.fetchDiscussions({ path: this.getNotesDataByProp('discussionsPath') }) return this.fetchDiscussions({ path: this.getNotesDataByProp('discussionsPath') })
.then(() => { .then(() => {
this.initPolling(); this.initPolling();
...@@ -149,6 +154,7 @@ export default { ...@@ -149,6 +154,7 @@ export default {
this.setLoadingState(false); this.setLoadingState(false);
this.setNotesFetchedState(true); this.setNotesFetchedState(true);
eventHub.$emit('fetchedNotesData'); eventHub.$emit('fetchedNotesData');
this.isFetching = false;
}) })
.then(() => this.$nextTick()) .then(() => this.$nextTick())
.then(() => this.checkLocationHash()) .then(() => this.checkLocationHash())
......
<script> <script>
import tooltip from '~/vue_shared/directives/tooltip'; import { GlTooltipDirective } from '@gitlab-org/gitlab-ui';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import { pluralize } from '~/lib/utils/text_utility'; import { pluralize } from '~/lib/utils/text_utility';
import { __, sprintf } from '~/locale'; import { __, sprintf } from '~/locale';
...@@ -10,7 +10,7 @@ export default { ...@@ -10,7 +10,7 @@ export default {
Icon, Icon,
}, },
directives: { directives: {
tooltip, GlTooltip: GlTooltipDirective,
}, },
props: { props: {
file: { file: {
...@@ -79,10 +79,8 @@ export default { ...@@ -79,10 +79,8 @@ export default {
<template> <template>
<span <span
v-tooltip v-gl-tooltip.right
:title="tooltipTitle" :title="tooltipTitle"
data-container="body"
data-placement="right"
class="file-changed-icon ml-auto" class="file-changed-icon ml-auto"
> >
<icon <icon
......
<script> <script>
import { GlTooltipDirective } from '@gitlab-org/gitlab-ui';
import CiIcon from './ci_icon.vue'; import CiIcon from './ci_icon.vue';
import tooltip from '../directives/tooltip';
/** /**
* Renders CI Badge link with CI icon and status text based on * Renders CI Badge link with CI icon and status text based on
* API response shared between all places where it is used. * API response shared between all places where it is used.
...@@ -27,7 +27,7 @@ export default { ...@@ -27,7 +27,7 @@ export default {
CiIcon, CiIcon,
}, },
directives: { directives: {
tooltip, GlTooltip: GlTooltipDirective,
}, },
props: { props: {
status: { status: {
...@@ -50,7 +50,7 @@ export default { ...@@ -50,7 +50,7 @@ export default {
</script> </script>
<template> <template>
<a <a
v-tooltip v-gl-tooltip
:href="status.details_path" :href="status.details_path"
:class="cssClass" :class="cssClass"
:title="!showText ? status.text : ''" :title="!showText ? status.text : ''"
......
<script> <script>
import { GlTooltipDirective } from '@gitlab-org/gitlab-ui';
import UserAvatarLink from './user_avatar/user_avatar_link.vue'; import UserAvatarLink from './user_avatar/user_avatar_link.vue';
import tooltip from '../directives/tooltip';
import Icon from '../../vue_shared/components/icon.vue'; import Icon from '../../vue_shared/components/icon.vue';
export default { export default {
directives: { directives: {
tooltip, GlTooltip: GlTooltipDirective,
}, },
components: { components: {
UserAvatarLink, UserAvatarLink,
...@@ -124,11 +124,10 @@ export default { ...@@ -124,11 +124,10 @@ export default {
</div> </div>
<a <a
v-tooltip v-gl-tooltip
:href="commitRef.ref_url" :href="commitRef.ref_url"
:title="commitRef.name" :title="commitRef.name"
class="ref-name" class="ref-name"
data-container="body"
> >
{{ commitRef.name }} {{ commitRef.name }}
</a> </a>
......
<script> <script>
// only allow classes in images.scss e.g. s12 // only allow classes in images.scss e.g. s12
const validSizes = [8, 10, 12, 16, 18, 24, 32, 48, 72]; const validSizes = [8, 10, 12, 14, 16, 18, 24, 32, 48, 72];
let iconValidator = () => true; let iconValidator = () => true;
/* /*
......
...@@ -207,6 +207,10 @@ ...@@ -207,6 +207,10 @@
@include btn-with-margin; @include btn-with-margin;
} }
&.btn-icon {
color: $gl-gray-700;
}
.fa-caret-down, .fa-caret-down,
.fa-chevron-down { .fa-chevron-down {
margin-left: 5px; margin-left: 5px;
......
...@@ -122,7 +122,7 @@ class Projects::BlobController < Projects::ApplicationController ...@@ -122,7 +122,7 @@ class Projects::BlobController < Projects::ApplicationController
@lines.map! do |line| @lines.map! do |line|
# These are marked as context lines but are loaded from blobs. # These are marked as context lines but are loaded from blobs.
# We also have context lines loaded from diffs in other places. # We also have context lines loaded from diffs in other places.
diff_line = Gitlab::Diff::Line.new(line, nil, nil, nil, nil) diff_line = Gitlab::Diff::Line.new(line, 'context', nil, nil, nil)
diff_line.rich_text = line diff_line.rich_text = line
diff_line diff_line
end end
......
...@@ -22,12 +22,6 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic ...@@ -22,12 +22,6 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
def render_diffs def render_diffs
@environment = @merge_request.environments_for(current_user).last @environment = @merge_request.environments_for(current_user).last
notes_grouped_by_path = @notes.group_by { |note| note.position.file_path }
@diffs.diff_files.each do |diff_file|
notes = notes_grouped_by_path.fetch(diff_file.file_path, [])
notes.each { |note| diff_file.unfold_diff_lines(note.position) }
end
@diffs.write_cache @diffs.write_cache
......
...@@ -66,10 +66,6 @@ class DiffNote < Note ...@@ -66,10 +66,6 @@ class DiffNote < Note
self.original_position.diff_refs == diff_refs self.original_position.diff_refs == diff_refs
end end
def discussion_first_note?
self == discussion.first_note
end
private private
def enqueue_diff_file_creation_job def enqueue_diff_file_creation_job
...@@ -82,33 +78,26 @@ class DiffNote < Note ...@@ -82,33 +78,26 @@ class DiffNote < Note
end end
def should_create_diff_file? def should_create_diff_file?
on_text? && note_diff_file.nil? && discussion_first_note? on_text? && note_diff_file.nil? && self == discussion.first_note
end end
def fetch_diff_file def fetch_diff_file
file = if note_diff_file
if note_diff_file diff = Gitlab::Git::Diff.new(note_diff_file.to_hash)
diff = Gitlab::Git::Diff.new(note_diff_file.to_hash) Gitlab::Diff::File.new(diff,
Gitlab::Diff::File.new(diff, repository: project.repository,
repository: project.repository, diff_refs: original_position.diff_refs)
diff_refs: original_position.diff_refs) elsif created_at_diff?(noteable.diff_refs)
elsif created_at_diff?(noteable.diff_refs) # We're able to use the already persisted diffs (Postgres) if we're
# We're able to use the already persisted diffs (Postgres) if we're # presenting a "current version" of the MR discussion diff.
# presenting a "current version" of the MR discussion diff. # So no need to make an extra Gitaly diff request for it.
# So no need to make an extra Gitaly diff request for it. # As an extra benefit, the returned `diff_file` already
# As an extra benefit, the returned `diff_file` already # has `highlighted_diff_lines` data set from Redis on
# has `highlighted_diff_lines` data set from Redis on # `Diff::FileCollection::MergeRequestDiff`.
# `Diff::FileCollection::MergeRequestDiff`. noteable.diffs(original_position.diff_options).diff_files.first
noteable.diffs(original_position.diff_options).diff_files.first else
else original_position.diff_file(self.project.repository)
original_position.diff_file(self.project.repository) end
end
# Since persisted diff files already have its content "unfolded"
# there's no need to make it pass through the unfolding process.
file&.unfold_diff_lines(position) unless note_diff_file
file
end end
def supported? def supported?
......
# frozen_string_literal: true
class IssueBoardEntity < Grape::Entity
include RequestAwareEntity
expose :id
expose :iid
expose :title
expose :confidential
expose :due_date
expose :project_id
expose :relative_position
expose :weight, if: -> (*) { respond_to?(:weight) }
expose :time_estimate
expose :project do |issue|
API::Entities::Project.represent issue.project, only: [:id, :path]
end
expose :milestone, expose_nil: false do |issue|
API::Entities::Project.represent issue.milestone, only: [:id, :title]
end
expose :assignees do |issue|
API::Entities::UserBasic.represent issue.assignees, only: [:id, :name, :username, :avatar_url]
end
expose :labels do |issue|
LabelEntity.represent issue.labels, project: issue.project, only: [:id, :title, :description, :color, :priority, :text_color]
end
expose :reference_path, if: -> (issue) { issue.project } do |issue, options|
options[:include_full_project_path] ? issue.to_reference(full: true) : issue.to_reference
end
expose :real_path, if: -> (issue) { issue.project } do |issue|
project_issue_path(issue.project, issue)
end
expose :issue_sidebar_endpoint, if: -> (issue) { issue.project } do |issue|
project_issue_path(issue.project, issue, format: :json, serializer: 'sidebar')
end
expose :toggle_subscription_endpoint, if: -> (issue) { issue.project } do |issue|
toggle_subscription_project_issue_path(issue.project, issue)
end
expose :assignable_labels_endpoint, if: -> (issue) { issue.project } do |issue|
project_labels_path(issue.project, format: :json, include_ancestor_groups: true)
end
end
...@@ -29,6 +29,10 @@ module MergeRequests ...@@ -29,6 +29,10 @@ module MergeRequests
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def clear_cache(new_diff) def clear_cache(new_diff)
# Executing the iteration we cache highlighted diffs for each diff file of
# MergeRequestDiff.
cacheable_collection(new_diff).write_cache
# Remove cache for all diffs on this MR. Do not use the association on the # Remove cache for all diffs on this MR. Do not use the association on the
# model, as that will interfere with other actions happening when # model, as that will interfere with other actions happening when
# reloading the diff. # reloading the diff.
......
# frozen_string_literal: true
module Notes
class BaseService < ::BaseService
def clear_noteable_diffs_cache(note)
noteable = note.noteable
if note.is_a?(DiffNote) &&
note.discussion_first_note? &&
note.position.unfolded_diff?(project.repository)
noteable.diffs.clear_cache
end
end
end
end
# frozen_string_literal: true # frozen_string_literal: true
module Notes module Notes
class CreateService < ::Notes::BaseService class CreateService < ::BaseService
def execute def execute
merge_request_diff_head_sha = params.delete(:merge_request_diff_head_sha) merge_request_diff_head_sha = params.delete(:merge_request_diff_head_sha)
...@@ -35,7 +35,6 @@ module Notes ...@@ -35,7 +35,6 @@ module Notes
if !only_commands && note.save if !only_commands && note.save
todo_service.new_note(note, current_user) todo_service.new_note(note, current_user)
clear_noteable_diffs_cache(note)
end end
if command_params.present? if command_params.present?
......
# frozen_string_literal: true # frozen_string_literal: true
module Notes module Notes
class DestroyService < ::Notes::BaseService class DestroyService < BaseService
def execute(note) def execute(note)
TodoService.new.destroy_target(note) do |note| TodoService.new.destroy_target(note) do |note|
note.destroy note.destroy
end end
clear_noteable_diffs_cache(note)
end end
end end
end end
...@@ -5,9 +5,4 @@ ...@@ -5,9 +5,4 @@
= render 'dashboard/snippets_head' = render 'dashboard/snippets_head'
= render partial: 'snippets/snippets_scope_menu', locals: { include_private: true } = render partial: 'snippets/snippets_scope_menu', locals: { include_private: true }
.d-block.d-sm-none
&nbsp;
= link_to new_snippet_path, class: "btn btn-success btn-block", title: "New snippet" do
New snippet
= render partial: 'snippets/snippets', locals: { link_project: true } = render partial: 'snippets/snippets', locals: { link_project: true }
...@@ -347,9 +347,7 @@ ...@@ -347,9 +347,7 @@
= link_to project_settings_ci_cd_path(@project), title: _('CI / CD') do = link_to project_settings_ci_cd_path(@project), title: _('CI / CD') do
%span %span
= _('CI / CD') = _('CI / CD')
= render_if_exists 'projects/sidebar/settings_operations' = render_if_exists 'projects/sidebar/settings_operations'
- if @project.pages_available? - if @project.pages_available?
= nav_link(controller: :pages) do = nav_link(controller: :pages) do
= link_to project_pages_path(@project), title: _('Pages') do = link_to project_pages_path(@project), title: _('Pages') do
......
---
title: Replaces tooltip directive with the new gl-tooltip directive for consistency
in some ci/cd code
merge_request:
author:
type: other
title: Adds new icon size to Vue icon component
merge_request: 22899
author:
type: other
---
title: Allow commenting on any diff line in Merge Requests
merge_request: 22398
author:
type: added
---
title: Remove duplicate primary button in dashboard snippets on small viewports
merge_request: 22902
author: George Tsiolis
type: fixed
...@@ -11,7 +11,7 @@ The following documentation enables Okta as a SAML provider. ...@@ -11,7 +11,7 @@ The following documentation enables Okta as a SAML provider.
1. When the app screen comes up you see another button to **Create an App** and 1. When the app screen comes up you see another button to **Create an App** and
choose SAML 2.0 on the next screen. choose SAML 2.0 on the next screen.
1. Now, very important, add a logo 1. Now, very important, add a logo
(you can choose it from https://about.gitlab.com/press/). You'll have to (you can choose it from <https://about.gitlab.com/press/>). You'll have to
crop and resize it. crop and resize it.
1. Next, you'll need the to fill in the SAML general config. Here's an example 1. Next, you'll need the to fill in the SAML general config. Here's an example
image. image.
......
...@@ -71,7 +71,7 @@ A Registry init file is not shipped with GitLab if you install it from source. ...@@ -71,7 +71,7 @@ A Registry init file is not shipped with GitLab if you install it from source.
Hence, [restarting GitLab][restart gitlab] will not restart the Registry should Hence, [restarting GitLab][restart gitlab] will not restart the Registry should
you modify its settings. Read the upstream documentation on how to achieve that. you modify its settings. Read the upstream documentation on how to achieve that.
At the absolute minimum, make sure your [Registry configuration][registry-auth] At the **absolute** minimum, make sure your [Registry configuration][registry-auth]
has `container_registry` as the service and `https://gitlab.example.com/jwt/auth` has `container_registry` as the service and `https://gitlab.example.com/jwt/auth`
as the realm: as the realm:
...@@ -84,6 +84,9 @@ auth: ...@@ -84,6 +84,9 @@ auth:
rootcertbundle: /root/certs/certbundle rootcertbundle: /root/certs/certbundle
``` ```
CAUTION: **Caution:**
If `auth` is not set up, users will be able to pull docker images without authentication.
## Container Registry domain configuration ## Container Registry domain configuration
There are two ways you can configure the Registry's external domain. There are two ways you can configure the Registry's external domain.
......
...@@ -45,7 +45,7 @@ The following metrics are available: ...@@ -45,7 +45,7 @@ The following metrics are available:
| redis_ping_success | Gauge | 9.4 | Whether or not the last redis ping succeeded | | redis_ping_success | Gauge | 9.4 | Whether or not the last redis ping succeeded |
| redis_ping_latency_seconds | Gauge | 9.4 | Round trip time of the redis ping | | redis_ping_latency_seconds | Gauge | 9.4 | Round trip time of the redis ping |
| user_session_logins_total | Counter | 9.4 | Counter of how many users have logged in | | user_session_logins_total | Counter | 9.4 | Counter of how many users have logged in |
| upload_file_does_not_exist | Counter | 10.7 | Number of times an upload record could not find its file | | upload_file_does_not_exist | Counter | 10.7 in EE, 11.5 in CE | Number of times an upload record could not find its file |
| failed_login_captcha_total | Gauge | 11.0 | Counter of failed CAPTCHA attempts during login | | failed_login_captcha_total | Gauge | 11.0 | Counter of failed CAPTCHA attempts during login |
| successful_login_captcha_total | Gauge | 11.0 | Counter of successful CAPTCHA attempts during login | | successful_login_captcha_total | Gauge | 11.0 | Counter of successful CAPTCHA attempts during login |
......
...@@ -17,6 +17,7 @@ Parameters: ...@@ -17,6 +17,7 @@ Parameters:
- `path` (optional) - The path inside repository. Used to get content of subdirectories - `path` (optional) - The path inside repository. Used to get content of subdirectories
- `ref` (optional) - The name of a repository branch or tag or if not given the default branch - `ref` (optional) - The name of a repository branch or tag or if not given the default branch
- `recursive` (optional) - Boolean value used to get a recursive tree (false by default) - `recursive` (optional) - Boolean value used to get a recursive tree (false by default)
- `per_page` (optional) - Number of results to show per page. If not specified, defaults to `20`
```json ```json
[ [
......
...@@ -812,7 +812,7 @@ deploy to production: ...@@ -812,7 +812,7 @@ deploy to production:
> defined, GitLab will automatically trigger a stop action when the associated > defined, GitLab will automatically trigger a stop action when the associated
> branch is deleted. > branch is deleted.
Closing (stoping) environments can be achieved with the `on_stop` keyword defined under Closing (stopping) environments can be achieved with the `on_stop` keyword defined under
`environment`. It declares a different job that runs in order to close `environment`. It declares a different job that runs in order to close
the environment. the environment.
......
# Database MySQL # Database MySQL
> **Note:** NOTE: **Note:**
> - We do not recommend using MySQL due to various issues. For example, case We do not recommend using MySQL due to various issues.
[(in)sensitivity](https://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html) For example, there have been bugs with case
and [problems](https://bugs.mysql.com/bug.php?id=65830) that [(in)sensitivity](https://dev.mysql.com/doc/refman/5.7/en/case-sensitivity.html).
[suggested](https://bugs.mysql.com/bug.php?id=50909)
[fixes](https://bugs.mysql.com/bug.php?id=65830) [have](https://bugs.mysql.com/bug.php?id=63164). Bugs relating to case sensitivity:
- <https://bugs.mysql.com/bug.php?id=65830>
- <https://bugs.mysql.com/bug.php?id=50909>
- <https://bugs.mysql.com/bug.php?id=65830>
- <https://bugs.mysql.com/bug.php?id=63164>
## Initial database setup ## Initial database setup
``` ```sh
# Install the database packages # Install the database packages
sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev
...@@ -84,8 +89,9 @@ GitLab 8.14 has introduced [a feature](https://gitlab.com/gitlab-org/gitlab-ce/m ...@@ -84,8 +89,9 @@ GitLab 8.14 has introduced [a feature](https://gitlab.com/gitlab-org/gitlab-ce/m
Follow the below instructions to ensure you use the most up to date requirements for your GitLab MySQL Database. Follow the below instructions to ensure you use the most up to date requirements for your GitLab MySQL Database.
**We are about to do the following:** **We are about to do the following:**
- Ensure you can enable `utf8mb4` encoding and `utf8mb4_general_ci` collation for your GitLab DB, tables and data. - Ensure you can enable `utf8mb4` encoding and `utf8mb4_general_ci` collation for your GitLab DB, tables and data.
- Convert your GitLab tables and data from `utf8`/`utf8_general_ci` to `utf8mb4`/`utf8mb4_general_ci` - Convert your GitLab tables and data from `utf8`/`utf8_general_ci` to `utf8mb4`/`utf8mb4_general_ci`.
### Check for utf8mb4 support ### Check for utf8mb4 support
...@@ -130,7 +136,8 @@ We need to check, enable and maybe convert your existing GitLab DB tables to the ...@@ -130,7 +136,8 @@ We need to check, enable and maybe convert your existing GitLab DB tables to the
Whatever the results of your checks above, we now need to check if your GitLab database has been created using [InnoDB File-Per-Table Tablespaces](http://dev.mysql.com/doc/refman/5.7/en/innodb-multiple-tablespaces.html) (i.e. `innodb_file_per_table` was set to **1** at initial setup time). Whatever the results of your checks above, we now need to check if your GitLab database has been created using [InnoDB File-Per-Table Tablespaces](http://dev.mysql.com/doc/refman/5.7/en/innodb-multiple-tablespaces.html) (i.e. `innodb_file_per_table` was set to **1** at initial setup time).
> Note: This setting is [enabled by default](http://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_file_per_table) since MySQL 5.6.6. NOTE: **Note:**
This setting is [enabled by default](http://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_file_per_table) since MySQL 5.6.6.
# Run this command with root privileges, replace the data dir if different: # Run this command with root privileges, replace the data dir if different:
sudo ls -lh /var/lib/mysql/gitlabhq_production/*.ibd | wc -l sudo ls -lh /var/lib/mysql/gitlabhq_production/*.ibd | wc -l
...@@ -138,20 +145,19 @@ Whatever the results of your checks above, we now need to check if your GitLab d ...@@ -138,20 +145,19 @@ Whatever the results of your checks above, we now need to check if your GitLab d
# Run this command with root privileges, replace the data dir if different: # Run this command with root privileges, replace the data dir if different:
sudo ls -lh /var/lib/mysql/gitlabhq_production/*.frm | wc -l sudo ls -lh /var/lib/mysql/gitlabhq_production/*.frm | wc -l
- **Case 1: a result > 0 for both commands** - **Case 1: a result > 0 for both commands**
Congrats, your GitLab database uses the right InnoDB tablespace format. Congratulations, your GitLab database uses the right InnoDB tablespace format.
However, you must still ensure that any **future tables** created by GitLab will still use the right format: However, you must still ensure that any **future tables** created by GitLab will still use the right format:
- If `SELECT @@innodb_file_per_table` returned **1** previously, your server is running correctly. - If `SELECT @@innodb_file_per_table` returned **1** previously, your server is running correctly.
> It's however a requirement to check *now* that this setting is indeed persisted in your [my.cnf](https://dev.mysql.com/doc/refman/5.7/en/tablespace-enabling.html) file! > It's however a requirement to check *now* that this setting is indeed persisted in your [`my.cnf`](https://dev.mysql.com/doc/refman/5.7/en/innodb-multiple-tablespaces.html) file!
- If `SELECT @@innodb_file_per_table` returned **0** previously, your server is not running correctly. - If `SELECT @@innodb_file_per_table` returned **0** previously, your server is not running correctly.
> [Enable innodb_file_per_table](https://dev.mysql.com/doc/refman/5.7/en/tablespace-enabling.html) by running in a MySQL session as root the command `SET GLOBAL innodb_file_per_table=1, innodb_file_format=Barracuda;` and persist the two settings in your [my.cnf](https://dev.mysql.com/doc/refman/5.7/en/tablespace-enabling.html) file > [Enable innodb_file_per_table](https://dev.mysql.com/doc/refman/5.7/en/innodb-multiple-tablespaces.html) by running in a MySQL session as root the command `SET GLOBAL innodb_file_per_table=1, innodb_file_format=Barracuda;` and persist the two settings in your [`my.cnf`](https://dev.mysql.com/doc/refman/5.7/en/innodb-multiple-tablespaces.html) file.
Now, if you have a **different result** returned by the 2 commands above, it means you have a **mix of tables format** uses in your GitLab database. This can happen if your MySQL server had different values for `innodb_file_per_table` in its life and you updated GitLab at different moments with those inconsistent values. So keep reading. Now, if you have a **different result** returned by the 2 commands above, it means you have a **mix of tables format** uses in your GitLab database. This can happen if your MySQL server had different values for `innodb_file_per_table` in its life and you updated GitLab at different moments with those inconsistent values. So keep reading.
...@@ -172,7 +178,7 @@ Let's enable what we need on the running server: ...@@ -172,7 +178,7 @@ Let's enable what we need on the running server:
# You can now quit the database session # You can now quit the database session
mysql> \q mysql> \q
> Now, **persist** [innodb_file_per_table](https://dev.mysql.com/doc/refman/5.6/en/tablespace-enabling.html) and [innodb_file_format](https://dev.mysql.com/doc/refman/5.6/en/innodb-file-format-enabling.html) in your `my.cnf` file. > Now, **persist** [innodb_file_per_table](https://dev.mysql.com/doc/refman/5.7/en/innodb-multiple-tablespaces.html) and [innodb_file_format](https://dev.mysql.com/doc/refman/5.7/en/innodb-file-format-enabling.html) in your `my.cnf` file.
Ensure at this stage that your GitLab instance is indeed **stopped**. Ensure at this stage that your GitLab instance is indeed **stopped**.
...@@ -184,7 +190,7 @@ Now, let's convert all the GitLab database tables to the new tablespace format: ...@@ -184,7 +190,7 @@ Now, let's convert all the GitLab database tables to the new tablespace format:
# Type the MySQL root password # Type the MySQL root password
mysql > use gitlabhq_production; mysql > use gitlabhq_production;
# Safety check: you should still have those values set as follow: # Safety check: you should still have those values set as follows:
mysql> SELECT @@innodb_file_per_table, @@innodb_file_format; mysql> SELECT @@innodb_file_per_table, @@innodb_file_format;
+-------------------------+----------------------+ +-------------------------+----------------------+
| @@innodb_file_per_table | @@innodb_file_format | | @@innodb_file_per_table | @@innodb_file_format |
...@@ -203,7 +209,7 @@ Now, let's convert all the GitLab database tables to the new tablespace format: ...@@ -203,7 +209,7 @@ Now, let's convert all the GitLab database tables to the new tablespace format:
#### Check for proper InnoDB File Format, Row Format, Large Prefix and tables conversion #### Check for proper InnoDB File Format, Row Format, Large Prefix and tables conversion
We need to check, enable and probably convert your existing GitLab DB tables to use the [Barracuda InnoDB file format](https://dev.mysql.com/doc/refman/5.6/en/innodb-file-format.html), the [DYNAMIC row format](https://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_dynamic_row_format) and [innodb_large_prefix](http://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_large_prefix) as a second prerequisite for supporting **utfb8mb4 with long indexes** used by recent GitLab databases. We need to check, enable and probably convert your existing GitLab DB tables to use the [Barracuda InnoDB file format](https://dev.mysql.com/doc/refman/5.7/en/innodb-file-format.html), the [DYNAMIC row format](https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_dynamic_row_format) and [innodb_large_prefix](http://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_large_prefix) as a second prerequisite for supporting **utfb8mb4 with long indexes** used by recent GitLab databases.
# Login to MySQL # Login to MySQL
mysql -u root -p mysql -u root -p
...@@ -229,7 +235,7 @@ We need to check, enable and probably convert your existing GitLab DB tables to ...@@ -229,7 +235,7 @@ We need to check, enable and probably convert your existing GitLab DB tables to
| utf8 | utf8_general_ci | | utf8 | utf8_general_ci |
+--------------------------+----------------------+ +--------------------------+----------------------+
> Now, ensure that [innodb_file_format](https://dev.mysql.com/doc/refman/5.6/en/tablespace-enabling.html) and [innodb_large_prefix](http://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_large_prefix) are **persisted** in your `my.cnf` file. > Now, ensure that [innodb_file_format](https://dev.mysql.com/doc/refman/5.7/en/innodb-multiple-tablespaces.html) and [innodb_large_prefix](http://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_large_prefix) are **persisted** in your `my.cnf` file.
#### Tables and data conversion to utf8mb4 #### Tables and data conversion to utf8mb4
...@@ -257,7 +263,7 @@ Now that you have a persistent MySQL setup, you can safely upgrade tables after ...@@ -257,7 +263,7 @@ Now that you have a persistent MySQL setup, you can safely upgrade tables after
Ensure your GitLab database configuration file uses a proper connection encoding and collation: Ensure your GitLab database configuration file uses a proper connection encoding and collation:
```sudo -u git -H editor config/database.yml``` `sudo -u git -H editor config/database.yml`
production: production:
adapter: mysql2 adapter: mysql2
...@@ -266,19 +272,19 @@ Ensure your GitLab database configuration file uses a proper connection encoding ...@@ -266,19 +272,19 @@ Ensure your GitLab database configuration file uses a proper connection encoding
[Restart your GitLab instance](../administration/restart_gitlab.md). [Restart your GitLab instance](../administration/restart_gitlab.md).
## MySQL strings limits ## MySQL strings limits
After installation or upgrade, remember to run the `add_limits_mysql` Rake task: After installation or upgrade, remember to run the `add_limits_mysql` Rake task:
**Omnibus GitLab installations** **Omnibus GitLab installations**
```
```sh
sudo gitlab-rake add_limits_mysql sudo gitlab-rake add_limits_mysql
``` ```
**Installations from source** **Installations from source**
``` ```sh
bundle exec rake add_limits_mysql RAILS_ENV=production bundle exec rake add_limits_mysql RAILS_ENV=production
``` ```
......
...@@ -31,7 +31,7 @@ to deploy. ...@@ -31,7 +31,7 @@ to deploy.
TIP: **Tip:** TIP: **Tip:**
For production deployments, we strongly recommend using the For production deployments, we strongly recommend using the
[detailed installation instructions](https://gitlab.com/charts/gitlab/blob/master/doc/installation/README.md) [detailed installation instructions](https://gitlab.com/charts/gitlab/blob/master/doc/installation/index.md)
utilizing [external Postgres, Redis, and object storage](https://gitlab.com/charts/gitlab/tree/master/doc/advanced) services. utilizing [external Postgres, Redis, and object storage](https://gitlab.com/charts/gitlab/tree/master/doc/advanced) services.
### Requirements ### Requirements
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
- The groups will be created as needed, including subgroups - The groups will be created as needed, including subgroups
- The owner of the group will be the first admin - The owner of the group will be the first admin
- Existing projects will be skipped - Existing projects will be skipped
- Projects in hashed storage may be skipped (see [Importing bare repositories from hashed storage](#importing-bare-repositories-from-hashed-storage))
- The existing Git repos will be moved from disk (removed from the original path) - The existing Git repos will be moved from disk (removed from the original path)
## How to use ## How to use
...@@ -26,7 +27,6 @@ sudo -u git mkdir /var/opt/gitlab/git-data/repository-import-<date>/new_group ...@@ -26,7 +27,6 @@ sudo -u git mkdir /var/opt/gitlab/git-data/repository-import-<date>/new_group
If we copy the repos to `/var/opt/gitlab/git-data/repository-import-<date>`, and repo A needs to be under the groups G1 and G2, it will If we copy the repos to `/var/opt/gitlab/git-data/repository-import-<date>`, and repo A needs to be under the groups G1 and G2, it will
have to be created under those folders: `/var/opt/gitlab/git-data/repository-import-<date>/G1/G2/A.git`. have to be created under those folders: `/var/opt/gitlab/git-data/repository-import-<date>/G1/G2/A.git`.
``` ```
sudo cp -r /old/git/foo.git /var/opt/gitlab/git-data/repository-import-<date>/new_group/ sudo cp -r /old/git/foo.git /var/opt/gitlab/git-data/repository-import-<date>/new_group/
...@@ -70,3 +70,73 @@ Processing /var/opt/gitlab/git-data/repository-import-1/group/xyz.git ...@@ -70,3 +70,73 @@ Processing /var/opt/gitlab/git-data/repository-import-1/group/xyz.git
* Skipping repo /var/opt/gitlab/git-data/repository-import-1/@shared/a/b/abcd.git * Skipping repo /var/opt/gitlab/git-data/repository-import-1/@shared/a/b/abcd.git
[...] [...]
``` ```
## Importing bare repositories from hashed storage
### Background
Projects in legacy storage have a directory structure that mirrors their full
project path in GitLab, including their namespace structure. This information is
leveraged by the bare repository importer to import projects into their proper
locations. Each project and its parent namespaces are meaningfully named.
However, the directory structure of projects in hashed storage do not contain
this information. This is beneficial for a variety of reasons, especially
improved performance and data integrity. See
[Repository Storage Types](../administration/repository_storage_types.md) for
more details.
### Which repositories are importable?
#### GitLab 10.3 or earlier
Importing bare repositories from hashed storage is unsupported.
#### GitLab 10.4 and later
To support importing bare repositories from hashed storage, GitLab 10.4 and
later stores the full project path with each repository, in a special section of
the git repository's config file. This section is formatted as follows:
```
[gitlab]
fullpath = gitlab-org/gitlab-ce
```
However, existing repositories were not migrated to include this path.
Bare repositories are importable if the following events occurred to the
repository in GitLab 10.4 and later:
- Created
- Migrated to hashed storage
- Renamed
- Transferred to another namespace
- Ancestor renamed
- Ancestor transferred to another namespace
Bare repositories are **not** importable by GitLab 10.4 and later when all the following are true about the repository:
- It was created in GitLab 10.3 or earlier.
- It was not renamed, transferred, or migrated to hashed storage in GitLab 10.4 and later.
- Its ancestor namespaces were not renamed or transferred in GitLab 10.4 and later.
There is an [open issue to add a migration to make all bare repositories
importable](https://gitlab.com/gitlab-org/gitlab-ce/issues/41776).
Until then, you may wish to manually migrate repositories yourself. You can use
[Rails console](https://docs.gitlab.com/omnibus/maintenance/#starting-a-rails-console-session)
to do so. In a Rails console session, run the following to migrate a project:
```
project = Project.find_by_full_path('gitlab-org/gitlab-ce')
project.write_repository_config
```
In a Rails console session, run the following to migrate all of a namespace's
projects (this may take a while if there are 1000s of projects in a namespace):
```
namespace = Namespace.find_by_full_path('gitlab-org')
namespace.send(:write_projects_repository_config)
```
...@@ -4,9 +4,9 @@ comments: false ...@@ -4,9 +4,9 @@ comments: false
# Additional Resources # Additional Resources
1. GitLab Documentation [http://docs.gitlab.com](http://docs.gitlab.com/) 1. GitLab Documentation: <http://docs.gitlab.com>.
2. GUI Clients [http://git-scm.com/downloads/guis](http://git-scm.com/downloads/guis) 1. GUI Clients: <http://git-scm.com/downloads/guis>.
3. Pro git book [http://git-scm.com/book](http://git-scm.com/book) 1. Pro Git book: <http://git-scm.com/book>.
4. Platzi Course [https://courses.platzi.com/courses/git-gitlab/](https://courses.platzi.com/courses/git-gitlab/) 1. Platzi Course: <https://courses.platzi.com/courses/git-gitlab/>.
5. Code School tutorial [http://try.github.io/](http://try.github.io/) 1. Code School tutorial: <http://try.github.io/>.
6. Contact Us at `subscribers@gitlab.com` 1. Contact us at `subscribers@gitlab.com`.
...@@ -22,7 +22,7 @@ comments: false ...@@ -22,7 +22,7 @@ comments: false
**Additional resources** **Additional resources**
[http://git-scm.com/book/en/Git-Basics-Tagging](http://git-scm.com/book/en/Git-Basics-Tagging) <http://git-scm.com/book/en/Git-Basics-Tagging>
---------- ----------
......
...@@ -385,7 +385,7 @@ Thank you for your hard work! ...@@ -385,7 +385,7 @@ Thank you for your hard work!
- GitLab Documentation: <http://docs.gitlab.com/>. - GitLab Documentation: <http://docs.gitlab.com/>.
- GUI Clients: <http://git-scm.com/downloads/guis>. - GUI Clients: <http://git-scm.com/downloads/guis>.
- Pro git book: <http://git-scm.com/book>. - Pro Git book: <http://git-scm.com/book>.
- Platzi Course: <https://courses.platzi.com/courses/git-gitlab/>. - Platzi Course: <https://courses.platzi.com/courses/git-gitlab/>.
- Code School tutorial: <http://try.github.io/>. - Code School tutorial: <http://try.github.io/>.
- Contact us at `subscribers@gitlab.com`. - Contact us at `subscribers@gitlab.com`.
...@@ -26,7 +26,6 @@ module Gitlab ...@@ -26,7 +26,6 @@ module Gitlab
@repository = repository @repository = repository
@diff_refs = diff_refs @diff_refs = diff_refs
@fallback_diff_refs = fallback_diff_refs @fallback_diff_refs = fallback_diff_refs
@unfolded = false
# Ensure items are collected in the the batch # Ensure items are collected in the the batch
new_blob_lazy new_blob_lazy
...@@ -136,24 +135,6 @@ module Gitlab ...@@ -136,24 +135,6 @@ module Gitlab
Gitlab::Diff::Parser.new.parse(raw_diff.each_line, diff_file: self).to_a Gitlab::Diff::Parser.new.parse(raw_diff.each_line, diff_file: self).to_a
end end
# Changes diff_lines according to the given position. That is,
# it checks whether the position requires blob lines into the diff
# in order to be presented.
def unfold_diff_lines(position)
return unless position
unfolder = Gitlab::Diff::LinesUnfolder.new(self, position)
if unfolder.unfold_required?
@diff_lines = unfolder.unfolded_diff_lines
@unfolded = true
end
end
def unfolded?
@unfolded
end
def highlighted_diff_lines def highlighted_diff_lines
@highlighted_diff_lines ||= @highlighted_diff_lines ||=
Gitlab::Diff::Highlight.new(self, repository: self.repository).highlight Gitlab::Diff::Highlight.new(self, repository: self.repository).highlight
......
...@@ -3,9 +3,9 @@ module Gitlab ...@@ -3,9 +3,9 @@ module Gitlab
class Line class Line
SERIALIZE_KEYS = %i(line_code rich_text text type index old_pos new_pos).freeze SERIALIZE_KEYS = %i(line_code rich_text text type index old_pos new_pos).freeze
attr_reader :line_code, :type, :old_pos, :new_pos attr_reader :line_code, :type, :index, :old_pos, :new_pos
attr_writer :rich_text attr_writer :rich_text
attr_accessor :text, :index attr_accessor :text
def initialize(text, type, index, old_pos, new_pos, parent_file: nil, line_code: nil, rich_text: nil) def initialize(text, type, index, old_pos, new_pos, parent_file: nil, line_code: nil, rich_text: nil)
@text, @type, @index = text, type, index @text, @type, @index = text, type, index
...@@ -19,14 +19,7 @@ module Gitlab ...@@ -19,14 +19,7 @@ module Gitlab
end end
def self.init_from_hash(hash) def self.init_from_hash(hash)
new(hash[:text], new(hash[:text], hash[:type], hash[:index], hash[:old_pos], hash[:new_pos], line_code: hash[:line_code], rich_text: hash[:rich_text])
hash[:type],
hash[:index],
hash[:old_pos],
hash[:new_pos],
parent_file: hash[:parent_file],
line_code: hash[:line_code],
rich_text: hash[:rich_text])
end end
def to_hash def to_hash
......
# frozen_string_literal: true
# Given a position, calculates which Blob lines should be extracted, treated and
# injected in the current diff file lines in order to present a "unfolded" diff.
module Gitlab
module Diff
class LinesUnfolder
include Gitlab::Utils::StrongMemoize
UNFOLD_CONTEXT_SIZE = 3
def initialize(diff_file, position)
@diff_file = diff_file
@blob = diff_file.old_blob
@position = position
@generate_top_match_line = true
@generate_bottom_match_line = true
# These methods update `@generate_top_match_line` and
# `@generate_bottom_match_line`.
@from_blob_line = calculate_from_blob_line!
@to_blob_line = calculate_to_blob_line!
end
# Returns merged diff lines with required blob lines with correct
# positions.
def unfolded_diff_lines
strong_memoize(:unfolded_diff_lines) do
next unless unfold_required?
merged_diff_with_blob_lines
end
end
# Returns the extracted lines from the old blob which should be merged
# with the current diff lines.
def blob_lines
strong_memoize(:blob_lines) do
# Blob lines, unlike diffs, doesn't start with an empty space for
# unchanged line, so the parsing and highlighting step can get fuzzy
# without the following change.
line_prefix = ' '
blob_as_diff_lines = @blob.data.each_line.map { |line| "#{line_prefix}#{line}" }
lines = Gitlab::Diff::Parser.new.parse(blob_as_diff_lines, diff_file: @diff_file).to_a
from = from_blob_line - 1
to = to_blob_line - 1
lines[from..to]
end
end
def unfold_required?
strong_memoize(:unfold_required) do
next false unless @diff_file.text?
next false unless @position.unchanged?
next false if @diff_file.new_file? || @diff_file.deleted_file?
next false unless @position.old_line
# Invalid position (MR import scenario)
next false if @position.old_line > @blob.lines.size
next false if @diff_file.diff_lines.empty?
next false if @diff_file.line_for_position(@position)
next false unless unfold_line
true
end
end
private
attr_reader :from_blob_line, :to_blob_line
def merged_diff_with_blob_lines
lines = @diff_file.diff_lines
match_line = unfold_line
insert_index = bottom? ? -1 : match_line.index
lines -= [match_line] unless bottom?
lines.insert(insert_index, *blob_lines_with_matches)
# The inserted blob lines have invalid indexes, so we need
# to reindex them.
reindex(lines)
lines
end
# Returns 'unchanged' blob lines with recalculated `old_pos` and
# `new_pos` and the recalculated new match line (needed if we for instance
# we unfolded once, but there are still folded lines).
def blob_lines_with_matches
old_pos = from_blob_line
new_pos = from_blob_line + offset
new_blob_lines = []
new_blob_lines.push(top_blob_match_line) if top_blob_match_line
blob_lines.each do |line|
new_blob_lines << Gitlab::Diff::Line.new(line.text, line.type, nil, old_pos, new_pos,
parent_file: @diff_file)
old_pos += 1
new_pos += 1
end
new_blob_lines.push(bottom_blob_match_line) if bottom_blob_match_line
new_blob_lines
end
def reindex(lines)
lines.each_with_index { |line, i| line.index = i }
end
def top_blob_match_line
strong_memoize(:top_blob_match_line) do
next unless @generate_top_match_line
old_pos = from_blob_line
new_pos = from_blob_line + offset
build_match_line(old_pos, new_pos)
end
end
def bottom_blob_match_line
strong_memoize(:bottom_blob_match_line) do
# The bottom line match addition is already handled on
# Diff::File#diff_lines_for_serializer
next if bottom?
next unless @generate_bottom_match_line
position = line_after_unfold_position.old_pos
old_pos = position
new_pos = position + offset
build_match_line(old_pos, new_pos)
end
end
def build_match_line(old_pos, new_pos)
blob_lines_length = blob_lines.length
old_line_ref = [old_pos, blob_lines_length].join(',')
new_line_ref = [new_pos, blob_lines_length].join(',')
new_match_line_str = "@@ -#{old_line_ref}+#{new_line_ref} @@"
Gitlab::Diff::Line.new(new_match_line_str, 'match', nil, old_pos, new_pos)
end
# Returns the first line position that should be extracted
# from `blob_lines`.
def calculate_from_blob_line!
return unless unfold_required?
from = comment_position - UNFOLD_CONTEXT_SIZE
# There's no line before the match if it's in the top-most
# position.
prev_line_number = line_before_unfold_position&.old_pos || 0
if from <= prev_line_number + 1
@generate_top_match_line = false
from = prev_line_number + 1
end
from
end
# Returns the last line position that should be extracted
# from `blob_lines`.
def calculate_to_blob_line!
return unless unfold_required?
to = comment_position + UNFOLD_CONTEXT_SIZE
return to if bottom?
next_line_number = line_after_unfold_position.old_pos
if to >= next_line_number - 1
@generate_bottom_match_line = false
to = next_line_number - 1
end
to
end
def offset
unfold_line.new_pos - unfold_line.old_pos
end
def line_before_unfold_position
return unless index = unfold_line&.index
@diff_file.diff_lines[index - 1] if index > 0
end
def line_after_unfold_position
return unless index = unfold_line&.index
@diff_file.diff_lines[index + 1] if index >= 0
end
def bottom?
strong_memoize(:bottom) do
@position.old_line > last_line.old_pos
end
end
# Returns the line which needed to be expanded in order to send a comment
# in `@position`.
def unfold_line
strong_memoize(:unfold_line) do
next last_line if bottom?
@diff_file.diff_lines.find do |line|
line.old_pos > comment_position && line.type == 'match'
end
end
end
def comment_position
@position.old_line
end
def last_line
@diff_file.diff_lines.last
end
end
end
end
...@@ -101,10 +101,6 @@ module Gitlab ...@@ -101,10 +101,6 @@ module Gitlab
@diff_refs ||= DiffRefs.new(base_sha: base_sha, start_sha: start_sha, head_sha: head_sha) @diff_refs ||= DiffRefs.new(base_sha: base_sha, start_sha: start_sha, head_sha: head_sha)
end end
def unfolded_diff?(repository)
diff_file(repository)&.unfolded?
end
def diff_file(repository) def diff_file(repository)
return @diff_file if defined?(@diff_file) return @diff_file if defined?(@diff_file)
...@@ -138,13 +134,7 @@ module Gitlab ...@@ -138,13 +134,7 @@ module Gitlab
return unless diff_refs.complete? return unless diff_refs.complete?
return unless comparison = diff_refs.compare_in(repository.project) return unless comparison = diff_refs.compare_in(repository.project)
file = comparison.diffs(diff_options).diff_files.first comparison.diffs(diff_options).diff_files.first
# We need to unfold diff lines according to the position in order
# to correctly calculate the line code and trace position changes.
file&.unfold_diff_lines(self)
file
end end
def get_formatter_class(type) def get_formatter_class(type)
......
...@@ -109,6 +109,28 @@ module QA ...@@ -109,6 +109,28 @@ module QA
known_hosts_file.close(true) known_hosts_file.close(true)
end end
def push_with_git_protocol(version, file_name, file_content, commit_message = 'Initial commit')
self.git_protocol = version
add_file(file_name, file_content)
commit(commit_message)
push_changes
fetch_supported_git_protocol
end
def git_protocol=(value)
raise ArgumentError, "Please specify the protocol you would like to use: 0, 1, or 2" unless %w[0 1 2].include?(value.to_s)
run("git config protocol.version #{value}")
end
def fetch_supported_git_protocol
# ls-remote is one command known to respond to Git protocol v2 so we use
# it to get output including the version reported via Git tracing
output = run("git ls-remote #{uri}", "GIT_TRACE_PACKET=1")
output[/git< version (\d+)/, 1] || 'unknown'
end
private private
attr_reader :uri, :username, :password, :known_hosts_file, :private_key_file attr_reader :uri, :username, :password, :known_hosts_file, :private_key_file
...@@ -117,8 +139,8 @@ module QA ...@@ -117,8 +139,8 @@ module QA
!private_key_file.nil? !private_key_file.nil?
end end
def run(command_str) def run(command_str, *extra_env)
command = [env_vars, command_str, '2>&1'].compact.join(' ') command = [env_vars, *extra_env, command_str, '2>&1'].compact.join(' ')
Runtime::Logger.debug "Git: command=[#{command}]" Runtime::Logger.debug "Git: command=[#{command}]"
output, _ = Open3.capture2(command) output, _ = Open3.capture2(command)
......
...@@ -36,6 +36,11 @@ module QA ...@@ -36,6 +36,11 @@ module QA
end end
def select_comments_only_filter def select_comments_only_filter
click_element :discussion_filter
all_elements(:filter_options)[1].click
end
def select_history_only_filter
click_element :discussion_filter click_element :discussion_filter
all_elements(:filter_options).last.click all_elements(:filter_options).last.click
end end
......
...@@ -9,6 +9,16 @@ module QA ...@@ -9,6 +9,16 @@ module QA
attr_writer :personal_access_token attr_writer :personal_access_token
# The environment variables used to indicate if the environment under test
# supports the given feature
SUPPORTED_FEATURES = {
git_protocol_v2: 'QA_CAN_TEST_GIT_PROTOCOL_V2'
}.freeze
def supported_features
SUPPORTED_FEATURES
end
def debug? def debug?
enabled?(ENV['QA_DEBUG'], default: false) enabled?(ENV['QA_DEBUG'], default: false)
end end
...@@ -106,6 +116,15 @@ module QA ...@@ -106,6 +116,15 @@ module QA
raise ArgumentError, "Please provide GITHUB_ACCESS_TOKEN" raise ArgumentError, "Please provide GITHUB_ACCESS_TOKEN"
end end
# Returns true if there is an environment variable that indicates that
# the feature is supported in the environment under test.
# All features are supported by default.
def can_test?(feature)
raise ArgumentError, %Q(Unknown feature "#{feature}") unless SUPPORTED_FEATURES.include? feature
enabled?(ENV[SUPPORTED_FEATURES[feature]], default: true)
end
private private
def enabled?(value, default: true) def enabled?(value, default: true)
......
...@@ -31,6 +31,7 @@ module QA ...@@ -31,6 +31,7 @@ module QA
create_issue create_issue
Page::Project::Issue::Show.perform do |show| Page::Project::Issue::Show.perform do |show|
show.select_all_activities_filter
show.comment('See attached banana for scale', attachment: file_to_attach) show.comment('See attached banana for scale', attachment: file_to_attach)
show.refresh show.refresh
......
...@@ -27,6 +27,11 @@ module QA ...@@ -27,6 +27,11 @@ module QA
expect(show_page).to have_content("made the issue confidential") expect(show_page).to have_content("made the issue confidential")
expect(show_page).to have_content("My own comment") expect(show_page).to have_content("My own comment")
show_page.select_history_only_filter
expect(show_page).to have_content("made the issue confidential")
expect(show_page).not_to have_content("My own comment")
end end
end end
end end
......
# frozen_string_literal: true
module QA
context 'Create' do
describe 'Push over SSH using Git protocol version 2', :requires_git_protocol_v2 do
# Note: If you run this test against GDK make sure you've enabled sshd and
# enabled setting the Git protocol by adding `AcceptEnv GIT_PROTOCOL` to
# `sshd_config`
# See: https://gitlab.com/gitlab-org/gitlab-qa/blob/master/docs/run_qa_against_gdk.md
let(:key_title) { "key for ssh tests #{Time.now.to_f}" }
let(:ssh_key) do
Factory::Resource::SSHKey.fabricate! do |resource|
resource.title = key_title
end
end
def login
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials)
end
around do |example|
# Create an SSH key to be used with Git
login
ssh_key
example.run
# Remove the SSH key
login
Page::Main::Menu.perform(&:go_to_profile_settings)
Page::Profile::Menu.perform(&:click_ssh_keys)
Page::Profile::SSHKeys.perform do |ssh_keys|
ssh_keys.remove_key(key_title)
end
end
it 'user pushes to the repository' do
# Create a project to push to
project = Factory::Resource::Project.fabricate! do |project|
project.name = 'git-protocol-project'
end
file_name = 'README.md'
file_content = 'Test Git protocol v2'
git_protocol = '2'
git_protocol_reported = nil
# Use Git to clone the project, push a file to it, and then check the
# supported Git protocol
Git::Repository.perform do |repository|
username = 'GitLab QA'
email = 'root@gitlab.com'
repository.uri = project.repository_ssh_location.uri
begin
repository.use_ssh_key(ssh_key)
repository.clone
repository.configure_identity(username, email)
git_protocol_reported = repository.push_with_git_protocol(
git_protocol,
file_name,
file_content)
ensure
repository.delete_ssh_key
end
end
project.visit!
Page::Project::Show.perform(&:wait_for_push)
# Check that the push worked
expect(page).to have_content(file_name)
expect(page).to have_content(file_content)
# And check that the correct Git protocol was used
expect(git_protocol_reported).to eq(git_protocol)
end
end
end
end
...@@ -26,6 +26,10 @@ module QA ...@@ -26,6 +26,10 @@ module QA
args.push(%w[--tag ~skip_signup_disabled]) if QA::Runtime::Env.signup_disabled? args.push(%w[--tag ~skip_signup_disabled]) if QA::Runtime::Env.signup_disabled?
QA::Runtime::Env.supported_features.each_key do |key|
args.push(["--tag", "~requires_#{key}"]) unless QA::Runtime::Env.can_test? key
end
args.push(options) args.push(options)
args.push(DEFAULT_TEST_PATH_ARGS) unless options.any? { |opt| opt =~ %r{/features/} } args.push(DEFAULT_TEST_PATH_ARGS) unless options.any? { |opt| opt =~ %r{/features/} }
......
...@@ -26,6 +26,36 @@ describe QA::Git::Repository do ...@@ -26,6 +26,36 @@ describe QA::Git::Repository do
end end
end end
describe '#git_protocol=' do
[0, 1, 2].each do |version|
it "configures git to use protocol version #{version}" do
expect(repository).to receive(:run).with("git config protocol.version #{version}")
repository.git_protocol = version
end
end
it 'raises an error if the version is unsupported' do
expect { repository.git_protocol = 'foo' }.to raise_error(ArgumentError, "Please specify the protocol you would like to use: 0, 1, or 2")
end
end
describe '#fetch_supported_git_protocol' do
it "reports the detected version" do
expect(repository).to receive(:run).and_return("packet: git< version 2")
expect(repository.fetch_supported_git_protocol).to eq('2')
end
it 'reports unknown if version is unknown' do
expect(repository).to receive(:run).and_return("packet: git< version -1")
expect(repository.fetch_supported_git_protocol).to eq('unknown')
end
it 'reports unknown if content does not identify a version' do
expect(repository).to receive(:run).and_return("foo")
expect(repository.fetch_supported_git_protocol).to eq('unknown')
end
end
def cd_empty_temp_directory def cd_empty_temp_directory
tmp_dir = 'tmp/git-repository-spec/' tmp_dir = 'tmp/git-repository-spec/'
FileUtils.rm_rf(tmp_dir) if ::File.exist?(tmp_dir) FileUtils.rm_rf(tmp_dir) if ::File.exist?(tmp_dir)
......
...@@ -3,49 +3,62 @@ ...@@ -3,49 +3,62 @@
describe QA::Runtime::Env do describe QA::Runtime::Env do
include Support::StubENV include Support::StubENV
shared_examples 'boolean method' do |method, env_key, default| shared_examples 'boolean method' do |**kwargs|
it_behaves_like 'boolean method with parameter', kwargs
end
shared_examples 'boolean method with parameter' do |method:, param: nil, env_key:, default:|
context 'when there is an env variable set' do context 'when there is an env variable set' do
it 'returns false when falsey values specified' do it 'returns false when falsey values specified' do
stub_env(env_key, 'false') stub_env(env_key, 'false')
expect(described_class.public_send(method)).to be_falsey expect(described_class.public_send(method, *param)).to be_falsey
stub_env(env_key, 'no') stub_env(env_key, 'no')
expect(described_class.public_send(method)).to be_falsey expect(described_class.public_send(method, *param)).to be_falsey
stub_env(env_key, '0') stub_env(env_key, '0')
expect(described_class.public_send(method)).to be_falsey expect(described_class.public_send(method, *param)).to be_falsey
end end
it 'returns true when anything else specified' do it 'returns true when anything else specified' do
stub_env(env_key, 'true') stub_env(env_key, 'true')
expect(described_class.public_send(method)).to be_truthy expect(described_class.public_send(method, *param)).to be_truthy
stub_env(env_key, '1') stub_env(env_key, '1')
expect(described_class.public_send(method)).to be_truthy expect(described_class.public_send(method, *param)).to be_truthy
stub_env(env_key, 'anything') stub_env(env_key, 'anything')
expect(described_class.public_send(method)).to be_truthy expect(described_class.public_send(method, *param)).to be_truthy
end end
end end
context 'when there is no env variable set' do context 'when there is no env variable set' do
it "returns the default, #{default}" do it "returns the default, #{default}" do
stub_env(env_key, nil) stub_env(env_key, nil)
expect(described_class.public_send(method)).to be(default) expect(described_class.public_send(method, *param)).to be(default)
end end
end end
end end
describe '.signup_disabled?' do describe '.signup_disabled?' do
it_behaves_like 'boolean method', :signup_disabled?, 'SIGNUP_DISABLED', false it_behaves_like 'boolean method',
method: :signup_disabled?,
env_key: 'SIGNUP_DISABLED',
default: false
end end
describe '.debug?' do describe '.debug?' do
it_behaves_like 'boolean method', :debug?, 'QA_DEBUG', false it_behaves_like 'boolean method',
method: :debug?,
env_key: 'QA_DEBUG',
default: false
end end
describe '.chrome_headless?' do describe '.chrome_headless?' do
it_behaves_like 'boolean method', :chrome_headless?, 'CHROME_HEADLESS', true it_behaves_like 'boolean method',
method: :chrome_headless?,
env_key: 'CHROME_HEADLESS',
default: true
end end
describe '.running_in_ci?' do describe '.running_in_ci?' do
...@@ -182,4 +195,16 @@ describe QA::Runtime::Env do ...@@ -182,4 +195,16 @@ describe QA::Runtime::Env do
expect(described_class.log_destination).to eq('path/to_file') expect(described_class.log_destination).to eq('path/to_file')
end end
end end
describe '.can_test?' do
it_behaves_like 'boolean method with parameter',
method: :can_test?,
param: :git_protocol_v2,
env_key: 'QA_CAN_TEST_GIT_PROTOCOL_V2',
default: true
it 'raises ArgumentError if feature is unknown' do
expect { described_class.can_test? :foo }.to raise_error(ArgumentError, 'Unknown feature "foo"')
end
end
end end
...@@ -76,6 +76,20 @@ describe QA::Specs::Runner do ...@@ -76,6 +76,20 @@ describe QA::Specs::Runner do
end end
end end
context 'when git protocol v2 is not supported' do
before do
allow(QA::Runtime::Env).to receive(:can_test?).with(:git_protocol_v2).and_return(false)
end
subject { described_class.new }
it 'it includes default args and excludes the requires_git_protocol_v2 tag' do
expect_rspec_runner_arguments(['--tag', '~orchestrated', '--tag', '~requires_git_protocol_v2', *described_class::DEFAULT_TEST_PATH_ARGS])
subject.perform
end
end
def expect_rspec_runner_arguments(arguments) def expect_rspec_runner_arguments(arguments)
expect(RSpec::Core::Runner).to receive(:run) expect(RSpec::Core::Runner).to receive(:run)
.with(arguments, $stderr, $stdout) .with(arguments, $stderr, $stdout)
......
...@@ -107,7 +107,8 @@ module Trigger ...@@ -107,7 +107,8 @@ module Trigger
{ {
'GITLAB_VERSION' => ENV['CI_COMMIT_SHA'], 'GITLAB_VERSION' => ENV['CI_COMMIT_SHA'],
'ALTERNATIVE_SOURCES' => 'true', 'ALTERNATIVE_SOURCES' => 'true',
'ee' => Trigger.ee? ? 'true' : 'false' 'ee' => Trigger.ee? ? 'true' : 'false',
'QA_BRANCH' => ENV['QA_BRANCH'] || 'master'
} }
end end
end end
......
...@@ -157,7 +157,7 @@ describe Projects::BlobController do ...@@ -157,7 +157,7 @@ describe Projects::BlobController do
match_line = JSON.parse(response.body).first match_line = JSON.parse(response.body).first
expect(match_line['type']).to be_nil expect(match_line['type']).to eq('context')
end end
it 'adds bottom match line when "t"o is less than blob size' do it 'adds bottom match line when "t"o is less than blob size' do
...@@ -177,7 +177,7 @@ describe Projects::BlobController do ...@@ -177,7 +177,7 @@ describe Projects::BlobController do
match_line = JSON.parse(response.body).last match_line = JSON.parse(response.body).last
expect(match_line['type']).to be_nil expect(match_line['type']).to eq('context')
end end
end end
end end
......
...@@ -85,13 +85,12 @@ describe 'Merge request > User posts diff notes', :js do ...@@ -85,13 +85,12 @@ describe 'Merge request > User posts diff notes', :js do
# `.line_holder` will be an unfolded line. # `.line_holder` will be an unfolded line.
let(:line_holder) { first('#a5cc2925ca8258af241be7e5b0381edf30266302 .line_holder') } let(:line_holder) { first('#a5cc2925ca8258af241be7e5b0381edf30266302 .line_holder') }
it 'allows commenting on the left side' do it 'does not allow commenting on the left side' do
should_allow_commenting(line_holder, 'left') should_not_allow_commenting(line_holder, 'left')
end end
it 'allows commenting on the right side' do it 'does not allow commenting on the right side' do
# Automatically shifts comment box to left side. should_not_allow_commenting(line_holder, 'right')
should_allow_commenting(line_holder, 'right')
end end
end end
end end
...@@ -148,8 +147,8 @@ describe 'Merge request > User posts diff notes', :js do ...@@ -148,8 +147,8 @@ describe 'Merge request > User posts diff notes', :js do
# `.line_holder` will be an unfolded line. # `.line_holder` will be an unfolded line.
let(:line_holder) { first('.line_holder[id="a5cc2925ca8258af241be7e5b0381edf30266302_1_1"]') } let(:line_holder) { first('.line_holder[id="a5cc2925ca8258af241be7e5b0381edf30266302_1_1"]') }
it 'allows commenting' do it 'does not allow commenting' do
should_allow_commenting line_holder should_not_allow_commenting line_holder
end end
end end
......
...@@ -98,7 +98,7 @@ describe('DiffsStoreMutations', () => { ...@@ -98,7 +98,7 @@ describe('DiffsStoreMutations', () => {
it('should call utils.addContextLines with proper params', () => { it('should call utils.addContextLines with proper params', () => {
const options = { const options = {
lineNumbers: { oldLineNumber: 1, newLineNumber: 2 }, lineNumbers: { oldLineNumber: 1, newLineNumber: 2 },
contextLines: [{ oldLine: 1, newLine: 1, lineCode: 'ff9200_1_1', discussions: [] }], contextLines: [{ oldLine: 1 }],
fileHash: 'ff9200', fileHash: 'ff9200',
params: { params: {
bottom: true, bottom: true,
...@@ -110,7 +110,7 @@ describe('DiffsStoreMutations', () => { ...@@ -110,7 +110,7 @@ describe('DiffsStoreMutations', () => {
parallelDiffLines: [], parallelDiffLines: [],
}; };
const state = { diffFiles: [diffFile] }; const state = { diffFiles: [diffFile] };
const lines = [{ oldLine: 1, newLine: 1 }]; const lines = [{ oldLine: 1 }];
const findDiffFileSpy = spyOnDependency(mutations, 'findDiffFile').and.returnValue(diffFile); const findDiffFileSpy = spyOnDependency(mutations, 'findDiffFile').and.returnValue(diffFile);
const removeMatchLineSpy = spyOnDependency(mutations, 'removeMatchLine'); const removeMatchLineSpy = spyOnDependency(mutations, 'removeMatchLine');
......
...@@ -118,6 +118,16 @@ describe Gitlab::Ci::Config::Entry::Job do ...@@ -118,6 +118,16 @@ describe Gitlab::Ci::Config::Entry::Job do
end end
end end
context 'when it is bigger than 50' do
let(:config) { { parallel: 51 } }
it 'returns error about value too high' do
expect(entry).not_to be_valid
expect(entry.errors)
.to include 'job parallel must be less than or equal to 50'
end
end
context 'when it is not an integer' do context 'when it is not an integer' do
let(:config) { { parallel: 1.5 } } let(:config) { { parallel: 1.5 } }
......
...@@ -41,52 +41,6 @@ describe Gitlab::Diff::File do ...@@ -41,52 +41,6 @@ describe Gitlab::Diff::File do
end end
end end
describe '#unfold_diff_lines' do
let(:unfolded_lines) { double('expanded-lines') }
let(:unfolder) { instance_double(Gitlab::Diff::LinesUnfolder) }
let(:position) { instance_double(Gitlab::Diff::Position, old_line: 10) }
before do
allow(Gitlab::Diff::LinesUnfolder).to receive(:new) { unfolder }
end
context 'when unfold required' do
before do
allow(unfolder).to receive(:unfold_required?) { true }
allow(unfolder).to receive(:unfolded_diff_lines) { unfolded_lines }
end
it 'changes @unfolded to true' do
diff_file.unfold_diff_lines(position)
expect(diff_file).to be_unfolded
end
it 'updates @diff_lines' do
diff_file.unfold_diff_lines(position)
expect(diff_file.diff_lines).to eq(unfolded_lines)
end
end
context 'when unfold not required' do
before do
allow(unfolder).to receive(:unfold_required?) { false }
end
it 'keeps @unfolded false' do
diff_file.unfold_diff_lines(position)
expect(diff_file).not_to be_unfolded
end
it 'does not update @diff_lines' do
expect { diff_file.unfold_diff_lines(position) }
.not_to change(diff_file, :diff_lines)
end
end
end
describe '#mode_changed?' do describe '#mode_changed?' do
it { expect(diff_file.mode_changed?).to be_falsey } it { expect(diff_file.mode_changed?).to be_falsey }
end end
......
This diff is collapsed.
...@@ -31,11 +31,32 @@ describe MergeRequests::ReloadDiffsService, :use_clean_rails_memory_store_cachin ...@@ -31,11 +31,32 @@ describe MergeRequests::ReloadDiffsService, :use_clean_rails_memory_store_cachin
end end
context 'cache clearing' do context 'cache clearing' do
before do
allow_any_instance_of(Gitlab::Diff::File).to receive(:text?).and_return(true)
allow_any_instance_of(Gitlab::Diff::File).to receive(:diffable?).and_return(true)
end
it 'retrieves the diff files to cache the highlighted result' do
new_diff = merge_request.create_merge_request_diff
cache_key = new_diff.diffs_collection.cache_key
expect(merge_request).to receive(:create_merge_request_diff).and_return(new_diff)
expect(Rails.cache).to receive(:read).with(cache_key).and_call_original
expect(Rails.cache).to receive(:write).with(cache_key, anything, anything).and_call_original
subject.execute
end
it 'clears the cache for older diffs on the merge request' do it 'clears the cache for older diffs on the merge request' do
old_diff = merge_request.merge_request_diff old_diff = merge_request.merge_request_diff
old_cache_key = old_diff.diffs_collection.cache_key old_cache_key = old_diff.diffs_collection.cache_key
new_diff = merge_request.create_merge_request_diff
new_cache_key = new_diff.diffs_collection.cache_key
expect(merge_request).to receive(:create_merge_request_diff).and_return(new_diff)
expect(Rails.cache).to receive(:delete).with(old_cache_key).and_call_original expect(Rails.cache).to receive(:delete).with(old_cache_key).and_call_original
expect(Rails.cache).to receive(:read).with(new_cache_key).and_call_original
expect(Rails.cache).to receive(:write).with(new_cache_key, anything, anything).and_call_original
subject.execute subject.execute
end end
......
...@@ -57,57 +57,6 @@ describe Notes::CreateService do ...@@ -57,57 +57,6 @@ describe Notes::CreateService do
end end
end end
context 'noteable highlight cache clearing' do
let(:project_with_repo) { create(:project, :repository) }
let(:merge_request) do
create(:merge_request, source_project: project_with_repo,
target_project: project_with_repo)
end
let(:position) do
Gitlab::Diff::Position.new(old_path: "files/ruby/popen.rb",
new_path: "files/ruby/popen.rb",
old_line: nil,
new_line: 14,
diff_refs: merge_request.diff_refs)
end
let(:new_opts) do
opts.merge(in_reply_to_discussion_id: nil,
type: 'DiffNote',
noteable_type: 'MergeRequest',
noteable_id: merge_request.id,
position: position.to_h)
end
before do
allow_any_instance_of(Gitlab::Diff::Position)
.to receive(:unfolded_diff?) { true }
end
it 'clears noteable diff cache when it was unfolded for the note position' do
expect_any_instance_of(Gitlab::Diff::HighlightCache).to receive(:clear)
described_class.new(project_with_repo, user, new_opts).execute
end
it 'does not clear cache when note is not the first of the discussion' do
prev_note =
create(:diff_note_on_merge_request, noteable: merge_request,
project: project_with_repo)
reply_opts =
opts.merge(in_reply_to_discussion_id: prev_note.discussion_id,
type: 'DiffNote',
noteable_type: 'MergeRequest',
noteable_id: merge_request.id,
position: position.to_h)
expect(merge_request).not_to receive(:diffs)
described_class.new(project_with_repo, user, reply_opts).execute
end
end
context 'note diff file' do context 'note diff file' do
let(:project_with_repo) { create(:project, :repository) } let(:project_with_repo) { create(:project, :repository) }
let(:merge_request) do let(:merge_request) do
......
...@@ -21,38 +21,5 @@ describe Notes::DestroyService do ...@@ -21,38 +21,5 @@ describe Notes::DestroyService do
expect { described_class.new(project, user).execute(note) } expect { described_class.new(project, user).execute(note) }
.to change { user.todos_pending_count }.from(1).to(0) .to change { user.todos_pending_count }.from(1).to(0)
end end
context 'noteable highlight cache clearing' do
let(:repo_project) { create(:project, :repository) }
let(:merge_request) do
create(:merge_request, source_project: repo_project,
target_project: repo_project)
end
let(:note) do
create(:diff_note_on_merge_request, project: repo_project,
noteable: merge_request)
end
before do
allow(note.position).to receive(:unfolded_diff?) { true }
end
it 'clears noteable diff cache when it was unfolded for the note position' do
expect(merge_request).to receive_message_chain(:diffs, :clear_cache)
described_class.new(repo_project, user).execute(note)
end
it 'does not clear cache when note is not the first of the discussion' do
reply_note = create(:diff_note_on_merge_request, in_reply_to: note,
project: repo_project,
noteable: merge_request)
expect(merge_request).not_to receive(:diffs)
described_class.new(repo_project, user).execute(reply_note)
end
end
end end
end end
# Built application files # Built application files
*.apk *.apk
*.ap_ *.ap_
*.aab
# Files for the ART/Dalvik VM # Files for the ART/Dalvik VM
*.dex *.dex
...@@ -43,8 +44,9 @@ captures/ ...@@ -43,8 +44,9 @@ captures/
.idea/caches .idea/caches
# Keystore files # Keystore files
# Uncomment the following line if you do not want to check your keystore files in. # Uncomment the following lines if you do not want to check your keystore files in.
#*.jks #*.jks
#*.keystore
# External native build folder generated in Android Studio 2.2 and later # External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild .externalNativeBuild
......
...@@ -64,3 +64,6 @@ __recovery/ ...@@ -64,3 +64,6 @@ __recovery/
# Castalia statistics file (since XE7 Castalia is distributed with Delphi) # Castalia statistics file (since XE7 Castalia is distributed with Delphi)
*.stat *.stat
# Boss dependency manager vendor folder https://github.com/HashLoad/boss
modules/
...@@ -7,3 +7,4 @@ erl_crash.dump ...@@ -7,3 +7,4 @@ erl_crash.dump
*.ez *.ez
*.beam *.beam
/config/*.secret.exs /config/*.secret.exs
.elixir_ls/
# JPEG
*.jpg
*.jpeg
*.jpe
*.jif
*.jfif
*.jfi
# JPEG 2000
*.jp2
*.j2k
*.jpf
*.jpx
*.jpm
*.mj2
# JPEG XR
*.jxr
*.hdp
*.wdp
# Graphics Interchange Format
*.gif
# RAW
*.raw
# Web P
*.webp
# Portable Network Graphics
*.png
# Animated Portable Network Graphics
*.apng
# Multiple-image Network Graphics
*.mng
# Tagged Image File Format
*.tiff
*.tif
# Scalable Vector Graphics
*.svg
*.svgz
# Portable Document Format
*.pdf
# X BitMap
*.xbm
# BMP
*.bmp
*.dib
# ICO
*.ico
# 3D Images
*.3dm
*.max
nbproject/private/ **/nbproject/private/
build/ build/
nbbuild/ nbbuild/
dist/ dist/
......
# Project Settings
*.cywrk.*
*.cyprj.*
# Generated Assets and Resources
Debug/
Release/
Export/
*/codegentemp
*/Generated_Source
*_datasheet.pdf
*_timing.html
*.cycdx
*.cyfit
*.rpt
*.svd
*.log
*.zip
...@@ -2,17 +2,11 @@ ...@@ -2,17 +2,11 @@
# #
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## User settings ## Build generated
xcuserdata/
## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
*.xcscmblueprint
*.xccheckout
## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
build/ build/
DerivedData/ DerivedData/
*.moved-aside
## Various settings
*.pbxuser *.pbxuser
!default.pbxuser !default.pbxuser
*.mode1v3 *.mode1v3
...@@ -21,3 +15,65 @@ DerivedData/ ...@@ -21,3 +15,65 @@ DerivedData/
!default.mode2v3 !default.mode2v3
*.perspectivev3 *.perspectivev3
!default.perspectivev3 !default.perspectivev3
xcuserdata/
## Other
*.moved-aside
*.xccheckout
*.xcscmblueprint
## Obj-C/Swift specific
*.hmap
*.ipa
*.dSYM.zip
*.dSYM
## Playgrounds
timeline.xctimeline
playground.xcworkspace
# Swift Package Manager
#
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
# Packages/
# Package.pins
# Package.resolved
.build/
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
#
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/#source-control
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output
# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode
iOSInjectionProject/
vendor/ /vendor/
node_modules/ node_modules/
npm-debug.log npm-debug.log
yarn-error.log yarn-error.log
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
# Magento Default Files # # Magento Default Files #
#--------------------------# #--------------------------#
/PATCH_*.sh
/app/etc/local.xml /app/etc/local.xml
/media/* /media/*
......
...@@ -71,3 +71,6 @@ typings/ ...@@ -71,3 +71,6 @@ typings/
# Serverless directories # Serverless directories
.serverless .serverless
# FuseBox cache
.fusebox/
...@@ -109,3 +109,6 @@ venv.bak/ ...@@ -109,3 +109,6 @@ venv.bak/
.mypy_cache/ .mypy_cache/
.dmypy.json .dmypy.json
dmypy.json dmypy.json
# Pyre type checker
.pyre/
...@@ -50,6 +50,7 @@ node_modules/ ...@@ -50,6 +50,7 @@ node_modules/
# Ignore precompiled javascript packs # Ignore precompiled javascript packs
/public/packs /public/packs
/public/packs-test /public/packs-test
/public/assets
# Ignore yarn files # Ignore yarn files
/yarn-error.log /yarn-error.log
......
...@@ -23,6 +23,7 @@ ExportedObj/ ...@@ -23,6 +23,7 @@ ExportedObj/
*.svd *.svd
*.pdb *.pdb
*.opendb *.opendb
*.VC.db
# Unity3D generated meta files # Unity3D generated meta files
*.pidb.meta *.pidb.meta
......
...@@ -67,8 +67,9 @@ ...@@ -67,8 +67,9 @@
@babel/template,7.1.2,MIT @babel/template,7.1.2,MIT
@babel/traverse,7.1.0,MIT @babel/traverse,7.1.0,MIT
@babel/types,7.1.2,MIT @babel/types,7.1.2,MIT
@gitlab-org/gitlab-svgs,1.32.0,MIT
@gitlab-org/gitlab-ui,1.10.0,MIT
@gitlab/svgs,1.35.0,MIT @gitlab/svgs,1.35.0,MIT
@gitlab-org/gitlab-ui,1.8.0,MIT
@sindresorhus/is,0.7.0,MIT @sindresorhus/is,0.7.0,MIT
@types/jquery,2.0.48,MIT @types/jquery,2.0.48,MIT
@vue/component-compiler-utils,2.2.0,MIT @vue/component-compiler-utils,2.2.0,MIT
...@@ -133,7 +134,6 @@ asciidoctor,1.5.6.2,MIT ...@@ -133,7 +134,6 @@ asciidoctor,1.5.6.2,MIT
asciidoctor-plantuml,0.0.8,MIT asciidoctor-plantuml,0.0.8,MIT
asn1.js,4.10.1,MIT asn1.js,4.10.1,MIT
assert,1.4.1,MIT assert,1.4.1,MIT
asset_sync,2.4.0,MIT
assign-symbols,1.0.0,MIT assign-symbols,1.0.0,MIT
async-each,1.0.1,MIT async-each,1.0.1,MIT
async-limiter,1.0.0,MIT async-limiter,1.0.0,MIT
...@@ -161,7 +161,6 @@ big.js,3.2.0,MIT ...@@ -161,7 +161,6 @@ big.js,3.2.0,MIT
binary-extensions,1.11.0,MIT binary-extensions,1.11.0,MIT
binaryextensions,2.1.1,MIT binaryextensions,2.1.1,MIT
bindata,2.4.3,ruby bindata,2.4.3,ruby
blackst0ne-mermaid,7.1.0-fixed,MIT
bluebird,3.5.1,MIT bluebird,3.5.1,MIT
bn.js,4.11.8,MIT bn.js,4.11.8,MIT
body-parser,1.18.2,MIT body-parser,1.18.2,MIT
...@@ -264,8 +263,8 @@ css-selector-tokenizer,0.7.0,MIT ...@@ -264,8 +263,8 @@ css-selector-tokenizer,0.7.0,MIT
css_parser,1.5.0,MIT css_parser,1.5.0,MIT
cssesc,0.1.0,MIT cssesc,0.1.0,MIT
cyclist,0.2.2,MIT* cyclist,0.2.2,MIT*
d3,3.5.17,New BSD
d3,4.12.2,New BSD d3,4.12.2,New BSD
d3,4.13.0,New BSD
d3-array,1.2.1,New BSD d3-array,1.2.1,New BSD
d3-axis,1.0.8,New BSD d3-axis,1.0.8,New BSD
d3-brush,1.0.4,New BSD d3-brush,1.0.4,New BSD
...@@ -278,6 +277,7 @@ d3-dsv,1.0.8,New BSD ...@@ -278,6 +277,7 @@ d3-dsv,1.0.8,New BSD
d3-ease,1.0.3,New BSD d3-ease,1.0.3,New BSD
d3-force,1.1.0,New BSD d3-force,1.1.0,New BSD
d3-format,1.2.1,New BSD d3-format,1.2.1,New BSD
d3-format,1.2.2,New BSD
d3-geo,1.9.1,New BSD d3-geo,1.9.1,New BSD
d3-hierarchy,1.1.5,New BSD d3-hierarchy,1.1.5,New BSD
d3-interpolate,1.1.6,New BSD d3-interpolate,1.1.6,New BSD
...@@ -289,6 +289,7 @@ d3-random,1.1.0,New BSD ...@@ -289,6 +289,7 @@ d3-random,1.1.0,New BSD
d3-request,1.0.6,New BSD d3-request,1.0.6,New BSD
d3-scale,1.0.7,New BSD d3-scale,1.0.7,New BSD
d3-selection,1.2.0,New BSD d3-selection,1.2.0,New BSD
d3-selection,1.3.0,New BSD
d3-shape,1.2.0,New BSD d3-shape,1.2.0,New BSD
d3-time,1.0.8,New BSD d3-time,1.0.8,New BSD
d3-time-format,2.1.1,New BSD d3-time-format,2.1.1,New BSD
...@@ -296,8 +297,8 @@ d3-timer,1.0.7,New BSD ...@@ -296,8 +297,8 @@ d3-timer,1.0.7,New BSD
d3-transition,1.1.1,New BSD d3-transition,1.1.1,New BSD
d3-voronoi,1.1.2,New BSD d3-voronoi,1.1.2,New BSD
d3-zoom,1.7.1,New BSD d3-zoom,1.7.1,New BSD
dagre-d3-renderer,0.4.24,MIT dagre-d3-renderer,0.5.8,MIT
dagre-layout,0.8.0,MIT dagre-layout,0.8.8,MIT
date-now,0.1.4,MIT date-now,0.1.4,MIT
dateformat,3.0.3,MIT dateformat,3.0.3,MIT
de-indent,1.0.2,MIT de-indent,1.0.2,MIT
...@@ -328,7 +329,6 @@ device_detector,1.0.0,LGPL ...@@ -328,7 +329,6 @@ device_detector,1.0.0,LGPL
devise,4.4.3,MIT devise,4.4.3,MIT
devise-two-factor,3.0.0,MIT devise-two-factor,3.0.0,MIT
diff,3.5.0,New BSD diff,3.5.0,New BSD
diff-lcs,1.3,"MIT,Artistic-2.0,GPL-2.0+"
diffie-hellman,5.0.2,MIT diffie-hellman,5.0.2,MIT
diffy,3.1.0,MIT diffy,3.1.0,MIT
document-register-element,1.3.0,MIT document-register-element,1.3.0,MIT
...@@ -370,6 +370,7 @@ es6-promise,3.0.2,MIT ...@@ -370,6 +370,7 @@ es6-promise,3.0.2,MIT
escape-html,1.0.3,MIT escape-html,1.0.3,MIT
escape-string-regexp,1.0.5,MIT escape-string-regexp,1.0.5,MIT
escape_utils,1.1.1,MIT escape_utils,1.1.1,MIT
escaper,2.5.3,MIT
eslint-scope,4.0.0,Simplified BSD eslint-scope,4.0.0,Simplified BSD
esrecurse,4.2.1,Simplified BSD esrecurse,4.2.1,Simplified BSD
estraverse,4.2.0,Simplified BSD estraverse,4.2.0,Simplified BSD
...@@ -447,12 +448,8 @@ get-value,2.0.6,MIT ...@@ -447,12 +448,8 @@ get-value,2.0.6,MIT
get_process_mem,0.2.0,MIT get_process_mem,0.2.0,MIT
gettext_i18n_rails,1.8.0,MIT gettext_i18n_rails,1.8.0,MIT
gettext_i18n_rails_js,1.3.0,MIT gettext_i18n_rails_js,1.3.0,MIT
gitaly-proto,0.118.1,MIT gitaly-proto,0.123.0,MIT
github-linguist,5.3.3,MIT
github-markup,1.7.0,MIT github-markup,1.7.0,MIT
gitlab-flowdock-git-hook,1.0.1,MIT
gitlab-gollum-lib,4.2.7.5,MIT
gitlab-grit,2.8.2,MIT
gitlab-markup,1.6.4,MIT gitlab-markup,1.6.4,MIT
gitlab-sidekiq-fetcher,0.3.0,LGPL gitlab-sidekiq-fetcher,0.3.0,LGPL
gitlab_omniauth-ldap,2.0.4,MIT gitlab_omniauth-ldap,2.0.4,MIT
...@@ -461,13 +458,12 @@ glob-parent,3.1.0,ISC ...@@ -461,13 +458,12 @@ glob-parent,3.1.0,ISC
global-modules-path,2.1.0,Apache 2.0 global-modules-path,2.1.0,Apache 2.0
globalid,0.4.1,MIT globalid,0.4.1,MIT
globals,11.7.0,MIT globals,11.7.0,MIT
gollum-grit_adapter,1.0.1,MIT
gon,6.2.0,MIT gon,6.2.0,MIT
good-listener,1.2.2,MIT good-listener,1.2.2,MIT
google-api-client,0.23.4,Apache 2.0 google-api-client,0.23.4,Apache 2.0
google-protobuf,3.5.1,New BSD google-protobuf,3.6.1,New BSD
googleapis-common-protos-types,1.0.1,Apache 2.0 googleapis-common-protos-types,1.0.2,Apache 2.0
googleauth,0.6.2,Apache 2.0 googleauth,0.6.6,Apache 2.0
got,8.3.0,MIT got,8.3.0,MIT
gpgme,2.0.13,LGPL-2.1+ gpgme,2.0.13,LGPL-2.1+
graceful-fs,4.1.11,ISC graceful-fs,4.1.11,ISC
...@@ -476,9 +472,9 @@ grape-entity,0.7.1,MIT ...@@ -476,9 +472,9 @@ grape-entity,0.7.1,MIT
grape-path-helpers,1.0.6,MIT grape-path-helpers,1.0.6,MIT
grape_logging,1.7.0,MIT grape_logging,1.7.0,MIT
graphiql-rails,1.4.10,MIT graphiql-rails,1.4.10,MIT
graphlib,2.1.1,MIT graphlibrary,2.2.0,MIT
graphql,1.8.1,MIT graphql,1.8.1,MIT
grpc,1.11.0,Apache 2.0 grpc,1.15.0,Apache 2.0
gzip-size,5.0.0,MIT gzip-size,5.0.0,MIT
hamlit,2.8.8,MIT hamlit,2.8.8,MIT
hangouts-chat,0.0.5,MIT hangouts-chat,0.0.5,MIT
...@@ -572,6 +568,7 @@ is-plain-obj,1.1.0,MIT ...@@ -572,6 +568,7 @@ is-plain-obj,1.1.0,MIT
is-plain-object,2.0.4,MIT is-plain-object,2.0.4,MIT
is-promise,2.1.0,MIT is-promise,2.1.0,MIT
is-regex,1.0.4,MIT is-regex,1.0.4,MIT
is-regexp,1.0.0,MIT
is-retry-allowed,1.1.0,MIT is-retry-allowed,1.1.0,MIT
is-stream,1.1.0,MIT is-stream,1.1.0,MIT
is-symbol,1.0.2,MIT is-symbol,1.0.2,MIT
...@@ -620,7 +617,6 @@ lazy-cache,2.0.2,MIT ...@@ -620,7 +617,6 @@ lazy-cache,2.0.2,MIT
lcid,2.0.0,MIT lcid,2.0.0,MIT
licensee,8.9.2,MIT licensee,8.9.2,MIT
lie,3.1.1,MIT lie,3.1.1,MIT
little-plugger,1.1.4,MIT
loader-runner,2.3.0,MIT loader-runner,2.3.0,MIT
loader-utils,1.1.0,MIT loader-utils,1.1.0,MIT
locale,2.1.2,"ruby,LGPLv3+" locale,2.1.2,"ruby,LGPLv3+"
...@@ -635,7 +631,6 @@ lodash.get,4.4.2,MIT ...@@ -635,7 +631,6 @@ lodash.get,4.4.2,MIT
lodash.isequal,4.5.0,MIT lodash.isequal,4.5.0,MIT
lodash.mergewith,4.6.0,MIT lodash.mergewith,4.6.0,MIT
lodash.startcase,4.4.0,MIT lodash.startcase,4.4.0,MIT
logging,2.2.2,MIT
lograge,0.10.0,MIT lograge,0.10.0,MIT
loofah,2.2.2,MIT loofah,2.2.2,MIT
loose-envify,1.4.0,MIT loose-envify,1.4.0,MIT
...@@ -658,6 +653,7 @@ memoist,0.16.0,MIT ...@@ -658,6 +653,7 @@ memoist,0.16.0,MIT
memory-fs,0.4.1,MIT memory-fs,0.4.1,MIT
merge-descriptors,1.0.1,MIT merge-descriptors,1.0.1,MIT
merge-source-map,1.1.0,MIT merge-source-map,1.1.0,MIT
mermaid,8.0.0-rc.8,MIT
method_source,0.9.0,MIT method_source,0.9.0,MIT
methods,1.1.2,MIT methods,1.1.2,MIT
micromatch,3.1.10,MIT micromatch,3.1.10,MIT
...@@ -685,11 +681,10 @@ mississippi,2.0.0,Simplified BSD ...@@ -685,11 +681,10 @@ mississippi,2.0.0,Simplified BSD
mississippi,3.0.0,Simplified BSD mississippi,3.0.0,Simplified BSD
mixin-deep,1.3.1,MIT mixin-deep,1.3.1,MIT
mkdirp,0.5.1,MIT mkdirp,0.5.1,MIT
moment,2.19.2,MIT moment,2.22.2,MIT
monaco-editor,0.14.3,MIT monaco-editor,0.14.3,MIT
monaco-editor-webpack-plugin,1.5.4,MIT monaco-editor-webpack-plugin,1.5.4,MIT
mousetrap,1.4.6,Apache 2.0 mousetrap,1.4.6,Apache 2.0
mousetrap-rails,1.4.6,"MIT,Apache"
move-concurrently,1.0.1,ISC move-concurrently,1.0.1,ISC
ms,2.0.0,MIT ms,2.0.0,MIT
ms,2.1.1,MIT ms,2.1.1,MIT
...@@ -760,7 +755,7 @@ opener,1.5.1,(WTFPL OR MIT) ...@@ -760,7 +755,7 @@ opener,1.5.1,(WTFPL OR MIT)
opn,4.0.2,MIT opn,4.0.2,MIT
org-ruby,0.9.12,MIT org-ruby,0.9.12,MIT
orm_adapter,0.5.0,MIT orm_adapter,0.5.0,MIT
os,0.9.6,MIT os,1.0.0,MIT
os-browserify,0.3.0,MIT os-browserify,0.3.0,MIT
os-homedir,1.0.2,MIT os-homedir,1.0.2,MIT
os-locale,3.0.1,MIT os-locale,3.0.1,MIT
...@@ -806,7 +801,6 @@ pkg-dir,3.0.0,MIT ...@@ -806,7 +801,6 @@ pkg-dir,3.0.0,MIT
po_to_json,1.0.1,MIT po_to_json,1.0.1,MIT
popper.js,1.14.3,MIT popper.js,1.14.3,MIT
posix-character-classes,0.1.1,MIT posix-character-classes,0.1.1,MIT
posix-spawn,0.3.13,MIT
postcss,6.0.23,MIT postcss,6.0.23,MIT
postcss-modules-extract-imports,1.2.0,ISC postcss-modules-extract-imports,1.2.0,ISC
postcss-modules-local-by-default,1.2.0,MIT postcss-modules-local-by-default,1.2.0,MIT
...@@ -830,6 +824,8 @@ prr,1.0.1,MIT ...@@ -830,6 +824,8 @@ prr,1.0.1,MIT
pseudomap,1.0.2,ISC pseudomap,1.0.2,ISC
public-encrypt,4.0.0,MIT public-encrypt,4.0.0,MIT
public_suffix,3.0.3,MIT public_suffix,3.0.3,MIT
puma,3.12.0,New BSD
puma_worker_killer,0.1.0,MIT
pump,2.0.1,MIT pump,2.0.1,MIT
pump,3.0.0,MIT pump,3.0.0,MIT
pumpify,1.4.0,MIT pumpify,1.4.0,MIT
...@@ -929,7 +925,7 @@ ruby_parser,3.9.0,MIT ...@@ -929,7 +925,7 @@ ruby_parser,3.9.0,MIT
rubyntlm,0.6.2,MIT rubyntlm,0.6.2,MIT
rubypants,0.2.0,BSD rubypants,0.2.0,BSD
rufus-scheduler,3.4.0,MIT rufus-scheduler,3.4.0,MIT
rugged,0.27.4,MIT rugged,0.27.5,MIT
run-async,2.3.0,MIT run-async,2.3.0,MIT
run-queue,1.0.3,ISC run-queue,1.0.3,ISC
rw,1.3.3,New BSD rw,1.3.3,New BSD
...@@ -949,6 +945,7 @@ sawyer,0.8.1,MIT ...@@ -949,6 +945,7 @@ sawyer,0.8.1,MIT
sax,1.2.4,ISC sax,1.2.4,ISC
schema-utils,0.4.5,MIT schema-utils,0.4.5,MIT
schema-utils,1.0.0,MIT schema-utils,1.0.0,MIT
scope-css,1.2.1,MIT
seed-fu,2.3.7,MIT seed-fu,2.3.7,MIT
select,1.1.2,MIT select,1.1.2,MIT
select2,3.5.2-browserify,Apache* select2,3.5.2-browserify,Apache*
...@@ -975,8 +972,9 @@ shebang-regex,1.0.0,MIT ...@@ -975,8 +972,9 @@ shebang-regex,1.0.0,MIT
sidekiq,5.2.1,LGPL sidekiq,5.2.1,LGPL
sidekiq-cron,0.6.0,MIT sidekiq-cron,0.6.0,MIT
signal-exit,3.0.2,ISC signal-exit,3.0.2,ISC
signet,0.8.1,Apache 2.0 signet,0.11.0,Apache 2.0
slack-notifier,1.5.1,MIT slack-notifier,1.5.1,MIT
slugify,1.3.1,MIT
smooshpack,0.0.48,LGPL smooshpack,0.0.48,LGPL
snapdragon,0.8.1,MIT snapdragon,0.8.1,MIT
snapdragon-node,2.1.1,MIT snapdragon-node,2.1.1,MIT
...@@ -1012,9 +1010,9 @@ string-width,1.0.2,MIT ...@@ -1012,9 +1010,9 @@ string-width,1.0.2,MIT
string-width,2.1.1,MIT string-width,2.1.1,MIT
string_decoder,0.10.31,MIT string_decoder,0.10.31,MIT
string_decoder,1.1.1,MIT string_decoder,1.1.1,MIT
stringex,2.8.4,MIT
strip-ansi,3.0.1,MIT strip-ansi,3.0.1,MIT
strip-ansi,4.0.0,MIT strip-ansi,4.0.0,MIT
strip-css-comments,3.0.0,MIT
strip-eof,1.0.0,MIT strip-eof,1.0.0,MIT
strip-json-comments,2.0.1,MIT strip-json-comments,2.0.1,MIT
style-loader,0.23.0,MIT style-loader,0.23.0,MIT
......
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