Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-10-18 00:11:06 +00:00
parent 613fdca844
commit 90e7f31698
18 changed files with 251 additions and 57 deletions

View file

@ -168,22 +168,22 @@ module TodosHelper
def todo_actions_options def todo_actions_options
[ [
{ id: '', text: 'Any Action' }, { id: '', text: s_('Todos|Any Action') },
{ id: Todo::ASSIGNED, text: 'Assigned' }, { id: Todo::ASSIGNED, text: s_('Todos|Assigned') },
{ id: Todo::REVIEW_REQUESTED, text: 'Review requested' }, { id: Todo::REVIEW_REQUESTED, text: s_('Todos|Review requested') },
{ id: Todo::MENTIONED, text: 'Mentioned' }, { id: Todo::MENTIONED, text: s_('Todos|Mentioned') },
{ id: Todo::MARKED, text: 'Added' }, { id: Todo::MARKED, text: s_('Todos|Added') },
{ id: Todo::BUILD_FAILED, text: 'Pipelines' } { id: Todo::BUILD_FAILED, text: s_('Todos|Pipelines') }
] ]
end end
def todo_types_options def todo_types_options
[ [
{ id: '', text: 'Any Type' }, { id: '', text: s_('Todos|Any Type') },
{ id: 'Issue', text: 'Issue' }, { id: 'Issue', text: s_('Todos|Issue') },
{ id: 'MergeRequest', text: 'Merge request' }, { id: 'MergeRequest', text: s_('Todos|Merge request') },
{ id: 'DesignManagement::Design', text: 'Design' }, { id: 'DesignManagement::Design', text: s_('Todos|Design') },
{ id: 'AlertManagement::Alert', text: 'Alert' } { id: 'AlertManagement::Alert', text: s_('Todos|Alert') }
] ]
end end

View file

@ -544,7 +544,7 @@ class Environment < ApplicationRecord
self.class.tiers[:development] self.class.tiers[:development]
when /(test|tst|int|ac(ce|)pt|qa|qc|control|quality)/i when /(test|tst|int|ac(ce|)pt|qa|qc|control|quality)/i
self.class.tiers[:testing] self.class.tiers[:testing]
when /(st(a|)g|mod(e|)l|pre|demo)/i when /(st(a|)g|mod(e|)l|pre|demo|non)/i
self.class.tiers[:staging] self.class.tiers[:staging]
when /(pr(o|)d|live)/i when /(pr(o|)d|live)/i
self.class.tiers[:production] self.class.tiers[:production]

View file

@ -3,10 +3,10 @@
module Releases module Releases
class CreateService < Releases::BaseService class CreateService < Releases::BaseService
def execute def execute
return error('Access Denied', 403) unless allowed? return error(_('Access Denied'), 403) unless allowed?
return error('You are not allowed to create this tag as it is protected.', 403) unless can_create_tag? return error(_('You are not allowed to create this tag as it is protected.'), 403) unless can_create_tag?
return error('Release already exists', 409) if release return error(_('Release already exists'), 409) if release
return error("Milestone(s) not found: #{inexistent_milestones.join(', ')}", 400) if inexistent_milestones.any? return error(format(_("Milestone(s) not found: %{milestones}"), milestones: inexistent_milestones.join(', ')), 400) if inexistent_milestones.any? # rubocop:disable Layout/LineLength
# should be found before the creation of new tag # should be found before the creation of new tag
# because tag creation can spawn new pipeline # because tag creation can spawn new pipeline

View file

@ -3,8 +3,8 @@
module Releases module Releases
class DestroyService < Releases::BaseService class DestroyService < Releases::BaseService
def execute def execute
return error('Release does not exist', 404) unless release return error(_('Release does not exist'), 404) unless release
return error('Access Denied', 403) unless allowed? return error(_('Access Denied'), 403) unless allowed?
if release.destroy if release.destroy
success(tag: existing_tag, release: release) success(tag: existing_tag, release: release)

View file

@ -31,11 +31,11 @@ module Releases
private private
def validate def validate
return error('Tag does not exist', 404) unless existing_tag return error(_('Tag does not exist'), 404) unless existing_tag
return error('Release does not exist', 404) unless release return error(_('Release does not exist'), 404) unless release
return error('Access Denied', 403) unless allowed? return error(_('Access Denied'), 403) unless allowed?
return error('params is empty', 400) if empty_params? return error(_('params is empty'), 400) if empty_params?
return error("Milestone(s) not found: #{inexistent_milestones.join(', ')}", 400) if inexistent_milestones.any? return error(format(_("Milestone(s) not found: %{milestones}"), milestones: inexistent_milestones.join(', ')), 400) if inexistent_milestones.any? # rubocop:disable Layout/LineLength
end end
def allowed? def allowed?

View file

@ -9,7 +9,7 @@
%span.js-clone-dropdown-label %span.js-clone-dropdown-label
= default_clone_protocol.upcase = default_clone_protocol.upcase
= sprite_icon('chevron-down', css_class: 'gl-icon') = sprite_icon('chevron-down', css_class: 'gl-icon')
%ul.dropdown-menu.dropdown-menu-selectable{ data: { qa_selector: 'clone_dropdown_content' } } %ul.dropdown-menu.dropdown-menu-selectable.clone-options-dropdown{ data: { qa_selector: 'clone_dropdown_content' } }
%li %li
= ssh_clone_button(container) = ssh_clone_button(container)
%li %li

View file

@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/373719
milestone: '15.4' milestone: '15.4'
type: development type: development
group: group::pipeline execution group: group::pipeline execution
default_enabled: false default_enabled: true

View file

@ -555,12 +555,15 @@ Additionally, the certificate (or its certificate authority) must be installed o
- Gitaly servers. - Gitaly servers.
- Gitaly clients that communicate with it. - Gitaly clients that communicate with it.
Note the following: ### Certificate requirements
- The certificate must specify the address you use to access the Gitaly server. You must add the hostname or IP address as a Subject Alternative Name to the certificate. - The certificate must specify the address you use to access the Gitaly server. You must add the hostname or IP address as a Subject Alternative Name to the certificate.
- You can configure Gitaly servers with both an unencrypted listening address `listen_addr` and an - You can configure Gitaly servers with both an unencrypted listening address `listen_addr` and an
encrypted listening address `tls_listen_addr` at the same time. This allows you to gradually encrypted listening address `tls_listen_addr` at the same time. This allows you to gradually
transition from unencrypted to encrypted traffic if necessary. transition from unencrypted to encrypted traffic if necessary.
- The certificate's Common Name field is ignored.
### Configure Gitaly with TLS
To configure Gitaly with TLS: To configure Gitaly with TLS:

View file

@ -67,6 +67,13 @@ remote: GitLab: 401 Unauthorized
You need to sync your `gitlab-secrets.json` file with your GitLab You need to sync your `gitlab-secrets.json` file with your GitLab
application nodes. application nodes.
### 500 and `fetching folder content` errors on repository pages
`Fetching folder content`, and in some cases `500`, errors indicate
connectivity problems between GitLab and Gitaly.
Consult the [client-side gRPC logs](#client-side-grpc-logs)
for details.
### Client side gRPC logs ### Client side gRPC logs
Gitaly uses the [gRPC](https://grpc.io/) RPC framework. The Ruby gRPC Gitaly uses the [gRPC](https://grpc.io/) RPC framework. The Ruby gRPC
@ -81,6 +88,19 @@ You can run a gRPC trace with:
sudo GRPC_TRACE=all GRPC_VERBOSITY=DEBUG gitlab-rake gitlab:gitaly:check sudo GRPC_TRACE=all GRPC_VERBOSITY=DEBUG gitlab-rake gitlab:gitaly:check
``` ```
If this command fails with a `failed to connect to all addresses` error,
check for an SSL or TLS problem:
```shell
/opt/gitlab/embedded/bin/openssl s_client -connect <gitaly-ipaddress>:<port> -verify_return_error
```
Check whether `Verify return code` field indicates a
[known Omnibus GitLab configuration problem](https://docs.gitlab.com/omnibus/settings/ssl.html).
If `openssl` succeeds but `gitlab-rake gitlab:gitaly:check` fails,
check [certificate requirements](configure_gitaly.md#certificate-requirements) for Gitaly.
### Server side gRPC logs ### Server side gRPC logs
gRPC tracing can also be enabled in Gitaly itself with the `GODEBUG=http2debug` gRPC tracing can also be enabled in Gitaly itself with the `GODEBUG=http2debug`

View file

@ -313,7 +313,7 @@ node throughout the process.
- If you're using PgBouncer: - If you're using PgBouncer:
You must bypass PgBouncer and connect directly to the database leader You must [bypass PgBouncer](../administration/postgresql/pgbouncer.md#procedure-for-bypassing-pgbouncer) and connect directly to the database leader
before running migrations. before running migrations.
Rails uses an advisory lock when attempting to run a migration to prevent Rails uses an advisory lock when attempting to run a migration to prevent
@ -699,7 +699,7 @@ sudo touch /etc/gitlab/skip-auto-reconfigure
1. If you're using PgBouncer: 1. If you're using PgBouncer:
You must bypass PgBouncer and connect directly to the database leader You must [bypass PgBouncer](../administration/postgresql/pgbouncer.md#procedure-for-bypassing-pgbouncer) and connect directly to the database leader
before running migrations. before running migrations.
Rails uses an advisory lock when attempting to run a migration to prevent Rails uses an advisory lock when attempting to run a migration to prevent

View file

@ -1933,6 +1933,9 @@ msgstr ""
msgid "Acceptable for use in this project" msgid "Acceptable for use in this project"
msgstr "" msgstr ""
msgid "Access Denied"
msgstr ""
msgid "Access Git repositories or the API." msgid "Access Git repositories or the API."
msgstr "" msgstr ""
@ -25994,6 +25997,9 @@ msgstr ""
msgid "Milestone lists not available with your current license" msgid "Milestone lists not available with your current license"
msgstr "" msgstr ""
msgid "Milestone(s) not found: %{milestones}"
msgstr ""
msgid "MilestoneCombobox|An error occurred while searching for milestones" msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr "" msgstr ""
@ -33441,6 +33447,9 @@ msgstr[1] ""
msgid "Release %{deletedRelease} has been successfully deleted." msgid "Release %{deletedRelease} has been successfully deleted."
msgstr "" msgstr ""
msgid "Release already exists"
msgstr ""
msgid "Release assets" msgid "Release assets"
msgstr "" msgstr ""
@ -33450,6 +33459,9 @@ msgstr ""
msgid "Release date" msgid "Release date"
msgstr "" msgstr ""
msgid "Release does not exist"
msgstr ""
msgid "Release does not have the same project as the milestone" msgid "Release does not have the same project as the milestone"
msgstr "" msgstr ""
@ -39576,6 +39588,9 @@ msgstr ""
msgid "Tag" msgid "Tag"
msgstr "" msgstr ""
msgid "Tag does not exist"
msgstr ""
msgid "Tag list:" msgid "Tag list:"
msgstr "" msgstr ""
@ -42222,9 +42237,30 @@ msgstr ""
msgid "Todos count" msgid "Todos count"
msgstr "" msgstr ""
msgid "Todos|Added"
msgstr ""
msgid "Todos|Alert"
msgstr ""
msgid "Todos|Any Action"
msgstr ""
msgid "Todos|Any Type"
msgstr ""
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item." msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr "" msgstr ""
msgid "Todos|Assigned"
msgstr ""
msgid "Todos|Design"
msgstr ""
msgid "Todos|Epic"
msgstr ""
msgid "Todos|Filter by author" msgid "Todos|Filter by author"
msgstr "" msgstr ""
@ -42246,18 +42282,33 @@ msgstr ""
msgid "Todos|Isn't an empty To-Do List beautiful?" msgid "Todos|Isn't an empty To-Do List beautiful?"
msgstr "" msgstr ""
msgid "Todos|Issue"
msgstr ""
msgid "Todos|It's how you always know what to work on next." msgid "Todos|It's how you always know what to work on next."
msgstr "" msgstr ""
msgid "Todos|Mark all as done" msgid "Todos|Mark all as done"
msgstr "" msgstr ""
msgid "Todos|Mentioned"
msgstr ""
msgid "Todos|Merge request"
msgstr ""
msgid "Todos|Nothing is on your to-do list. Nice work!" msgid "Todos|Nothing is on your to-do list. Nice work!"
msgstr "" msgstr ""
msgid "Todos|Nothing left to do. High five!" msgid "Todos|Nothing left to do. High five!"
msgstr "" msgstr ""
msgid "Todos|Pipelines"
msgstr ""
msgid "Todos|Review requested"
msgstr ""
msgid "Todos|Undo mark all as done" msgid "Todos|Undo mark all as done"
msgstr "" msgstr ""
@ -46020,6 +46071,9 @@ msgstr ""
msgid "You are not allowed to approve a user" msgid "You are not allowed to approve a user"
msgstr "" msgstr ""
msgid "You are not allowed to create this tag as it is protected."
msgstr ""
msgid "You are not allowed to log in using password" msgid "You are not allowed to log in using password"
msgstr "" msgstr ""
@ -48589,6 +48643,9 @@ msgstr ""
msgid "pages" msgid "pages"
msgstr "" msgstr ""
msgid "params is empty"
msgstr ""
msgid "parent" msgid "parent"
msgid_plural "parents" msgid_plural "parents"
msgstr[0] "" msgstr[0] ""

View file

@ -4,7 +4,7 @@ source 'https://rubygems.org'
gem 'gitlab-qa', '~> 8', require: 'gitlab/qa' gem 'gitlab-qa', '~> 8', require: 'gitlab/qa'
gem 'activesupport', '~> 6.1.4.7' # This should stay in sync with the root's Gemfile gem 'activesupport', '~> 6.1.4.7' # This should stay in sync with the root's Gemfile
gem 'allure-rspec', '~> 2.16.0' gem 'allure-rspec', '~> 2.18.0'
gem 'capybara', '~> 3.35.0' gem 'capybara', '~> 3.35.0'
gem 'capybara-screenshot', '~> 1.0.26' gem 'capybara-screenshot', '~> 1.0.26'
gem 'rake', '~> 13' gem 'rake', '~> 13'
@ -14,7 +14,7 @@ gem 'airborne', '~> 0.3.7', require: false # airborne is messing with rspec sand
gem 'rest-client', '~> 2.1.0' gem 'rest-client', '~> 2.1.0'
gem 'rspec-retry', '~> 0.6.1', require: 'rspec/retry' gem 'rspec-retry', '~> 0.6.1', require: 'rspec/retry'
gem 'rspec_junit_formatter', '~> 0.6.0' gem 'rspec_junit_formatter', '~> 0.6.0'
gem 'faker', '~> 2.19', '>= 2.19.0' gem 'faker', '~> 2.23'
gem 'knapsack', '~> 4.0' gem 'knapsack', '~> 4.0'
gem 'parallel_tests', '~> 2.32' gem 'parallel_tests', '~> 2.32'
gem 'rotp', '~> 6.2.0' gem 'rotp', '~> 6.2.0'

View file

@ -15,10 +15,10 @@ GEM
rack-test (>= 1.1.0, < 2.0) rack-test (>= 1.1.0, < 2.0)
rest-client (>= 2.0.2, < 3.0) rest-client (>= 2.0.2, < 3.0)
rspec (~> 3.8) rspec (~> 3.8)
allure-rspec (2.16.1) allure-rspec (2.18.0)
allure-ruby-commons (= 2.16.1) allure-ruby-commons (= 2.18.0)
rspec-core (>= 3.8, < 4) rspec-core (>= 3.8, < 4)
allure-ruby-commons (2.16.1) allure-ruby-commons (2.18.0)
mime-types (>= 3.3, < 4) mime-types (>= 3.3, < 4)
oj (>= 3.10, < 4) oj (>= 3.10, < 4)
require_all (>= 2, < 4) require_all (>= 2, < 4)
@ -60,8 +60,8 @@ GEM
domain_name (0.5.20190701) domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0) unf (>= 0.0.5, < 1.0.0)
excon (0.92.4) excon (0.92.4)
faker (2.19.0) faker (2.23.0)
i18n (>= 1.6, < 2) i18n (>= 1.8.11, < 2)
faraday (2.5.2) faraday (2.5.2)
faraday-net_http (>= 2.0, < 3.1) faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4) ruby2_keywords (>= 0.0.4)
@ -182,7 +182,7 @@ GEM
octokit (5.6.1) octokit (5.6.1)
faraday (>= 1, < 3) faraday (>= 1, < 3)
sawyer (~> 0.9) sawyer (~> 0.9)
oj (3.13.11) oj (3.13.21)
os (1.1.4) os (1.1.4)
parallel (1.19.2) parallel (1.19.2)
parallel_tests (2.32.0) parallel_tests (2.32.0)
@ -299,14 +299,14 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
activesupport (~> 6.1.4.7) activesupport (~> 6.1.4.7)
airborne (~> 0.3.7) airborne (~> 0.3.7)
allure-rspec (~> 2.16.0) allure-rspec (~> 2.18.0)
capybara (~> 3.35.0) capybara (~> 3.35.0)
capybara-screenshot (~> 1.0.26) capybara-screenshot (~> 1.0.26)
chemlab (~> 0.10) chemlab (~> 0.10)
chemlab-library-www-gitlab-com (~> 0.1) chemlab-library-www-gitlab-com (~> 0.1)
confiner (~> 0.3) confiner (~> 0.3)
deprecation_toolkit (~> 2.0.0) deprecation_toolkit (~> 2.0.0)
faker (~> 2.19, >= 2.19.0) faker (~> 2.23)
faraday-retry (~> 2.0) faraday-retry (~> 2.0)
fog-core (= 2.1.0) fog-core (= 2.1.0)
fog-google (~> 1.19) fog-google (~> 1.19)
@ -336,4 +336,4 @@ DEPENDENCIES
zeitwerk (~> 2.4) zeitwerk (~> 2.4)
BUNDLED WITH BUNDLED WITH
2.3.23 2.3.24

View file

@ -26,10 +26,14 @@ module RuboCop
@cop_class&.support_autocorrect? @cop_class&.support_autocorrect?
end end
def generate?
previously_disabled || grace_period || files.any?
end
def to_yaml def to_yaml
yaml = [] yaml = []
yaml << '---' yaml << '---'
yaml << '# Cop supports --auto-correct.' if autocorrectable? yaml << '# Cop supports --autocorrect.' if autocorrectable?
yaml << "#{cop_name}:" yaml << "#{cop_name}:"
if previously_disabled if previously_disabled
@ -39,8 +43,12 @@ module RuboCop
end end
yaml << " #{RuboCop::Formatter::GracefulFormatter.grace_period_key_value}" if grace_period yaml << " #{RuboCop::Formatter::GracefulFormatter.grace_period_key_value}" if grace_period
yaml << ' Exclude:'
yaml.concat files.sort.map { |file| " - '#{file}'" } if files.any?
yaml << ' Exclude:'
yaml.concat files.sort.map { |file| " - '#{file}'" }
end
yaml << '' yaml << ''
yaml.join("\n") yaml.join("\n")

View file

@ -31,6 +31,7 @@ module RuboCop
@config_inspect_todo_dir = load_config_inspect_todo_dir @config_inspect_todo_dir = load_config_inspect_todo_dir
@config_old_todo_yml = load_config_old_todo_yml @config_old_todo_yml = load_config_old_todo_yml
check_multiple_configurations! check_multiple_configurations!
create_empty_todos(@config_inspect_todo_dir)
super super
end end
@ -47,11 +48,9 @@ module RuboCop
def finished(_inspected_files) def finished(_inspected_files)
@todos.values.sort_by(&:cop_name).each do |todo| @todos.values.sort_by(&:cop_name).each do |todo|
todo.previously_disabled = previously_disabled?(todo) next unless configure_and_validate_todo(todo)
todo.grace_period = grace_period?(todo)
validate_todo!(todo)
path = @todo_dir.write(todo.cop_name, todo.to_yaml)
path = @todo_dir.write(todo.cop_name, todo.to_yaml)
output.puts "Written to #{relative_path(path)}\n" output.puts "Written to #{relative_path(path)}\n"
end end
end end
@ -82,6 +81,14 @@ module RuboCop
raise "Multiple configurations found for cops:\n#{list}\n" raise "Multiple configurations found for cops:\n#{list}\n"
end end
# For each inspected cop TODO config create a TODO object to make sure
# the cop TODO config will be written even without any offenses.
def create_empty_todos(inspected_cop_config)
inspected_cop_config.each_key do |cop_name|
@todos[cop_name]
end
end
def config_for(todo) def config_for(todo)
cop_name = todo.cop_name cop_name = todo.cop_name
@ -101,10 +108,15 @@ module RuboCop
GracefulFormatter.grace_period?(todo.cop_name, config) GracefulFormatter.grace_period?(todo.cop_name, config)
end end
def validate_todo!(todo) def configure_and_validate_todo(todo)
return unless todo.previously_disabled && todo.grace_period todo.previously_disabled = previously_disabled?(todo)
todo.grace_period = grace_period?(todo)
raise "#{todo.cop_name}: Cop must be enabled to use `#{GracefulFormatter.grace_period_key_value}`." if todo.previously_disabled && todo.grace_period
raise "#{todo.cop_name}: Cop must be enabled to use `#{GracefulFormatter.grace_period_key_value}`."
end
todo.generate?
end end
def load_config_inspect_todo_dir def load_config_inspect_todo_dir

View file

@ -390,7 +390,10 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
'staging' | described_class.tiers[:staging] 'staging' | described_class.tiers[:staging]
'pre-prod' | described_class.tiers[:staging] 'pre-prod' | described_class.tiers[:staging]
'blue-kit-stage' | described_class.tiers[:staging] 'blue-kit-stage' | described_class.tiers[:staging]
'pre-prod' | described_class.tiers[:staging] 'nonprod' | described_class.tiers[:staging]
'nonlive' | described_class.tiers[:staging]
'non-prod' | described_class.tiers[:staging]
'non-live' | described_class.tiers[:staging]
'gprd' | described_class.tiers[:production] 'gprd' | described_class.tiers[:production]
'gprd-cny' | described_class.tiers[:production] 'gprd-cny' | described_class.tiers[:production]
'production' | described_class.tiers[:production] 'production' | described_class.tiers[:production]

View file

@ -66,6 +66,38 @@ RSpec.describe RuboCop::CopTodo do
end end
end end
describe '#generate?' do
subject { cop_todo.generate? }
context 'when empty todo' do
it { is_expected.to eq(false) }
end
context 'when previously disabled' do
before do
cop_todo.previously_disabled = true
end
it { is_expected.to eq(true) }
end
context 'when in grace period' do
before do
cop_todo.grace_period = true
end
it { is_expected.to eq(true) }
end
context 'with offenses recorded' do
before do
cop_todo.record('a.rb', 1)
end
it { is_expected.to eq(true) }
end
end
describe '#to_yaml' do describe '#to_yaml' do
subject(:yaml) { cop_todo.to_yaml } subject(:yaml) { cop_todo.to_yaml }
@ -77,9 +109,8 @@ RSpec.describe RuboCop::CopTodo do
specify do specify do
expect(yaml).to eq(<<~YAML) expect(yaml).to eq(<<~YAML)
--- ---
# Cop supports --auto-correct. # Cop supports --autocorrect.
#{cop_name}: #{cop_name}:
Exclude:
YAML YAML
end end
end end

View file

@ -82,7 +82,7 @@ RSpec.describe RuboCop::Formatter::TodoFormatter do
expect(todo_yml('B/AutoCorrect')).to eq(<<~YAML) expect(todo_yml('B/AutoCorrect')).to eq(<<~YAML)
--- ---
# Cop supports --auto-correct. # Cop supports --autocorrect.
B/AutoCorrect: B/AutoCorrect:
Exclude: Exclude:
- 'd.rb' - 'd.rb'
@ -309,18 +309,78 @@ RSpec.describe RuboCop::Formatter::TodoFormatter do
context 'without offenses detected' do context 'without offenses detected' do
before do before do
todo_dir.write('A/Cop', yaml) if yaml
todo_dir.inspect_all
formatter.started(%w[a.rb b.rb]) formatter.started(%w[a.rb b.rb])
formatter.file_finished('a.rb', []) formatter.file_finished('a.rb', [])
formatter.file_finished('b.rb', []) formatter.file_finished('b.rb', [])
formatter.finished(%w[a.rb b.rb]) formatter.finished(%w[a.rb b.rb])
todo_dir.delete_inspected
end end
it 'does not output anything' do context 'without existing TODOs' do
expect(stdout.string).to eq('') let(:yaml) { nil }
it 'does not output anything' do
expect(stdout.string).to eq('')
end
it 'does not write any YAML files' do
expect(rubocop_todo_dir_listing).to be_empty
end
end end
it 'does not write any YAML files' do context 'with existing TODOs' do
expect(rubocop_todo_dir_listing).to be_empty context 'when existing offenses only' do
let(:yaml) do
<<~YAML
---
A/Cop:
Exclude:
- x.rb
YAML
end
it 'does not output anything' do
expect(stdout.string).to eq('')
end
it 'does not write any YAML files' do
expect(rubocop_todo_dir_listing).to be_empty
end
end
context 'when in grace period' do
let(:yaml) do
<<~YAML
---
A/Cop:
Details: grace period
Exclude:
- x.rb
YAML
end
it 'outputs its actions' do
expect(stdout.string).to eq(<<~OUTPUT)
Written to .rubocop_todo/a/cop.yml
OUTPUT
end
it 'creates YAML file with Details only', :aggregate_failures do
expect(rubocop_todo_dir_listing).to contain_exactly(
'a/cop.yml'
)
expect(todo_yml('A/Cop')).to eq(<<~YAML)
---
A/Cop:
Details: grace period
YAML
end
end
end end
end end