Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-04-19 15:08:54 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-04-19 15:08:54 +0300
commit2ef0b7f13d72eee215e3491a8db4623cbcdd845c (patch)
tree17863be2de76defcc7ba52691181275b2ce68881
parent541758119cb1a4e029a2d0fb0551f52f6cf9a511 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.rubocop_todo/database/disable_referential_integrity.yml4
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/assets/javascripts/pipelines/components/graph/stage_column_component.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/child_content.vue26
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/utils.js2
-rw-r--r--app/controllers/projects/graphs_controller.rb2
-rw-r--r--app/presenters/gitlab/blame_presenter.rb4
-rw-r--r--app/views/projects/blame/show.html.haml2
-rw-r--r--doc/development/database/background_migrations.md2
-rw-r--r--lib/gitlab/application_rate_limiter.rb2
-rw-r--r--lib/gitlab/blame.rb13
-rw-r--r--lib/gitlab/git/blame.rb26
-rw-r--r--lib/gitlab/gitaly_client/commit_service.rb5
-rw-r--r--lib/gitlab/graphql/pagination/keyset/generic_keyset_pagination.rb17
-rw-r--r--rubocop/cop/database/disable_referential_integrity.rb32
-rw-r--r--spec/frontend/vue_mr_widget/components/extensions/utils_spec.js2
-rw-r--r--spec/lib/gitlab/blame_spec.rb66
-rw-r--r--spec/lib/gitlab/git/blame_spec.rb117
-rw-r--r--spec/lib/gitlab/gitaly_client/commit_service_spec.rb35
-rw-r--r--spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb11
-rw-r--r--spec/presenters/gitlab/blame_presenter_spec.rb8
-rw-r--r--spec/rubocop/cop/database/disable_referential_integrity_spec.rb36
-rw-r--r--spec/spec_helper.rb2
24 files changed, 318 insertions, 106 deletions
diff --git a/.rubocop_todo/database/disable_referential_integrity.yml b/.rubocop_todo/database/disable_referential_integrity.yml
new file mode 100644
index 00000000000..95cfc5920d4
--- /dev/null
+++ b/.rubocop_todo/database/disable_referential_integrity.yml
@@ -0,0 +1,4 @@
+---
+Database/DisableReferentialIntegrity:
+ Exclude:
+ - 'spec/lib/gitlab/background_migration/cleanup_orphaned_lfs_objects_projects_spec.rb'
diff --git a/Gemfile b/Gemfile
index c802d4a03e3..6f9340ebd7d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -482,7 +482,7 @@ gem 'ssh_data', '~> 1.2'
gem 'spamcheck', '~> 0.1.0'
# Gitaly GRPC protocol definitions
-gem 'gitaly', '~> 14.9.0-rc5'
+gem 'gitaly', '~> 14.10.0-rc1'
# KAS GRPC protocol definitions
gem 'kas-grpc', '~> 0.0.2'
diff --git a/Gemfile.lock b/Gemfile.lock
index a111c89c9bc..9a67aa1b017 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -455,7 +455,7 @@ GEM
rails (>= 3.2.0)
git (1.7.0)
rchardet (~> 1.8)
- gitaly (14.9.0.pre.rc5)
+ gitaly (14.10.0.pre.rc1)
grpc (~> 1.0)
github-markup (1.7.0)
gitlab (4.16.1)
@@ -1494,7 +1494,7 @@ DEPENDENCIES
gettext (~> 3.3)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3)
- gitaly (~> 14.9.0.pre.rc5)
+ gitaly (~> 14.10.0.pre.rc1)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
gitlab-dangerfiles (~> 3.0)
diff --git a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue
index b0f375c9aeb..6ab4eb58977 100644
--- a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue
+++ b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue
@@ -141,7 +141,9 @@ export default {
class="gl-display-flex gl-justify-content-space-between gl-relative"
:class="$options.titleClasses"
>
- <div>{{ formattedTitle }}</div>
+ <span :title="formattedTitle" class="gl-text-truncate gl-pr-3 gl-w-85p">
+ {{ formattedTitle }}
+ </span>
<action-component
v-if="hasAction && canUpdatePipeline"
:action-icon="action.icon"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/child_content.vue b/app/assets/javascripts/vue_merge_request_widget/components/extensions/child_content.vue
index 5f42c6c7acb..5cfee21dd5e 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/child_content.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/child_content.vue
@@ -55,19 +55,21 @@ export default {
<div class="gl-display-flex">
<status-icon v-if="data.icon" :icon-name="data.icon.name" :size="12" class="gl-pl-0" />
<div class="gl-w-full">
- <div class="gl-flex-wrap gl-display-flex gl-w-full">
- <div class="gl-mr-4 gl-display-flex gl-align-items-center">
- <p v-safe-html="generateText(data.text)" class="gl-m-0"></p>
+ <div class="gl-display-flex gl-flex-nowrap">
+ <div class="gl-flex-wrap gl-display-flex gl-w-full">
+ <div class="gl-mr-4 gl-display-flex gl-align-items-center">
+ <p v-safe-html="generateText(data.text)" class="gl-m-0"></p>
+ </div>
+ <div v-if="data.link">
+ <gl-link :href="data.link.href">{{ data.link.text }}</gl-link>
+ </div>
+ <div v-if="data.supportingText">
+ <p v-safe-html="generateText(data.supportingText)" class="gl-m-0"></p>
+ </div>
+ <gl-badge v-if="data.badge" :variant="data.badge.variant || 'info'">
+ {{ data.badge.text }}
+ </gl-badge>
</div>
- <div v-if="data.link">
- <gl-link :href="data.link.href">{{ data.link.text }}</gl-link>
- </div>
- <div v-if="data.supportingText">
- <p v-safe-html="generateText(data.supportingText)" class="gl-m-0"></p>
- </div>
- <gl-badge v-if="data.badge" :variant="data.badge.variant || 'info'">
- {{ data.badge.text }}
- </gl-badge>
<actions :widget="widgetLabel" :tertiary-buttons="data.actions" class="gl-ml-auto" />
</div>
<p
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/utils.js b/app/assets/javascripts/vue_merge_request_widget/components/extensions/utils.js
index 8ba13cf8252..5fba070f79c 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/utils.js
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/utils.js
@@ -32,7 +32,7 @@ const textStyleTags = {
[getStartTag('critical')]: '<span class="gl-font-weight-bold gl-text-red-800">',
[getStartTag('same')]: '<span class="gl-font-weight-bold gl-text-gray-700">',
[getStartTag('strong')]: '<span class="gl-font-weight-bold">',
- [getStartTag('small')]: '<span class="gl-font-sm">',
+ [getStartTag('small')]: '<span class="gl-font-sm gl-text-gray-700">',
};
export const generateText = (text) => {
diff --git a/app/controllers/projects/graphs_controller.rb b/app/controllers/projects/graphs_controller.rb
index d3a05736a47..606f6ac7941 100644
--- a/app/controllers/projects/graphs_controller.rb
+++ b/app/controllers/projects/graphs_controller.rb
@@ -102,3 +102,5 @@ class Projects::GraphsController < Projects::ApplicationController
render json: @log.to_json
end
end
+
+Projects::GraphsController.prepend_mod
diff --git a/app/presenters/gitlab/blame_presenter.rb b/app/presenters/gitlab/blame_presenter.rb
index 2bd1a82b02d..81a954761ea 100644
--- a/app/presenters/gitlab/blame_presenter.rb
+++ b/app/presenters/gitlab/blame_presenter.rb
@@ -28,6 +28,10 @@ module Gitlab
precalculate_data_by_commit!
end
+ def first_line
+ blame.first_line
+ end
+
def groups
@groups ||= blame.groups
end
diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml
index ae8f89bf16a..7f72438c3f9 100644
--- a/app/views/projects/blame/show.html.haml
+++ b/app/views/projects/blame/show.html.haml
@@ -22,7 +22,7 @@
.table-responsive.file-content.blame.code{ class: user_color_scheme }
%table
- - current_line = 1
+ - current_line = @blame.first_line
- @blame.groups.each do |blame_group|
- commit_data = @blame.commit_data(blame_group[:commit])
- line_count = blame_group[:lines].count
diff --git a/doc/development/database/background_migrations.md b/doc/development/database/background_migrations.md
index b5a9566ecdb..1f7e0d76c89 100644
--- a/doc/development/database/background_migrations.md
+++ b/doc/development/database/background_migrations.md
@@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
Background migrations are strongly discouraged in favor of the new [batched background migrations framework](../batched_background_migrations.md).
-Please check that documentation and determine if that framework will suit your needs and fall back
+Please check that documentation and determine if that framework suits your needs and fall back
to these only if required.
Background migrations should be used to perform data migrations whenever a
diff --git a/lib/gitlab/application_rate_limiter.rb b/lib/gitlab/application_rate_limiter.rb
index 2b80b525f3a..09775297def 100644
--- a/lib/gitlab/application_rate_limiter.rb
+++ b/lib/gitlab/application_rate_limiter.rb
@@ -42,7 +42,7 @@ module Gitlab
search_rate_limit: { threshold: -> { application_settings.search_rate_limit }, interval: 1.minute },
search_rate_limit_unauthenticated: { threshold: -> { application_settings.search_rate_limit_unauthenticated }, interval: 1.minute },
gitlab_shell_operation: { threshold: 600, interval: 1.minute },
- pipelines_create: { threshold: 4, interval: 1.minute }
+ pipelines_create: { threshold: 25, interval: 1.minute }
}.freeze
end
diff --git a/lib/gitlab/blame.rb b/lib/gitlab/blame.rb
index 9d3903ac839..e210c18e3d1 100644
--- a/lib/gitlab/blame.rb
+++ b/lib/gitlab/blame.rb
@@ -2,11 +2,16 @@
module Gitlab
class Blame
- attr_accessor :blob, :commit
+ attr_accessor :blob, :commit, :range
- def initialize(blob, commit)
+ def initialize(blob, commit, range: nil)
@blob = blob
@commit = commit
+ @range = range
+ end
+
+ def first_line
+ range&.first || 1
end
def groups(highlight: true)
@@ -14,7 +19,7 @@ module Gitlab
groups = []
current_group = nil
- i = 0
+ i = first_line - 1
blame.each do |commit, line, previous_path|
commit = Commit.new(commit, project)
commit.lazy_author # preload author
@@ -37,7 +42,7 @@ module Gitlab
private
def blame
- @blame ||= Gitlab::Git::Blame.new(repository, @commit.id, @blob.path)
+ @blame ||= Gitlab::Git::Blame.new(repository, @commit.id, @blob.path, range: range)
end
def highlighted_lines
diff --git a/lib/gitlab/git/blame.rb b/lib/gitlab/git/blame.rb
index 702ae5e062d..30977adaea1 100644
--- a/lib/gitlab/git/blame.rb
+++ b/lib/gitlab/git/blame.rb
@@ -5,12 +5,13 @@ module Gitlab
class Blame
include Gitlab::EncodingHelper
- attr_reader :lines, :blames
+ attr_reader :lines, :blames, :range
- def initialize(repository, sha, path)
+ def initialize(repository, sha, path, range: nil)
@repo = repository
@sha = sha
@path = path
+ @range = range
@lines = []
@blames = load_blame
end
@@ -23,13 +24,20 @@ module Gitlab
private
+ def range_spec
+ "#{range.first},#{range.last}" if range
+ end
+
def load_blame
- output = encode_utf8(@repo.gitaly_commit_client.raw_blame(@sha, @path))
+ output = encode_utf8(
+ @repo.gitaly_commit_client.raw_blame(@sha, @path, range: range_spec)
+ )
process_raw_blame(output)
end
def process_raw_blame(output)
+ start_line = nil
lines = []
final = []
info = {}
@@ -47,6 +55,10 @@ module Gitlab
commit_id = m[1]
commits[commit_id] = nil unless commits.key?(commit_id)
info[m[3].to_i] = [commit_id, m[2].to_i]
+
+ # Assumption: the first line returned by git blame is lowest-numbered
+ # This is true unless we start passing it `--incremental`.
+ start_line = m[3].to_i if start_line.nil?
elsif line.start_with?("previous ")
# previous 1485b69e7b839a21436e81be6d3aa70def5ed341 initial-commit
# previous 9521e52704ee6100e7d2a76896a4ef0eb53ff1b8 "\303\2511\\\303\251\\303\\251\n"
@@ -61,7 +73,13 @@ module Gitlab
# get it together
info.sort.each do |lineno, (commit_id, old_lineno)|
- final << BlameLine.new(lineno, old_lineno, commits[commit_id], lines[lineno - 1], previous_paths[commit_id])
+ final << BlameLine.new(
+ lineno,
+ old_lineno,
+ commits[commit_id],
+ lines[lineno - start_line],
+ previous_paths[commit_id]
+ )
end
@lines = final
diff --git a/lib/gitlab/gitaly_client/commit_service.rb b/lib/gitlab/gitaly_client/commit_service.rb
index 3112b47c5cf..4fe5c8df36f 100644
--- a/lib/gitlab/gitaly_client/commit_service.rb
+++ b/lib/gitlab/gitaly_client/commit_service.rb
@@ -315,11 +315,12 @@ module Gitlab
response.languages.map { |l| { value: l.share.round(2), label: l.name, color: l.color, highlight: l.color } }
end
- def raw_blame(revision, path)
+ def raw_blame(revision, path, range:)
request = Gitaly::RawBlameRequest.new(
repository: @gitaly_repo,
revision: encode_binary(revision),
- path: encode_binary(path)
+ path: encode_binary(path),
+ range: (encode_binary(range) if range)
)
response = GitalyClient.call(@repository.storage, :commit_service, :raw_blame, request, timeout: GitalyClient.medium_timeout)
diff --git a/lib/gitlab/graphql/pagination/keyset/generic_keyset_pagination.rb b/lib/gitlab/graphql/pagination/keyset/generic_keyset_pagination.rb
index e8335a3c79c..bf9b73d918a 100644
--- a/lib/gitlab/graphql/pagination/keyset/generic_keyset_pagination.rb
+++ b/lib/gitlab/graphql/pagination/keyset/generic_keyset_pagination.rb
@@ -73,9 +73,24 @@ module Gitlab
strong_memoize(:generic_keyset_pagination_items) do
rebuilt_items_with_keyset_order, success = Gitlab::Pagination::Keyset::SimpleOrderBuilder.build(original_items)
- success ? rebuilt_items_with_keyset_order : original_items
+ if success
+ rebuilt_items_with_keyset_order
+ else
+ if original_items.is_a?(ActiveRecord::Relation)
+ old_keyset_pagination_usage.increment({ model: original_items.model.to_s })
+ end
+
+ original_items
+ end
end
end
+
+ def old_keyset_pagination_usage
+ @old_keyset_pagination_usage ||= Gitlab::Metrics.counter(
+ :old_keyset_pagination_usage,
+ 'The number of times the old keyset pagination code was used'
+ )
+ end
end
end
end
diff --git a/rubocop/cop/database/disable_referential_integrity.rb b/rubocop/cop/database/disable_referential_integrity.rb
new file mode 100644
index 00000000000..80d52678011
--- /dev/null
+++ b/rubocop/cop/database/disable_referential_integrity.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module RuboCop
+ module Cop
+ module Database
+ # Cop that checks if 'disable_referential_integrity' method is called.
+ class DisableReferentialIntegrity < RuboCop::Cop::Cop
+ MSG = <<~TEXT
+ Do not use `disable_referential_integrity`, disable triggers in a safe
+ transaction instead. Follow the format:
+ BEGIN;
+ ALTER TABLE my_table DISABLE TRIGGER ALL;
+ -- execute query that requires disabled triggers
+ ALTER TABLE my_table ENABLE TRIGGER ALL;
+ COMMIT;
+ TEXT
+
+ def_node_matcher :disable_referential_integrity?, <<~PATTERN
+ (send _ :disable_referential_integrity)
+ PATTERN
+
+ RESTRICT_ON_SEND = %i[disable_referential_integrity].freeze
+
+ def on_send(node)
+ return unless disable_referential_integrity?(node)
+
+ add_offense(node)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/frontend/vue_mr_widget/components/extensions/utils_spec.js b/spec/frontend/vue_mr_widget/components/extensions/utils_spec.js
index 64e802c4fa5..98cfc04eb25 100644
--- a/spec/frontend/vue_mr_widget/components/extensions/utils_spec.js
+++ b/spec/frontend/vue_mr_widget/components/extensions/utils_spec.js
@@ -8,7 +8,7 @@ describe('generateText', () => {
${'%{danger_start}Hello world%{danger_end}'} | ${'<span class="gl-font-weight-bold gl-text-red-500">Hello world</span>'}
${'%{critical_start}Hello world%{critical_end}'} | ${'<span class="gl-font-weight-bold gl-text-red-800">Hello world</span>'}
${'%{same_start}Hello world%{same_end}'} | ${'<span class="gl-font-weight-bold gl-text-gray-700">Hello world</span>'}
- ${'%{small_start}Hello world%{small_end}'} | ${'<span class="gl-font-sm">Hello world</span>'}
+ ${'%{small_start}Hello world%{small_end}'} | ${'<span class="gl-font-sm gl-text-gray-700">Hello world</span>'}
${'%{strong_start}%{danger_start}Hello world%{danger_end}%{strong_end}'} | ${'<span class="gl-font-weight-bold"><span class="gl-font-weight-bold gl-text-red-500">Hello world</span></span>'}
${'%{no_exist_start}Hello world%{no_exist_end}'} | ${'Hello world'}
${['array']} | ${null}
diff --git a/spec/lib/gitlab/blame_spec.rb b/spec/lib/gitlab/blame_spec.rb
index 0f3c9e65d33..f636ce283ae 100644
--- a/spec/lib/gitlab/blame_spec.rb
+++ b/spec/lib/gitlab/blame_spec.rb
@@ -3,13 +3,31 @@
require 'spec_helper'
RSpec.describe Gitlab::Blame do
- let(:project) { create(:project, :repository) }
+ let_it_be(:project) { create(:project, :repository) }
+
let(:path) { 'files/ruby/popen.rb' }
let(:commit) { project.commit('master') }
let(:blob) { project.repository.blob_at(commit.id, path) }
+ let(:range) { nil }
+
+ subject(:blame) { described_class.new(blob, commit, range: range) }
+
+ describe '#first_line' do
+ subject { blame.first_line }
+
+ it { is_expected.to eq(1) }
+
+ context 'with a range' do
+ let(:range) { 2..3 }
+
+ it { is_expected.to eq(range.first) }
+ end
+ end
describe "#groups" do
- let(:subject) { described_class.new(blob, commit).groups(highlight: false) }
+ let(:highlighted) { false }
+
+ subject(:groups) { blame.groups(highlight: highlighted) }
it 'groups lines properly' do
expect(subject.count).to eq(18)
@@ -23,6 +41,50 @@ RSpec.describe Gitlab::Blame do
expect(subject[-1][:lines]).to eq([" end", "end"])
end
+ context 'with a range 1..5' do
+ let(:range) { 1..5 }
+
+ it 'returns the correct lines' do
+ expect(groups.count).to eq(2)
+ expect(groups[0][:lines]).to eq(["require 'fileutils'", "require 'open3'", ""])
+ expect(groups[1][:lines]).to eq(['module Popen', ' extend self'])
+ end
+
+ context 'with highlighted lines' do
+ let(:highlighted) { true }
+
+ it 'returns the correct lines' do
+ expect(groups.count).to eq(2)
+ expect(groups[0][:lines][0]).to match(/LC1.*fileutils/)
+ expect(groups[0][:lines][1]).to match(/LC2.*open3/)
+ expect(groups[0][:lines][2]).to eq("<span id=\"LC3\" class=\"line\" lang=\"ruby\"></span>\n")
+ expect(groups[1][:lines][0]).to match(/LC4.*Popen/)
+ expect(groups[1][:lines][1]).to match(/LC5.*extend/)
+ end
+ end
+ end
+
+ context 'with a range 2..4' do
+ let(:range) { 2..4 }
+
+ it 'returns the correct lines' do
+ expect(groups.count).to eq(2)
+ expect(groups[0][:lines]).to eq(["require 'open3'", ""])
+ expect(groups[1][:lines]).to eq(['module Popen'])
+ end
+
+ context 'with highlighted lines' do
+ let(:highlighted) { true }
+
+ it 'returns the correct lines' do
+ expect(groups.count).to eq(2)
+ expect(groups[0][:lines][0]).to match(/LC2.*open3/)
+ expect(groups[0][:lines][1]).to eq("<span id=\"LC3\" class=\"line\" lang=\"ruby\"></span>\n")
+ expect(groups[1][:lines][0]).to match(/LC4.*Popen/)
+ end
+ end
+ end
+
context 'renamed file' do
let(:path) { 'files/plain_text/renamed' }
let(:commit) { project.commit('blame-on-renamed') }
diff --git a/spec/lib/gitlab/git/blame_spec.rb b/spec/lib/gitlab/git/blame_spec.rb
index f95ea478975..7dd7460b142 100644
--- a/spec/lib/gitlab/git/blame_spec.rb
+++ b/spec/lib/gitlab/git/blame_spec.rb
@@ -4,106 +4,81 @@ require "spec_helper"
RSpec.describe Gitlab::Git::Blame, :seed_helper do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '', 'group/project') }
- let(:blame) do
- Gitlab::Git::Blame.new(repository, SeedRepo::Commit::ID, "CONTRIBUTING.md")
+
+ let(:sha) { SeedRepo::Commit::ID }
+ let(:path) { 'CONTRIBUTING.md' }
+ let(:range) { nil }
+
+ subject(:blame) { Gitlab::Git::Blame.new(repository, sha, path, range: range) }
+
+ let(:result) do
+ [].tap do |data|
+ blame.each do |commit, line, previous_path|
+ data << { commit: commit, line: line, previous_path: previous_path }
+ end
+ end
end
describe 'blaming a file' do
- context "each count" do
- it do
- data = []
- blame.each do |commit, line|
- data << {
- commit: commit,
- line: line
- }
- end
+ it 'has the right number of lines' do
+ expect(result.size).to eq(95)
+ expect(result.first[:commit]).to be_kind_of(Gitlab::Git::Commit)
+ expect(result.first[:line]).to eq("# Contribute to GitLab")
+ expect(result.first[:line]).to be_utf8
+ end
+
+ context 'blaming a range' do
+ let(:range) { 2..4 }
- expect(data.size).to eq(95)
- expect(data.first[:commit]).to be_kind_of(Gitlab::Git::Commit)
- expect(data.first[:line]).to eq("# Contribute to GitLab")
- expect(data.first[:line]).to be_utf8
+ it 'only returns the range' do
+ expect(result.size).to eq(range.size)
+ expect(result.map {|r| r[:line] }).to eq(['', 'This guide details how contribute to GitLab.', ''])
end
end
context "ISO-8859 encoding" do
- let(:blame) do
- Gitlab::Git::Blame.new(repository, SeedRepo::EncodingCommit::ID, "encoding/iso8859.txt")
- end
+ let(:sha) { SeedRepo::EncodingCommit::ID }
+ let(:path) { 'encoding/iso8859.txt' }
it 'converts to UTF-8' do
- data = []
- blame.each do |commit, line|
- data << {
- commit: commit,
- line: line
- }
- end
-
- expect(data.size).to eq(1)
- expect(data.first[:commit]).to be_kind_of(Gitlab::Git::Commit)
- expect(data.first[:line]).to eq("Ä ü")
- expect(data.first[:line]).to be_utf8
+ expect(result.size).to eq(1)
+ expect(result.first[:commit]).to be_kind_of(Gitlab::Git::Commit)
+ expect(result.first[:line]).to eq("Ä ü")
+ expect(result.first[:line]).to be_utf8
end
end
context "unknown encoding" do
- let(:blame) do
- Gitlab::Git::Blame.new(repository, SeedRepo::EncodingCommit::ID, "encoding/iso8859.txt")
- end
+ let(:sha) { SeedRepo::EncodingCommit::ID }
+ let(:path) { 'encoding/iso8859.txt' }
it 'converts to UTF-8' do
expect_next_instance_of(CharlockHolmes::EncodingDetector) do |detector|
expect(detector).to receive(:detect).and_return(nil)
end
- data = []
- blame.each do |commit, line|
- data << {
- commit: commit,
- line: line
- }
- end
-
- expect(data.size).to eq(1)
- expect(data.first[:commit]).to be_kind_of(Gitlab::Git::Commit)
- expect(data.first[:line]).to eq(" ")
- expect(data.first[:line]).to be_utf8
+ expect(result.size).to eq(1)
+ expect(result.first[:commit]).to be_kind_of(Gitlab::Git::Commit)
+ expect(result.first[:line]).to eq(" ")
+ expect(result.first[:line]).to be_utf8
end
end
context "renamed file" do
let(:project) { create(:project, :repository) }
+ let(:repository) { project.repository.raw_repository }
let(:commit) { project.commit('blame-on-renamed') }
+ let(:sha) { commit.id }
let(:path) { 'files/plain_text/renamed' }
- let(:blame) { described_class.new(project.repository, commit.id, path) }
-
- it do
- data = []
- blame.each do |commit, line, previous_path|
- data << {
- commit: commit,
- line: line,
- previous_path: previous_path
- }
- end
-
- expect(data.size).to eq(5)
-
- expect(data[0][:line]).to eq('Initial commit')
- expect(data[0][:previous_path]).to be nil
- expect(data[1][:line]).to eq('Initial commit')
- expect(data[1][:previous_path]).to be nil
-
- expect(data[2][:line]).to eq('Renamed as "filename"')
- expect(data[2][:previous_path]).to eq('files/plain_text/initial-commit')
-
- expect(data[3][:line]).to eq('Renamed as renamed')
- expect(data[3][:previous_path]).to eq('files/plain_text/"filename"')
+ it 'includes the previous path' do
+ expect(result.size).to eq(5)
- expect(data[4][:line]).to eq('Last edit, no rename')
- expect(data[4][:previous_path]).to eq('files/plain_text/renamed')
+ expect(result[0]).to include(line: 'Initial commit', previous_path: nil)
+ expect(result[1]).to include(line: 'Initial commit', previous_path: nil)
+ expect(result[2]).to include(line: 'Renamed as "filename"', previous_path: 'files/plain_text/initial-commit')
+ expect(result[3]).to include(line: 'Renamed as renamed', previous_path: 'files/plain_text/"filename"')
+ expect(result[4]).to include(line: 'Last edit, no rename', previous_path: path)
end
end
end
diff --git a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
index 8d9ab5db886..50a0f20e775 100644
--- a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb
@@ -563,4 +563,39 @@ RSpec.describe Gitlab::GitalyClient::CommitService do
expect(response).not_to have_key 'nonexistent'
end
end
+
+ describe '#raw_blame' do
+ let(:project) { create(:project, :test_repo) }
+ let(:revision) { 'blame-on-renamed' }
+ let(:path) { 'files/plain_text/renamed' }
+
+ let(:blame_headers) do
+ [
+ '405a45736a75e439bb059e638afaa9a3c2eeda79 1 1 2',
+ '405a45736a75e439bb059e638afaa9a3c2eeda79 2 2',
+ 'bed1d1610ebab382830ee888288bf939c43873bb 3 3 1',
+ '3685515c40444faf92774e72835e1f9c0e809672 4 4 1',
+ '32c33da59f8a1a9f90bdeda570337888b00b244d 5 5 1'
+ ]
+ end
+
+ subject(:blame) { client.raw_blame(revision, path, range: range).split("\n") }
+
+ context 'without a range' do
+ let(:range) { nil }
+
+ it 'blames a whole file' do
+ is_expected.to include(*blame_headers)
+ end
+ end
+
+ context 'with a range' do
+ let(:range) { '3,4' }
+
+ it 'blames part of a file' do
+ is_expected.to include(blame_headers[2], blame_headers[3])
+ is_expected.not_to include(blame_headers[0], blame_headers[1], blame_headers[4])
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb b/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb
index fcae89a9025..f31ec6c09fd 100644
--- a/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb
+++ b/spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb
@@ -77,6 +77,17 @@ RSpec.describe Gitlab::Graphql::Pagination::Keyset::Connection do
expect(decoded_cursor(cursor)).to eq('id' => project.id.to_s)
end
+ context 'when SimpleOrderBuilder cannot build keyset paginated query' do
+ it 'increments the `old_keyset_pagination_usage` counter', :prometheus do
+ expect(Gitlab::Pagination::Keyset::SimpleOrderBuilder).to receive(:build).and_return([false, nil])
+
+ decoded_cursor(cursor)
+
+ counter = Gitlab::Metrics.registry.get(:old_keyset_pagination_usage)
+ expect(counter.get(model: 'Project')).to eq(1)
+ end
+ end
+
context 'when an order is specified' do
let(:nodes) { Project.order(:updated_at) }
diff --git a/spec/presenters/gitlab/blame_presenter_spec.rb b/spec/presenters/gitlab/blame_presenter_spec.rb
index c97b9ebdce9..ff128416692 100644
--- a/spec/presenters/gitlab/blame_presenter_spec.rb
+++ b/spec/presenters/gitlab/blame_presenter_spec.rb
@@ -27,6 +27,14 @@ RSpec.describe Gitlab::BlamePresenter do
end
end
+ describe '#first_line' do
+ it 'delegates #first_line call to the blame' do
+ expect(blame).to receive(:first_line).at_least(:once).and_call_original
+
+ subject.first_line
+ end
+ end
+
describe '#commit_data' do
it 'has the data necessary to render the view' do
commit = blame.groups.first[:commit]
diff --git a/spec/rubocop/cop/database/disable_referential_integrity_spec.rb b/spec/rubocop/cop/database/disable_referential_integrity_spec.rb
new file mode 100644
index 00000000000..9ac67363cb6
--- /dev/null
+++ b/spec/rubocop/cop/database/disable_referential_integrity_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require_relative '../../../../rubocop/cop/database/disable_referential_integrity'
+
+RSpec.describe RuboCop::Cop::Database::DisableReferentialIntegrity do
+ subject(:cop) { described_class.new }
+
+ it 'does not flag the use of disable_referential_integrity with a send receiver' do
+ expect_offense(<<~SOURCE)
+ foo.disable_referential_integrity
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use `disable_referential_integrity`, [...]
+ SOURCE
+ end
+
+ it 'flags the use of disable_referential_integrity with a full definition' do
+ expect_offense(<<~SOURCE)
+ ActiveRecord::Base.connection.disable_referential_integrity
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use `disable_referential_integrity`, [...]
+ SOURCE
+ end
+
+ it 'flags the use of disable_referential_integrity with a nil receiver' do
+ expect_offense(<<~SOURCE)
+ class Foo ; disable_referential_integrity ; end
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use `disable_referential_integrity`, [...]
+ SOURCE
+ end
+
+ it 'flags the use of disable_referential_integrity when passing a block' do
+ expect_offense(<<~SOURCE)
+ class Foo ; disable_referential_integrity { :foo } ; end
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use `disable_referential_integrity`, [...]
+ SOURCE
+ end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index c2825b63452..88f10cc2a01 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -3,7 +3,7 @@
if $".include?(File.expand_path('fast_spec_helper.rb', __dir__))
warn 'Detected fast_spec_helper is loaded first than spec_helper.'
warn 'If running test files using both spec_helper and fast_spec_helper,'
- warn 'make sure test file with spec_helper is loaded first.'
+ warn 'make sure spec_helper is loaded first, or run rspec with `-r spec_helper`.'
abort 'Aborting...'
end