diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index f3e23f5324df85341e16149e15fb60e48e8492b9..520cde9eceed18889de0ca9a0ad1649690d3c12e 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -168,22 +168,22 @@ def todos_filter_path(options = {}) def todo_actions_options [ - { id: '', text: 'Any Action' }, - { id: Todo::ASSIGNED, text: 'Assigned' }, - { id: Todo::REVIEW_REQUESTED, text: 'Review requested' }, - { id: Todo::MENTIONED, text: 'Mentioned' }, - { id: Todo::MARKED, text: 'Added' }, - { id: Todo::BUILD_FAILED, text: 'Pipelines' } + { id: '', text: s_('Todos|Any Action') }, + { id: Todo::ASSIGNED, text: s_('Todos|Assigned') }, + { id: Todo::REVIEW_REQUESTED, text: s_('Todos|Review requested') }, + { id: Todo::MENTIONED, text: s_('Todos|Mentioned') }, + { id: Todo::MARKED, text: s_('Todos|Added') }, + { id: Todo::BUILD_FAILED, text: s_('Todos|Pipelines') } ] end def todo_types_options [ - { id: '', text: 'Any Type' }, - { id: 'Issue', text: 'Issue' }, - { id: 'MergeRequest', text: 'Merge request' }, - { id: 'DesignManagement::Design', text: 'Design' }, - { id: 'AlertManagement::Alert', text: 'Alert' } + { id: '', text: s_('Todos|Any Type') }, + { id: 'Issue', text: s_('Todos|Issue') }, + { id: 'MergeRequest', text: s_('Todos|Merge request') }, + { id: 'DesignManagement::Design', text: s_('Todos|Design') }, + { id: 'AlertManagement::Alert', text: s_('Todos|Alert') } ] end diff --git a/app/models/environment.rb b/app/models/environment.rb index a601b3a88a8d517f52bfeefc87f2618c2e9376d9..2d3f342953f715bd9193e80e94daed402439098e 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -544,7 +544,7 @@ def guess_tier self.class.tiers[:development] when /(test|tst|int|ac(ce|)pt|qa|qc|control|quality)/i 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] when /(pr(o|)d|live)/i self.class.tiers[:production] diff --git a/app/services/releases/create_service.rb b/app/services/releases/create_service.rb index b7df201824ae5c5e46009704c0e83b08e3f3e314..01dd6323d94903c086c8280abb2caff142486a38 100644 --- a/app/services/releases/create_service.rb +++ b/app/services/releases/create_service.rb @@ -3,10 +3,10 @@ module Releases class CreateService < Releases::BaseService def execute - 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('Release already exists', 409) if release - return error("Milestone(s) not found: #{inexistent_milestones.join(', ')}", 400) if inexistent_milestones.any? + 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(_('Release already exists'), 409) if release + 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 # because tag creation can spawn new pipeline diff --git a/app/services/releases/destroy_service.rb b/app/services/releases/destroy_service.rb index 8abf93086895fe6a5e39a2975fe4f3ea895a743d..ff2b3a7bd1863bd95f2252c65abe2522d9d45491 100644 --- a/app/services/releases/destroy_service.rb +++ b/app/services/releases/destroy_service.rb @@ -3,8 +3,8 @@ module Releases class DestroyService < Releases::BaseService def execute - return error('Release does not exist', 404) unless release - return error('Access Denied', 403) unless allowed? + return error(_('Release does not exist'), 404) unless release + return error(_('Access Denied'), 403) unless allowed? if release.destroy success(tag: existing_tag, release: release) diff --git a/app/services/releases/update_service.rb b/app/services/releases/update_service.rb index 2e0a2f8488a153cde15ce33249dd8f19c45d7892..b9b2aba9805cd40aebb0e996c93945157aedf349 100644 --- a/app/services/releases/update_service.rb +++ b/app/services/releases/update_service.rb @@ -31,11 +31,11 @@ def execute private def validate - return error('Tag does not exist', 404) unless existing_tag - return error('Release does not exist', 404) unless release - return error('Access Denied', 403) unless allowed? - 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(_('Tag does not exist'), 404) unless existing_tag + return error(_('Release does not exist'), 404) unless release + return error(_('Access Denied'), 403) unless allowed? + return error(_('params is empty'), 400) if empty_params? + return error(format(_("Milestone(s) not found: %{milestones}"), milestones: inexistent_milestones.join(', ')), 400) if inexistent_milestones.any? # rubocop:disable Layout/LineLength end def allowed? diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml index abaf250fa698aa819361a576bf086fbe6f958125..48ae1f7eb1d9431388fa003e605bfb8b6f0bd224 100644 --- a/app/views/shared/_clone_panel.html.haml +++ b/app/views/shared/_clone_panel.html.haml @@ -9,7 +9,7 @@ %span.js-clone-dropdown-label = default_clone_protocol.upcase = 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 = ssh_clone_button(container) %li diff --git a/config/feature_flags/development/ci_limit_complete_hierarchy_size.yml b/config/feature_flags/development/ci_limit_complete_hierarchy_size.yml index ad0dd85a25aa13b480c309b3d691b93626efb910..d6cc87873331aa539031b17410d8d0d162214f5f 100644 --- a/config/feature_flags/development/ci_limit_complete_hierarchy_size.yml +++ b/config/feature_flags/development/ci_limit_complete_hierarchy_size.yml @@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/373719 milestone: '15.4' type: development group: group::pipeline execution -default_enabled: false +default_enabled: true diff --git a/doc/administration/gitaly/configure_gitaly.md b/doc/administration/gitaly/configure_gitaly.md index f6bf563b8cd6efae8a3d7c065d8e1c431e476f32..e4aef2db9a8292cab85889d6a245f9ce27c58ca9 100644 --- a/doc/administration/gitaly/configure_gitaly.md +++ b/doc/administration/gitaly/configure_gitaly.md @@ -555,12 +555,15 @@ Additionally, the certificate (or its certificate authority) must be installed o - Gitaly servers. - 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. - 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 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: diff --git a/doc/administration/gitaly/troubleshooting.md b/doc/administration/gitaly/troubleshooting.md index b53534cdcebae8ab3158a121b0fb83adcb19ca5d..1c5f0d438646cd8fb15281ac77c77a5fb22e742d 100644 --- a/doc/administration/gitaly/troubleshooting.md +++ b/doc/administration/gitaly/troubleshooting.md @@ -67,6 +67,13 @@ remote: GitLab: 401 Unauthorized You need to sync your `gitlab-secrets.json` file with your GitLab 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 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 ``` +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 gRPC tracing can also be enabled in Gitaly itself with the `GODEBUG=http2debug` diff --git a/doc/update/zero_downtime.md b/doc/update/zero_downtime.md index 9ed09e17d01d116a33dae3180fce221f83657161..aebd27f84a9729aaf6701f096fb87112bd7b4362 100644 --- a/doc/update/zero_downtime.md +++ b/doc/update/zero_downtime.md @@ -313,7 +313,7 @@ node throughout the process. - 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. 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: - 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. Rails uses an advisory lock when attempting to run a migration to prevent diff --git a/ee/app/helpers/ee/todos_helper.rb b/ee/app/helpers/ee/todos_helper.rb index d0a0acadb7fd62d25c86509b375f39e219178a2a..0b06a17ca4c6b7c39ca6b8274bd52f6b6c8ce8f6 100644 --- a/ee/app/helpers/ee/todos_helper.rb +++ b/ee/app/helpers/ee/todos_helper.rb @@ -6,7 +6,7 @@ module TodosHelper override :todo_types_options def todo_types_options - super + [{ id: 'Epic', text: 'Epic' }] + super + [{ id: 'Epic', text: s_('Todos|Epic') }] end override :todo_author_display? diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 6e155e9bc7b96282573eccc5ecca2df6154e14c3..a4ac7b42231a7e6c773c34274dbd9a10ea8b22f6 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -1933,6 +1933,9 @@ msgstr "" msgid "Acceptable for use in this project" msgstr "" +msgid "Access Denied" +msgstr "" + msgid "Access Git repositories or the API." msgstr "" @@ -25994,6 +25997,9 @@ msgstr "" msgid "Milestone lists not available with your current license" msgstr "" +msgid "Milestone(s) not found: %{milestones}" +msgstr "" + msgid "MilestoneCombobox|An error occurred while searching for milestones" msgstr "" @@ -33441,6 +33447,9 @@ msgstr[1] "" msgid "Release %{deletedRelease} has been successfully deleted." msgstr "" +msgid "Release already exists" +msgstr "" + msgid "Release assets" msgstr "" @@ -33450,6 +33459,9 @@ msgstr "" msgid "Release date" msgstr "" +msgid "Release does not exist" +msgstr "" + msgid "Release does not have the same project as the milestone" msgstr "" @@ -39576,6 +39588,9 @@ msgstr "" msgid "Tag" msgstr "" +msgid "Tag does not exist" +msgstr "" + msgid "Tag list:" msgstr "" @@ -42222,9 +42237,30 @@ msgstr "" msgid "Todos count" 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." msgstr "" +msgid "Todos|Assigned" +msgstr "" + +msgid "Todos|Design" +msgstr "" + +msgid "Todos|Epic" +msgstr "" + msgid "Todos|Filter by author" msgstr "" @@ -42246,18 +42282,33 @@ msgstr "" msgid "Todos|Isn't an empty To-Do List beautiful?" msgstr "" +msgid "Todos|Issue" +msgstr "" + msgid "Todos|It's how you always know what to work on next." msgstr "" msgid "Todos|Mark all as done" msgstr "" +msgid "Todos|Mentioned" +msgstr "" + +msgid "Todos|Merge request" +msgstr "" + msgid "Todos|Nothing is on your to-do list. Nice work!" msgstr "" msgid "Todos|Nothing left to do. High five!" msgstr "" +msgid "Todos|Pipelines" +msgstr "" + +msgid "Todos|Review requested" +msgstr "" + msgid "Todos|Undo mark all as done" msgstr "" @@ -46020,6 +46071,9 @@ msgstr "" msgid "You are not allowed to approve a user" 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" msgstr "" @@ -48589,6 +48643,9 @@ msgstr "" msgid "pages" msgstr "" +msgid "params is empty" +msgstr "" + msgid "parent" msgid_plural "parents" msgstr[0] "" diff --git a/qa/Gemfile b/qa/Gemfile index 4dd02c7b3d849d6219e48ba0c917b7ab97723d20..61d4b2d5059a8d62b939e12214cb79ab13d8923b 100644 --- a/qa/Gemfile +++ b/qa/Gemfile @@ -4,7 +4,7 @@ source 'https://rubygems.org' gem 'gitlab-qa', '~> 8', require: 'gitlab/qa' 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-screenshot', '~> 1.0.26' 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 'rspec-retry', '~> 0.6.1', require: 'rspec/retry' gem 'rspec_junit_formatter', '~> 0.6.0' -gem 'faker', '~> 2.19', '>= 2.19.0' +gem 'faker', '~> 2.23' gem 'knapsack', '~> 4.0' gem 'parallel_tests', '~> 2.32' gem 'rotp', '~> 6.2.0' diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock index 280d0a72c29ca017bb15132758eef5dd83c82928..837e7e8bdb0bf1f24b7dbc50e37af83aa3baea04 100644 --- a/qa/Gemfile.lock +++ b/qa/Gemfile.lock @@ -15,10 +15,10 @@ GEM rack-test (>= 1.1.0, < 2.0) rest-client (>= 2.0.2, < 3.0) rspec (~> 3.8) - allure-rspec (2.16.1) - allure-ruby-commons (= 2.16.1) + allure-rspec (2.18.0) + allure-ruby-commons (= 2.18.0) rspec-core (>= 3.8, < 4) - allure-ruby-commons (2.16.1) + allure-ruby-commons (2.18.0) mime-types (>= 3.3, < 4) oj (>= 3.10, < 4) require_all (>= 2, < 4) @@ -60,8 +60,8 @@ GEM domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) excon (0.92.4) - faker (2.19.0) - i18n (>= 1.6, < 2) + faker (2.23.0) + i18n (>= 1.8.11, < 2) faraday (2.5.2) faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) @@ -182,7 +182,7 @@ GEM octokit (5.6.1) faraday (>= 1, < 3) sawyer (~> 0.9) - oj (3.13.11) + oj (3.13.21) os (1.1.4) parallel (1.19.2) parallel_tests (2.32.0) @@ -299,14 +299,14 @@ PLATFORMS DEPENDENCIES activesupport (~> 6.1.4.7) airborne (~> 0.3.7) - allure-rspec (~> 2.16.0) + allure-rspec (~> 2.18.0) capybara (~> 3.35.0) capybara-screenshot (~> 1.0.26) chemlab (~> 0.10) chemlab-library-www-gitlab-com (~> 0.1) confiner (~> 0.3) deprecation_toolkit (~> 2.0.0) - faker (~> 2.19, >= 2.19.0) + faker (~> 2.23) faraday-retry (~> 2.0) fog-core (= 2.1.0) fog-google (~> 1.19) @@ -336,4 +336,4 @@ DEPENDENCIES zeitwerk (~> 2.4) BUNDLED WITH - 2.3.23 + 2.3.24 diff --git a/qa/qa/resource/project_imported_from_github.rb b/qa/qa/resource/project_imported_from_github.rb index b9dbd2a6131d08274a80a6a542b87189b6d0d1e4..9ba9723f0cca6d8f27140f3f78768faa23e806d4 100644 --- a/qa/qa/resource/project_imported_from_github.rb +++ b/qa/qa/resource/project_imported_from_github.rb @@ -3,6 +3,8 @@ module QA module Resource class ProjectImportedFromGithub < Resource::Project + attr_accessor :issue_events_import, :full_notes_import, :attachments_import + attribute :github_repo_id do github_client.repository(github_repository_path).id end @@ -51,7 +53,12 @@ def api_post_body new_name: name, target_namespace: @personal_namespace || group.full_path, personal_access_token: github_personal_access_token, - ci_cd_only: false + ci_cd_only: false, + optional_stages: { + single_endpoint_issue_events_import: issue_events_import, + single_endpoint_notes_import: full_notes_import, + attachments_import: attachments_import + } } end diff --git a/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb index 85eb28e901c6f758e26ed992150032da0c009973..c3e41e9298b7015e03d00efbc8e5f44e1cbdbabf 100644 --- a/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb +++ b/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb @@ -21,6 +21,8 @@ module QA project.github_personal_access_token = Runtime::Env.github_access_token project.github_repository_path = 'gitlab-qa-github/import-test' project.api_client = Runtime::API::Client.new(user: user) + project.issue_events_import = true + project.full_notes_import = true end end diff --git a/qa/qa/specs/features/api/1_manage/import/import_large_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import/import_large_github_repo_spec.rb index 9728eee386958ed127f7034e93814584f2fe77f0..5acf15dd2b4a9e21d9bed42d0d9b6c7a319a0e6f 100644 --- a/qa/qa/specs/features/api/1_manage/import/import_large_github_repo_spec.rb +++ b/qa/qa/specs/features/api/1_manage/import/import_large_github_repo_spec.rb @@ -199,13 +199,11 @@ module QA project.github_repository_path = github_repo project.personal_namespace = user.username project.api_client = Runtime::API::Client.new(user: user) + project.issue_events_import = true + project.full_notes_import = true end end - before do - Runtime::Feature.enable(:github_importer_single_endpoint_issue_events_import) - end - after do |example| next unless defined?(@import_time) diff --git a/rubocop/cop_todo.rb b/rubocop/cop_todo.rb index a36afc08673a3378a396e4cf9c2498bbcebce3c5..943f33754617ce5711d5ce0efa672f21d6d03a6e 100644 --- a/rubocop/cop_todo.rb +++ b/rubocop/cop_todo.rb @@ -26,10 +26,14 @@ def autocorrectable? @cop_class&.support_autocorrect? end + def generate? + previously_disabled || grace_period || files.any? + end + def to_yaml yaml = [] yaml << '---' - yaml << '# Cop supports --auto-correct.' if autocorrectable? + yaml << '# Cop supports --autocorrect.' if autocorrectable? yaml << "#{cop_name}:" if previously_disabled @@ -39,8 +43,12 @@ def to_yaml end 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.join("\n") diff --git a/rubocop/formatter/todo_formatter.rb b/rubocop/formatter/todo_formatter.rb index b1c6d1c1688b220e6a43688f80324d1982640e2d..5e49e2dc082411d3815bf6a74c1e096826f250fc 100644 --- a/rubocop/formatter/todo_formatter.rb +++ b/rubocop/formatter/todo_formatter.rb @@ -31,6 +31,7 @@ def initialize(output, _options = {}) @config_inspect_todo_dir = load_config_inspect_todo_dir @config_old_todo_yml = load_config_old_todo_yml check_multiple_configurations! + create_empty_todos(@config_inspect_todo_dir) super end @@ -47,11 +48,9 @@ def file_finished(file, offenses) def finished(_inspected_files) @todos.values.sort_by(&:cop_name).each do |todo| - todo.previously_disabled = previously_disabled?(todo) - todo.grace_period = grace_period?(todo) - validate_todo!(todo) - path = @todo_dir.write(todo.cop_name, todo.to_yaml) + next unless configure_and_validate_todo(todo) + path = @todo_dir.write(todo.cop_name, todo.to_yaml) output.puts "Written to #{relative_path(path)}\n" end end @@ -82,6 +81,14 @@ def check_multiple_configurations! raise "Multiple configurations found for cops:\n#{list}\n" 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) cop_name = todo.cop_name @@ -101,10 +108,15 @@ def grace_period?(todo) GracefulFormatter.grace_period?(todo.cop_name, config) end - def validate_todo!(todo) - return unless todo.previously_disabled && todo.grace_period + def configure_and_validate_todo(todo) + todo.previously_disabled = previously_disabled?(todo) + todo.grace_period = grace_period?(todo) + + if todo.previously_disabled && todo.grace_period + raise "#{todo.cop_name}: Cop must be enabled to use `#{GracefulFormatter.grace_period_key_value}`." + end - raise "#{todo.cop_name}: Cop must be enabled to use `#{GracefulFormatter.grace_period_key_value}`." + todo.generate? end def load_config_inspect_todo_dir diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index a5806910b23f653ead7222dc4625ce7899af06f7..a442856d993704df7cacd69c8c67d3157f4b47cd 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -390,7 +390,10 @@ 'staging' | described_class.tiers[:staging] 'pre-prod' | 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-cny' | described_class.tiers[:production] 'production' | described_class.tiers[:production] diff --git a/spec/rubocop/cop_todo_spec.rb b/spec/rubocop/cop_todo_spec.rb index 3f9c378b3036e2f71c0c8feff604c50287f86a01..c641001789fc29d3a2c2d94371f3e19cfee28fa9 100644 --- a/spec/rubocop/cop_todo_spec.rb +++ b/spec/rubocop/cop_todo_spec.rb @@ -66,6 +66,38 @@ 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 subject(:yaml) { cop_todo.to_yaml } @@ -77,9 +109,8 @@ specify do expect(yaml).to eq(<<~YAML) --- - # Cop supports --auto-correct. + # Cop supports --autocorrect. #{cop_name}: - Exclude: YAML end end diff --git a/spec/rubocop/formatter/todo_formatter_spec.rb b/spec/rubocop/formatter/todo_formatter_spec.rb index edd846324096a6da1d5ded21b591756b7fdafc40..5494d51860572005a48aa2a1a366d598ed056c3d 100644 --- a/spec/rubocop/formatter/todo_formatter_spec.rb +++ b/spec/rubocop/formatter/todo_formatter_spec.rb @@ -82,7 +82,7 @@ def run_formatter expect(todo_yml('B/AutoCorrect')).to eq(<<~YAML) --- - # Cop supports --auto-correct. + # Cop supports --autocorrect. B/AutoCorrect: Exclude: - 'd.rb' @@ -309,18 +309,78 @@ def run_formatter context 'without offenses detected' do before do + todo_dir.write('A/Cop', yaml) if yaml + todo_dir.inspect_all + formatter.started(%w[a.rb b.rb]) formatter.file_finished('a.rb', []) formatter.file_finished('b.rb', []) formatter.finished(%w[a.rb b.rb]) + + todo_dir.delete_inspected end - it 'does not output anything' do - expect(stdout.string).to eq('') + context 'without existing TODOs' do + 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 - it 'does not write any YAML files' do - expect(rubocop_todo_dir_listing).to be_empty + context 'with existing TODOs' do + 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